Commit Graph

883 Commits

Author SHA1 Message Date
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
simoleo89 8db6281cc8 fix(guilds): only accept pending memberships
Guard the guild acceptance update with level_id = REQUESTED so a stale or concurrent accept cannot promote a membership row that has already changed state.

Tests: mvn '-Dtest=GuildManagerMembershipContractTest,GuildMembershipManagementContractTest,GuildMembershipRequestContractTest' test
2026-06-14 20:56:36 +02:00
simoleo89 8672c2d0ea fix(catalog): validate admin offer payloads 2026-06-14 20:56:36 +02:00
simoleo89 a92feb2ef0 fix(commands): quiet optional descriptions 2026-06-14 20:56:35 +02:00
simoleo89 478c4c70b8 fix(trading): prevent duplicate active trades
Guard RoomTradeManager.startTrade while holding the activeTrades lock so concurrent trade starts cannot register the same participant in multiple active trades before room status updates settle.

Add a contract test covering the lock-scoped participant guard and keep the existing trade safety tests green.
2026-06-14 20:56:34 +02:00
simoleo89 7ba0029ba8 fix(bots): preserve owner on pickup
Room owners can remove bots from their room, but picking up another user's bot must return it to the original owner instead of transferring ownership to the picker.

Tests: mvn -Dtest=BotPickupOwnershipContractTest test; mvn -DskipTests package
2026-06-14 20:51:19 +02:00
simoleo89 39c6e24097 fix(items): persist clothing grants before redeem
Redeeming clothing furniture now inserts the wardrobe grant before removing/deleting the voucher furniture. If the DB insert fails, the item remains in the room and the in-memory wardrobe is not updated.

Tests: mvn -Dtest=RedeemClothingContractTest test; mvn -DskipTests package
2026-06-14 20:51:19 +02:00
simoleo89 2b18ca2deb fix(housekeeping): allow core rank peer actions
Keep the housekeeping rank ceiling for normal staff, but treat the highest configured rank as the core rank so rank 7 can act on other rank 7 users without opening peer actions for lower staff ranks.

Tests: mvn '-Dtest=HousekeepingTargetRankGuardContractTest,HousekeepingMutationGuardTest,HousekeepingSetUserRankEventTest,HousekeepingTargetRankGuardContractTest' test
2026-06-14 20:24:51 +02:00
simoleo89 9ac50600f6 fix(housekeeping): enforce target rank ceiling 2026-06-14 20:24:50 +02:00
simoleo89 edddc551c5 fix(modtool): enforce sanction rank ceilings 2026-06-14 19:17:27 +02:00
simoleo89 1a03b8f3a9 fix(gui): require explicit dashboard autostart 2026-06-14 19:01:40 +02:00
simoleo89 d7fa02a453 fix(rcon): validate privileged payloads 2026-06-14 18:42:52 +02:00
simoleo89 994d539caf fix(rcon): rate limit remote command bursts 2026-06-14 18:31:58 +02:00
simoleo89 c6e43c6d55 fix(config): keep gui disabled by default 2026-06-14 18:18:20 +02:00
simoleo89 61972dafa4 fix(config): register gui enabled default 2026-06-14 18:15:29 +02:00
simoleo89 14a590235c fix(console): install jansi for forced ansi startup 2026-06-14 18:15:29 +02:00
simoleo89 39d21daeff chore(deps): add resilience and validation libraries 2026-06-14 17:56:20 +02:00
simoleo89 c9214bac07 fix(catalog): guard page mutations 2026-06-14 16:40:57 +02:00
simoleo89 fdcd3a7323 fix(furnieditor): validate item update payloads 2026-06-14 16:23:59 +02:00
simoleo89 7a7e38311d fix(guilds): validate badge packet parts 2026-06-14 15:51:43 +02:00
simoleo89 4359650621 fix(texts): add missing command descriptions 2026-06-14 15:51:10 +02:00
simoleo89 82c6f3f9ff fix(items): charge rentable space purchases
Deduct the computed rent cost when a user rents an InteractionRentableSpace. The previous flow only checked that the user had enough credits, then marked the space as rented without charging them, allowing free weekly rentals.

Honor ACC_INFINITE_CREDITS for staff accounts and add a contract test that keeps the charge before the rented state is assigned.
2026-06-13 18:24:16 +02:00
simoleo89 60ccc8c80b fix(items): require seed ownership for monsterplants
Reject monsterplant seed redemption when the caller does not own the placed seed. Without this guard, a user in the same room could trigger ToggleFloorItemEvent against another user's seed and have the server delete that item while creating the monsterplant pet for the attacker.

Add a contract test covering the ownership guard before createMonsterplant is reached.
2026-06-13 18:24:16 +02:00
simoleo89 eb41e3afb9 fix(rooms): scope self moderation to current room
Reject client-supplied room ids for self-moderation packets unless they match the caller's current room. This prevents users with saved rights or ownership in another room from muting, banning, or unbanning users remotely via crafted packets.

RoomUserBanEvent now also ignores invalid ban type values instead of letting valueOf throw through the message handler.

Add a contract test covering ban, mute, and unban current-room scoping.
2026-06-13 18:24:11 +02:00
simoleo89 a8e0534634 style(logging): colorize adaptive console logs
Route console log level and logger columns through custom Logback converters so terminals with ANSI support get colored severity badges and compact colored class names.

Keep the same habbo.console.style auto/ansi/plain behavior as the startup splash, including plain fallback for non-interactive output, NO_COLOR, and legacy Windows console paths.

The file appenders keep their existing verbose patterns unchanged, so debug/error log files remain plain and grep-friendly.

Cover the level formatter, logger formatter, override behavior, and Logback pattern wiring with tests.
2026-06-13 18:24:02 +02:00
simoleo89 98e366dd07 style(startup): add adaptive console colors
Add an auto-detected styled startup splash for terminals that support ANSI colors, including Windows Terminal, ANSICON, ConEmu ANSI, and common TERM-based consoles.

Keep the default and redirected-output path plain text so legacy CMD, logs, and service wrappers remain readable. The style can also be forced with -Dhabbo.console.style=ansi or disabled with -Dhabbo.console.style=plain.

Cover the styled splash, Windows Terminal detection, non-interactive fallback, and forced plain mode with startup console tests.
2026-06-13 18:24:02 +02:00
simoleo89 9edb984f56 style(startup): improve universal console layout
Keep the Morningstar ASCII logo while using a structured plain-text startup card that works in CMD, Windows Terminal, and other consoles without ANSI support.

Compact the Logback console pattern to use simple class names, clean separators, and a wider message column so startup logs do not wrap as aggressively. Simplify Infostand startup output to a one-line asset count while preserving category breakdown at DEBUG level.

Also normalize generic server start/stop messages so Game Server and RCON Server are labeled correctly instead of being glued to host:port output.
2026-06-13 18:24:02 +02:00
simoleo89 ea55258979 style(startup): use universal console splash
Replace the temporary ASCII-art banner with a structured startup splash that uses plain ASCII, aligned fields, and no ANSI or terminal-specific features. This keeps the emulator startup readable across CMD, PowerShell, Linux terminals, Docker logs, CI output, and copied log files. Add a contract test to keep the splash universal.
2026-06-13 18:24:02 +02:00
simoleo89 16d89cdb31 style(startup): customize emulator console banner
Add a clean ASCII startup banner for the emulator CMD window and use it instead of the legacy wide block logo. The new banner stays ASCII-only for Windows console compatibility and keeps the Morningstar identity visible before the startup logs.
2026-06-13 18:24:01 +02:00
simoleo89 ede7eb8284 style(startup): tidy console banner logs
Shorten the infostand background startup message into a compact asset summary and print the project/version/build details as a single ASCII startup card instead of several timestamped log lines. Add a small contract test for the compact infostand summary format.
2026-06-13 18:24:01 +02:00
simoleo89 216078f62c fix(messages): silence duplicate packet aliases
PacketNames reflects public static final packet constants and warns when two names share the same header. RequestCatalogIndexEvent is a legacy alias for the active Builders Club catalog index header, and InClientLinkComposer shares the NUX link payload/header. Keep those aliases available to existing code while removing them from the reflected packet-name set, and add a contract test so future public final packet names stay unique.
2026-06-13 18:23:57 +02:00
simoleo89 0f15371676 fix(marketplace): only pay out claimed offers after detach
MarketPlace.getCredits previously removed sold offers from memory and granted credits before knowing whether marketplace_items.user_id had been detached in the database. If that update failed, the same sold offer could be loaded as claimable again later. Make removeUser report success, keep the offer claimable on failure, and only grant credits after the database detach succeeds.
2026-06-13 18:23:37 +02:00
simoleo89 c25cb2a9b6 fix(trading): abort item exchange when persistence fails
RoomTrade previously caught SQLException during ownership updates but continued into the in-memory inventory and credit transfer path. That could desynchronize or duplicate trade results if the database batch failed while the live session still completed the exchange. Keep item owner mutations after the successful batch, return offered items on failed completion, and add a contract test that prevents SQL failures from falling through to the transfer path.
2026-06-13 18:23:33 +02:00
DuckieTM 87e1ef94f7 Merge pull request #169 from duckietm/main
Main to Dev
2026-06-12 15:56:21 +02:00
github-actions[bot] 510e0d082e 🆙 Bump version to 4.2.44 [skip ci] v4.2.44 2026-06-12 13:53:22 +00:00
DuckieTM e13c7fdbb6 Merge pull request #168 from hotellidev/multicolorfurnifix
Fix multicolor furni in furni editor
2026-06-12 15:52:23 +02:00