Arcturus' RoomSettingsComposer appends an extra int at the end of the
payload — room.isAllowUnderpass() ? 1 : 0 — and RoomSettingsSaveEvent
optionally reads back a boolean at the end (if bytesAvailable > 0).
The renderer side never modeled this trailing field, so the client
couldn't surface or persist it.
- RoomSettingsData: add _allowUnderpass field + getter/setter +
propagation through the .from() copy.
- RoomSettingsDataParser: read one trailing int after the moderation
settings, guarded by 'if(wrapper.bytesAvailable)' so older servers
that don't emit it keep parsing cleanly.
- SaveRoomSettingsComposer: optional trailing allowUnderpass arg. The
server's optional-read guard tolerates 24-arg or 25-arg payloads, so
callers that don't care about the field still send the legacy shape.
Cross-repo reference points:
- Arcturus emit side: Emulator/src/main/java/com/eu/habbo/messages/
outgoing/rooms/RoomSettingsComposer.java line 55.
- Arcturus read side: Emulator/src/main/java/com/eu/habbo/messages/
incoming/rooms/RoomSettingsSaveEvent.java lines 133-135.
Net client tsgo error count: 3 -> 0 on the NavigatorRoomSettings cluster.
Arcturus' RequestRoomLoadEvent reads the two extra ints only when
the inbound packet has 8+ bytes remaining after roomId+password, so
the renderer can send 2-arg or 4-arg payloads against the same
header. The client already calls 'new RoomEnterComposer(roomId,
password, spawnX, spawnY)' in two places inside RoomSession /
RoomSessionManager (the reconnect/respawn flow) — the composer
signature is what was lagging behind.
Server-side reference:
Arcturus-Morningstar-Extended/Emulator/src/main/java/com/eu/habbo/
messages/incoming/rooms/RequestRoomLoadEvent.java
bytesAvailable is a boolean (IMessageDataWrapper.bytesAvailable: boolean,
returns 'there is at least one byte left'); the parser was doing
'wrapper.bytesAvailable < 12' as if it were a count, which both
mis-compares boolean to number and short-circuits incorrectly when
exactly 11 bytes remain.
Align with every other parser in the codebase: 'if(!wrapper ||
!wrapper.bytesAvailable) return false;'. The downstream readInt
calls already throw on truncated packets so the explicit length
check was load-bearing only against malformed inputs that wouldn't
parse anyway.
WiredRoomSettingsRequestComposer and WiredUserVariablesRequestComposer
declared 'implements IMessageComposer<ConstructorParameters<typeof Self>>'
but neither defines a constructor, so ConstructorParameters resolved
to 'any[]' and getMessageArray() returning [] (any[]) failed the
narrower base-type signature () => [].
Both composers send zero payload; type as IMessageComposer<[]>
directly + annotate the return type.
- CatalogAdminSavePageImagesComposer (header 10060): pageId, headerImage, teaserImage
- CatalogAdminSavePageIconComposer (header 10061): pageId, iconId
- Registered in OutgoingHeader, catalog index, and NitroMessages
- Server handler required in Arcturus to process these packets
- parse extra room snapshot data such as hotel time, room item limit and group context
- expose richer furni metadata including flags, dimensions and teleport targets
- expose richer user metadata including room-entry fields and ids needed by inspection tools
- keep session and room engine models aligned with the new wired monitor/inspection flow
- Parser bounds: Added Math.min() caps on all loop counts: offers (1000), products (200), front page items (100), localization images/texts (100), node children (500)
- Recursion depth limit: Added static depth counter to NodeData with max depth of 20 to prevent stack overflow from deeply nested catalog trees
- add ClickUserMessageComposer and outgoing header wiring\n- send the user click packet from RoomObjectEventHandler for avatar single clicks\n- support wf_trg_click_user in the linked Nitro UI/emulator flow
- Validate data URL format (must start with data:image/png)
- Validate PNG magic bytes on binary data before sending
- Enforce 2MB size limit matching server
- Add try/catch around atob() to handle invalid base64 gracefully
- Fix XSS vulnerability in editor download: replace unsafe window.open()+document.write()
with safe anchor-based download that also validates data URL scheme
- add ClickUserMessageComposer and outgoing header wiring\n- send the user click packet from RoomObjectEventHandler for avatar single clicks\n- support wf_trg_click_user in the linked Nitro UI/emulator flow