| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579 |
- import Actions from "./enum/Actions.js"
- import {eventsManager} from "./EventsManager.js"
- import util from "./util.js"
- import Person from "./enum/Person.js"
- import ClickType from "./enum/ClickType.js"
- import Logger from "./Logger.js"
- import MessageHandleType from "./enum/MessageHandleType.js"
- import FrequencyLimitError from "./error/FrequencyLimitError.js"
- import ParamError from "./error/ParamError.js"
- const logger = new Logger('Action')
- const QueueActions = [Actions.Transfer, Actions.ChangeSkin, Actions.GetOnVehicle, Actions.GetOffVehicle];
- export default class ActionsHandler {
- constructor(room) {
- this.currentActiveAction = null
- this.room = room
- }
- // 在_handleAvatar时调用
- async avatarComponentsSync(avatarComponents) {
- this.sendData({
- data: {
- action_type: Actions.SetPlayerState,
- set_player_state_action: {
- player_state: {
- avatar_components: JSON.stringify(avatarComponents)
- }
- }
- }
- })
- }
- async sendData(actionData)
- {
- // console.error("[Action]", Actions[actionData.data.action_type])
- //console.log('发送数据:'+JSON.stringify(actionData))
- await this.beforeSend(actionData);
- const traceId = util.uuid();
- // 向后端发送action_type信息,获取signal和stream
- this.room.networkController.sendRtcData(le(oe({}, actionData.data), {
- trace_id: traceId,
- user_id: this.room.options.userId
- }));
- if (actionData.track === !1) {
- return Promise.resolve(null);
- }
-
- const { sampleRate=1, timeout=2e3, tag, data, special } = actionData;
- return eventsManager.track({
- timeout,
- traceId,
- event: data.action_type,
- tag,
- extra: data
- }, {
- special,
- sampleRate,
- noReport: this.room.viewMode === "serverless" || this.room.options.viewMode === "serverless"
- }).finally(()=>{
- QueueActions.includes(actionData.data.action_type) && (this.currentActiveAction = void 0)
- })
- }
- async beforeSend(e)
- {
- var o;
- const t = (o = this.room._userAvatar) == null ? void 0 : o.isMoving
- , r = e.data.action_type;
- if (QueueActions.includes(r)) {
- if (this.currentActiveAction)
- return logger.error(`${Actions[this.currentActiveAction]} still pending, reject ${Actions[r]}`),
- Promise.reject(new FrequencyLimitError(`${Actions[r]} action request frequency limit`));
- this.currentActiveAction = r
- }
- if (t && QueueActions.includes(e.data.action_type))
- try {
- await this.stopMoving()
- } catch (a) {
- this.currentActiveAction = void 0,
- logger.error("before action stopMoving failed", a)
- }
- }
- // 点击行走至某一点时执行
- async moveTo({point, extra="", motionType})
- {
- return this.sendData({
- data: {
- action_type: Actions.Clicking,
- clicking_action: {
- clicking_point: point,
- clicking_type: ClickType.IgnoreView,
- extra: encodeURIComponent(extra),
- attitude: motionType
- },
- clicking_state: this.room._currentClickingState
- }
- })
- }
- transfer({renderType, player, camera, areaName, attitude, pathName, person:personType, noMedia, timeout, tag, special})
- {
- return this.sendData({
- data: {
- action_type: Actions.Transfer,
- transfer_action: {
- render_type: renderType,
- player,
- camera,
- areaName,
- attitude,
- pathName,
- person: {
- type: personType
- },
- noMedia,
- tiles: [0, 1, 2, 4]
- }
- },
- special,
- timeout: timeout || 4e3,
- tag
- }).then(_ => (
- typeof personType != "undefined" && this.room.updateCurrentNetworkOptions({
- person: personType,
- rotationRenderType: renderType
- }),
- _
- ))
- }
- // 用于Panorama.exit()
- changeRotationRenderType({renderType, player, camera, areaName, attitude, pathName})
- {
- return this.transfer({
- renderType,
- player,
- camera,
- areaName,
- attitude,
- pathName,
- tag: "changeToRotationVideo"
- })
- }
- // 用于请求第一人称视角下的pano数据
- requestPanorama({camera, player, areaName, attitude, pathName, tag}, noMedia, timeout)
- {
- return this.transfer({
- renderType: RenderType.ClientRotationPano,
- player,
- camera,
- person: Person.First,
- areaName,
- attitude,
- pathName,
- noMedia: noMedia,
- timeout: timeout,
- tag: tag || "requestPanorama",
- special: !noMedia
- })
- }
- // 用于XverseAvatar.setMotionType()。方法未执行
- setMotionType(type)
- {
- return this.transfer({
- attitude: type,
- tag: "setMotionType"
- })
- }
- // 设置角色昵称。用于XverseAvatar.setNickname()
- setNickName(nickname)
- {
- return this.sendData({
- data: {
- action_type: Actions.ChangeNickname,
- change_nickname_action: {
- nickname
- }
- }
- })
- }
- // 方法未执行
- getReserveSeat({routeId, name})
- {
- return this.sendData({
- data: {
- action_type: Actions.ReserveSeat,
- reserve_seat_action: {
- route_id: routeId,
- name
- }
- }
- })
- }
- // 方法未执行
- getReserveStatus({routeId, name, need_detail})
- {
- return this.sendData({
- data: {
- action_type: Actions.GetReserveStatus,
- get_reserve_status_action: {
- route_id: routeId,
- name,
- need_detail
- }
- },
- timeout: 2e3
- }).then(o=>o.reserveDetail)
- }
- // 停止移动。在playAnimation时调用
- stopMoving()
- {
- return this.sendData({
- data: {
- action_type: Actions.StopMoving,
- stop_move_action: {}
- }
- })
- }
- // 方法未执行
- getOnVehicle({routeId, name, camera})
- {
- return this.sendData({
- data: {
- action_type: Actions.GetOnVehicle,
- get_on_vehicle_action: {
- route_id: routeId,
- name,
- camera
- }
- }
- })
- }
- // 方法未执行
- getOffVehicle({renderType, player, camera})
- {
- return this.sendData({
- data: {
- action_type: Actions.GetOffVehicle,
- get_off_vehicle_action: {
- render_type: renderType,
- player,
- camera
- }
- }
- })
- }
- // 在_handleAvatar时调用
- confirmEvent(id)
- {
- return this.sendData({
- data: {
- action_type: Actions.ConfirmEvent,
- confirm_event_action: {
- id
- }
- },
- track: !1
- })
- }
- // 心跳
- echo(echoMsg)
- {
- return this.sendData({
- data: {
- action_type: Actions.Echo,
- echo_msg: {
- echoMsg
- }
- },
- track: !1
- })
- }
- // 方法未执行
- async changeSkin(skinData)
- {
- const { skinId, mode, landingType=LandingType.Stay, landingPoint, landingCamera, renderType, areaName, attitude, pathName, person, noMedia, timeout,
- roomTypeId="", special } = skinData
- const newSkin = this.room.skinList.filter(skin => skin.id === skinId)[0];
- if (!newSkin) {
- const y = `skin ${skinId} is invalid`;
- return logger.error(y),
- Promise.reject(new ParamError(y))
- }
- return this.sendData({
- data: {
- action_type: Actions.ChangeSkin,
- change_skin_action: {
- skinID: skinId,
- mode: mode === ChangeMode.Preview ? ChangeMode.Preview : ChangeMode.Confirm,
- skin_data_version: skinId + newSkin.versionId,
- landing_type: landingType,
- landing_point: landingPoint,
- landing_camera: landingCamera,
- render_wrapper: {
- render_type: renderType
- },
- areaName,
- attitude,
- noMedia,
- person,
- pathName,
- roomTypeId
- }
- },
- timeout: timeout || 6e3,
- special: special === void 0 ? renderType === RenderType.ClientRotationPano : special
- })
- .then(async y=>{
- if (renderType === RenderType.ClientRotationPano && y) {
- const route = await this.room.modelManager.findRoute(skinId, pathName)
- , {camera} = util.getRandomItem(route.birthPointList) || {};
- await this.room.panorama.handleReceivePanorama(y, camera)
- }
- return this.handleChangeSkin(skinData)
- })
- .catch(e => noMedia ? this.handleChangeSkin(skinData) : Promise.reject(e))
- }
- handleChangeSkin({skinId, mode, renderType, areaName, attitude, pathName})
- {
- return this.room.sceneManager.staticmeshComponent.getCgMesh().show(),
- this.room.sceneManager.cameraComponent.switchToCgCamera(),
- this.room.engineProxy._updateSkinAssets(skinId).then(()=>{
- this.room.sceneManager.staticmeshComponent.getCgMesh().hide(),
- this.room.sceneManager.cameraComponent.switchToMainCamera(),
- this.room.pathManager.currentArea = areaName,
- logger.info("changeSkin _updateSkinAssets susccss"),
- this.room.updateCurrentNetworkOptions({ pathName, attitude, areaName }),
- this.room.skinChangedHook(),
- this.room.emit("skinChanged", { skin: { id: skinId }, mode }),
- renderType === RenderType.ClientRotationPano && this.room.sceneManager.cameraComponent.allowMainCameraController()
- })
- }
- // 相机旋转
- rotate({pitch, yaw})
- {
- if (
- this.room.disableRotate ||
- this.room.isPano ||
- (this.room._userAvatar && this.room._userAvatar._isChangingComponentsMode)
- ) return;
-
- this.sendData({
- data: {
- action_type: Actions.Rotation,
- rotation_action: {
- vertical_move: pitch,
- horizontal_move: -yaw
- },
- sampleRate: .02
- },
- sampleRate: .02
- })
- }
- // 用于XverseAvatar.turnTo()。方法未执行
- turnTo({point, timeout=2e3, offset=8} = {})
- {
- return this.sendData({
- data: {
- action_type: Actions.TurnTo,
- turn_to_action: {
- turn_to_point: point,
- offset
- }
- },
- timeout
- })
- }
- // 用于XverseAvatar.rotateTo()。方法未执行
- rotateTo({point, offset=0, speed=3} = {})
- {
- return this.sendData({
- data: {
- action_type: Actions.RotateTo,
- rotate_to_action: {
- rotate_to_point: point,
- offset,
- speed
- }
- }
- })
- }
- broadcast({data, msgType=MessageHandleType.MHT_FollowListMulticast, targetUserIds})
- {
- if (msgType === MessageHandleType.MHT_CustomTargetSync && !Array.isArray(targetUserIds))
- return Promise.reject(new ParamError(`param targetUserIds is required when msgType is ${MessageHandleType[msgType]}`));
- let sendData = {
- action_type: Actions.Broadcast,
- broadcast_action: {
- data: JSON.stringify(data),
- user_id: this.room.options.userId,
- msgType
- }
- }
- if (msgType === MessageHandleType.MHT_CustomTargetSync && Array.isArray(targetUserIds)) {
- sendData.broadcast_action.target_user_ids = targetUserIds
- }
- return this.room.actionsHandler.sendData({
- data: sendData,
- tag: data.broadcastType
- })
- }
- // 显示呼吸点。用于Debug.getPointsAndRender()
- getNeighborPoints({point, containSelf=!1, searchRange=500})
- {
- return this.sendData({
- data: {
- action_type: Actions.GetNeighborPoints,
- get_neighbor_points_action: {
- point,
- level: 1,
- containSelf,
- searchRange
- }
- }
- }).then(a=>a.nps)
- }
- // 方法未执行
- playCG(cgName)
- {
- return this.sendData({
- data: {
- action_type: Actions.PlayCG,
- play_cg_action: {
- cg_name: cgName
- }
- }
- })
- }
- // 方法未执行
- audienceToVisitor({avatarId, avatarComponents, player, camera})
- {
- return logger.debug("send data: audience to visitor"),
- this.sendData({
- data: {
- action_type: Actions.AudienceChangeToVisitor,
- audienceChangeToVisitorAction: {
- avatarID: avatarId,
- avatarComponents,
- player,
- camera
- }
- }
- })
- }
- // 方法未执行
- visitorToAudience({renderType, player, camera, areaName, attitude, pathName, person:personType, noMedia})
- {
- return logger.debug("send data: visitor to audience"),
- this.sendData({
- data: {
- action_type: Actions.VisitorChangeToAudience,
- visitorChangeToAudienceAction: {
- transferAction: {
- render_type: renderType,
- player,
- camera,
- areaName,
- attitude,
- pathName,
- person: {
- type: personType
- },
- noMedia,
- tiles: [0, 1, 2, 4]
- }
- }
- }
- })
- }
- // 方法未执行
- removeVisitor({removeType, userIDList, extraInfo=""})
- {
- return logger.debug("send data: remove visitor"),
- this.sendData({
- data: {
- action_type: Actions.RemoveVisitor,
- removeVisitorAction: {
- removeVisitorEvent: removeType,
- userIDList,
- extraInfo: encodeURIComponent(extraInfo)
- }
- }
- })
- }
- // 方法未执行
- getUserWithAvatar(userType, roomID)
- {
- return logger.debug("send data: get user with avatar"),
- this.sendData({
- data: {
- action_type: Actions.GetUserWithAvatar,
- getUserWithAvatarAction: {
- userType,
- roomID
- }
- }
- }).then(n=>n.userWithAvatarList)
- }
- // 每2秒获取一次新数据。在Xverse_Room.afterJoinRoom()中调用
- getNewUserState(userType)
- {
- return this.sendData({
- data: {
- action_type: Actions.GetNewUserState,
- getNewUserStateAction: {
- userType
- }
- },
- sampleRate: 0
- }).then(o => o)
- }
- // 方法未执行
- setSyncPolicy({syncPolicy})
- {
- return this.sendData({
- data: {
- action_type: Actions.SetSyncPolicy,
- setSyncPolicyAction: {
- syncPolicy
- }
- }
- })
- }
- // 拖动手柄
- joystick({degree, level=1})
- {
- const uuid = util.uuid();
- let angle = -degree + 90 + 360;
- angle >= 360 && (angle -= 360);
- return this.sendData({
- data: {
- action_type: Actions.Joystick,
- dir_action: {
- move_angle: angle,
- speed_level: level
- },
- trace_id: uuid,
- user_id: this.room.options.userId,
- packet_id: uuid
- },
- track: !1
- })
- }
- }
|