Final audit: fix ghost-online, SQL injection, resource leak, NPE
CRITICAL-1/2: Remove duplicate online=1 writes from doPlayerJoin. The synchronous onPlayerLoggedInKickCheck already sets online=1. The background thread writes raced with logout's online=0, permanently locking players as "online" after crash-disconnect during join. HIGH-1: Startup SQL uses PreparedStatement for server_id (was string concat). HIGH-2: update() method now uses try-with-resources for PreparedStatement. HIGH-3: NPE guard in RS2 data file logging when getRS2DataFile returns null. Vyrriox
This commit is contained in:
parent
b1563cc9ae
commit
484f1a8c05
|
|
@ -204,7 +204,7 @@ public class PlayerSync {
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JDBCsetUp.executeUpdate("UPDATE player_data SET online=0 WHERE last_server=" + JdbcConfig.SERVER_ID.get() +" AND online=1 LIMIT 1000");
|
JDBCsetUp.executePreparedUpdate("UPDATE player_data SET online=0 WHERE last_server=? AND online=1 LIMIT 1000", JdbcConfig.SERVER_ID.get());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("An exception occurred while trying change wrong player-status\n" + e.getMessage());
|
LOGGER.error("An exception occurred while trying change wrong player-status\n" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -269,12 +269,13 @@ public class VanillaSync {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!playerExists) {
|
if (!playerExists) {
|
||||||
|
// FIX CRITICAL-1/2: online=1 is already set by onPlayerLoggedInKickCheck (synchronous).
|
||||||
|
// Do NOT write online=1 again from background/queued threads - if the player disconnects
|
||||||
|
// quickly, the background write races with logout's online=0 and permanently locks the player.
|
||||||
server.execute(() -> {
|
server.execute(() -> {
|
||||||
try {
|
try {
|
||||||
new ModsSupport().doCuriosRestore(serverPlayer);
|
new ModsSupport().doCuriosRestore(serverPlayer);
|
||||||
store(serverPlayer, true);
|
store(serverPlayer, true); // INSERT with online=1 handled by store() init path
|
||||||
JDBCsetUp.executePreparedUpdate("UPDATE server_info SET last_update=? WHERE id=?", System.currentTimeMillis(), JdbcConfig.SERVER_ID.get());
|
|
||||||
JDBCsetUp.executePreparedUpdate("UPDATE player_data SET online=1, last_server=? WHERE uuid=?", JdbcConfig.SERVER_ID.get(), player_uuid);
|
|
||||||
serverPlayer.addTag("player_synced");
|
serverPlayer.addTag("player_synced");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
PlayerSync.LOGGER.error("Error initializing new player {}", player_uuid, e);
|
PlayerSync.LOGGER.error("Error initializing new player {}", player_uuid, e);
|
||||||
|
|
@ -285,8 +286,7 @@ public class VanillaSync {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JDBCsetUp.executePreparedUpdate("UPDATE server_info SET last_update=? WHERE id=?", System.currentTimeMillis(), JdbcConfig.SERVER_ID.get());
|
// online=1 already set by onPlayerLoggedInKickCheck - no duplicate write here
|
||||||
JDBCsetUp.executePreparedUpdate("UPDATE player_data SET online=1, last_server=? WHERE uuid=?", JdbcConfig.SERVER_ID.get(), player_uuid);
|
|
||||||
|
|
||||||
// Read all DB data into local variables (background thread - safe)
|
// Read all DB data into local variables (background thread - safe)
|
||||||
final int health, foodLevel, xp, score;
|
final int health, foodLevel, xp, score;
|
||||||
|
|
|
||||||
|
|
@ -462,7 +462,7 @@ public class ModsSupport {
|
||||||
// Read the .dat file directly (getDataFile is private, use reflection)
|
// Read the .dat file directly (getDataFile is private, use reflection)
|
||||||
java.io.File datFile = getRS2DataFile(sp);
|
java.io.File datFile = getRS2DataFile(sp);
|
||||||
if (datFile == null || !datFile.exists()) {
|
if (datFile == null || !datFile.exists()) {
|
||||||
PlayerSync.LOGGER.warn("RS2 storage data file not found: {}", datFile.getAbsolutePath());
|
PlayerSync.LOGGER.warn("RS2 storage data file not found: {}", datFile != null ? datFile.getAbsolutePath() : "<null>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,8 @@ public class JDBCsetUp {
|
||||||
*/
|
*/
|
||||||
public static void update(String sql, String... argument) throws SQLException {
|
public static void update(String sql, String... argument) throws SQLException {
|
||||||
LOGGER.trace(sql);
|
LOGGER.trace(sql);
|
||||||
try (Connection connection = getConnection()) { // With database selected
|
try (Connection connection = getConnection();
|
||||||
PreparedStatement updateStatement = connection.prepareStatement(sql);
|
PreparedStatement updateStatement = connection.prepareStatement(sql)) {
|
||||||
for (int i = 0; i < argument.length; i++) {
|
for (int i = 0; i < argument.length; i++) {
|
||||||
updateStatement.setString(i + 1, argument[i]);
|
updateStatement.setString(i + 1, argument[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user