From 5c4111b6a767f0f04a7ac6e6fc7ac684899f4cf2 Mon Sep 17 00:00:00 2001 From: "its.bread" <38575088+cyljacky02@users.noreply.github.com> Date: Sun, 30 Nov 2025 03:32:28 +0800 Subject: [PATCH] fix: prevent race condition in CHECK_IN_PETITION handler (#614) - Replace confusing 'online' boolean with direct state checks - Only release DATA_CHECKOUT when user is truly offline AND unlocked --- .../william278/husksync/redis/RedisManager.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/common/src/main/java/net/william278/husksync/redis/RedisManager.java b/common/src/main/java/net/william278/husksync/redis/RedisManager.java index 1e844e61..19996f88 100644 --- a/common/src/main/java/net/william278/husksync/redis/RedisManager.java +++ b/common/src/main/java/net/william278/husksync/redis/RedisManager.java @@ -202,15 +202,19 @@ public class RedisManager extends JedisPubSub { } final String payload = new String(redisMessage.getPayload(), StandardCharsets.UTF_8); final User user = new User(UUID.fromString(payload.split("/")[0]), payload.split("/")[1]); - boolean online = plugin.getDisconnectingPlayers().contains(user.getUuid()) - || plugin.getOnlineUser(user.getUuid()).isEmpty(); - if (!online && !plugin.isLocked(user.getUuid())) { - plugin.debug("[%s] Received check-in petition for online/unlocked user, ignoring" - .formatted(user.getName())); + + // Only release checkout if user is truly offline AND not being processed + final boolean isOnline = plugin.getOnlineUser(user.getUuid()).isPresent(); + final boolean isLocked = plugin.isLocked(user.getUuid()); + + if (isOnline || isLocked) { + plugin.debug("[%s] Petition ignored - user still being processed (online=%s, locked=%s)" + .formatted(user.getName(), isOnline, isLocked)); return; } + plugin.getRedisManager().setUserCheckedOut(user, false); - plugin.debug("[%s] Received petition for offline user, checking them in".formatted(user.getName())); + plugin.debug("[%s] Petition accepted - user checked in".formatted(user.getName())); } case RETURN_USER_DATA -> { final UUID target = redisMessage.getTargetUuid().orElse(null);