feat(session): apply FurnitureDataReload delta + reload-hint (separate path)

This commit is contained in:
simoleo89
2026-06-04 22:01:08 +02:00
parent dbd398ae80
commit 1d6c102fd6
3 changed files with 100 additions and 2 deletions
+21 -2
View File
@@ -1,5 +1,7 @@
import { IFurnitureData, IGroupInformationManager, IMessageComposer, IMessageEvent, IProductData, ISessionDataManager, IUserDataSnapshot, 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 { AccountSafetyLockStatusChangeMessageEvent, AccountSafetyLockStatusChangeParser, AvailabilityStatusMessageEvent, ChangeUserNameResultMessageEvent, EmailStatusResultEvent, FigureUpdateEvent, FurnitureDataReloadEvent, GetCommunication, GetUserTagsComposer, InClientLinkEvent, MysteryBoxKeysEvent, NoobnessLevelMessageEvent, PetRespectComposer, PetScratchFailedMessageEvent, RoomReadyMessageEvent, RoomUnitChatComposer, UserInfoEvent, UserNameChangeMessageEvent, UserPermissionsEvent, UserRespectComposer, UserTagsMessageEvent } from '@nitrots/communication';
import type { FurnidataDeltaEntry } from '@nitrots/communication';
import { applyFurnidataDeltaTo } from './furniture/applyFurnidataDelta';
import { GetConfiguration } from '@nitrots/configuration'; import { GetConfiguration } from '@nitrots/configuration';
import { GetLocalizationManager } from '@nitrots/localization'; import { GetLocalizationManager } from '@nitrots/localization';
import { GetEventDispatcher, MysteryBoxKeysUpdateEvent, NitroEvent, NitroEventType, NitroSettingsEvent, SessionDataPreferencesEvent, UserNameUpdateEvent } from '@nitrots/events'; import { GetEventDispatcher, MysteryBoxKeysUpdateEvent, NitroEvent, NitroEventType, NitroSettingsEvent, SessionDataPreferencesEvent, UserNameUpdateEvent } from '@nitrots/events';
@@ -171,7 +173,13 @@ export class SessionDataManager implements ISessionDataManager
GetCommunication().registerMessageEvent(new MysteryBoxKeysEvent(this.onMysteryBoxKeysEvent.bind(this))), GetCommunication().registerMessageEvent(new MysteryBoxKeysEvent(this.onMysteryBoxKeysEvent.bind(this))),
GetCommunication().registerMessageEvent(new NoobnessLevelMessageEvent(this.onNoobnessLevelMessageEvent.bind(this))), GetCommunication().registerMessageEvent(new NoobnessLevelMessageEvent(this.onNoobnessLevelMessageEvent.bind(this))),
GetCommunication().registerMessageEvent(new AccountSafetyLockStatusChangeMessageEvent(this.onAccountSafetyLockStatusChangeMessageEvent.bind(this))), GetCommunication().registerMessageEvent(new AccountSafetyLockStatusChangeMessageEvent(this.onAccountSafetyLockStatusChangeMessageEvent.bind(this))),
GetCommunication().registerMessageEvent(new EmailStatusResultEvent(this.onEmailStatus.bind(this))) GetCommunication().registerMessageEvent(new EmailStatusResultEvent(this.onEmailStatus.bind(this))),
GetCommunication().registerMessageEvent(new FurnitureDataReloadEvent((event: FurnitureDataReloadEvent) =>
{
const parser = event.getParser();
if(parser.mode === 1) { void this.applyFurnidataReloadHint(); }
else { this.applyFurnidataDelta(parser.entries); }
}))
); );
// Store event dispatcher callback for cleanup // Store event dispatcher callback for cleanup
@@ -564,6 +572,17 @@ export class SessionDataManager implements ISessionDataManager
} }
} }
public applyFurnidataDelta(entries: FurnidataDeltaEntry[]): void
{
applyFurnidataDeltaTo(entries, this._floorItems as any, this._wallItems as any, GetLocalizationManager(), (typeof window !== 'undefined') ? window : { dispatchEvent: () => {} } as any);
}
public async applyFurnidataReloadHint(): Promise<void>
{
await this._furnitureData.init();
if(typeof window !== 'undefined') window.dispatchEvent(new CustomEvent('nitro-localization-updated'));
}
public getBadgeUrl(name: string): string public getBadgeUrl(name: string): string
{ {
return this._badgeImageManager.getBadgeUrl(name); return this._badgeImageManager.getBadgeUrl(name);
@@ -0,0 +1,36 @@
import { describe, expect, it, vi, beforeEach } from 'vitest';
import { applyFurnidataDeltaTo } from '../furniture/applyFurnidataDelta';
describe('applyFurnidataDeltaTo', () => {
const setValue = vi.fn();
beforeEach(() => setValue.mockClear());
it('patches floor FurnitureData name/desc + localization keys, dispatches window event', () => {
const floor: any = { _localizedName: 'Old', _description: 'Old desc' };
const floorItems = new Map<number, any>([[ 5, floor ]]);
const dispatched: string[] = [];
const win: any = { dispatchEvent: (e: any) => dispatched.push(e.type) };
applyFurnidataDeltaTo(
[ { type: 'S', id: 5, classname: 'chair', name: 'New', description: 'New desc' } ],
floorItems, new Map(), { setValue }, win
);
expect(floor._localizedName).toBe('New');
expect(floor._description).toBe('New desc');
expect(setValue).toHaveBeenCalledWith('roomItem.name.5', 'New');
expect(setValue).toHaveBeenCalledWith('roomItem.desc.5', 'New desc');
expect(dispatched).toContain('nitro-localization-updated');
});
it('patches wall items by id', () => {
const wall: any = { _localizedName: 'W', _description: '' };
const wallItems = new Map<number, any>([[ 9, wall ]]);
applyFurnidataDeltaTo(
[ { type: 'I', id: 9, classname: 'poster', name: 'WallNew', description: 'd' } ],
new Map(), wallItems, { setValue }, { dispatchEvent: () => {} }
);
expect(wall._localizedName).toBe('WallNew');
expect(setValue).toHaveBeenCalledWith('wallItem.name.9', 'WallNew');
});
});
@@ -0,0 +1,43 @@
import type { FurnidataDeltaEntry } from '@nitrots/communication';
/**
* Pure, testable furnidata-delta patcher. Mutates the FurnitureData objects in
* the given maps (by id) and the localization keys, then dispatches the
* `nitro-localization-updated` window event so subscribed React surfaces refresh.
*/
export function applyFurnidataDeltaTo(
entries: FurnidataDeltaEntry[],
floorItems: Map<number, any>,
wallItems: Map<number, any>,
localization: { setValue: (key: string, value: string) => void },
win: { dispatchEvent: (event: any) => void }
): void
{
if(!entries || !entries.length) return;
for(const e of entries)
{
if(e.type === 'I')
{
const wall = wallItems.get(e.id);
if(wall) { wall._localizedName = e.name; wall._description = e.description; }
localization.setValue('wallItem.name.' + e.id, e.name);
localization.setValue('wallItem.desc.' + e.id, e.description);
}
else
{
const floor = floorItems.get(e.id);
if(floor) { floor._localizedName = e.name; floor._description = e.description; }
localization.setValue('roomItem.name.' + e.id, e.name);
localization.setValue('roomItem.desc.' + e.id, e.description);
}
}
if(win && typeof win.dispatchEvent === 'function')
{
const evt = (typeof CustomEvent !== 'undefined')
? new CustomEvent('nitro-localization-updated')
: { type: 'nitro-localization-updated' } as any;
win.dispatchEvent(evt);
}
}