Commit Graph

21 Commits

Author SHA1 Message Date
simoleo89 159c5eb6e8 feat(session): resolved permission map snapshot (USER_PERMISSIONS_UPDATED)
Adds the wire pipeline for `Outgoing.UserPermissionsMapComposer = 10070`
shipped by Arcturus-Morningstar-Extended ≥ 4.2.10. The composer sends
the resolved `permission_definitions` map for the current user
(filtered to ALLOWED / ROOM_OWNER entries) at login and after every
`HabboManager.setRank` — so a runtime promote/demote re-derives every
React-side permission gate.

- NitroEventType.USER_PERMISSIONS_UPDATED — new invalidation event.
- IncomingHeader.USER_PERMISSIONS_MAP = 10070.
- UserPermissionsMapParser reads `int count + (string key, int value)*`.
- UserPermissionsMapEvent + NitroMessages registration.
- SessionDataManager._permissions Map + getPermissionsSnapshot()
  referentially-stable per the snapshot convention. New handler
  onUserPermissionsMapEvent copies the parser map into the manager
  (so the parser's mutable reference doesn't leak) and invalidates.
- ISessionDataManager.getPermissionsSnapshot() — public contract.

React-side consumers ship in the companion commit on
feat/react19-modernization. The wire is backward-compatible: older
emulators never send the packet, the snapshot stays empty Map, and
all useHasPermission(key) gates return false (mod-only UI hidden by
default = safe).

Verification: tsgo clean, vitest 138/138.
2026-05-19 18:59:35 +02:00
simoleo89 892d16b393 feat(sound): snapshot getter + volume-update event on SoundManager
Extends the snapshot pattern to the three audio volume levels (system /
furni / trax) so volume-slider widgets on the React client can subscribe
to a single source of truth via useSyncExternalStore.

API additions on ISoundManager:
- systemVolume / furniVolume getters (parity with the existing
  traxVolume getter)
- getVolumesSnapshot(): Readonly<ISoundVolumesSnapshot> with the same
  lazy-frozen + invalidation-on-change semantics as the user/session
  snapshots
- new ISoundVolumesSnapshot { system, furni, trax } interface

New event: NitroEventType.SOUND_VOLUMES_UPDATED. Dispatched only when
the incoming NitroSettingsEvent.SETTINGS_UPDATED actually changes one
of the three volumes (a no-op refresh stays quiet).

While in there, fixed a real bug: the previous implementation cached
`volumeFurniUpdated` / `volumeTraxUpdated` BEFORE writing the new
values, but read `castedEvent.volumeFurni` / `castedEvent.volumeTrax`
in their pre-division form — comparing percent (e.g. 75) against the
already-divided stored value (e.g. 0.75) — so the change check almost
always reported "updated" for a real settings push and never reported
"updated" if the percent matched the stored fraction by coincidence
(only 0/100 are stable). Updated check is now consistent (compare
fraction vs fraction) and also tracks systemVolume changes for the
new snapshot invalidation.
2026-05-18 20:55:12 +02:00
simoleo89 761d8ffe19 feat(session): snapshot getter for UserDataManager room user list
Extends the snapshot pattern to the room's user list. The React client
currently has many widgets each calling `getUserDataByIndex(idx)` in a
loop (chat, doorbell, room player list, infostand …) — every render
walks the underlying Map and rebuilds an array. With
`getRoomUserListSnapshot(): ReadonlyArray<IRoomUserData>` consumers can
memoize on the array reference and only rebuild when something actually
changed.

Invalidation fires on every state-changing path:
- updateUserData (add/replace)
- removeUserData (leave)
- updateFigure / updateName / updateMotto / updateNickIcon /
  updateCustomization / updateBackground / updateAchievementScore /
  updatePetLevel / updatePetBreedingStatus

The inner IRoomUserData objects keep their existing in-place mutation
semantics (deep-clone would be too expensive for 30+ avatars on every
single status push). Consumers should treat each entry as a
snapshot-at-time-of-read and not retain references across an
invalidation.

New event: NitroEventType.ROOM_USER_LIST_UPDATED. Interface and event
additions are backwards-compatible; no existing accessors changed.

Also tidied: `updatePetLevel` now uses the explicit `if(!userData)
return;` guard pattern matching the rest of the methods (was a one-line
inline conditional).
2026-05-18 20:52:33 +02:00
simoleo89 a599e0cf89 feat(session): snapshot getters for IgnoredUsersManager + GroupInformationManager
Extends the v2.1.0 React-friendly snapshot pattern (originally on
SessionDataManager / RoomSessionManager) to two more session-state
holders the React client reads frequently:

- IgnoredUsersManager.getIgnoredUsersSnapshot(): ReadonlyArray<string>
- GroupInformationManager.getGroupBadgesSnapshot(): ReadonlyMap<number, string>

Both follow the same shape: lazy-frozen snapshot, cached until the
underlying state mutates, then invalidated and a dispatched event lets
the React client rebuild via useSyncExternalStore.

Two new NitroEventType members carry the invalidation signal:
- IGNORED_USERS_UPDATED — dispatched by IgnoredUsersManager whenever
  the list changes (initial load, add, remove, queue-truncate case 2).
- GROUP_BADGES_UPDATED — dispatched by GroupInformationManager only
  when the incoming HabboGroupBadges payload contains at least one
  new or changed mapping (no-op refresh stays quiet).

This lets the user-info popup, profile page, friend/guild filtering,
and any other consumer share a single read through useSyncExternalStore
instead of each subscribing to the underlying message events
independently.

API additions are interface-respecting and backwards-compatible — the
existing `isIgnored(name)` / `getGroupBadge(groupId)` accessors stay
untouched.
2026-05-18 20:50:24 +02:00
simoleo89 ddb7222b66 chore: bump TypeScript pins to ^6.0.3 across all 12 workspaces + thumbmarkjs 1.9 + add CLAUDE.md
Each workspace package was still pinning `typescript: ~5.5.x` or
`~5.8.2` in its own devDependencies even though the root bumped to 6.0.3
in 60b1143. The pins were dead (yarn 1 hoists from root) but they're
misleading when reading a single package.json. Bring them all to
`^6.0.3` to match the root.

Other:
- @thumbmarkjs/thumbmarkjs 1.8.1 → 1.9.0 (root + communication package)
- yarn.lock regenerated from a clean install (vitest 4 hoisting was
  flaking on the patch vite bump; reverted vite to ^8.0.10)

Adds CLAUDE.md at the repo root: short project context for future
sessions — stack, the 12-workspace layout, the React-friendly v2.1.0
additions (`subscribe()`, `subscribeMessage()`, snapshot getters), build
scripts, and known gotchas (`SessionDataManager.getUserData` does NOT
exist; sendChat* expects 3 args; dispatchEvent is sync).
2026-05-10 21:29:50 +02:00
simoleo89 87cf47847c 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.
2026-05-10 19:16:32 +02:00
Lorenzune 5fc4564467 Merge remote-tracking branch 'duckie/main' into merge-duckie-main-2026-05-06
# Conflicts:
#	packages/communication/src/messages/parser/room/unit/RoomUnitInfoParser.ts
#	packages/communication/src/messages/parser/user/data/UserProfileParser.ts
#	packages/events/src/session/RoomSessionUserFigureUpdateEvent.ts
#	packages/session/src/handler/RoomUsersHandler.ts
2026-05-06 04:23:13 +02:00
duckietm 2f7b80e894 🆕 Card Background 2026-05-04 08:44:40 +02:00
Lorenzune 7bf552824f Sync renderer safety push 2026-04-21 08:57:35 +02:00
duckietm 4701c0b153 🆙 Automatic resume / reconnect when conection was lost 2026-03-23 13:24:32 +01:00
simoleo89 68af013c60 feat: custom prefix system protocol layer
Prefix parsers, composers and events:
- UserPrefixesParser, PrefixReceivedParser, ActivePrefixUpdatedParser
- PurchasePrefixComposer, SetActivePrefixComposer, DeletePrefixComposer, RequestPrefixesComposer
- RoomUnitChatParser reads prefixText/Color/Icon/Effect from chat packets
- RoomSessionChatEvent carries prefix data to client
- RoomChatHandler passes prefix fields through event chain
2026-03-20 17:22:50 +01:00
duckietm 958693fe2e 🆙 Stage 1 reconnect 2026-03-20 16:06:03 +01:00
duckietm 5aef7a3de2 🆕 Disconnection handler, when you got disconnected you automatic go back to the room 2026-03-19 15:04:47 +01:00
DuckieTM eb4fe80612 🆙 Updates
- Added Test Coverage
- Fix Potential Memory Leaks
2026-01-31 13:21:59 +01:00
duckietm 476f71a482 🆙 Add backgrounds to renderer 2025-05-22 10:31:31 +02:00
DuckieTM d864fe3018 🆙 Update Deps. + WiP 2025-03-15 14:54:10 +01:00
duckietm 14bf0fdcbd 🆙 Fix firework memory leak and update pixi.js 2024-09-13 08:04:35 +02:00
duckietm 1e4f45a107 🆙 the latest updates to Renderer 2024-07-15 10:23:54 +02:00
duckietm bd09ea8b25 🆙 added latest changes 2024-07-04 15:03:26 +02:00
duckietm 95bc0045ec Added Color to the Renderer and Avatar update 2024-04-04 09:26:05 +02:00
duckietm b3134ce50b Move to Renderer V2 2024-04-03 09:27:56 +02:00