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
+1
-1
@@ -37,7 +37,7 @@
|
||||
"json5": "^2.2.3",
|
||||
"pako": "^2.1.0",
|
||||
"pixi-filters": "^6.1.5",
|
||||
"pixi.js": "^8.18.1"
|
||||
"pixi.js": "^8.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.13.0",
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface ISessionDataManager
|
||||
{
|
||||
init(): Promise<void>;
|
||||
getAllFurnitureData(): IFurnitureData[];
|
||||
mergeFurnitureDataFromUrl(url: string): Promise<IFurnitureData[]>;
|
||||
applyFurnitureDataOverrides(url: string): Promise<void>;
|
||||
clearFurnitureDataOverrides(): void;
|
||||
getFloorItemData(id: number): IFurnitureData;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -496,6 +496,8 @@ export class IncomingHeader
|
||||
|
||||
// Catalog Admin
|
||||
public static CATALOG_ADMIN_RESULT = 10059;
|
||||
public static CATALOG_ADMIN_OFFER_DETAILS = 10062;
|
||||
public static CATALOG_ADMIN_PAGE_DETAILS = 10063;
|
||||
|
||||
// Custom Prefixes
|
||||
public static USER_PREFIXES = 7001;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { IMessageEvent } from '@nitrots/api';
|
||||
import { MessageEvent } from '@nitrots/events';
|
||||
import { CatalogAdminOfferDetailsMessageParser } from '../../parser';
|
||||
|
||||
export class CatalogAdminOfferDetailsEvent extends MessageEvent implements IMessageEvent
|
||||
{
|
||||
constructor(callBack: Function)
|
||||
{
|
||||
super(callBack, CatalogAdminOfferDetailsMessageParser);
|
||||
}
|
||||
|
||||
public getParser(): CatalogAdminOfferDetailsMessageParser
|
||||
{
|
||||
return this.parser as CatalogAdminOfferDetailsMessageParser;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { IMessageEvent } from '@nitrots/api';
|
||||
import { MessageEvent } from '@nitrots/events';
|
||||
import { CatalogAdminPageDetailsMessageParser } from '../../parser';
|
||||
|
||||
export class CatalogAdminPageDetailsEvent extends MessageEvent implements IMessageEvent
|
||||
{
|
||||
constructor(callBack: Function)
|
||||
{
|
||||
super(callBack, CatalogAdminPageDetailsMessageParser);
|
||||
}
|
||||
|
||||
public getParser(): CatalogAdminPageDetailsMessageParser
|
||||
{
|
||||
return this.parser as CatalogAdminPageDetailsMessageParser;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
export * from './BonusRareInfoMessageEvent';
|
||||
export * from './CatalogAdminOfferDetailsEvent';
|
||||
export * from './CatalogAdminPageDetailsEvent';
|
||||
export * from './CatalogAdminResultEvent';
|
||||
export * from './BuildersClubFurniCountMessageEvent';
|
||||
export * from './BuildersClubSubscriptionStatusMessageEvent';
|
||||
|
||||
@@ -507,6 +507,8 @@ export class OutgoingHeader
|
||||
public static CATALOG_ADMIN_MOVE_OFFER = 10056;
|
||||
public static CATALOG_ADMIN_MOVE_PAGE = 10057;
|
||||
public static CATALOG_ADMIN_PUBLISH = 10058;
|
||||
public static CATALOG_ADMIN_LOAD_OFFER = 10062;
|
||||
public static CATALOG_ADMIN_LOAD_PAGE = 10063;
|
||||
|
||||
public static DELETE_ITEM = 10018;
|
||||
public static DELETE_PET = 10030;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { IMessageComposer } from '@nitrots/api';
|
||||
|
||||
export class CatalogAdminLoadOfferComposer implements IMessageComposer<ConstructorParameters<typeof CatalogAdminLoadOfferComposer>>
|
||||
{
|
||||
private _data: ConstructorParameters<typeof CatalogAdminLoadOfferComposer>;
|
||||
|
||||
constructor(offerId: number, catalogMode: string = 'NORMAL')
|
||||
{
|
||||
this._data = [ offerId, catalogMode ];
|
||||
}
|
||||
|
||||
dispose(): void
|
||||
{
|
||||
this._data = null;
|
||||
}
|
||||
|
||||
public getMessageArray()
|
||||
{
|
||||
return this._data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { IMessageComposer } from '@nitrots/api';
|
||||
|
||||
export class CatalogAdminLoadPageComposer implements IMessageComposer<ConstructorParameters<typeof CatalogAdminLoadPageComposer>>
|
||||
{
|
||||
private _data: ConstructorParameters<typeof CatalogAdminLoadPageComposer>;
|
||||
|
||||
constructor(pageId: number, catalogMode: string = 'NORMAL')
|
||||
{
|
||||
this._data = [ pageId, catalogMode ];
|
||||
}
|
||||
|
||||
dispose(): void
|
||||
{
|
||||
this._data = null;
|
||||
}
|
||||
|
||||
public getMessageArray()
|
||||
{
|
||||
return this._data;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ export * from './CatalogAdminCreateOfferComposer';
|
||||
export * from './CatalogAdminCreatePageComposer';
|
||||
export * from './CatalogAdminDeleteOfferComposer';
|
||||
export * from './CatalogAdminDeletePageComposer';
|
||||
export * from './CatalogAdminLoadOfferComposer';
|
||||
export * from './CatalogAdminLoadPageComposer';
|
||||
export * from './CatalogAdminMoveOfferComposer';
|
||||
export * from './CatalogAdminMovePageComposer';
|
||||
export * from './CatalogAdminPublishComposer';
|
||||
@@ -14,6 +16,8 @@ export * from './CatalogAdminCreateOfferComposer';
|
||||
export * from './CatalogAdminCreatePageComposer';
|
||||
export * from './CatalogAdminDeleteOfferComposer';
|
||||
export * from './CatalogAdminDeletePageComposer';
|
||||
export * from './CatalogAdminLoadOfferComposer';
|
||||
export * from './CatalogAdminLoadPageComposer';
|
||||
export * from './CatalogAdminMoveOfferComposer';
|
||||
export * from './CatalogAdminMovePageComposer';
|
||||
export * from './CatalogAdminPublishComposer';
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
|
||||
|
||||
export class CatalogAdminOfferDetailsMessageParser implements IMessageParser
|
||||
{
|
||||
private _offerId: number;
|
||||
private _offerIdGroup: number;
|
||||
private _limitedStack: number;
|
||||
private _orderNumber: number;
|
||||
|
||||
public flush(): boolean
|
||||
{
|
||||
this._offerId = -1;
|
||||
this._offerIdGroup = 0;
|
||||
this._limitedStack = 0;
|
||||
this._orderNumber = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public parse(wrapper: IMessageDataWrapper): boolean
|
||||
{
|
||||
if(!wrapper) return false;
|
||||
|
||||
this._offerId = wrapper.readInt();
|
||||
this._offerIdGroup = wrapper.readInt();
|
||||
this._limitedStack = wrapper.readInt();
|
||||
this._orderNumber = wrapper.readInt();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public get offerId(): number
|
||||
{
|
||||
return this._offerId;
|
||||
}
|
||||
|
||||
public get offerIdGroup(): number
|
||||
{
|
||||
return this._offerIdGroup;
|
||||
}
|
||||
|
||||
public get limitedStack(): number
|
||||
{
|
||||
return this._limitedStack;
|
||||
}
|
||||
|
||||
public get orderNumber(): number
|
||||
{
|
||||
return this._orderNumber;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
|
||||
|
||||
export class CatalogAdminPageDetailsMessageParser implements IMessageParser
|
||||
{
|
||||
private _pageId: number;
|
||||
private _caption: string;
|
||||
private _captionSave: string;
|
||||
private _minRank: number;
|
||||
private _orderNum: number;
|
||||
private _visible: boolean;
|
||||
private _enabled: boolean;
|
||||
|
||||
public flush(): boolean
|
||||
{
|
||||
this._pageId = -1;
|
||||
this._caption = '';
|
||||
this._captionSave = '';
|
||||
this._minRank = 1;
|
||||
this._orderNum = 0;
|
||||
this._visible = true;
|
||||
this._enabled = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public parse(wrapper: IMessageDataWrapper): boolean
|
||||
{
|
||||
if(!wrapper) return false;
|
||||
|
||||
this._pageId = wrapper.readInt();
|
||||
this._caption = wrapper.readString();
|
||||
this._captionSave = wrapper.readString();
|
||||
this._minRank = wrapper.readInt();
|
||||
this._orderNum = wrapper.readInt();
|
||||
this._visible = wrapper.readBoolean();
|
||||
this._enabled = wrapper.readBoolean();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public get pageId(): number { return this._pageId; }
|
||||
public get caption(): string { return this._caption; }
|
||||
public get captionSave(): string { return this._captionSave; }
|
||||
public get minRank(): number { return this._minRank; }
|
||||
public get orderNum(): number { return this._orderNum; }
|
||||
public get visible(): boolean { return this._visible; }
|
||||
public get enabled(): boolean { return this._enabled; }
|
||||
}
|
||||
@@ -3,6 +3,8 @@ export * from './BuildersClubFurniCountMessageParser';
|
||||
export * from './BuildersClubSubscriptionStatusMessageParser';
|
||||
export * from './BundleDiscountRuleset';
|
||||
export * from './BundleDiscountRulesetMessageParser';
|
||||
export * from './CatalogAdminOfferDetailsMessageParser';
|
||||
export * from './CatalogAdminPageDetailsMessageParser';
|
||||
export * from './CatalogAdminResultMessageParser';
|
||||
export * from './CatalogIndexMessageParser';
|
||||
export * from './CatalogLocalizationData';
|
||||
|
||||
@@ -5,6 +5,7 @@ export class MentionListItem
|
||||
private _mentionId: number;
|
||||
private _senderId: number;
|
||||
private _senderUsername: string;
|
||||
private _senderFigure: string;
|
||||
private _roomId: number;
|
||||
private _roomName: string;
|
||||
private _message: string;
|
||||
@@ -17,6 +18,10 @@ export class MentionListItem
|
||||
this._mentionId = wrapper.readInt();
|
||||
this._senderId = wrapper.readInt();
|
||||
this._senderUsername = wrapper.readString();
|
||||
// Wire order: sender_figure sits between username and roomId. The
|
||||
// server composer writes it unconditionally; an empty string is
|
||||
// produced for legacy rows where the column wasn't loaded.
|
||||
this._senderFigure = wrapper.readString();
|
||||
this._roomId = wrapper.readInt();
|
||||
this._roomName = wrapper.readString();
|
||||
this._message = wrapper.readString();
|
||||
@@ -28,6 +33,7 @@ export class MentionListItem
|
||||
public get mentionId(): number { return this._mentionId; }
|
||||
public get senderId(): number { return this._senderId; }
|
||||
public get senderUsername(): string { return this._senderUsername; }
|
||||
public get senderFigure(): string { return this._senderFigure; }
|
||||
public get roomId(): number { return this._roomId; }
|
||||
public get roomName(): string { return this._roomName; }
|
||||
public get message(): string { return this._message; }
|
||||
|
||||
+5
-2
@@ -23,7 +23,7 @@ describe('MentionReceivedParser', () =>
|
||||
it('parses a single mention without read flag', () =>
|
||||
{
|
||||
const w = new BinaryWriter();
|
||||
w.writeInt(7); w.writeInt(42); w.writeString('Bob'); w.writeInt(99);
|
||||
w.writeInt(7); w.writeInt(42); w.writeString('Bob'); w.writeString('hd-180-2.ch-210-66'); w.writeInt(99);
|
||||
w.writeString('My Room'); w.writeString('ciao @me'); w.writeInt(0); w.writeInt(1717000000);
|
||||
const parser = new MentionReceivedParser();
|
||||
parser.flush();
|
||||
@@ -32,6 +32,7 @@ describe('MentionReceivedParser', () =>
|
||||
expect(m.mentionId).toBe(7);
|
||||
expect(m.senderId).toBe(42);
|
||||
expect(m.senderUsername).toBe('Bob');
|
||||
expect(m.senderFigure).toBe('hd-180-2.ch-210-66');
|
||||
expect(m.roomId).toBe(99);
|
||||
expect(m.roomName).toBe('My Room');
|
||||
expect(m.message).toBe('ciao @me');
|
||||
@@ -46,7 +47,8 @@ describe('MentionsListParser', () =>
|
||||
it('parses a count-prefixed list with read flags', () =>
|
||||
{
|
||||
const w = new BinaryWriter();
|
||||
w.writeInt(1); w.writeInt(3); w.writeInt(42); w.writeString('Bob'); w.writeInt(99);
|
||||
w.writeInt(1);
|
||||
w.writeInt(3); w.writeInt(42); w.writeString('Bob'); w.writeString('hd-180-2.ch-210-66'); w.writeInt(99);
|
||||
w.writeString('My Room'); w.writeString('@all festa'); w.writeInt(1); w.writeInt(1717000000); w.writeByte(1);
|
||||
const parser = new MentionsListParser();
|
||||
parser.flush();
|
||||
@@ -54,6 +56,7 @@ describe('MentionsListParser', () =>
|
||||
expect(parser.mentions).toHaveLength(1);
|
||||
expect(parser.mentions[0].mentionId).toBe(3);
|
||||
expect(parser.mentions[0].senderUsername).toBe('Bob');
|
||||
expect(parser.mentions[0].senderFigure).toBe('hd-180-2.ch-210-66');
|
||||
expect(parser.mentions[0].read).toBe(true);
|
||||
expect(parser.mentions[0].mentionType).toBe(1);
|
||||
expect(parser.mentions[0].message).toBe('@all festa');
|
||||
|
||||
@@ -136,10 +136,6 @@ export class RoomPreviewer
|
||||
|
||||
public updatePreviewModel(model: string, wallHeight: number, scale: boolean = true): void
|
||||
{
|
||||
// Defensive: dispose() nulls _planeParser, and React 19
|
||||
// StrictMode dev double-mount can leave a stale reference
|
||||
// briefly pointing at a disposed instance. Bail rather
|
||||
// than crashing with "cannot read property reset of null".
|
||||
if(!this._planeParser) return;
|
||||
|
||||
const parser = new FloorHeightMapMessageParser();
|
||||
@@ -394,6 +390,11 @@ export class RoomPreviewer
|
||||
}
|
||||
}
|
||||
|
||||
public setAutomaticStateChange(enabled: boolean): void
|
||||
{
|
||||
this._automaticStateChange = enabled;
|
||||
}
|
||||
|
||||
public changeRoomObjectDirection(): void
|
||||
{
|
||||
if(this.isRoomEngineReady)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AlphaTolerance, IGraphicAsset, IObjectVisualizationData, IRoomGeometry, IRoomObjectSprite, RoomObjectVariable, RoomObjectVisualizationType } from '@nitrots/api';
|
||||
import { BlackToAlphaFilter, ChooserSelectionFilter } from '@nitrots/utils';
|
||||
import { ChooserSelectionFilter } from '@nitrots/utils';
|
||||
import { BLEND_MODES, Filter, Texture } from 'pixi.js';
|
||||
import { RoomObjectSpriteVisualization } from '../RoomObjectSpriteVisualization';
|
||||
import { ColorData, LayerData } from '../data';
|
||||
@@ -8,7 +8,6 @@ import { FurnitureVisualizationData } from './FurnitureVisualizationData';
|
||||
export class FurnitureVisualization extends RoomObjectSpriteVisualization
|
||||
{
|
||||
protected static DEPTH_MULTIPLIER: number = Math.sqrt(0.5);
|
||||
private static _blackToAlphaFilter: BlackToAlphaFilter = null;
|
||||
|
||||
public static TYPE: string = RoomObjectVisualizationType.FURNITURE_STATIC;
|
||||
|
||||
@@ -340,20 +339,7 @@ export class FurnitureVisualization extends RoomObjectSpriteVisualization
|
||||
|
||||
const chooserFilters = (sprite.filters || []).filter(f => f instanceof ChooserSelectionFilter);
|
||||
|
||||
if(sprite.blendMode === 'add' && !this.isBackgroundColorBlack())
|
||||
{
|
||||
if(!FurnitureVisualization._blackToAlphaFilter) FurnitureVisualization._blackToAlphaFilter = new BlackToAlphaFilter();
|
||||
|
||||
sprite.filters = chooserFilters.length > 0
|
||||
? [FurnitureVisualization._blackToAlphaFilter, ...chooserFilters]
|
||||
: [FurnitureVisualization._blackToAlphaFilter];
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.filters = chooserFilters.length > 0
|
||||
? [...this._filters, ...chooserFilters]
|
||||
: this._filters;
|
||||
}
|
||||
sprite.filters = chooserFilters.length > 0 ? [...this._filters, ...chooserFilters] : this._filters;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -224,6 +224,21 @@ export class SessionDataManager implements ISessionDataManager
|
||||
];
|
||||
}
|
||||
|
||||
// Mergia a runtime un chunk furnidata (es. custom/imported.json5) nelle Map
|
||||
// esistenti, SENZA reload del client. Ritorna gli entry aggiunti cosi il
|
||||
// chiamante puo' aggiornare anche il RoomContentLoader. Fa comparire i furni
|
||||
// appena importati nel catalogo in tempo reale.
|
||||
public async mergeFurnitureDataFromUrl(url: string): Promise<IFurnitureData[]>
|
||||
{
|
||||
if(!url || !url.length) return [];
|
||||
|
||||
const added = await this._furnitureData.mergeFromUrl(url);
|
||||
|
||||
if(added && added.length) GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SESSION_DATA_UPDATED));
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
public async applyFurnitureDataOverrides(url: string): Promise<void>
|
||||
{
|
||||
if(!url || !url.length)
|
||||
|
||||
@@ -37,9 +37,38 @@ export class FurnitureDataLoader
|
||||
if(responseData.wallitemtypes) this.parseWallItems(responseData.wallitemtypes);
|
||||
}
|
||||
|
||||
private parseFloorItems(data: any): void
|
||||
// Ri-carica un singolo chunk furnidata (es. custom/imported.json5) e
|
||||
// mergia i suoi entry nelle Map esistenti. Ritorna gli entry aggiunti/aggiornati
|
||||
// cosi il chiamante puo' aggiornare anche il RoomContentLoader senza reload.
|
||||
public async mergeFromUrl(url: string): Promise<IFurnitureData[]>
|
||||
{
|
||||
if(!data || !data.furnitype) return;
|
||||
if(!url || !url.length) return [];
|
||||
|
||||
let responseData: any;
|
||||
|
||||
try
|
||||
{
|
||||
responseData = await loadGamedata(url);
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
const added: IFurnitureData[] = [];
|
||||
|
||||
if(responseData.roomitemtypes) added.push(...this.parseFloorItems(responseData.roomitemtypes));
|
||||
|
||||
if(responseData.wallitemtypes) added.push(...this.parseWallItems(responseData.wallitemtypes));
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
private parseFloorItems(data: any): IFurnitureData[]
|
||||
{
|
||||
const added: IFurnitureData[] = [];
|
||||
|
||||
if(!data || !data.furnitype) return added;
|
||||
|
||||
for(const furniture of data.furnitype)
|
||||
{
|
||||
@@ -76,13 +105,19 @@ export class FurnitureDataLoader
|
||||
|
||||
this._floorItems.set(furnitureData.id, furnitureData);
|
||||
|
||||
added.push(furnitureData);
|
||||
|
||||
this.updateLocalizations(furnitureData);
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
private parseWallItems(data: any): void
|
||||
private parseWallItems(data: any): IFurnitureData[]
|
||||
{
|
||||
if(!data || !data.furnitype) return;
|
||||
const added: IFurnitureData[] = [];
|
||||
|
||||
if(!data || !data.furnitype) return added;
|
||||
|
||||
for(const furniture of data.furnitype)
|
||||
{
|
||||
@@ -93,8 +128,12 @@ export class FurnitureDataLoader
|
||||
|
||||
this._wallItems.set(furnitureData.id, furnitureData);
|
||||
|
||||
added.push(furnitureData);
|
||||
|
||||
this.updateLocalizations(furnitureData);
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
private updateLocalizations(furniture: FurnitureData): void
|
||||
|
||||
Reference in New Issue
Block a user