Merge remote-tracking branch 'duckie-temp/main' into duckie-merge-2026-04-21

# Conflicts:
#	packages/communication/src/NitroMessages.ts
#	packages/communication/src/messages/incoming/IncomingHeader.ts
#	packages/communication/src/messages/outgoing/OutgoingHeader.ts
This commit is contained in:
Lorenzune
2026-04-21 11:20:02 +02:00
20 changed files with 218 additions and 1 deletions
@@ -6,6 +6,7 @@ import { WiredMovementsEvent } from './messages';
import { ConfInvisStateMessageEvent } from './messages';
import { HanditemBlockStateMessageEvent } from './messages';
import { TranslationLanguagesEvent, TranslationLanguagesRequestComposer, TranslationResultEvent, TranslationTextRequestComposer } from './messages';
import { YouTubeRoomBroadcastEvent, YouTubeRoomPlayComposer, YouTubeRoomSettingsComposer, YouTubeRoomSettingsEvent, YouTubeRoomWatchersEvent, YouTubeRoomWatchingComposer } from './messages';
export class NitroMessages implements IMessageConfiguration
{
private _events: Map<number, Function>;
@@ -501,6 +502,9 @@ export class NitroMessages implements IMessageConfiguration
this._events.set(IncomingHeader.HANDITEM_BLOCK_STATE, HanditemBlockStateMessageEvent);
this._events.set(IncomingHeader.TRANSLATION_LANGUAGES, TranslationLanguagesEvent);
this._events.set(IncomingHeader.TRANSLATION_RESULT, TranslationResultEvent);
this._events.set(IncomingHeader.YOUTUBE_ROOM_BROADCAST, YouTubeRoomBroadcastEvent);
this._events.set(IncomingHeader.YOUTUBE_ROOM_SETTINGS, YouTubeRoomSettingsEvent);
this._events.set(IncomingHeader.YOUTUBE_ROOM_WATCHERS, YouTubeRoomWatchersEvent);
this._events.set(IncomingHeader.WIRED_REWARD, WiredRewardResultMessageEvent);
this._events.set(IncomingHeader.WIRED_SAVE, WiredSaveSuccessEvent);
this._events.set(IncomingHeader.WIRED_ERROR, WiredValidationErrorEvent);
@@ -1248,6 +1252,9 @@ export class NitroMessages implements IMessageConfiguration
this._composers.set(OutgoingHeader.PURCHASE_PREFIX, PurchasePrefixComposer);
this._composers.set(OutgoingHeader.PURCHASE_CATALOG_PREFIX, PurchaseCatalogPrefixComposer);
this._composers.set(OutgoingHeader.SET_DISPLAY_ORDER, SetDisplayOrderComposer);
this._composers.set(OutgoingHeader.YOUTUBE_ROOM_PLAY, YouTubeRoomPlayComposer);
this._composers.set(OutgoingHeader.YOUTUBE_ROOM_SETTINGS, YouTubeRoomSettingsComposer);
this._composers.set(OutgoingHeader.YOUTUBE_ROOM_WATCHING, YouTubeRoomWatchingComposer);
}
public get events(): Map<number, Function>
@@ -498,4 +498,9 @@ export class IncomingHeader
public static PREFIX_RECEIVED = 7002;
public static ACTIVE_PREFIX_UPDATED = 7003;
public static USER_NICK_ICONS = 7004;
// YouTube Room Broadcast
public static YOUTUBE_ROOM_BROADCAST = 8001;
public static YOUTUBE_ROOM_WATCHERS = 8002;
public static YOUTUBE_ROOM_SETTINGS = 8003;
}
@@ -13,3 +13,4 @@ export * from './pet';
export * from './session';
export * from './unit';
export * from './unit/chat';
export * from './youtube';
@@ -0,0 +1,16 @@
import { IMessageEvent } from '@nitrots/api';
import { MessageEvent } from '@nitrots/events';
import { YouTubeRoomBroadcastParser } from '../../../parser';
export class YouTubeRoomBroadcastEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, YouTubeRoomBroadcastParser);
}
public getParser(): YouTubeRoomBroadcastParser
{
return this.parser as YouTubeRoomBroadcastParser;
}
}
@@ -0,0 +1,16 @@
import { IMessageEvent } from '@nitrots/api';
import { MessageEvent } from '@nitrots/events';
import { YouTubeRoomSettingsParser } from '../../../parser';
export class YouTubeRoomSettingsEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, YouTubeRoomSettingsParser);
}
public getParser(): YouTubeRoomSettingsParser
{
return this.parser as YouTubeRoomSettingsParser;
}
}
@@ -0,0 +1,16 @@
import { IMessageEvent } from '@nitrots/api';
import { MessageEvent } from '@nitrots/events';
import { YouTubeRoomWatchersParser } from '../../../parser';
export class YouTubeRoomWatchersEvent extends MessageEvent implements IMessageEvent
{
constructor(callBack: Function)
{
super(callBack, YouTubeRoomWatchersParser);
}
public getParser(): YouTubeRoomWatchersParser
{
return this.parser as YouTubeRoomWatchersParser;
}
}
@@ -0,0 +1,3 @@
export * from './YouTubeRoomBroadcastEvent';
export * from './YouTubeRoomSettingsEvent';
export * from './YouTubeRoomWatchersEvent';
@@ -517,4 +517,9 @@ export class OutgoingHeader
public static SET_ACTIVE_NICK_ICON = 7017;
public static PURCHASE_CATALOG_PREFIX = 7018;
public static SET_DISPLAY_ORDER = 7019;
// YouTube Room Broadcast
public static YOUTUBE_ROOM_PLAY = 8001;
public static YOUTUBE_ROOM_WATCHING = 8002;
public static YOUTUBE_ROOM_SETTINGS = 8003;
}
@@ -17,3 +17,4 @@ export * from './RedeemItemClothingComposer';
export * from './session';
export * from './unit';
export * from './unit/chat';
export * from './youtube';
@@ -0,0 +1,14 @@
import { IMessageComposer } from '@nitrots/api';
export class YouTubeRoomPlayComposer implements IMessageComposer<any[]>
{
private _data: any[];
constructor(videoId: string, playlist: string[])
{
this._data = [videoId, playlist.length, ...playlist];
}
public getMessageArray() { return this._data; }
public dispose(): void {}
}
@@ -0,0 +1,14 @@
import { IMessageComposer } from '@nitrots/api';
export class YouTubeRoomSettingsComposer implements IMessageComposer<any[]>
{
private _data: any[];
constructor(enabled: boolean)
{
this._data = [enabled ? 1 : 0];
}
public getMessageArray() { return this._data; }
public dispose(): void {}
}
@@ -0,0 +1,16 @@
import { IMessageComposer } from '@nitrots/api';
export class YouTubeRoomWatchingComposer implements IMessageComposer<any[]>
{
private _data: any[];
constructor(watching: boolean)
{
// Send as int (0/1) instead of bare boolean to avoid
// serialization ambiguity in the Nitro wire protocol.
this._data = [watching ? 1 : 0];
}
public getMessageArray() { return this._data; }
public dispose(): void {}
}
@@ -0,0 +1,3 @@
export * from './YouTubeRoomPlayComposer';
export * from './YouTubeRoomSettingsComposer';
export * from './YouTubeRoomWatchingComposer';
@@ -1,14 +1,16 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
export class BadgeReceivedParser implements IMessageParser
{
private _badgeId: number;
private _badgeCode: string;
private _senderName: string;
public flush(): boolean
{
this._badgeId = 0;
this._badgeCode = null;
this._senderName = '';
return true;
}
@@ -19,6 +21,10 @@ export class BadgeReceivedParser implements IMessageParser
this._badgeId = wrapper.readInt();
this._badgeCode = wrapper.readString();
// Extra field appended by the Arcturus-Nitro fork: sender username for
// badges awarded by a staff member via the `:badge` command. Read
// defensively so older servers that don't send it still parse cleanly.
this._senderName = wrapper.bytesAvailable ? wrapper.readString() : '';
return true;
}
@@ -32,4 +38,9 @@ export class BadgeReceivedParser implements IMessageParser
{
return this._badgeCode;
}
public get senderName(): string
{
return this._senderName;
}
}
@@ -13,3 +13,4 @@ export * from './pet';
export * from './session';
export * from './unit';
export * from './unit/chat';
export * from './youtube';
@@ -0,0 +1,35 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
export class YouTubeRoomBroadcastParser implements IMessageParser
{
private _videoId: string;
private _senderName: string;
private _playlist: string[];
public flush(): boolean
{
this._videoId = '';
this._senderName = '';
this._playlist = [];
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._videoId = wrapper.readString();
this._senderName = wrapper.readString();
const count = wrapper.readInt();
this._playlist = [];
for(let i = 0; i < count; i++)
{
this._playlist.push(wrapper.readString());
}
return true;
}
public get videoId(): string { return this._videoId; }
public get senderName(): string { return this._senderName; }
public get playlist(): string[] { return this._playlist; }
}
@@ -0,0 +1,21 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
export class YouTubeRoomSettingsParser implements IMessageParser
{
private _youtubeEnabled: boolean;
public flush(): boolean
{
this._youtubeEnabled = false;
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
this._youtubeEnabled = wrapper.readInt() === 1;
return true;
}
public get youtubeEnabled(): boolean { return this._youtubeEnabled; }
}
@@ -0,0 +1,27 @@
import { IMessageDataWrapper, IMessageParser } from '@nitrots/api';
export class YouTubeRoomWatchersParser implements IMessageParser
{
private _watcherIds: number[];
public flush(): boolean
{
this._watcherIds = [];
return true;
}
public parse(wrapper: IMessageDataWrapper): boolean
{
if(!wrapper) return false;
const count = wrapper.readInt();
this._watcherIds = [];
for(let i = 0; i < count; i++)
{
this._watcherIds.push(wrapper.readInt());
}
return true;
}
public get watcherIds(): number[] { return this._watcherIds; }
}
@@ -0,0 +1,3 @@
export * from './YouTubeRoomBroadcastParser';
export * from './YouTubeRoomSettingsParser';
export * from './YouTubeRoomWatchersParser';
+2
View File
@@ -239,6 +239,8 @@ export class RoomPreviewer
if(this.isRoomEngineReady)
{
if((this._currentPreviewObjectCategory === RoomObjectCategory.FLOOR) && (this._currentPreviewObjectType === classId) && (this._currentPreviewObjectData === (extra || ''))) return RoomPreviewer.PREVIEW_OBJECT_ID;
this.reset(false);
this._currentPreviewObjectType = classId;