Modernization following the dependency upgrades:
- Joda-Time was used in exactly one place (ModToolSanctionInfoComposer, to
subtract probation days from a Date). Migrated to java.time
(Instant/ZoneId.systemDefault, calendar-accurate like the old Joda call) and
removed the joda-time dependency entirely — confirmed gone from the shaded jar.
- Make string<->bytes conversions explicitly UTF-8 instead of relying on the
platform default. Most importantly the wire codec (ClientMessage.readString /
ServerMessage.appendString) — both sides now pinned to UTF-8 so international
characters are robust regardless of -Dfile.encoding. Also RCONServerHandler,
PluginManager and the WS origin-forbidden response.
Verified: clean compile, 15/15 tests, shaded jar.
Major-version upgrades of the three the previous bump deliberately held back.
Verified: clean compile, all 15 tests run green (surefire 3.5.2 drives the JUnit 6
platform fine — no extra launcher dep needed), and the shaded jar assembles.
- io.netty:netty-all 4.1.135.Final -> 4.2.15.Final
- com.zaxxer:HikariCP 6.3.3 -> 7.0.2
- org.junit.jupiter:junit-jupiter 5.14.4 -> 6.1.0
Notes:
- Stayed on Netty 4.2 (GA), not 5.0 which is still Alpha. No source changes
needed; the channel ALLOCATOR is set explicitly so 4.2's new default adaptive
allocator doesn't apply. NioEventLoopGroup is deprecated in 4.2 but still
functions as before (left as-is to avoid an event-loop behavioural change).
netty-all 4.2 pulls more transitive modules, so the fat jar grows (~20->32 MB).
- HikariCP 7.x baselines Java 17; our HikariConfig usage is unchanged.
Continuation of the concurrency hardening from the audit:
- InteractionWired/WiredHandler (E4): add an atomic per-box processing guard so
one trigger box is handled by a single thread at a time, making the cooldown
check-and-set effectively atomic; mark `cooldown` volatile. Prevents a packet
thread and the room cycle thread from double-firing the same wired stack
(double teleport/reward).
- RoomUnit (C1): the walk path is now a volatile ConcurrentLinkedDeque instead of
a plain LinkedList, so the room cycle popping steps can't corrupt it while a
walk packet rebuilds it via findPath/setPath.
- RoomItemManager (C2): iterate roomItems under its own monitor in getFloorItems/
getWallItems/getPostItNotes/getUserUniqueFurniCount/getItemsAt, matching the
existing put/remove sync sites — stops place/pickup from corrupting the
traversal into a silently-incomplete item set.
- pom.xml (S4): bump netty-all 4.1.115 -> 4.1.118.Final (CVE-2025-24970 SslHandler
pre-auth DoS, CVE-2025-25193).
The :about / :info hotel-info title was hardcoded ("Arcturus Morningstar
4.1.0") and drifted from the real build. Now Emulator.version reads the
jar manifest's Implementation-Version (= ${project.version}, added via the
assembly plugin) and falls back to MAJOR.MINOR.BUILD only outside a jar.
Title becomes "Arcturus Morningstar Extended <version>" (e.g. 4.2.24).
Pairs with the CMS-side change introducing auth_ticket_expires_at (60s
expiry written on every ticket issuance). Without an emulator-side
verification the column was advisory only — this commit gates every
SELECT that resolves a user by auth_ticket on
auth_ticket = ?
AND (auth_ticket_expires_at IS NULL OR auth_ticket_expires_at >= NOW())
The NULL branch preserves backward-compatibility: CMS deployments that
do not yet populate the column keep working exactly like before
(every ticket passes the WHERE clause as soon as auth_ticket matches),
and the TTL takes effect automatically the moment a CMS starts writing
the expiry value.
Five SELECTs touched:
- SessionEndpoints.java (cms-issued SSO + remember-token flow)
- HabboManager.loadHabbo (game client login by ticket)
- SecureLoginEvent (legacy handshake path)
DB schema delivered both ways:
- Database Updates/Own_Database_RunFirst/020_auth_ticket_ttl.sql:
idempotent ALTER, skips if column already present (information_schema
guard so re-running the bundle is safe).
- Default Database/FullDatabase.sql: column added to the `users` table
definition for fresh installs.
Bumps the emulator version to 4.2.7.
Aligns the :furnidata in-game admin command with the split-aware gamedata
layout shipped by the Nitro V3 client. FurniDataManager now resolves the
furnidata source through three accepted shapes:
- legacy single-file path (filesystem or http URL ending in .json/.json5)
- split-mode directory (URL ending with '/') — walks core/custom/seasonal
tiers via manifest.json5 files and merges by item id, with later tiers
overriding earlier ones (same semantics as the client-side loader)
- fallback to furni.editor.asset.base.path when the renderer config is
missing or contains an unresolved placeholder
Adds a small JSON5 sanitiser (stripJson5) that removes line and block
comments and trailing commas before handing the content to Gson, so both
the renderer config and the split-mode files can be JSON or JSON5
without pulling in a JSON5 dependency. String contents are preserved
verbatim — comment-looking substrings inside strings (e.g. URLs) are
not touched.
Bumps the emulator version to 4.2.6.