XverseAvatar.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. const log$1 = new Logger("xverse-avatar");
  2. class XverseAvatar extends EventEmitter {
  3. constructor({userId: e, isHost: t, room: r, avatarId: n, isSelf: o, group: a=AvatarGroup.Npc}) {
  4. super();
  5. E(this, "xAvatar");
  6. E(this, "_isHost", !1);
  7. E(this, "_room");
  8. E(this, "_withModel", !1);
  9. E(this, "_userId");
  10. E(this, "group", AvatarGroup.User);
  11. E(this, "state", "idle");
  12. E(this, "isLoading", !0);
  13. E(this, "_isMoving", !1);
  14. E(this, "_isRotating", !1);
  15. E(this, "_failed", !1);
  16. E(this, "disconnected", !1);
  17. E(this, "_avatarId");
  18. E(this, "prioritySync", !1);
  19. E(this, "priority", EAvatarRelationRank.Stranger);
  20. E(this, "_avatarModel");
  21. E(this, "_motionType", MotionType.Walk);
  22. E(this, "isSelf", !1);
  23. E(this, "_lastAnimTraceId", "");
  24. E(this, "statusSyncQueue", new Queue);
  25. E(this, "extraInfo", {});
  26. E(this, "setPosition", e=>{
  27. var t;
  28. !this._room.signal.isUpdatedYUV || (t = this.xAvatar) == null || t.setPosition(positionPrecisionProtect(e))
  29. }
  30. );
  31. E(this, "setRotation", e=>{
  32. var t;
  33. !this._room.signal.isUpdatedYUV || (t = this.xAvatar) == null || t.setRotation(rotationPrecisionProtect(e))
  34. }
  35. );
  36. E(this, "stopAnimation", ()=>{
  37. var e, t;
  38. (t = (e = this.xAvatar) == null ? void 0 : e.controller) == null || t.stopAnimation()
  39. }
  40. );
  41. E(this, "_playAnimation", async(e,t=!0,r=!1)=>{
  42. var o;
  43. if (!this._room.signal.isUpdatedYUV)
  44. return;
  45. if (this.state !== "idle" && !r)
  46. return log$1.debug("_playAnimation", "state is not idle"),
  47. Promise.resolve("_playAnimation, state is not idle");
  48. const n = Date.now();
  49. try {
  50. if (!((o = this.xAvatar) != null && o.controller))
  51. return Promise.reject(new InternalError(`[avatar: ${this.userId}] Play animation failed: ${e}, no controller`));
  52. this.isSelf && setTimeout(()=>{
  53. log$1.infoAndReportMeasurement({
  54. tag: e,
  55. startTime: n,
  56. value: 0,
  57. metric: "playAnimationStart"
  58. })
  59. }
  60. );
  61. const a = uuid$1();
  62. this._lastAnimTraceId = a,
  63. await this.xAvatar.controller.playAnimation(e, t),
  64. a === this._lastAnimTraceId && !this.isMoving && !t && e !== "Idle" && this.xAvatar.controller.playAnimation("Idle", t).catch(s=>{
  65. log$1.error(`[avatar: ${this.userId}] Play animation failed [force idle]`, s)
  66. }
  67. ),
  68. this.isSelf && log$1.infoAndReportMeasurement({
  69. tag: e,
  70. startTime: n,
  71. extra: {
  72. loop: t
  73. },
  74. metric: "playAnimationEnd"
  75. })
  76. } catch (a) {
  77. return log$1.error(`[avatar: ${this.userId}] Play animation failed: ${e}`, a),
  78. this.isSelf && log$1.infoAndReportMeasurement({
  79. tag: e,
  80. startTime: n,
  81. metric: "playAnimationEnd",
  82. error: a,
  83. extra: {
  84. loop: t
  85. }
  86. }),
  87. Promise.reject(a)
  88. }
  89. }
  90. );
  91. E(this, "changeComponents", async e=>{
  92. const {mode: t, endAnimation: r=""} = e || {}
  93. , n = JSON.parse(JSON.stringify(e.avatarComponents));
  94. let o = avatarComponentsValidate(n, this._avatarModel);
  95. return !ChangeComponentsMode[t] && !o && (o = new ParamError(`changeComponents failed, mode: ${t} is invalid`)),
  96. o ? (log$1.error(o),
  97. Promise.reject(o)) : this._changeComponents({
  98. avatarComponents: n,
  99. mode: t,
  100. endAnimation: r
  101. }).then(()=>{
  102. this.isSelf && t !== ChangeComponentsMode.Preview && this.avatarComponentsSync(this.avatarComponents)
  103. }
  104. )
  105. }
  106. );
  107. E(this, "_changeComponents", async e=>{
  108. var o;
  109. const {avatarComponents: t=[], mode: r} = e || {}
  110. , n = Date.now();
  111. try {
  112. if (!this.xAvatar)
  113. return Promise.reject(new InternalError("changeComponents failed, without instance: xAvatar"));
  114. const a = await avatarComponentsModify(this._avatarModel, t)
  115. , s = []
  116. , l = await avatarComponentsParser(this._avatarModel, a, this.avatarComponents);
  117. if (l.length === 0)
  118. return this.avatarComponents;
  119. await this.beforeChangeComponentsHook(e);
  120. for (const u of l) {
  121. const {id: c, type: h, url: f, suitComb: d} = u;
  122. s.push((o = this.xAvatar) == null ? void 0 : o.addComponent(c, h, f, d))
  123. }
  124. return await Promise.all(s),
  125. this.emit("componentsChanged", {
  126. components: this.avatarComponents,
  127. mode: r
  128. }),
  129. this.isSelf && log$1.infoAndReportMeasurement({
  130. tag: "changeComponents",
  131. startTime: n,
  132. metric: "changeComponents",
  133. extra: {
  134. inputComponents: t,
  135. finalComponents: this.avatarComponents,
  136. mode: ChangeComponentsMode[r]
  137. }
  138. }),
  139. this.avatarComponents
  140. } catch (a) {
  141. return this.isSelf && log$1.infoAndReportMeasurement({
  142. tag: "changeComponents",
  143. startTime: n,
  144. metric: "changeComponents",
  145. error: a,
  146. extra: {
  147. inputComponents: t,
  148. finalComponents: this.avatarComponents,
  149. mode: ChangeComponentsMode[r]
  150. }
  151. }),
  152. Promise.reject(a)
  153. }
  154. }
  155. );
  156. E(this, "avatarComponentsSync", e=>{
  157. e = e.map(t=>({
  158. type: t.type,
  159. id: t.id
  160. })),
  161. this._room.actionsHandler.avatarComponentsSync(e)
  162. }
  163. );
  164. E(this, "hide", ()=>{
  165. var e;
  166. if ((e = this.xAvatar) != null && e.hide())
  167. return Promise.resolve(`avatar: ${this.userId} hide success`);
  168. {
  169. const t = `avatar: ${this.userId} hide failed ${!this.xAvatar && "without instance: xAvatar"}`;
  170. return log$1.warn(t),
  171. Promise.reject(t)
  172. }
  173. }
  174. );
  175. E(this, "show", ()=>{
  176. var e;
  177. if ((e = this.xAvatar) != null && e.show())
  178. return Promise.resolve(`avatar: ${this.userId} show success`);
  179. {
  180. const t = `avatar: ${this.userId} show failed ${!this.xAvatar && "without instance: xAvatar"}`;
  181. return log$1.warn(t),
  182. Promise.reject(t)
  183. }
  184. }
  185. );
  186. E(this, "sayTimer");
  187. this._userId = e,
  188. this._room = r,
  189. this.isSelf = o || !1,
  190. this._withModel = !!n,
  191. this._isHost = t || !1,
  192. this._avatarId = n,
  193. this.group = a,
  194. this._room.modelManager.getAvatarModelList().then(s=>{
  195. const l = s.find(u=>u.id === n);
  196. l && (this._avatarModel = l)
  197. }
  198. )
  199. }
  200. get avatarId() {
  201. return this._avatarId
  202. }
  203. get isRender() {
  204. var e;
  205. return !!((e = this.xAvatar) != null && e.isRender)
  206. }
  207. get isHidden() {
  208. var e;
  209. return !!((e = this.xAvatar) != null && e.isHide)
  210. }
  211. get motionType() {
  212. return this._motionType
  213. }
  214. set motionType(e) {
  215. this._motionType = e
  216. }
  217. get nickname() {
  218. var e;
  219. return (e = this.xAvatar) == null ? void 0 : e.nickName
  220. }
  221. get words() {
  222. var e;
  223. return (e = this.xAvatar) == null ? void 0 : e.words
  224. }
  225. get isHost() {
  226. return this._isHost
  227. }
  228. get failed() {
  229. return this._failed
  230. }
  231. get scale() {
  232. var e;
  233. return (e = this.xAvatar) == null ? void 0 : e.scale
  234. }
  235. get animations() {
  236. var e;
  237. return !this.xAvatar || !this.xAvatar.controller ? [] : ((e = this.xAvatar) == null ? void 0 : e.getAvaliableAnimations()) || []
  238. }
  239. get position() {
  240. var e;
  241. return (e = this.xAvatar) == null ? void 0 : e.position
  242. }
  243. get rotation() {
  244. var e;
  245. return (e = this.xAvatar) == null ? void 0 : e.rotation
  246. }
  247. get pose() {
  248. return {
  249. position: this.position,
  250. angle: this.rotation
  251. }
  252. }
  253. get id() {
  254. return this.userId
  255. }
  256. get isMoving() {
  257. return this._isMoving
  258. }
  259. set isMoving(e) {
  260. this._isMoving = e,
  261. this.state = e ? "moving" : "idle"
  262. }
  263. get isRotating() {
  264. return this._isRotating
  265. }
  266. set isRotating(e) {
  267. this._isRotating = e,
  268. this.state = e ? "rotating" : "idle"
  269. }
  270. get withModel() {
  271. return this._withModel
  272. }
  273. get avatarComponents() {
  274. var e;
  275. return JSON.parse(JSON.stringify(((e = this.xAvatar) == null ? void 0 : e.clothesList) || []))
  276. }
  277. get userId() {
  278. return this._userId
  279. }
  280. get removeWhenDisconnected() {
  281. return this.extraInfo && this.extraInfo.removeWhenDisconnected !== void 0 ? this.extraInfo.removeWhenDisconnected : !0
  282. }
  283. setConnectionStatus(e) {
  284. this.disconnected !== e && (this.disconnected = e,
  285. e ? this.emit("disconnected") : this.emit("reconnected"),
  286. log$1.warn(`avatar ${this.userId} status changed, disconnected:`, e))
  287. }
  288. setScale(e) {
  289. var t;
  290. (t = this.xAvatar) == null || t.setScale(e > 0 ? e : 1)
  291. }
  292. async playAnimation(e) {
  293. const {animationName: t, loop: r, extra: n} = e || {};
  294. if (this.isSelf) {
  295. if (this.isMoving)
  296. try {
  297. await this.stopMoving()
  298. } catch (a) {
  299. return log$1.error(`stopMoving error before playAnimation ${t}`, a),
  300. Promise.reject(`stopMoving error before playAnimation ${t}`)
  301. }
  302. const o = {
  303. info: {
  304. userId: this.userId,
  305. animation: t,
  306. loop: r,
  307. extra: encodeURIComponent(n || "")
  308. },
  309. broadcastType: CoreBroadcastType.PlayAnimation
  310. };
  311. this._room.avatarManager.broadcast.broadcast({
  312. data: o
  313. })
  314. }
  315. return this.emit("animationStart", {
  316. animationName: t,
  317. extra: safeDecodeURIComponent(n || "")
  318. }),
  319. this._playAnimation(t, r).then(()=>{
  320. this.emit("animationEnd", {
  321. animationName: t,
  322. extra: safeDecodeURIComponent(n || "")
  323. })
  324. }
  325. )
  326. }
  327. async beforeChangeComponentsHook(e) {}
  328. turnTo(e) {
  329. if (this._room.viewMode === "observer") {
  330. this._room.sceneManager.cameraComponent.MainCamera.setTarget(ue4Position2Xverse(e.point));
  331. return
  332. }
  333. return this._room.actionsHandler.turnTo(e).then(()=>{
  334. this.emit("viewChanged", {
  335. extra: (e == null ? void 0 : e.extra) || ""
  336. })
  337. }
  338. )
  339. }
  340. async moveTo(e) {
  341. const {point: t, extra: r=""} = e || {};
  342. if (!this.position)
  343. return Promise.reject(new ParamError("avatar position is empty"));
  344. if (typeof r != "string" || typeof r == "string" && r.length > 64) {
  345. const a = "extra shoud be string which length less than 64";
  346. return log$1.warn(a),
  347. Promise.reject(new ParamError(a))
  348. }
  349. const o = getDistance(this.position, t) / 100 > 100 ? MotionType.Run : MotionType.Walk;
  350. return this._room.actionsHandler.moveTo({
  351. point: t,
  352. motionType: o,
  353. extra: r
  354. })
  355. }
  356. async stopMoving() {
  357. return this._room.actionsHandler.stopMoving()
  358. }
  359. rotateTo(e) {
  360. return this._room.actionsHandler.rotateTo(e)
  361. }
  362. setRayCast(e) {
  363. this.xAvatar && (this.xAvatar.isRayCastEnable = e)
  364. }
  365. say(e, t) {
  366. if (this.sayTimer && window.clearTimeout(this.sayTimer),
  367. !this.xAvatar) {
  368. log$1.error("say failed, without instance: xAvatar");
  369. return
  370. }
  371. this.xAvatar.say(e, {
  372. scale: this.xAvatar.scale,
  373. isUser: this.group === AvatarGroup.User
  374. }),
  375. !(t === void 0 || t <= 0) && (this.sayTimer = window.setTimeout(()=>{
  376. this.silent()
  377. }
  378. , t))
  379. }
  380. silent() {
  381. var e;
  382. if (!this.xAvatar) {
  383. log$1.error("silent failed, without instance: xAvatar");
  384. return
  385. }
  386. (e = this.xAvatar) == null || e.silent()
  387. }
  388. setMotionType({type: e=MotionType.Walk}) {
  389. return this.motionType === e ? Promise.resolve() : this._room.actionsHandler.setMotionType(e).then(()=>{
  390. this._motionType = e
  391. }
  392. )
  393. }
  394. setNickname(e) {
  395. return this._room.actionsHandler.setNickName(encodeURIComponent(e))
  396. }
  397. _setNickname(e) {
  398. var r, n;
  399. if (!e)
  400. return;
  401. const t = safeDecodeURIComponent(e);
  402. ((r = this.xAvatar) == null ? void 0 : r.nickName) !== t && (this.isSelf && (this._room.updateCurrentNetworkOptions({
  403. nickname: t
  404. }),
  405. this._room.options.nickname = t),
  406. (n = this.xAvatar) == null || n.setNickName(t, {
  407. scale: this.xAvatar.scale
  408. }))
  409. }
  410. _move(e) {
  411. var s;
  412. const {start: t, end: r, walkSpeed: n, moveAnimation: o="Walking", inter: a=[]} = e || {};
  413. return (s = this.xAvatar) == null ? void 0 : s.move(t, r, n, o, a)
  414. }
  415. setPickBoxScale(e=1) {
  416. return this.xAvatar ? (this.xAvatar.setPickBoxScale(e),
  417. !0) : (log$1.error("setPickBoxScale failed, without instance: xAvatar"),
  418. !1)
  419. }
  420. transfer(e) {
  421. const {player: t, camera: r, areaName: n, attitude: o, pathName: a} = e;
  422. return this._room.actionsHandler.transfer({
  423. renderType: RenderType.RotationVideo,
  424. player: t,
  425. camera: r,
  426. areaName: n,
  427. attitude: o,
  428. pathName: a,
  429. tag: "transfer"
  430. })
  431. }
  432. avatarLoadedHook() {}
  433. avatarStartMovingHook() {}
  434. avatarStopMovingHook() {}
  435. async statusSync(e) {
  436. var t, r, n;
  437. try {
  438. if ((t = e.event) != null && t.rotateEvent) {
  439. const {angle: o, speed: a} = e.event.rotateEvent
  440. , s = this.motionType === MotionType.Run ? "Running" : "Walking";
  441. this.rotation && (this.rotation.yaw = this.rotation.yaw % 360,
  442. o.yaw - this.rotation.yaw > 180 && (o.yaw = 180 - o.yaw),
  443. this.isRotating = !0,
  444. await this.xAvatar.rotateTo(o, this.rotation, s).then(()=>{
  445. this._playAnimation("Idle", !0),
  446. this.isRotating = !1
  447. }
  448. ))
  449. }
  450. if (e.event && (((r = e.event) == null ? void 0 : r.points.length) || 0) > 1 && !this.isSelf) {
  451. this.isMoving = !0,
  452. e.playerState.attitude && (this._motionType = e.playerState.attitude);
  453. const o = this.motionType === MotionType.Run ? "Running" : "Walking"
  454. , a = this._room.skin.routeList.find(l=>l.areaName === this._room.currentState.areaName)
  455. , s = ((a == null ? void 0 : a.step) || 7.5) * 30 * (25 / 30);
  456. this.position && await this._move({
  457. start: this.position,
  458. end: e.event.points[e.event.points.length - 1],
  459. walkSpeed: s,
  460. moveAnimation: o,
  461. inter: (n = e.event) == null ? void 0 : n.points.slice(0, -1)
  462. }).then(()=>{
  463. this.isMoving = !1
  464. }
  465. )
  466. }
  467. } catch {
  468. return
  469. }
  470. }
  471. }