Final hardening: online=0 in finally + auto-save race fix
CRITICAL-1: online=0 moved to finally block in logout handler. If store() threw an exception, online=0 was never written and the player was permanently locked out of all servers. CRITICAL-2: Same fix for shutdown handler. Any save failure during shutdown left the player permanently stuck as online=1. IMPORTANT: Auto-save background DB write now acquires tryLock() before writing. If logout already saved newer data and holds/held the lock, the stale auto-save snapshot is skipped. Prevents overwriting correct logout data with an older snapshot. Vyrriox
This commit is contained in:
parent
1bf2a67e8d
commit
e511414463
|
|
@ -731,11 +731,17 @@ public class VanillaSync {
|
|||
if (ModList.get().isLoaded("refinedstorage")) {
|
||||
ModsSupport.storeRefinedStorageDisks(player);
|
||||
}
|
||||
JDBCsetUp.executePreparedUpdate("UPDATE player_data SET online=0 WHERE uuid=?", puuid);
|
||||
PlayerSync.LOGGER.info("Saved player {} data on server shutdown", player.getUUID());
|
||||
} catch (Exception e) {
|
||||
PlayerSync.LOGGER.error("Error saving player {} on shutdown", player.getUUID(), e);
|
||||
} finally {
|
||||
// CRITICAL: online=0 MUST be in finally - if any save throws,
|
||||
// player gets permanently locked as online=1
|
||||
try {
|
||||
JDBCsetUp.executePreparedUpdate("UPDATE player_data SET online=0 WHERE uuid=?", puuid);
|
||||
} catch (Exception e2) {
|
||||
PlayerSync.LOGGER.error("CRITICAL: Failed to mark player {} offline on shutdown", puuid, e2);
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
|
@ -794,10 +800,16 @@ public class VanillaSync {
|
|||
ModCompatSync.storeAll(player);
|
||||
// Save main inventory + effects + advancements (main thread - safe)
|
||||
store(player, false);
|
||||
JDBCsetUp.executePreparedUpdate("UPDATE player_data SET online=0 WHERE uuid=?", player_uuid);
|
||||
} catch (Exception e) {
|
||||
PlayerSync.LOGGER.error("Error during player logout save for {}", player_uuid, e);
|
||||
} finally {
|
||||
// CRITICAL: online=0 MUST be in finally - if store() throws, player gets
|
||||
// permanently locked as online=1 and can never reconnect.
|
||||
try {
|
||||
JDBCsetUp.executePreparedUpdate("UPDATE player_data SET online=0 WHERE uuid=?", player_uuid);
|
||||
} catch (Exception e2) {
|
||||
PlayerSync.LOGGER.error("CRITICAL: Failed to mark player {} offline", player_uuid, e2);
|
||||
}
|
||||
lock.unlock();
|
||||
removePlayerLock(player_uuid);
|
||||
}
|
||||
|
|
@ -1137,11 +1149,16 @@ public class VanillaSync {
|
|||
}
|
||||
|
||||
// === BACKGROUND THREAD: Write main snapshot to DB (slow, off main thread) ===
|
||||
// Use tryLock in the background task to skip if logout already saved newer data
|
||||
executorService.submit(() -> {
|
||||
ReentrantLock bgLock = getPlayerLock(puuid);
|
||||
if (!bgLock.tryLock()) return; // logout won the race, skip stale snapshot
|
||||
try {
|
||||
writeSnapshotToDB(snapshot);
|
||||
} catch (Exception e) {
|
||||
PlayerSync.LOGGER.error("Error auto-saving player {}", puuid, e);
|
||||
} finally {
|
||||
bgLock.unlock();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user