Commit Graph

768 Commits

Author SHA1 Message Date
simoleo89 dac83e8a62 docs(earnings): define emulator rewards center 2026-06-15 20:25:48 +02:00
DuckieTM c48e01cb8e Merge pull request #205 from Lorenzune/pr-emulator-release-dispatch
Allow manual emulator release workflow
2026-06-15 07:25:13 +02:00
DuckieTM 916cf9ba9e Merge pull request #203 from simoleo89/fix/housekeeping-core-peer-rank
fix(housekeeping): harden privileged staff actions
2026-06-15 07:24:55 +02:00
DuckieTM 0af489cef2 Merge pull request #199 from simoleo89/fix/modtool-sanction-rank-ceilings
fix(modtool): enforce permissions and sanction rank ceilings
2026-06-15 07:24:30 +02:00
DuckieTM 6171ec7bab Merge pull request #198 from simoleo89/chore/deps-resilience-validation
fix(rcon): harden privileged commands and payloads
2026-06-15 07:24:12 +02:00
DuckieTM c048713b22 Merge branch 'dev' into chore/deps-resilience-validation 2026-06-15 07:24:02 +02:00
DuckieTM e5e3918513 Merge pull request #190 from simoleo89/fix/catalog-page-mutation-guards
fix(catalog): harden admin mutations and voucher claims
2026-06-15 07:22:47 +02:00
DuckieTM 14593b4638 Merge pull request #188 from simoleo89/fix/furnieditor-update-validation
fix(furni-editor): validate and sync furnidata changes
2026-06-15 07:22:24 +02:00
DuckieTM c199d805d8 Merge pull request #184 from simoleo89/fix/guild-badge-packet-parts
fix(guilds): validate badge packets and memberships
2026-06-15 07:22:01 +02:00
DuckieTM 3282430b67 Merge pull request #183 from simoleo89/fix/command-description-texts
fix(commands): complete and quiet command descriptions
2026-06-15 07:21:39 +02:00
DuckieTM 560def21d7 Merge pull request #180 from simoleo89/fix/items-ownership-and-charges
fix(items): harden ownership and redeem lifecycle
2026-06-15 07:21:09 +02:00
DuckieTM 5011fdf848 Merge pull request #179 from simoleo89/fix/rooms-self-moderation-scope
fix(rooms): scope room actions and bound rights removal
2026-06-15 07:20:41 +02:00
DuckieTM d34b44a656 Merge pull request #177 from simoleo89/style/startup-console
style(startup): console banner/splash/colors
2026-06-15 07:20:23 +02:00
DuckieTM 848b8bd5ce Merge pull request #176 from simoleo89/fix/messages-duplicate-aliases
fix(messages): silence duplicate packet aliases
2026-06-15 07:19:39 +02:00
DuckieTM 80400f828c Merge pull request #172 from simoleo89/fix/marketplace-claimed-payout
fix(marketplace): only pay out claimed offers after detach
2026-06-15 07:19:10 +02:00
DuckieTM 6868dd8d3d Merge pull request #171 from simoleo89/fix/trading-persistence-abort
fix(trading): harden trade lifecycle
2026-06-15 07:18:51 +02:00
Lorenzune 9f1e036310 Allow manual emulator release workflow 2026-06-15 02:16:23 +02:00
simoleo89 ec24283e0f fix(housekeeping): protect room owner mutations 2026-06-14 22:17:47 +02:00
simoleo89 93c4565660 fix(housekeeping): bound staff supplied text 2026-06-14 22:14:41 +02:00
simoleo89 31027095ec fix(housekeeping): enforce rank ceilings on rank changes 2026-06-14 21:55:19 +02:00
simoleo89 aa6dcd1062 fix(rcon): bound alert payloads 2026-06-14 21:40:59 +02:00
simoleo89 11554eae7b fix(rcon): validate social and room commands 2026-06-14 21:23:21 +02:00
simoleo89 25273679a1 fix(rcon): constrain remote command execution 2026-06-14 21:18:28 +02:00
simoleo89 15b56f9519 fix(rcon): bound mute and achievement mutations 2026-06-14 21:13:24 +02:00
simoleo89 8412a51ec4 fix(rcon): guard user update mutations 2026-06-14 21:02:28 +02:00
simoleo89 5d8dc670bd fix(rcon): cap subscription duration changes 2026-06-14 21:02:28 +02:00
simoleo89 81c8dfc605 fix(rcon): harden gift creation requests 2026-06-14 21:02:27 +02:00
simoleo89 4747699656 fix(rcon): validate room ownership and clothing grants 2026-06-14 21:02:27 +02:00
simoleo89 dba0337a7b fix(rcon): validate grant requests 2026-06-14 21:02:18 +02:00
simoleo89 3cb24a5185 fix(rcon): constrain setrank requests 2026-06-14 21:01:27 +02:00
simoleo89 775197984f fix(rcon): validate offline badge targets
GiveBadge could treat a missing offline user as eligible for a badge and insert through a nullable user subquery. Depending on SQL mode this could fail late or persist an orphaned user_id value. Resolve the offline user first, return HABBO_NOT_FOUND when absent, and insert badges with the resolved user id only.
2026-06-14 21:01:27 +02:00
simoleo89 4eafb54c57 fix(rcon): allow online motto updates outside rooms
SetMotto updated the in-memory motto and then unconditionally broadcast RoomUserData through the current room. Online users without a current room could throw a null-pointer exception after the state change, making the RCON call report an error despite mutating the user. Only broadcast room data when a room is present and cover the invariant with a contract test.
2026-06-14 21:01:26 +02:00
simoleo89 d8260ec461 fix(rcon): bind offline respect counters correctly
GiveRespect inverted the offline SQL parameters for respects_given and respects_received. Online users received the intended counters, but offline users had the two persisted counters swapped. Bind respect_given to respects_given and respect_received to respects_received, with a contract test to keep the RCON offline path aligned.
2026-06-14 21:01:26 +02:00
simoleo89 b94acdf719 fix(rcon): report missing offline credit targets
GiveCredits treated offline UPDATE execution as success without checking whether any user row was changed. Nonexistent user ids could therefore return an offline success response while granting nothing. Use executeUpdate(), return HABBO_NOT_FOUND when no row is affected, and keep SQL errors from falling through to the offline success message.
2026-06-14 21:01:26 +02:00
simoleo89 4330bf5a62 fix(rcon): always release inbound buffers
RCONServerHandler released the inbound ByteBuf only after successfully parsing, writing, flushing, and closing the response. Any exception before the tail release could leak Netty buffers and let malformed RCON traffic consume memory over time. Guard non-ByteBuf messages, release accepted buffers from a finally block, and add a contract test for the release invariant.
2026-06-14 21:01:16 +02:00
simoleo89 aaad94f954 fix(rcon): upsert offline pixel grants
RCON GivePixels previously used an UPDATE for offline users, so users without an existing users_currency type 0 row received no pixels while the command still returned success. Match the GivePoints and housekeeping paths with an upsert and add a contract test that keeps offline pixel grants creating missing currency rows.
2026-06-14 21:00:49 +02:00
simoleo89 d9cf70910f fix(housekeeping): cap sanction durations safely 2026-06-14 21:00:37 +02:00
simoleo89 fe0ba3b9e9 fix(housekeeping): validate grant mutations 2026-06-14 20:59:51 +02:00
simoleo89 4b81997e62 test(housekeeping): cover rank and currency audit logs
Rank changes and manual currency grants are among the highest-risk housekeeping actions. They already write audit entries, but the coverage contract did not list them, so a future regression could silently remove those logs. Extend the contract test to require audit logging for credit grants, currency grants, and rank changes.
2026-06-14 20:59:15 +02:00
simoleo89 79d734ef26 fix(housekeeping): audit room and session actions
The first audit coverage pass covered economy/account-impacting HK actions, but room and session mutators still returned success without an audit row. Add audit entries for room deletion, force disconnect, room kicks, user kicks, room mute, room state changes, and successful unbans, and extend the coverage contract to keep these privileged actions tracked.
2026-06-14 20:59:15 +02:00
simoleo89 dbcf139a52 fix(housekeeping): audit sensitive actions
Several privileged housekeeping handlers returned success without appending an audit entry, so the action log stayed incomplete even after the log table schema was fixed. Add audit writes for ban, mute, password reset, HC changes, trade lock, item grants, room ownership transfer, and hotel alerts, and cover the expected logging surface with a contract test.
2026-06-14 20:59:14 +02:00
simoleo89 98aab95d58 fix(housekeeping): align audit log schema
Housekeeping audit writes used an obsolete housekeeping_log schema with operator_id, operator_name, target_user_id and ip columns, while the migration and list composer read actor_id, actor_name, target_type, target_id, target_label, action, detail and success. That made log inserts fail against migrated databases and made auto-created tables unreadable by the client. Align the writer and auto-create DDL with the action-log schema, preserve operator IP in detail, and add a contract test for schema drift.
2026-06-14 20:59:14 +02:00
simoleo89 fb85952e88 fix(modtool): require support permission for kicks
ModToolKickEvent was the only staff-only modtool handler that called the moderation kick path without checking ACC_SUPPORTTOOL first. Gate it with the same support-tool permission and scripter handling used by the neighboring moderation actions, and add a contract test that keeps all staff-only modtool handlers behind ACC_SUPPORTTOOL.
2026-06-14 20:59:00 +02:00
simoleo89 54ef2ee251 docs(furni-editor): design spec — create furnidata entry if missing (upsert) 2026-06-14 20:58:23 +02:00
simoleo89 df2a849adc fix(rooms): bound rights removal batches 2026-06-14 20:58:23 +02:00
simoleo89 8e21765676 fix(polls): scope answers to active room poll
Require poll answer, cancel, and question-data packets to match the poll configured on the caller's current room. Previously a crafted packet could target any loaded poll id and submit the final question directly, including badge-reward polls, without being in a room where that poll was active.

Keep word quiz handling null-safe and add a contract test covering current-room poll scoping for all poll handlers.
2026-06-14 20:58:23 +02:00
simoleo89 0081280328 fix(catalog): claim vouchers before rewards
Move voucher exhaustion checks and history persistence behind a synchronized per-voucher claim path. Rewards are now applied only after the history row is inserted successfully, preventing duplicate or failed-claim redemption from granting credits, points, or catalog items.

Adds a contract test for claim ordering. Maven verification was attempted but blocked by sandbox network/plugin resolution after escalation usage was exhausted; diff --check passes.
2026-06-14 20:56:37 +02:00
simoleo89 2bc4340ec9 feat(furni-editor): create furnidata entry when missing (upsert on 10046)
FurniEditorUpdateFurnidataEvent (10046) was edit-only: FurnidataWriter.write()
refuses classnames absent from furnidata, so a furni with no entry showed the
DB-fallback name with locked fields and "Classname not found". Make it an upsert:

- FurnidataWriter.create(): append a complete entry (JSON5-preserving, atomic +
  backup) into the matching roomitemtypes/wallitemtypes furnitype array; guards
  against duplicate classname (ALREADY_EXISTS) and id collision (ID_COLLISION);
  split-tier writes to items.furnidata.create_tier (default "custom", file
  created with a shell if absent), single-file writes to the source.
- FurnidataEntryBuilder: build the complete entry from the item's items_base row
  (id = sprite id, classname, type-driven section, xdim/ydim, canstandon/
  cansiton/canlayon, name/desc, sane defaults matching existing entries).
- Handler: on write()==false, load the Item, build + create the entry, map
  CreateResult to a precise message; then the existing reindex + 10047 broadcast
  + public_name mirror run for both paths; audit action is "create" vs "edit".

No renderer change, no new packet. Pairs with the client unlocking name/desc when
the entry is missing (separate Nitro-V3 change).
2026-06-14 20:56:37 +02:00
simoleo89 93e5ea15aa docs(furni-editor): implementation plan — create furnidata entry if missing 2026-06-14 20:56:37 +02:00
simoleo89 aec61064ae fix(furnidata): prefer renderer config source
Resolve furnidata from the renderer config and asset base before falling back to the legacy items.furnidata.path override. This keeps the emulator aligned with the same furnidata URL the UI/renderer already consume.

Keep the legacy path as a compatibility fallback for older installs, but stop exposing absolute furnidata file paths in the startup log. The provider now reports a compact manager-style source label instead.

Add coverage proving renderer-config furnidata.url wins over the legacy path when both are present.
2026-06-14 20:56:37 +02:00