You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
8b51be4940
Backward-compatible wire extension of `UserPermissionsComposer`
(header 411) that lets Nitro clients display per-deployment rank
info and drive UI gates against the actual `permission_definitions`
table instead of hardcoded SecurityLevel constants.
Wire layout after this change (each trailing block is guarded by
`bytesAvailable` on the client side so older Nitro builds keep
parsing the prefix and stop):
int clubLevel
int rank.level // mapped to securityLevel on the client
bool isAmbassador // existing ACC_AMBASSADOR flag
--- new: rank metadata ---
int rank.id
string rank.name // permission_ranks.rank_name
string rank.badge
string rank.prefix
string rank.prefixColor
--- new: resolved permission map ---
int count
loop: string permission_key + int value // 1 = ALLOWED, 2 = ROOM_OWNER
The permission map is the union of:
* Rank entries whose `PermissionSetting != DISALLOWED` (value 1
for ALLOWED, 2 for ROOM_OWNER).
* For every rank-DISALLOWED key, each installed
`HabboPlugin.hasPermission(habbo, key)` is consulted; if any
plugin grants the permission, the key lands on the wire with
value 1 (plugins do not have a ROOM_OWNER concept).
Iterating `rank.getPermissions().keySet()` covers every key in
`permission_definitions` because `PermissionsManager.loadPermissionsNormalized()`
calls `rank.setPermission(key, ...)` for every row of the table —
including DISALLOWED ones. Custom keys a plugin invents that are
not in `permission_definitions` stay invisible (there is no
enumeration API on `HabboPlugin` to discover them); this is a rare
case documented in the class-level Javadoc.
The result is a client-side permission map whose semantics match
exactly what `PermissionsManager.hasPermission(habbo, key)` would
return server-side — including plugin-granted permissions, which
were invisible to the client before.
Performance: at login the loop is O(N keys × P plugins), with
N ≈ 200 (size of permission_definitions) and P typically 1-5.
`HabboPlugin.hasPermission` is O(1) hashset lookups in
real-world implementations. Sub-millisecond at login, and the
composer is only sent at login + `HabboManager.setRank` +
`:update_permissions` broadcast.
Backward compatibility: all new fields are appended in tail
position with `bytesAvailable` guards on the parser side, so:
* existing Nitro clients keep parsing only the prefix and ignore
the trailing bytes (no error, no behavior change);
* new Nitro clients with the matching parser extension expose the
extra data via `IUserDataSnapshot` snapshot getters and the
React-side `useUserRank()` / `useHasPermission(key)` /
`useUserPermissions()` hooks (see companion PRs on
`duckietm/Nitro_Render_V3` and `duckietm/Nitro-V3`).