ActionsHandler.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. import Actions from "./enum/Actions.js"
  2. import {eventsManager} from "./EventsManager.js"
  3. import util from "./util.js"
  4. import Person from "./enum/Person.js"
  5. import ClickType from "./enum/ClickType.js"
  6. import Logger from "./Logger.js"
  7. import { VDecoder } from "./h264Decoder/VDecoder.js";
  8. const logger = new Logger('actions-handler')
  9. const QueueActions = [Actions.Transfer, Actions.ChangeSkin, Actions.GetOnVehicle, Actions.GetOffVehicle];
  10. export default class ActionsHandler {
  11. constructor(e) {
  12. this.currentActiveAction = null
  13. this.room = e
  14. //xst
  15. window.workerReady = false
  16. this.vDecoder = new VDecoder({
  17. maxChip: 100,
  18. });
  19. window.vDecoder = this.vDecoder
  20. this.init()
  21. }
  22. init(){
  23. this.vDecoder.on('ready', () => {
  24. console.log("ready");
  25. window.workerReady = true
  26. })
  27. }
  28. async avatarComponentsSync(e){
  29. const t = {
  30. action_type: Actions.SetPlayerState,
  31. set_player_state_action: {
  32. player_state: {
  33. avatar_components: JSON.stringify(e)
  34. }
  35. }
  36. };
  37. this.sendData({
  38. data: t
  39. })
  40. }
  41. async sendData(e) {
  42. //console.log('发送数据:'+JSON.stringify(e))
  43. await this.beforeSend(e);
  44. const t = util.uuid();
  45. this.room.networkController.sendRtcData(le(oe({}, e.data), {
  46. trace_id: t,
  47. user_id: this.room.options.userId
  48. }));
  49. if (e.track === !1)
  50. {
  51. return Promise.resolve(null);
  52. }
  53. const {sampleRate: r=1, timeout: n=2e3, tag: o, data: a, special: s} = e;
  54. return eventsManager.track({
  55. timeout: n,
  56. traceId: t,
  57. event: a.action_type,
  58. tag: o,
  59. extra: a
  60. }, {
  61. special: s,
  62. sampleRate: r,
  63. noReport: this.room.viewMode === "serverless" || this.room.options.viewMode === "serverless"
  64. }).finally(()=>{
  65. QueueActions.includes(e.data.action_type) && (this.currentActiveAction = void 0)
  66. }
  67. )
  68. }
  69. //async sendData(e) {
  70. //console.log('发送数据:'+JSON.stringify(e))
  71. //旋转
  72. //window.room.sceneManager.scene.activeCamera.rotation.y
  73. //心跳:要去掉
  74. //邻居点:要去掉
  75. //漫游
  76. //人物所在位置和角度,相机的位置和角度,相机的目标点,点击的坐标
  77. //}
  78. async beforeSend(e) {
  79. var o;
  80. const t = (o = this.room._userAvatar) == null ? void 0 : o.isMoving
  81. , r = e.data.action_type;
  82. if (QueueActions.includes(r)) {
  83. if (this.currentActiveAction)
  84. return logger.error(`${Actions[this.currentActiveAction]} still pending, reject ${Actions[r]}`),
  85. Promise.reject(new FrequencyLimitError(`${Actions[r]} action request frequency limit`));
  86. this.currentActiveAction = r
  87. }
  88. if (t && QueueActions.includes(e.data.action_type))
  89. try {
  90. await this.stopMoving()
  91. } catch (a) {
  92. this.currentActiveAction = void 0,
  93. logger.error("before action stopMoving failed", a)
  94. }
  95. }
  96. async moveTo(e) {
  97. const {point: t, extra: r="", motionType: n} = e
  98. , o = {
  99. action_type: Actions.Clicking,
  100. clicking_action: {
  101. clicking_point: t,
  102. clicking_type: ClickType.IgnoreView,
  103. extra: encodeURIComponent(r),
  104. attitude: n
  105. },
  106. clicking_state: this.room._currentClickingState
  107. };
  108. return this.sendData({
  109. data: o
  110. })
  111. }
  112. transfer(e) {
  113. const {renderType: t, player: r, camera: n, areaName: o, attitude: a, pathName: s, person: l, noMedia: u, timeout: c, tag: h, special: f} = e
  114. , d = {
  115. data: {
  116. action_type: Actions.Transfer,
  117. transfer_action: {
  118. render_type: t,
  119. player: r,
  120. camera: n,
  121. areaName: o,
  122. attitude: a,
  123. pathName: s,
  124. person: {
  125. type: l
  126. },
  127. noMedia: u,
  128. tiles: [0, 1, 2, 4]
  129. }
  130. },
  131. special: f,
  132. timeout: c || 4e3,
  133. tag: h
  134. };
  135. return this.sendData(d).then(_=>(typeof l != "undefined" && this.room.updateCurrentNetworkOptions({
  136. person: l,
  137. rotationRenderType: t
  138. }),
  139. _))
  140. }
  141. changeRotationRenderType(e) {
  142. const {renderType: t, player: r, camera: n, areaName: o, attitude: a, pathName: s} = e;
  143. return this.transfer({
  144. renderType: t,
  145. player: r,
  146. camera: n,
  147. areaName: o,
  148. attitude: a,
  149. pathName: s,
  150. tag: "changeToRotationVideo"
  151. })
  152. }
  153. requestPanorama(e, noMedia, timeout) {
  154. const {camera: camera, player: player, areaName: areaName, attitude: attitude, pathName: pathName, tag: tag} = e;
  155. return this.transfer({
  156. renderType: RenderType.ClientRotationPano,
  157. player: player,
  158. camera: camera,
  159. person: Person.First,
  160. areaName: areaName,
  161. attitude: attitude,
  162. pathName: pathName,
  163. noMedia: noMedia,
  164. timeout: timeout,
  165. tag: tag || "requestPanorama",
  166. special: !noMedia
  167. })
  168. }
  169. setMotionType(e) {
  170. return this.transfer({
  171. attitude: e,
  172. tag: "setMotionType"
  173. })
  174. }
  175. setNickName(e) {
  176. const t = {
  177. action_type: Actions.ChangeNickname,
  178. change_nickname_action: {
  179. nickname: e
  180. }
  181. };
  182. return this.sendData({
  183. data: t
  184. })
  185. }
  186. getReserveSeat({routeId: e, name: t}) {
  187. const r = {
  188. action_type: Actions.ReserveSeat,
  189. reserve_seat_action: {
  190. route_id: e,
  191. name: t
  192. }
  193. };
  194. return this.sendData({
  195. data: r
  196. })
  197. }
  198. getReserveStatus({routeId: e, name: t, need_detail: r}) {
  199. const n = {
  200. action_type: Actions.GetReserveStatus,
  201. get_reserve_status_action: {
  202. route_id: e,
  203. name: t,
  204. need_detail: r
  205. }
  206. };
  207. return this.sendData({
  208. data: n,
  209. timeout: 2e3
  210. }).then(o=>o.reserveDetail)
  211. }
  212. stopMoving() {
  213. const e = {
  214. action_type: Actions.StopMoving,
  215. stop_move_action: {}
  216. };
  217. return this.sendData({
  218. data: e
  219. })
  220. }
  221. getOnVehicle({routeId: e, name: t, camera: r}) {
  222. const n = {
  223. action_type: Actions.GetOnVehicle,
  224. get_on_vehicle_action: {
  225. route_id: e,
  226. name: t,
  227. camera: r
  228. }
  229. };
  230. return this.sendData({
  231. data: n
  232. })
  233. }
  234. getOffVehicle({renderType: e, player: t, camera: r}) {
  235. const n = {
  236. action_type: Actions.GetOffVehicle,
  237. get_off_vehicle_action: {
  238. render_type: e,
  239. player: t,
  240. camera: r
  241. }
  242. };
  243. return this.sendData({
  244. data: n
  245. })
  246. }
  247. confirmEvent(e) {
  248. const t = {
  249. action_type: Actions.ConfirmEvent,
  250. confirm_event_action: {
  251. id: e
  252. }
  253. };
  254. return this.sendData({
  255. data: t,
  256. track: !1
  257. })
  258. }
  259. echo(e) {
  260. const t = {
  261. action_type: Actions.Echo,
  262. echo_msg: {
  263. echoMsg: e
  264. }
  265. };
  266. return this.sendData({
  267. data: t,
  268. track: !1
  269. })
  270. }
  271. async changeSkin(e) {
  272. const t = e.special === void 0 ? e.renderType === RenderType.ClientRotationPano : e.special
  273. , {skinId: r, mode: n, landingType: o=LandingType.Stay, landingPoint: a, landingCamera: s, renderType: l, areaName: u, attitude: c, pathName: h, person: f, noMedia: d, timeout: _, roomTypeId: g=""} = e
  274. , m = this.room.skinList.filter(y=>y.id === r)[0];
  275. if (!m) {
  276. const y = `skin ${r} is invalid`;
  277. return logger.error(y),
  278. Promise.reject(new ParamError(y))
  279. }
  280. const v = {
  281. action_type: Actions.ChangeSkin,
  282. change_skin_action: {
  283. skinID: r,
  284. mode: n === ChangeMode.Preview ? ChangeMode.Preview : ChangeMode.Confirm,
  285. skin_data_version: r + m.versionId,
  286. landing_type: o,
  287. landing_point: a,
  288. landing_camera: s,
  289. render_wrapper: {
  290. render_type: l
  291. },
  292. areaName: u,
  293. attitude: c,
  294. noMedia: d,
  295. person: f,
  296. pathName: h,
  297. roomTypeId: g
  298. }
  299. };
  300. return this.sendData({
  301. data: v,
  302. timeout: _ || 6e3,
  303. special: t
  304. }).then(async y=>{
  305. if (l === RenderType.ClientRotationPano && y) {
  306. const b = await this.room.modelManager.findRoute(r, h)
  307. , {camera: T} = util.getRandomItem(b.birthPointList) || {};
  308. await this.room.panorama.handleReceivePanorama(y, T)
  309. }
  310. return this.handleChangeSkin(e)
  311. }
  312. ).catch(y=>d ? this.handleChangeSkin(e) : Promise.reject(y))
  313. }
  314. handleChangeSkin(e) {
  315. const {skinId: t, mode: r, renderType: n, areaName: o, attitude: a, pathName: s} = e;
  316. return this.room.sceneManager.staticmeshComponent.getCgMesh().show(),
  317. this.room.sceneManager.cameraComponent.switchToCgCamera(),
  318. this.room.engineProxy._updateSkinAssets(t).then(()=>{
  319. this.room.sceneManager.staticmeshComponent.getCgMesh().hide(),
  320. this.room.sceneManager.cameraComponent.switchToMainCamera(),
  321. this.room.pathManager.currentArea = o,
  322. logger.info("changeSkin _updateSkinAssets susccss"),
  323. this.room.updateCurrentNetworkOptions({
  324. pathName: s,
  325. attitude: a,
  326. areaName: o
  327. }),
  328. this.room.skinChangedHook(),
  329. this.room.emit("skinChanged", {
  330. skin: {
  331. id: t
  332. },
  333. mode: r
  334. }),
  335. n === RenderType.ClientRotationPano && this.room.sceneManager.cameraComponent.allowMainCameraController()
  336. }
  337. )
  338. }
  339. /***********************************************************************xst****************************************************************/
  340. /*
  341. rotate({pitch: e, yaw: t}) {
  342. var n;
  343. if (this.room.disableRotate || this.room.isPano || ((n = this.room._userAvatar) == null ? void 0 : n._isChangingComponentsMode))
  344. return;
  345. const r = {
  346. action_type: Actions.Rotation,
  347. rotation_action: {
  348. vertical_move: e,
  349. horizontal_move: -t
  350. }
  351. };
  352. //console.log('发送数据rotate:'+JSON.stringify(r.rotation_action))
  353. this.sendData({
  354. data: r,
  355. sampleRate: .02
  356. })
  357. }
  358. */
  359. //zeg
  360. rotate({type: type, offsetX: offsetX, width: width}) {
  361. //camera的position,angle
  362. //起始和结束的帧
  363. let angle = offsetX / width * 2 * Math.PI
  364. let endRotation = util.xverseRotation2Ue4(window.room.sceneManager.cameraComponent.mainCamera.rotation).yaw
  365. endRotation = (endRotation % 360 + 360) % 360
  366. let sfns = Math.round(endRotation/6)
  367. endRotation += angle/Math.PI*180
  368. let efns = Math.round(endRotation/6)
  369. console.log('取帧:'+sfns+','+efns);
  370. this.fetchData({
  371. type:type,
  372. sFrame:sfns,
  373. eFrame:efns
  374. })
  375. this.room.sceneManager.materialComponent.initreceveFrames()
  376. let cameraPostion0 = util.xversePosition2Ue4(window.room.sceneManager.cameraComponent.mainCamera.position.clone())
  377. let playerPosition = window.room.sceneManager.avatarComponent._mainUser.position
  378. let rotationQuaternion = BABYLON.Quaternion.RotationAxis( new BABYLON.Vector3(0, 0, 1), angle )
  379. let cameraPos = new BABYLON.Vector3( cameraPostion0.x, cameraPostion0.y, cameraPostion0.z )
  380. let cameraCenter = new BABYLON.Vector3( playerPosition.x, playerPosition.y, playerPosition.z )
  381. // console.error(cameraPos, cameraCenter)
  382. cameraPos.rotateByQuaternionAroundPointToRef(rotationQuaternion, cameraCenter, cameraPos)
  383. let cameraState = {
  384. "position": {
  385. "x": cameraPos.x,
  386. "y": cameraPos.y,
  387. "z": cameraPos.z
  388. },
  389. "angle": {
  390. "pitch": 0,
  391. "yaw": endRotation,
  392. "roll": 0
  393. }
  394. }
  395. window.room.sceneManager.cameraComponent.mainCamera.rotation.y += angle
  396. window.room.sceneManager.cameraComponent.setCameraPose(cameraState)
  397. }
  398. /*
  399. rotate0({type: type, angle: angle}) {
  400. let endRotation = window.room.sceneManager.cameraComponent.mainCamera.rotation.y
  401. if(endRotation<0){
  402. endRotation += 2*Math.PI
  403. }
  404. else if(endRotation>2*Math.PI){
  405. endRotation -= 2*Math.PI
  406. }
  407. let sfns = Math.round(endRotation/Math.PI * 180 /6)
  408. //每6°一帧
  409. for(let i=0;i<60;++i){
  410. if(Math.abs(Math.abs(angle) - i/60 * 2 * Math.PI)<0.01){
  411. //找到了
  412. endRotation += angle
  413. break;
  414. }
  415. }
  416. let efns = Math.round(endRotation/Math.PI * 180 /6)
  417. console.log('取帧:'+sfns+','+efns);
  418. this.fetchData({
  419. type:type,
  420. sFrame:sfns,
  421. eFrame:efns
  422. })
  423. this.room.sceneManager.materialComponent.initreceveFrames()
  424. this.room.sceneManager.cameraComponent.mainCamera.rotation.y = endRotation
  425. window.room.sceneManager.cameraComponent._cameraPose.rotation._y = endRotation
  426. window.room.sceneManager.cameraComponent.mainCamera.rotation.y=endRotation
  427. }
  428. */
  429. fetchData({sFrame: sfns, eFrame: efns}){
  430. if(window.workerReady){
  431. this.vDecoder.fetch({
  432. path: "https://laser-data.oss-cn-shenzhen.aliyuncs.com/test-video/earth",
  433. range: [sfns, efns],
  434. });
  435. }
  436. else{
  437. console.error('还没准备好')
  438. }
  439. }
  440. /*******************************************************************************************************************************************/
  441. turnTo(e) {
  442. const {point: t, timeout: r=2e3, offset: n=8} = e || {}
  443. , o = {
  444. action_type: Actions.TurnTo,
  445. turn_to_action: {
  446. turn_to_point: t,
  447. offset: n
  448. }
  449. };
  450. return this.sendData({
  451. data: o,
  452. timeout: r
  453. })
  454. }
  455. rotateTo(e) {
  456. const {point: t, offset: r=0, speed: n=3} = e || {}
  457. , o = {
  458. action_type: Actions.RotateTo,
  459. rotate_to_action: {
  460. rotate_to_point: t,
  461. offset: r,
  462. speed: n
  463. }
  464. };
  465. console.log('发送数据rotateTo:'+JSON.stringify(o.rotate_to_action))
  466. return this.sendData({
  467. data: o
  468. })
  469. }
  470. broadcast(e) {
  471. const {data: t, msgType: r=MessageHandleType.MHT_FollowListMulticast, targetUserIds: n} = e;
  472. if (r === MessageHandleType.MHT_CustomTargetSync && !Array.isArray(n))
  473. return Promise.reject(new ParamError(`param targetUserIds is required when msgType is ${MessageHandleType[r]}`));
  474. const o = {
  475. action_type: Actions.Broadcast,
  476. broadcast_action: {
  477. data: JSON.stringify(t),
  478. user_id: this.room.options.userId,
  479. msgType: r
  480. }
  481. };
  482. return Array.isArray(n) && r === MessageHandleType.MHT_CustomTargetSync && (o.broadcast_action.target_user_ids = n),
  483. this.room.actionsHandler.sendData({
  484. data: o,
  485. tag: t.broadcastType
  486. })
  487. }
  488. getNeighborPoints(e) {
  489. const {point: t, containSelf: r=!1, searchRange: n=500} = e
  490. , o = {
  491. action_type: Actions.GetNeighborPoints,
  492. get_neighbor_points_action: {
  493. point: t,
  494. level: 1,
  495. containSelf: r,
  496. searchRange: n
  497. }
  498. };
  499. return this.sendData({
  500. data: o
  501. }).then(a=>a.nps)
  502. }
  503. playCG(e) {
  504. const t = {
  505. action_type: Actions.PlayCG,
  506. play_cg_action: {
  507. cg_name: e
  508. }
  509. };
  510. return this.sendData({
  511. data: t
  512. })
  513. }
  514. audienceToVisitor(e) {
  515. const {avatarId: t, avatarComponents: r, player: n, camera: o} = e
  516. , a = {
  517. action_type: Actions.AudienceChangeToVisitor,
  518. audienceChangeToVisitorAction: {
  519. avatarID: t,
  520. avatarComponents: r,
  521. player: n,
  522. camera: o
  523. }
  524. };
  525. return logger.debug("send data: audience to visitor"),
  526. this.sendData({
  527. data: a
  528. })
  529. }
  530. visitorToAudience(e) {
  531. const {renderType: t, player: r, camera: n, areaName: o, attitude: a, pathName: s, person: l, noMedia: u} = e
  532. , c = {
  533. action_type: Actions.VisitorChangeToAudience,
  534. visitorChangeToAudienceAction: {
  535. transferAction: {
  536. render_type: t,
  537. player: r,
  538. camera: n,
  539. areaName: o,
  540. attitude: a,
  541. pathName: s,
  542. person: {
  543. type: l
  544. },
  545. noMedia: u,
  546. tiles: [0, 1, 2, 4]
  547. }
  548. }
  549. };
  550. return logger.debug("send data: visitor to audience"),
  551. this.sendData({
  552. data: c
  553. })
  554. }
  555. removeVisitor(e) {
  556. const {removeType: t, userIDList: r, extraInfo: n=""} = e
  557. , o = {
  558. action_type: Actions.RemoveVisitor,
  559. removeVisitorAction: {
  560. removeVisitorEvent: t,
  561. userIDList: r,
  562. extraInfo: encodeURIComponent(n)
  563. }
  564. };
  565. return logger.debug("send data: remove visitor"),
  566. this.sendData({
  567. data: o
  568. })
  569. }
  570. getUserWithAvatar(e, t) {
  571. const r = {
  572. action_type: Actions.GetUserWithAvatar,
  573. getUserWithAvatarAction: {
  574. userType: e,
  575. roomID: t
  576. }
  577. };
  578. return logger.debug("send data: get user with avatar"),
  579. this.sendData({
  580. data: r
  581. }).then(n=>n.userWithAvatarList)
  582. }
  583. joystick(e) {
  584. const {degree: t, level: r=1} = e
  585. , n = util.uuid();
  586. let o = -t + 90 + 360;
  587. o >= 360 && (o -= 360);
  588. const a = {
  589. action_type: Actions.Joystick,
  590. dir_action: {
  591. move_angle: o,
  592. speed_level: r
  593. },
  594. trace_id: n,
  595. user_id: this.room.options.userId,
  596. packet_id: n
  597. };
  598. return this.sendData({
  599. data: a,
  600. track: !1
  601. })
  602. }
  603. }