You've already forked Nitro_Render_V3
mirror of
https://github.com/duckietm/Nitro_Render_V3.git
synced 2026-06-19 15:06:20 +00:00
feat(events,session): add React-friendly subscribe APIs and snapshot getters
Adds backwards-compatible primitives needed to consume the renderer from React 19 hooks (useSyncExternalStore, use(), TanStack Query) without re-architecting the event bus. - EventDispatcher.subscribe(type, cb): () => void — unsubscriber-returning wrapper matching the useSyncExternalStore subscribe signature. - CommunicationManager.subscribeMessage(eventCtor, handler): () => void — packet-stream equivalent. - SessionDataManager.getUserDataSnapshot() and RoomSessionManager.getActiveRoomSessionSnapshot() — referentially-stable read-only views invalidated through new SESSION_DATA_UPDATED and ROOM_SESSION_UPDATED events. All additive; existing addEventListener/removeEventListener / IRoomSession APIs are unchanged. Bumps renderer to 2.1.0.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { IRoomHandlerListener, IRoomSession, IRoomSessionManager } from '@nitrots/api';
|
||||
import { IRoomHandlerListener, IRoomSession, IRoomSessionManager, IRoomSessionSnapshot } from '@nitrots/api';
|
||||
import { GetCommunication, RoomEnterComposer, RoomUnitWalkComposer } from '@nitrots/communication';
|
||||
import { GetEventDispatcher, NitroEventType, RoomSessionEvent } from '@nitrots/events';
|
||||
import { GetEventDispatcher, NitroEvent, NitroEventType, RoomSessionEvent } from '@nitrots/events';
|
||||
import { NitroLogger } from '@nitrots/utils';
|
||||
import { RoomSession } from './RoomSession';
|
||||
import { BaseHandler, GenericErrorHandler, PetPackageHandler, PollHandler, RoomChatHandler, RoomDataHandler, RoomDimmerPresetsHandler, RoomPermissionsHandler, RoomPresentHandler, RoomSessionHandler, RoomUsersHandler, WordQuizHandler } from './handler';
|
||||
@@ -26,6 +26,41 @@ export class RoomSessionManager implements IRoomSessionManager, IRoomHandlerList
|
||||
private _pendingRoomClear: ReturnType<typeof setTimeout> = null;
|
||||
private _savedPosX: number = -1;
|
||||
private _savedPosY: number = -1;
|
||||
private _activeRoomSessionSnapshot: Readonly<IRoomSessionSnapshot> | null = null;
|
||||
|
||||
private invalidateRoomSessionSnapshot(): void
|
||||
{
|
||||
this._activeRoomSessionSnapshot = null;
|
||||
|
||||
GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.ROOM_SESSION_UPDATED));
|
||||
}
|
||||
|
||||
public getActiveRoomSessionSnapshot(): Readonly<IRoomSessionSnapshot> | null
|
||||
{
|
||||
const session = this._viewerSession;
|
||||
|
||||
if(!session) return null;
|
||||
|
||||
if(this._activeRoomSessionSnapshot && this._activeRoomSessionSnapshot.session === session) return this._activeRoomSessionSnapshot;
|
||||
|
||||
this._activeRoomSessionSnapshot = Object.freeze<IRoomSessionSnapshot>({
|
||||
roomId: session.roomId,
|
||||
state: session.state,
|
||||
isRoomOwner: session.isRoomOwner,
|
||||
isSpectator: session.isSpectator,
|
||||
isDecorating: session.isDecorating,
|
||||
isGuildRoom: session.isGuildRoom,
|
||||
isPrivateRoom: session.isPrivateRoom,
|
||||
controllerLevel: session.controllerLevel,
|
||||
doorMode: session.doorMode,
|
||||
tradeMode: session.tradeMode,
|
||||
allowPets: session.allowPets,
|
||||
groupId: session.groupId,
|
||||
session
|
||||
});
|
||||
|
||||
return this._activeRoomSessionSnapshot;
|
||||
}
|
||||
|
||||
public async init(): Promise<void>
|
||||
{
|
||||
@@ -196,6 +231,7 @@ export class RoomSessionManager implements IRoomSessionManager, IRoomHandlerList
|
||||
|
||||
this._sessions.clear();
|
||||
this._viewerSession = null;
|
||||
this.invalidateRoomSessionSnapshot();
|
||||
this.createSession(roomId, password, this._savedPosX, this._savedPosY);
|
||||
this.clearGuardTimer();
|
||||
this._reconnectGuardTimer = setTimeout(() =>
|
||||
@@ -384,6 +420,8 @@ export class RoomSessionManager implements IRoomSessionManager, IRoomHandlerList
|
||||
this._lastRoomPassword = roomSession.password;
|
||||
this.persistRoom(roomSession.roomId, roomSession.password);
|
||||
|
||||
this.invalidateRoomSessionSnapshot();
|
||||
|
||||
this.startSession(this._viewerSession);
|
||||
|
||||
return true;
|
||||
@@ -406,6 +444,8 @@ export class RoomSessionManager implements IRoomSessionManager, IRoomHandlerList
|
||||
|
||||
this.setHandlers(session);
|
||||
|
||||
this.invalidateRoomSessionSnapshot();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -429,6 +469,10 @@ export class RoomSessionManager implements IRoomSessionManager, IRoomHandlerList
|
||||
}
|
||||
|
||||
GetEventDispatcher().dispatchEvent(new RoomSessionEvent(RoomSessionEvent.ENDED, session, openLandingView));
|
||||
|
||||
if(this._viewerSession === session) this._viewerSession = null;
|
||||
|
||||
this.invalidateRoomSessionSnapshot();
|
||||
}
|
||||
|
||||
public sessionUpdate(id: number, type: string): void
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { IFurnitureData, IGroupInformationManager, IMessageComposer, IMessageEvent, IProductData, ISessionDataManager, NoobnessLevelEnum, SecurityLevel } from '@nitrots/api';
|
||||
import { IFurnitureData, IGroupInformationManager, IMessageComposer, IMessageEvent, IProductData, ISessionDataManager, IUserDataSnapshot, NoobnessLevelEnum, SecurityLevel } from '@nitrots/api';
|
||||
import { AccountSafetyLockStatusChangeMessageEvent, AccountSafetyLockStatusChangeParser, AvailabilityStatusMessageEvent, ChangeUserNameResultMessageEvent, EmailStatusResultEvent, FigureUpdateEvent, GetCommunication, GetUserTagsComposer, InClientLinkEvent, MysteryBoxKeysEvent, NoobnessLevelMessageEvent, PetRespectComposer, PetScratchFailedMessageEvent, RoomReadyMessageEvent, RoomUnitChatComposer, UserInfoEvent, UserNameChangeMessageEvent, UserPermissionsEvent, UserRespectComposer, UserTagsMessageEvent } from '@nitrots/communication';
|
||||
import { GetConfiguration } from '@nitrots/configuration';
|
||||
import { GetLocalizationManager } from '@nitrots/localization';
|
||||
import { GetEventDispatcher, MysteryBoxKeysUpdateEvent, NitroSettingsEvent, SessionDataPreferencesEvent, UserNameUpdateEvent } from '@nitrots/events';
|
||||
import { GetEventDispatcher, MysteryBoxKeysUpdateEvent, NitroEvent, NitroEventType, NitroSettingsEvent, SessionDataPreferencesEvent, UserNameUpdateEvent } from '@nitrots/events';
|
||||
import { CreateLinkEvent, HabboWebTools } from '@nitrots/utils';
|
||||
import { Texture } from 'pixi.js';
|
||||
import { GroupInformationManager } from './GroupInformationManager';
|
||||
@@ -52,11 +52,49 @@ export class SessionDataManager implements ISessionDataManager
|
||||
|
||||
private _badgeImageManager: BadgeImageManager = new BadgeImageManager();
|
||||
|
||||
private _userDataSnapshot: Readonly<IUserDataSnapshot> | null = null;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.resetUserInfo();
|
||||
}
|
||||
|
||||
private invalidateUserDataSnapshot(): void
|
||||
{
|
||||
this._userDataSnapshot = null;
|
||||
|
||||
GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SESSION_DATA_UPDATED));
|
||||
}
|
||||
|
||||
public getUserDataSnapshot(): Readonly<IUserDataSnapshot>
|
||||
{
|
||||
if(this._userDataSnapshot) return this._userDataSnapshot;
|
||||
|
||||
this._userDataSnapshot = Object.freeze<IUserDataSnapshot>({
|
||||
userId: this._userId,
|
||||
userName: this._name,
|
||||
figure: this._figure,
|
||||
gender: this._gender,
|
||||
realName: this._realName,
|
||||
respectsReceived: this._respectsReceived,
|
||||
respectsLeft: this._respectsLeft,
|
||||
respectsPetLeft: this._respectsPetLeft,
|
||||
canChangeName: this._canChangeName,
|
||||
clubLevel: this._clubLevel,
|
||||
securityLevel: this._securityLevel,
|
||||
isAmbassador: this._isAmbassador,
|
||||
isEmailVerified: this._isEmailVerified,
|
||||
isNoob: (this._noobnessLevel !== NoobnessLevelEnum.OLD_IDENTITY),
|
||||
isAuthenticHabbo: this._isAuthenticHabbo,
|
||||
isSystemOpen: this._systemOpen,
|
||||
isSystemShutdown: this._systemShutdown,
|
||||
uiFlags: this._uiFlags,
|
||||
tags: Object.freeze<string[]>([...this._tags]) as ReadonlyArray<string>
|
||||
});
|
||||
|
||||
return this._userDataSnapshot;
|
||||
}
|
||||
|
||||
public async init(): Promise<void>
|
||||
{
|
||||
await Promise.all([
|
||||
@@ -75,6 +113,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this._gender = event.getParser().gender;
|
||||
|
||||
HabboWebTools.updateFigure(this._figure);
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
})),
|
||||
GetCommunication().registerMessageEvent(new UserInfoEvent(this.onUserInfoEvent.bind(this))),
|
||||
GetCommunication().registerMessageEvent(new UserPermissionsEvent(this.onUserPermissionsEvent.bind(this))),
|
||||
@@ -98,6 +138,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this._uiFlags = event.flags;
|
||||
|
||||
GetEventDispatcher().dispatchEvent(new SessionDataPreferencesEvent(this._uiFlags));
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
};
|
||||
|
||||
GetEventDispatcher().addEventListener<NitroSettingsEvent>(NitroSettingsEvent.SETTINGS_UPDATED, this._settingsEventCallback);
|
||||
@@ -189,6 +231,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this._safetyLocked = userInfo.safetyLocked;
|
||||
|
||||
this._ignoredUsersManager.requestIgnoredUsers(userInfo.username);
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
private onUserPermissionsEvent(event: UserPermissionsEvent): void
|
||||
@@ -198,6 +242,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this._clubLevel = event.getParser().clubLevel;
|
||||
this._securityLevel = event.getParser().securityLevel;
|
||||
this._isAmbassador = event.getParser().isAmbassador;
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
private onAvailabilityStatusMessageEvent(event: AvailabilityStatusMessageEvent): void
|
||||
@@ -211,6 +257,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this._systemOpen = parser.isOpen;
|
||||
this._systemShutdown = parser.onShutdown;
|
||||
this._isAuthenticHabbo = parser.isAuthenticUser;
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
private onPetRespectFailed(event: PetScratchFailedMessageEvent): void
|
||||
@@ -218,6 +266,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
if(!event || !event.connection) return;
|
||||
|
||||
this._respectsPetLeft++;
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
private onChangeNameUpdateEvent(event: ChangeUserNameResultMessageEvent): void
|
||||
@@ -233,6 +283,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this._canChangeName = false;
|
||||
|
||||
GetEventDispatcher().dispatchEvent(new UserNameUpdateEvent(parser.name));
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
private onUserNameChangeMessageEvent(event: UserNameChangeMessageEvent): void
|
||||
@@ -249,6 +301,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this._canChangeName = false;
|
||||
|
||||
GetEventDispatcher().dispatchEvent(new UserNameUpdateEvent(this._name));
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
private onUserTags(event: UserTagsMessageEvent): void
|
||||
@@ -260,6 +314,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
if(!parser) return;
|
||||
|
||||
this._tags = parser.tags;
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
private onRoomModelNameEvent(event: RoomReadyMessageEvent): void
|
||||
@@ -300,6 +356,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this._noobnessLevel = event.getParser().noobnessLevel;
|
||||
|
||||
if(this._noobnessLevel !== NoobnessLevelEnum.OLD_IDENTITY) GetConfiguration().setValue<number>('new.identity', 1);
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
private onAccountSafetyLockStatusChangeMessageEvent(event: AccountSafetyLockStatusChangeMessageEvent): void
|
||||
@@ -316,6 +374,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
private onEmailStatus(event: EmailStatusResultEvent): void
|
||||
{
|
||||
this._isEmailVerified = event?.getParser()?.isVerified ?? false;
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
public getFloorItemData(id: number): IFurnitureData
|
||||
@@ -476,6 +536,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this.send(new UserRespectComposer(userId));
|
||||
|
||||
this._respectsLeft--;
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
public givePetRespect(petId: number): void
|
||||
@@ -485,6 +547,8 @@ export class SessionDataManager implements ISessionDataManager
|
||||
this.send(new PetRespectComposer(petId));
|
||||
|
||||
this._respectsPetLeft--;
|
||||
|
||||
this.invalidateUserDataSnapshot();
|
||||
}
|
||||
|
||||
public sendSpecialCommandMessage(text: string, styleId: number = 0): void
|
||||
|
||||
Reference in New Issue
Block a user