XverseRoom.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. class XverseRoom extends XverseRoom$1 {
  2. constructor() {
  3. super(...arguments);
  4. E(this, "joyStick", new JoyStick(this))
  5. }
  6. afterJoinRoomHook() {
  7. this.joyStick.init({})
  8. }
  9. }
  10. const log$3 = new Logger("xverse-room");
  11. class XverseRoom$1 extends EventEmitter {
  12. constructor(e) {
  13. super();
  14. E(this, "disableAutoTurn", !1);
  15. E(this, "options");
  16. E(this, "_currentNetworkOptions");
  17. E(this, "lastSkinId");
  18. E(this, "debug");
  19. E(this, "isFirstDataUsed", !1);
  20. E(this, "userId", null);
  21. E(this, "pathManager", new PathManager);
  22. E(this, "networkController");
  23. E(this, "_startTime", Date.now());
  24. E(this, "canvas");
  25. E(this, "modelManager");
  26. E(this, "eventsController");
  27. E(this, "panorama");
  28. E(this, "engineProxy");
  29. E(this, "_id");
  30. E(this, "skinList", []);
  31. E(this, "isHost", !1);
  32. E(this, "avatarManager", new XverseAvatarManager(this));
  33. E(this, "effectManager", new XverseEffectManager(this));
  34. E(this, "sceneManager");
  35. E(this, "scene");
  36. E(this, "breathPointManager");
  37. E(this, "_currentState");
  38. E(this, "joined", !1);
  39. E(this, "disableRotate", !1);
  40. E(this, "isPano", !1);
  41. E(this, "movingByClick", !0);
  42. E(this, "camera", new Camera(this));
  43. E(this, "stats", new Stats(this));
  44. E(this, "isUpdatedRawYUVData", !1);
  45. E(this, "actionsHandler", new ActionsHandler(this));
  46. E(this, "_currentClickingState", null);
  47. E(this, "signal", new Signal(this));
  48. E(this, "firstFrameTimestamp");
  49. E(this, "receiveRtcData", async()=>{
  50. log$3.info("Invoke receiveRtcData");
  51. let e = !1
  52. , t = !1
  53. , r = !1
  54. , n = !1;
  55. return this.viewMode === "serverless" ? (log$3.warn("set view mode to serverless"),
  56. this.setViewMode("observer").then(()=>this, ()=>this)) : new Promise(o=>{
  57. const a = this.networkController.rtcp.workers;
  58. a.registerFunction("signal", s=>{
  59. this.signal.handleSignal(s)
  60. }
  61. ),
  62. a.registerFunction("stream", s=>{
  63. var l;
  64. if (this.emit("streamTimestamp", {
  65. timestamp: Date.now()
  66. }),
  67. t || (t = !0,
  68. log$3.info("Invoke stream event")),
  69. s.stream) {
  70. r || (r = !0,
  71. log$3.info("Invoke updateRawYUVData")),
  72. this.isUpdatedRawYUVData = !1;
  73. const u = (l = this._currentState.skin) == null ? void 0 : l.fov;
  74. this.sceneManager.materialComponent.updateRawYUVData(s.stream, s.width, s.height, u),
  75. this.isUpdatedRawYUVData = !0
  76. }
  77. e || (log$3.info("Invoke isAfterRenderRegistered"),
  78. e = !0,
  79. this.scene.registerAfterRender(()=>{
  80. this.engineProxy.frameRenderNumber >= 2 && (n || (n = !0,
  81. log$3.info("Invoke registerAfterRender")),
  82. this.isFirstDataUsed || (log$3.info("Invoke isStreamAvailable"),
  83. this.isFirstDataUsed = !0,
  84. this.firstFrameTimestamp = Date.now(),
  85. o(this),
  86. this.afterJoinRoom()))
  87. }
  88. ))
  89. }
  90. ),
  91. this.panorama.bindListener(()=>{
  92. o(this),
  93. this.afterJoinRoom()
  94. }
  95. ),
  96. a.registerFunction("reconnectedFrame", ()=>{}
  97. ),
  98. log$3.info("Invoke decoderWorker.postMessage"),
  99. a.decoderWorker.postMessage({
  100. t: 5
  101. })
  102. }
  103. )
  104. }
  105. );
  106. E(this, "moveToExtra", "");
  107. this.options = e,
  108. this.options.wsServerUrl || (this.options.wsServerUrl = SERVER_URLS.DEV),
  109. this.modelManager = ModelManager.getInstance(e.appId, e.releaseId),
  110. this.updateReporter();
  111. const n = e
  112. , {canvas: t} = n
  113. , r = Oe(n, ["canvas"]);
  114. log$3.infoAndReportMeasurement({
  115. metric: "startJoinRoomAt",
  116. startTime: Date.now(),
  117. group: "joinRoom",
  118. extra: r,
  119. value: 0
  120. })
  121. }
  122. get currentNetworkOptions() {
  123. return this._currentNetworkOptions
  124. }
  125. get viewMode() {
  126. var e;
  127. return ((e = this._currentState) == null ? void 0 : e.viewMode) || "full"
  128. }
  129. get id() {
  130. return this._id
  131. }
  132. get skinId() {
  133. return this._currentState.skinId
  134. }
  135. get skin() {
  136. return this._currentState.skin
  137. }
  138. get sessionId() {
  139. return this.currentNetworkOptions.sessionId
  140. }
  141. get pictureQualityLevel() {
  142. return this.currentState.pictureQualityLevel
  143. }
  144. get avatars() {
  145. return Array.from(this.avatarManager.avatars.values())
  146. }
  147. get currentState() {
  148. var e;
  149. return le(oe({}, this._currentState), {
  150. state: (e = this.networkController) == null ? void 0 : e._state
  151. })
  152. }
  153. get _userAvatar() {
  154. return this.avatars.find(e=>e.userId === this.userId)
  155. }
  156. get tvs() {
  157. return this.engineProxy._tvs
  158. }
  159. get tv() {
  160. return this.tvs[0]
  161. }
  162. get currentClickingState() {
  163. return this._currentClickingState
  164. }
  165. afterJoinRoomHook() {}
  166. beforeJoinRoomResolveHook() {}
  167. afterReconnectedHook() {}
  168. handleSignalHook(e) {}
  169. skinChangedHook() {}
  170. async beforeStartGameHook(e) {}
  171. loadAssetsHook() {}
  172. afterUserAvatarLoadedHook() {}
  173. audienceViewModeHook() {}
  174. setViewModeToObserver() {}
  175. handleVehicleHook(e) {}
  176. updateReporter() {
  177. const {avatarId: e, skinId: t, userId: r, roomId: n, role: o, appId: a, wsServerUrl: s} = this.options;
  178. reporter.updateHeader({
  179. userId: r
  180. }),
  181. reporter.updateBody({
  182. roomId: n,
  183. role: o,
  184. skinId: t,
  185. avatarId: e,
  186. appId: a,
  187. wsServerUrl: s
  188. })
  189. }
  190. async initRoom() {
  191. const {timeout: e=DEFAULT_JOINROOM_TIMEOUT} = this.options;
  192. return isSupported() ? this._initRoom()._timeout(e, new TimeoutError("initRoom timeout")) : Promise.reject(new UnsupportedError)
  193. }
  194. async _initRoom() {
  195. const e = this.validateOptions(this.options);
  196. if (e)
  197. return log$3.error("initRoom param error", e),
  198. Promise.reject(e);
  199. const {canvas: t, avatarId: r, skinId: n, userId: o, wsServerUrl: a, role: s, token: l, pageSession: u, rotationRenderType: c, isAllSync: h=!1, appId: f, camera: d, player: _, avatarComponents: g, nickname: m, avatarScale: v, firends: y=[], syncByEvent: b=!1, areaName: T, attitude: C=MotionType.Walk, pathName: A, viewMode: S="full", person: P, roomId: R, roomTypeId: M, hasAvatar: x=!1, syncToOthers: I=!1, prioritySync: w=!1, removeWhenDisconnected: O=!0, extra: D} = this.options;
  200. this.setCurrentNetworkOptions({
  201. avatarId: r,
  202. skinId: n,
  203. roomId: R,
  204. userId: o,
  205. wsServerUrl: a,
  206. role: s,
  207. token: l,
  208. pageSession: u,
  209. rotationRenderType: c,
  210. isAllSync: h,
  211. appId: f,
  212. camera: d,
  213. player: _,
  214. avatarComponents: g,
  215. nickname: m,
  216. avatarScale: v,
  217. firends: y,
  218. syncByEvent: b,
  219. areaName: T,
  220. attitude: C,
  221. pathName: A,
  222. person: P,
  223. roomTypeId: M,
  224. hasAvatar: x,
  225. syncToOthers: I,
  226. prioritySync: w,
  227. extra: D,
  228. removeWhenDisconnected: O
  229. }),
  230. this.userId = o,
  231. this.canvas = t,
  232. T && (this.pathManager.currentArea = T),
  233. this.networkController = new NetworkController(this),
  234. this.setCurrentState({
  235. areaName: T,
  236. pathName: A,
  237. attitude: C,
  238. speed: 0,
  239. viewMode: S,
  240. state: this.networkController._state,
  241. skinId: n
  242. });
  243. try {
  244. await Promise.all([this.initNetwork(), this.initConfig(), this.initWasm()]),
  245. log$3.info("network config wasm all ready, start to create game");
  246. const F = await this.requestCreateRoom({
  247. skinId: n
  248. })
  249. , V = F.routeList.find(L=>L.areaName === T)
  250. , N = ((V == null ? void 0 : V.step) || 7.5) * 30;
  251. this.updateCurrentState({
  252. skin: F,
  253. skinId: F.id,
  254. versionId: F.versionId,
  255. speed: N
  256. }),
  257. await this.initEngine(F)
  258. } catch (F) {
  259. return Promise.reject(F)
  260. }
  261. return this.beforeJoinRoomResolve(),
  262. this.receiveRtcData()
  263. }
  264. beforeJoinRoomResolve() {
  265. this.setupStats(),
  266. this.eventsController = new EventsController(this),
  267. this.eventsController.bindEvents(),
  268. this.panorama = new Panorama(this),
  269. this.beforeJoinRoomResolveHook()
  270. }
  271. afterJoinRoom() {
  272. this.joined = !0,
  273. this.viewMode === "observer" && this.setViewModeToObserver(),
  274. log$3.infoAndReportMeasurement({
  275. tag: this.viewMode,
  276. value: this.firstFrameTimestamp - this._startTime,
  277. startTime: Date.now(),
  278. metric: "joinRoom"
  279. }),
  280. this.camera.initialFov = this.sceneManager.cameraComponent.getCameraFov(),
  281. this.stats.on("stats", ({stats: e})=>{
  282. reporter.report("stats", oe({}, e))
  283. }
  284. ),
  285. this.debug = new Debug(this),
  286. this.afterJoinRoomHook()
  287. }
  288. afterReconnected() {
  289. this.avatarManager.clearOtherUsers(),
  290. this.afterReconnectedHook()
  291. }
  292. leave() {
  293. var e, t;
  294. return log$3.info("Invoke room.leave"),
  295. (e = this.eventsController) == null || e.clearEvents(),
  296. (t = this.networkController) == null || t.quit(),
  297. this
  298. }
  299. validateOptions(e) {
  300. const {canvas: t, avatarId: r, skinId: n, userId: o, role: a, roomId: s, token: l, appId: u, avatarComponents: c} = e || {}
  301. , h = [];
  302. return t instanceof HTMLCanvasElement || h.push(new ParamError("`canvas` must be instanceof of HTMLCanvasElement")),
  303. (!o || typeof o != "string") && h.push(new ParamError("`userId` must be string")),
  304. (!l || typeof l != "string") && h.push(new ParamError("`token` must be string")),
  305. (!u || typeof u != "string") && h.push(new ParamError("`appId` must be string")),
  306. a == "audience" || (!r || !n) && h.push(new ParamError("`avatarId` and `skinId` is required when create room")),
  307. h[0]
  308. }
  309. async initNetwork() {
  310. if (this.viewMode === "serverless")
  311. return Promise.resolve();
  312. const e = Date.now();
  313. try {
  314. await this.networkController.connect()._timeout(8e3, new InitNetworkTimeoutError),
  315. log$3.infoAndReportMeasurement({
  316. metric: "networkInitAt",
  317. startTime: this._startTime,
  318. group: "joinRoom"
  319. }),
  320. log$3.infoAndReportMeasurement({
  321. metric: "networkInitCost",
  322. startTime: e,
  323. group: "joinRoom"
  324. })
  325. } catch (t) {
  326. throw log$3.infoAndReportMeasurement({
  327. metric: "networkInitAt",
  328. startTime: e,
  329. group: "joinRoom",
  330. error: t
  331. }),
  332. t
  333. }
  334. }
  335. async initConfig() {
  336. const e = Date.now();
  337. try {
  338. await this.modelManager.getApplicationConfig()._timeout(8e3, new InitConfigTimeoutError),
  339. log$3.infoAndReportMeasurement({
  340. metric: "configInitAt",
  341. startTime: this._startTime,
  342. group: "joinRoom"
  343. }),
  344. log$3.infoAndReportMeasurement({
  345. metric: "configInitCost",
  346. startTime: e,
  347. group: "joinRoom"
  348. })
  349. } catch (t) {
  350. throw log$3.infoAndReportMeasurement({
  351. metric: "configInitAt",
  352. startTime: e,
  353. group: "joinRoom",
  354. error: t
  355. }),
  356. t
  357. }
  358. }
  359. async initEngine(e) {
  360. const t = Date.now();
  361. try {
  362. this.engineProxy = new EngineProxy(this),
  363. await this.engineProxy.initEngine(e),
  364. log$3.infoAndReportMeasurement({
  365. metric: "webglInitAt",
  366. startTime: this._startTime,
  367. group: "joinRoom"
  368. }),
  369. log$3.infoAndReportMeasurement({
  370. metric: "webglInitCost",
  371. startTime: t,
  372. group: "joinRoom"
  373. });
  374. return
  375. } catch (r) {
  376. let n = r;
  377. return r.code !== Codes$1.InitEngineTimeout && (n = new InitEngineError),
  378. log$3.error(r),
  379. log$3.infoAndReportMeasurement({
  380. metric: "webglInitAt",
  381. startTime: t,
  382. group: "joinRoom",
  383. error: n
  384. }),
  385. Promise.reject(n)
  386. }
  387. }
  388. async initWasm() {
  389. if (this.viewMode === "serverless")
  390. return Promise.resolve();
  391. const e = Date.now();
  392. try {
  393. await this.networkController.rtcp.workers.init(this.options.resolution)._timeout(8e3, new InitDecoderTimeoutError),
  394. this.networkController.rtcp.workers.registerFunction("error", t=>{
  395. log$3.error("decode error", t);
  396. const {code: r, message: n} = t;
  397. this.emit("error", {
  398. code: r,
  399. msg: n
  400. })
  401. }
  402. ),
  403. log$3.infoAndReportMeasurement({
  404. metric: "wasmInitAt",
  405. group: "joinRoom",
  406. startTime: this._startTime
  407. }),
  408. log$3.infoAndReportMeasurement({
  409. metric: "wasmInitCost",
  410. group: "joinRoom",
  411. startTime: e
  412. }),
  413. eventsManager.on("traceId", t=>{
  414. this.networkController.rtcp.workers.onTraceId(t)
  415. }
  416. )
  417. } catch (t) {
  418. throw log$3.infoAndReportMeasurement({
  419. metric: "wasmInitAt",
  420. group: "joinRoom",
  421. startTime: e,
  422. error: t
  423. }),
  424. t
  425. }
  426. }
  427. async requestCreateRoom({skinId: e}) {
  428. let t;
  429. if (e) {
  430. t = await this.getSkin(e);
  431. const r = await this.modelManager.findRoute(e, this.options.pathName);
  432. this.updateCurrentNetworkOptions({
  433. areaName: r.areaName,
  434. attitude: r.attitude,
  435. versionId: t.versionId
  436. });
  437. const {camera: n, player: o} = getRandomItem(r.birthPointList) || this.options;
  438. this.options.camera || this.updateCurrentNetworkOptions({
  439. camera: n
  440. }),
  441. this.options.player || this.updateCurrentNetworkOptions({
  442. player: o
  443. })
  444. }
  445. if (this.viewMode === "serverless")
  446. return t;
  447. try {
  448. await this.beforeStartGameHook(this.options);
  449. const {room_id: r, data: n, session_id: o} = await this.networkController.startGame();
  450. this._id = r;
  451. const a = JSON.parse(n);
  452. this.isHost = a.IsHost,
  453. e = a.SkinID || e;
  454. const s = await this.getSkin(e);
  455. return this.updateCurrentNetworkOptions({
  456. roomId: r,
  457. sessionId: o
  458. }),
  459. reporter.updateBody({
  460. roomId: r,
  461. skinId: e,
  462. serverSession: o
  463. }),
  464. s
  465. } catch (r) {
  466. throw log$3.error("Request create room error", r),
  467. r
  468. }
  469. }
  470. pause() {
  471. return this.engineProxy.pause()
  472. }
  473. resume() {
  474. return this.engineProxy.resume()
  475. }
  476. reconnect() {
  477. this.networkController.reconnect()
  478. }
  479. async setViewMode(e) {}
  480. handleRepetLogin() {
  481. log$3.warn("receive " + Codes$1.RepeatLogin + " for repeat login"),
  482. this.emit("repeatLogin"),
  483. reporter.disable(),
  484. this.networkController.quit()
  485. }
  486. setPictureQualityLevel(e) {
  487. const t = {
  488. high: EImageQuality.high,
  489. low: EImageQuality.low,
  490. average: EImageQuality.mid
  491. };
  492. return this.updateCurrentState({
  493. pictureQualityLevel: e
  494. }),
  495. this.sceneManager.setImageQuality(t[e])
  496. }
  497. async getSkin(e) {
  498. let t = null;
  499. if (t = (this.skinList = await this.modelManager.getSkinsList()).find(n=>n.id === e || n.id === e),
  500. t)
  501. return t;
  502. {
  503. const n = `skin is invalid: skinId: ${e}`;
  504. return Promise.reject(new ParamError(n))
  505. }
  506. }
  507. setupStats() {
  508. this.stats.assign({
  509. roomId: this.id,
  510. userId: this.userId
  511. }),
  512. setInterval(this.engineProxy.updateStats, 1e3)
  513. }
  514. proxyEvents(e, t) {
  515. this.emit(e, t)
  516. }
  517. setCurrentNetworkOptions(e) {
  518. this._currentNetworkOptions = e
  519. }
  520. updateCurrentNetworkOptions(e) {
  521. Object.assign(this._currentNetworkOptions, e),
  522. Object.assign(this.options, e)
  523. }
  524. setCurrentState(e) {
  525. this._currentState = e
  526. }
  527. updateCurrentState(e) {
  528. e.skinId && (this.lastSkinId = this.currentState.skinId,
  529. this.updateCurrentNetworkOptions({
  530. skinId: e.skinId
  531. })),
  532. e.versionId && this.updateCurrentNetworkOptions({
  533. versionId: e.versionId
  534. }),
  535. Object.assign(this._currentState, e)
  536. }
  537. }