123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- const log = new Logger("xverse-avatar-manager")
- class XverseAvatarManager extends EventEmitter {
- constructor(e) {
- super();
- E(this, "xAvatarManager");
- E(this, "_room");
- E(this, "avatars", new Map);
- E(this, "syncAvatarsLength", 0);
- E(this, "broadcast");
- this._room = e,
- this._usersStatistics(),
- this.broadcast = this.setupBroadcast(),
- e.on("skinChanged", ()=>{
- this.avatars.forEach(t=>{
- t.disconnected && this.removeAvatar(t.userId, !0)
- }
- )
- }
- )
- }
- setupBroadcast() {
- return new Broadcast(this._room,async e=>{
- const {broadcastType: t, info: r} = e;
- if (t !== CoreBroadcastType.PlayAnimation)
- return;
- const {userId: n, animation: o, extra: a, loop: s=!1} = r
- , l = this.avatars.get(n);
- l && !l.isSelf && (l.emit("animationStart", {
- animationName: o,
- extra: decodeURIComponent(a)
- }),
- await (l == null ? void 0 : l._playAnimation(o, s)),
- l.emit("animationEnd", {
- animationName: o,
- extra: decodeURIComponent(a)
- }))
- }
- )
- }
- hideAll(e=!0) {
- this.xAvatarManager.hideAll(e)
- }
- showAll(e=!0) {
- this.xAvatarManager.showAll(e)
- }
- async init() {
- this.xAvatarManager = this._room.sceneManager.avatarComponent;
- try {
- const e = await this._room.modelManager.getApplicationConfig()
- , {avatars: t} = e;
- if (t) {
- await avatarLoader.parse(this._room.sceneManager, t);
- return
- }
- return Promise.reject("cannot find avatar config list")
- } catch (e) {
- return log.error(e),
- Promise.reject("avatar mananger init error!")
- }
- }
- async handleAvatar(e) {
- var r;
- if (this._room.viewMode === "simple" || !this._room.joined || !e.newUserStates)
- return;
- let t = e.newUserStates;
- if (((r = this._room._userAvatar) == null ? void 0 : r.isMoving) && this._room._userAvatar.motionType === MotionType.Run) {
- const n = t.filter(a=>a.userId === this._room.userId)
- , o = t.filter(a=>a.userId !== this._room.userId).slice(0, 2);
- t = n.concat(o)
- }
- if (e.getStateType === GetStateTypes.Event) {
- this.syncAvatarsLength = (t || []).length;
- const n = this._room.avatars.filter(s=>s.group == AvatarGroup.User);
- n.filter(s=>!(t != null && t.find(l=>l.userId == s.userId))).forEach(s=>{
- this.removeAvatar(s.userId)
- }
- );
- const a = t.filter(s=>!n.find(l=>l.userId == s.userId));
- this._handleAvatar(a)
- }
- this._handleAvatar(t)
- }
- async _handleAvatar(e) {
- e == null || e.forEach(t=>{
- var n, o, a, s, l, u, c, h, f;
- const r = this._room.userId === t.userId;
- if (((n = t.event) == null ? void 0 : n.type) === SyncEventType.ET_RemoveVisitor) {
- const d = (a = (o = t.event) == null ? void 0 : o.removeVisitorEvent) == null ? void 0 : a.removeVisitorEvent
- , _ = JSON.parse(safeDecodeURIComponent(((l = (s = t.event) == null ? void 0 : s.removeVisitorEvent) == null ? void 0 : l.extraInfo) || ""))
- , {code: g, msg: m} = _;
- d === RemoveVisitorType.RVT_ChangeToObserver ? this._room.audienceViewModeHook() : d === RemoveVisitorType.RVT_MoveOutOfTheRoom && this._room.leave(),
- this._room.emit("visitorStatusChanged", {
- code: g,
- msg: m
- })
- }
- if (t.event && [SyncEventType.Appear, SyncEventType.Reset].includes(t.event.type) || !t.event) {
- let d = this.avatars.get(t.userId);
- if (t.playerState.avatarId && (d == null ? void 0 : d.avatarId) !== t.playerState.avatarId && (d = void 0,
- this.removeAvatar(t.userId)),
- d) {
- if (d.disconnected && d.setConnectionStatus(!1),
- (u = t.event) != null && u.id && this._room.actionsHandler.confirmEvent(t.event.id),
- t.playerState.nickName && (d == null || d._setNickname(t.playerState.nickName)),
- t.playerState.avatarComponents && !d.isSelf && d.xAvatar) {
- const _ = safeParseComponents(t.playerState.avatarComponents);
- d._changeComponents({
- avatarComponents: _,
- mode: ChangeComponentsMode.Preview
- })
- }
- } else {
- const {position: _, angle: g} = t.playerState.player
- , m = t.playerState.avatarId
- , v = t.playerState.prioritySync
- , y = safelyJsonParse(t.playerState.extra);
- if (!m)
- return;
- const b = safeParseComponents(t.playerState.avatarComponents)
- , T = safeDecodeURIComponent(t.playerState.nickName)
- , C = this.calculatePriority(t.userId, y);
- this.addAvatar({
- userId: t.userId,
- isHost: t.playerState.isHost,
- nickname: T,
- avatarPosition: _,
- avatarRotation: g,
- avatarScale: t.playerState.avatarSize,
- avatarId: m,
- avatarComponents: t.playerState.person === Person.First ? [] : b,
- priority: C,
- group: AvatarGroup.User,
- prioritySync: v,
- extraInfo: y
- }).then(()=>{
- var A;
- (A = t.event) != null && A.id && this._room.actionsHandler.confirmEvent(t.event.id),
- this.updateAvatarPositionAndRotation(t),
- r && (this.xAvatarManager.setMainAvatar(t.userId),
- this._room.emit("userAvatarLoaded"),
- log.info("userAvatarLoaded"))
- }
- ).catch(A=>{
- r && (this.xAvatarManager.setMainAvatar(t.userId),
- this._room.emit("userAvatarFailed", {
- error: A
- }),
- log.error("userAvatarFailed", A))
- }
- )
- }
- }
- if (t.event && SyncEventType.Disappear === t.event.type && ((c = t == null ? void 0 : t.event) != null && c.id && this._room.actionsHandler.confirmEvent(t.event.id),
- this.removeAvatar(t.userId)),
- t.event && [SyncEventType.Move, SyncEventType.ChangeRenderInfo].includes(t.event.type) || !t.event) {
- (h = t == null ? void 0 : t.event) != null && h.id && this._room.actionsHandler.confirmEvent(t.event.id);
- const d = this.avatars.get(t.userId);
- d && d.withModel && !d.isLoading && this.updateAvatarPositionAndRotation(t)
- }
- if (!r && ((f = t.event) == null ? void 0 : f.type) === SyncEventType.Rotate) {
- const d = this.avatars.get(t.userId);
- d.statusSyncQueue.append({
- type: QueueType.Rotate,
- action: ()=>d.statusSync(t)
- })
- }
- }
- )
- }
- calculatePriority(e, t) {
- var n;
- return e === this._room.userId ? EAvatarRelationRank.Self : (n = this._room.options.firends) != null && n.includes(e) ? EAvatarRelationRank.Friend : EAvatarRelationRank.Stranger
- }
- updateAvatarPositionAndRotation(e) {
- var t, r;
- if ((t = e == null ? void 0 : e.playerState) != null && t.player) {
- let {position: n, angle: o} = e.playerState.player;
- const a = this.avatars.get(e.userId);
- if (!a)
- return;
- if (n = positionPrecisionProtect(n),
- o = rotationPrecisionProtect(o),
- a.isSelf && !this._room.networkController.rtcp.workers.inPanoMode && (a.setPosition(n),
- a.setRotation(o)),
- e.event && (((r = e.event) == null ? void 0 : r.points.length) || 0) > 1 && !a.isSelf && a.statusSyncQueue.append({
- type: QueueType.Move,
- action: ()=>a.statusSync(e)
- }),
- e.renderInfo && a.isSelf) {
- const {isMoving: s, isRotating: l} = e.renderInfo;
- this._updateAvatarMovingStatus({
- id: e.userId,
- isMoving: !!s,
- isRotating: !!l
- })
- }
- }
- }
- async addAvatar(e) {
- const {userId: t, isHost: r, avatarPosition: n, avatarId: o, avatarRotation: a, nickname: s, avatarComponents: l=[], priority: u, group: c=AvatarGroup.Npc, avatarScale: h=DEFAULT_AVATAR_SCALE, extraInfo: f, prioritySync: d} = e
- , _ = t === this._room.userId;
- let g = this.avatars.get(t);
- if (g)
- return Promise.resolve(g);
- if (g = new xe.subAvatar({
- userId: t,
- isHost: r,
- isSelf: _,
- room: this._room,
- avatarComponents: l,
- avatarId: o,
- nickname: s,
- group: c
- }),
- this.avatars.set(t, g),
- !g.withModel)
- return g.isLoading = !1,
- g.avatarLoadedHook(),
- this._room.emit("avatarChanged", {
- avatars: this._room.avatars
- }),
- g;
- const v = (await this._room.modelManager.getAvatarModelList()).find(b=>b.id === o)
- , y = Date.now();
- if (!v)
- return this._room.emit("avatarChanged", {
- avatars: this._room.avatars
- }),
- this.avatars.delete(t),
- Promise.reject(`no such avatar model with id: ${o}`);
- try {
- let b = await avatarComponentsModify(v, l);
- b = b.filter(A=>A.type != "pendant");
- const T = await avatarComponentsParser(v, b)
- , C = await this.xAvatarManager.loadAvatar({
- id: t,
- avatarType: o,
- priority: u,
- avatarManager: this.xAvatarManager,
- assets: T,
- status: {
- avatarPosition: n,
- avatarRotation: a,
- avatarScale: h
- }
- })._timeout(8e3, new TimeoutError$1("loadAvatar timeout(8s)"));
- return C.setPickBoxScale(t === this._room.userId ? 0 : 1),
- g.xAvatar = C,
- g.setScale(h),
- g.extraInfo = f,
- g.priority = u,
- g.isLoading = !1,
- g.prioritySync = !!d,
- g._playAnimation("Idle", !0, !0),
- g.avatarLoadedHook(),
- this._room.emit("avatarChanged", {
- avatars: this._room.avatars
- }),
- s && g._setNickname(s),
- t === this._room.userId && (log.infoAndReportMeasurement({
- metric: "avatarLoadDuration",
- startTime: y,
- group: "costs"
- }),
- log.infoAndReportMeasurement({
- metric: "avatarLoadAt",
- startTime: this._room._startTime,
- group: "costs"
- })),
- g
- } catch (b) {
- return g.isLoading = !1,
- this._room.emit("avatarChanged", {
- avatars: this._room.avatars
- }),
- log.error(b),
- Promise.reject(b)
- }
- }
- removeAvatar(e, t=!1) {
- const r = this.avatars.get(e);
- if (!!r) {
- if (r.removeWhenDisconnected || t) {
- r.xAvatar && this.xAvatarManager.deleteAvatar(r.xAvatar),
- this.avatars.delete(e),
- this._room.emit("avatarChanged", {
- avatars: this._room.avatars
- });
- return
- }
- r.setConnectionStatus(!0)
- }
- }
- clearOtherUsers() {
- this.avatars.forEach(e=>{
- !e.isSelf && e.group === AvatarGroup.User && this.removeAvatar(e.userId)
- }
- )
- }
- async _updateAvatarMovingStatus(e) {
- const {id: t, isMoving: r, isRotating: n} = e
- , o = this.avatars.get(t);
- if (!!o) {
- if (o.isRotating !== n) {
- o.isRotating = n;
- let a = "Idle";
- n && (a = "Walking",
- o.motionType === MotionType.Run && (a = "Running")),
- o._playAnimation(a, !0, !0),
- log.infoAndReportMeasurement({
- startTime: Date.now(),
- value: 0,
- metric: n ? "userAvatarStartRotating" : "userAvatarStopRotating",
- extra: {
- motionType: o.motionType,
- moveToExtra: this._room.moveToExtra
- }
- })
- }
- if (o.isMoving !== r) {
- o.isMoving = r;
- let a = "Idle";
- r && (a = "Walking",
- o.motionType === MotionType.Run && (a = "Running")),
- r ? (o.avatarStartMovingHook(),
- o.emit("startMoving", {
- target: o,
- extra: this._room.moveToExtra
- })) : (o.avatarStopMovingHook(),
- o.emit("stopMoving", {
- target: o,
- extra: this._room.moveToExtra
- })),
- o._playAnimation(a, !0, !0),
- log.infoAndReportMeasurement({
- startTime: Date.now(),
- value: 0,
- metric: r ? "userAvatarStartMoving" : "userAvatarStopMoving",
- extra: {
- motionType: o.motionType,
- moveToExtra: this._room.moveToExtra
- }
- })
- }
- }
- }
- _usersStatistics() {
- this.on("userAvatarLoaded", ()=>{
- window.setInterval(()=>{
- const e = this._room.avatars.filter(r=>r.group === AvatarGroup.User).length || 0
- , t = this._room.avatars.filter(r=>r.group === AvatarGroup.User && r.isRender).length || 0;
- this._room.stats.assign({
- userNum: e,
- syncUserNum: this.syncAvatarsLength,
- renderedUserNum: t
- })
- }
- , 3e3)
- }
- )
- }
- }
- ;
|