Skip to content

Releases: MrPippi/HuskSync-26.1

3.8.8.6

Choose a tag to compare

@MrPippi MrPippi released this 06 Jun 14:05

Changes

  • fix: replace jedis.keys() with cursor-based SCAN in clearUsersCheckedOutOnServer to avoid O(N) blocking scan on startup/shutdown
  • fix: null-guard jedis.get(key) in scan loop to prevent NPE on concurrent key deletion
  • fix: getVersion() now calls jedis.info("server") instead of the full INFO dump; add .trim() to strip CRLF from redis_version
  • fix: register pendingRequests cleanup via future.whenComplete() on the original future before orTimeout(), closing potential stale-entry leak
  • fix: replace INVENTORY_COMMAND with API as SaveCause for cross-server REQUEST_USER_DATA responses
  • fix: debug timestamp format mm:ss.SSSHH:mm:ss.SSS; replace per-call SimpleDateFormat + new Date() with static DateTimeFormatter + LocalTime.now()
  • fix: replace triple-lookup TOCTOU pattern in getPlayerCustomDataStore(OnlineUser) with computeIfAbsent
  • fix: split("/") called twice in CHECK_IN_PETITION handler
  • fix: add DataSyncer.syncAbortUserData(); LockstepDataSyncer overrides to conditionally release DATA_CHECKOUT (only if this server owns it) then unlock the player
  • fix: call syncAbortUserData() from handlePlayerQuit when player is still locked (join-sync in-flight), preventing orphaned DATA_CHECKOUT keys and permanently stuck players on their next server

Fix Details

Orphaned DATA_CHECKOUT / player stuck in loading screen (critical)
When a player disconnected while their join-sync was still in-flight (isLocked=true at quit time), handlePlayerQuit silently skipped both the data save and the DATA_CHECKOUT key release. On reconnect to another server, that server would petition the original server to release checkout; the original server would ignore the petition because isLocked=true, leaving the player permanently stuck in the loading screen until a server restart.

Redis KEYS blocking scan
clearUsersCheckedOutOnServer() used jedis.keys(pattern), which blocks the entire Redis event loop for the duration of the scan. On large deployments this stalls the lockstep sync pipeline for all connected servers at every startup/shutdown. Replaced with cursor-based jedis.scan().

Concurrent-deletion NPE in KEYS loop
jedis.get(key).equals(serverName) threw NullPointerException when a peer server deleted the key between the KEYS result and the GET call. The Throwable catch absorbed the crash, silently skipping remaining checkout keys.

Debug timestamp wrong pattern
mm:ss.SSS uses minutes-of-hour for both fields, dropping hours entirely. Two events one hour apart produced identical timestamps. Pattern corrected to HH:mm:ss.SSS.

Based On

Upstream HuskSync — includes all fixes through 3.8.8 with additional Paper 26.1.2 support.

3.8.8.5

Choose a tag to compare

@MrPippi MrPippi released this 09 May 17:47

Changes

  • feat: add VERSION26_1 = 4786 to DataVersionSupplier for Paper 26.1.x

Fix Details

DataVersion mapping for Paper 26.1.x
DataVersionSupplier previously had no entry for the 26.1.x version line. Items deserialized on a 26.1.x server fell through to the default branch, which returned the last explicitly mapped version (1.21.11 = 4671). The correct data version for 26.1 is 4786. Without the correct mapping, NBTAPI's Data Fixer would migrate items from the wrong baseline, potentially corrupting enchantments, custom model data, and other item attributes.

Based On

Upstream HuskSync — includes all fixes through 3.8.8 with additional Paper 26.1.2 support.

3.8.8.4

Choose a tag to compare

@MrPippi MrPippi released this 08 May 17:39

Changes

  • fix: use plugin.runAsync() in runTrackedAsync() instead of bare CompletableFuture.runAsync()
  • fix: log ExecutionException (failed save) at WARNING level in awaitPendingSaves(); restore interrupt flag on InterruptedException
  • fix: remove redundant pendingSaves.isEmpty() early return

Fix Details

ForkJoinPool / Folia compatibility
runTrackedAsync() previously submitted work to the bare JVM ForkJoinPool via CompletableFuture.runAsync(task). On shutdown, if awaitPendingSaves() timed out, those tasks could continue running after redisManager.terminate() closed the Jedis pool, causing JedisConnectionException that was silently swallowed — re-introducing the WiIIiam278#654 data-loss scenario. On Folia, the bare pool also lacked region context. The fix pre-creates a CompletableFuture and completes it inside the plugin.runAsync() lambda (MorePaperLib AsynchronousScheduler on Bukkit, ASYNC_EXEC on Fabric), ensuring tasks are bounded to the plugin lifecycle and Folia-safe.

Exception handling in awaitPendingSaves()
The previous catch (Exception ignored) silently discarded both ExecutionException (a player save failed mid-shutdown) and InterruptedException (interrupt flag lost). The fix logs a WARNING for failed saves and correctly restores Thread.currentThread().interrupt() on interruption.

Based On

Upstream HuskSync — includes all fixes through 3.8.8 with additional Paper 26.1.2 support.

3.8.8.3

Choose a tag to compare

@MrPippi MrPippi released this 08 May 10:10

Changes

  • feat: add ASCII startup banner with unofficial fork notice on plugin load
  • fix: move Redis connection termination out of EventListener into platform onDisable() to ensure correct shutdown order

Fix Details

Redis shutdown order
In 3.8.8.2 the shutdown sequence called redisManager.terminate() inside EventListener.handlePluginDisable(), immediately after database.terminate(). Moving it to platform onDisable() (with a null guard) ensures Redis stays open until dataSyncer.terminate() has finished clearing checkout keys — then Redis closes last. This prevents a narrow window where another server could see a stale LATEST_SNAPSHOT key that was never cleaned up.

Startup banner
Adds an ASCII art banner and an unofficial-fork disclaimer box printed to the server log during onEnable(). No functional change.

Based On

Upstream HuskSync — includes all fixes through 3.8.8 with additional Paper 26.1.2 support.

3.8.8.2

Choose a tag to compare

@MrPippi MrPippi released this 07 May 04:08

Changes

  • fix: prevent item duplication when dropping items before server shutdown (upstream #654)
  • fix: gracefully handle per-data-type deserialization failures instead of crashing (upstream #584)

Fix Details

WiIIiam278#654 — Item duplication on shutdown
Paper fires PlayerQuitEvent (queueing an async save) before onDisable(). The async task raced against DB/Redis connection termination, failed silently, and left LATEST_SNAPSHOT stale — causing the destination server to restore the dropped item. The fix ensures all in-flight saves complete before connections are closed and checkout keys are cleared.

WiIIiam278#584 — NBT deserialization failure
When a player's stored NBT data is malformed or too large to parse, the plugin now gracefully skips the affected data type (logging a warning) instead of throwing an exception that prevented the player from loading their data at all.

Based On

Upstream HuskSync — includes all fixes through 3.8.8 with additional Paper 26.1.2 support.

3.8.8.1

Choose a tag to compare

@MrPippi MrPippi released this 04 May 08:09

HuskSync 3.8.8.1 (Paper 26.1.2 Fork)

This is an unofficial fork of WiIIiam278/HuskSync adding Paper 26.1.2 support and backporting upstream bug fixes.

Bug Fixes

  • fix WiIIiam278#647 — Reduced latest_snapshot Redis TTL from 1 year (~31M seconds) to 7 days, preventing Redis from accumulating tens of thousands of stale player keys over time
  • fix WiIIiam278#642 — Removed duplicate DataFixer item upgrade in BukkitSerializer; NBTAPI 2.15.7 already applies DataFixerUtil internally via DataVersion tag, so the manual upgradeItemStacks() call was causing double-migration of item NBT data
  • fix WiIIiam278#588 — Pre-filtered Registry.MATERIAL into block-only and item-only sets (lazily cached), eliminating the N×M nested loop over all materials per statistic type that could cause CPU spikes to 100% on server startup

Supported Platforms

JAR Minecraft Version Java
HuskSync-Bukkit-3.8.8.1+mc.1.21.1.jar Paper 1.21.1 21
HuskSync-Bukkit-3.8.8.1+mc.1.21.4.jar Paper 1.21.4 21
HuskSync-Bukkit-3.8.8.1+mc.1.21.5.jar Paper 1.21.5 21
HuskSync-Bukkit-3.8.8.1+mc.1.21.8.jar Paper 1.21.8 21
HuskSync-Bukkit-3.8.8.1+mc.1.21.10.jar Paper 1.21.10 21
HuskSync-Bukkit-3.8.8.1+mc.1.21.11.jar Paper 1.21.11 21
HuskSync-Bukkit-3.8.8.1+mc.26.1.2.jar Paper 26.1.2 25

Paper 26.1.2 requires Java 25. All other versions require Java 21.

Based On

  • Upstream: HuskSync 3.8.8
  • item-nbt-api: 2.15.7 (fixes Paper 26.1.x version string format)
  • triumph-gui: 3.1.13

HuskSync 3.8.8+mc26.1

Choose a tag to compare

@MrPippi MrPippi released this 03 May 10:09

HuskSync 3.8.8 adds support for Paper 26.1.2 (the new Minecraft versioning scheme).

What's new

  • Paper 26.1.2 is now supported — Compatible with 26.1.2.build.53-stable and later 26.1.x builds
  • Updated NBT-API from 2.15.5 → 2.15.7, fixing a startup failure caused by Paper's new version string format (26.x.x.build.xx-stable)
  • Updated Triumph-GUI from 3.1.12 → 3.1.13, adding improved support for 1.21.7+ inventory handling

Upgrading

To update from 3.8.7, drag and drop the correct jar for your server version. No config changes required.

Note: Paper 26.1.2 servers require Java 25. Ensure your server JVM is Java 25 or newer before upgrading.