diff --git a/src/de/diddiz/LogBlock/Config.java b/src/de/diddiz/LogBlock/Config.java index f388423..45b83e3 100644 --- a/src/de/diddiz/LogBlock/Config.java +++ b/src/de/diddiz/LogBlock/Config.java @@ -22,7 +22,7 @@ public class Config public final boolean useBukkitScheduler; public final int keepLogDays; public final boolean dumpDeletedLog; - public final boolean logBlockCreations, logBlockDestroyings, logSignTexts, logExplosions, logFire, logLeavesDecay, logLavaFlow, logChestAccess, logButtonsAndLevers, logKills; + public final boolean logBlockCreations, logBlockDestroyings, logSignTexts, logExplosions, logFire, logLeavesDecay, logLavaFlow, logChestAccess, logButtonsAndLevers, logKills, logChat; public final boolean logCreeperExplosionsAsPlayerWhoTriggeredThese; public final LogKillsLevel logKillsLevel; public final Set dontRollback, replaceAnyway; @@ -107,6 +107,8 @@ public class Config config.setProperty("logging.logKills", false); if (!subkeys.contains("logKillsLevel")) config.setProperty("logging.logKillsLevel", "PLAYERS"); + if (!subkeys.contains("logChat")) + config.setProperty("logging.logChat", false); if (!subkeys.contains("hiddenPlayers")) config.setProperty("logging.hiddenPlayers", new ArrayList()); if (!subkeys.contains("hiddenBlocks")) @@ -174,6 +176,7 @@ public class Config logLeavesDecay = config.getBoolean("logging.logLeavesDecay", false); logLavaFlow = config.getBoolean("logging.logLavaFlow", false); logKills = config.getBoolean("logging.logKills", false); + logChat = config.getBoolean("logging.logChat", false); try { logKillsLevel = LogKillsLevel.valueOf(config.getString("logging.logKillsLevel")); } catch (final IllegalArgumentException ex) { diff --git a/src/de/diddiz/LogBlock/Consumer.java b/src/de/diddiz/LogBlock/Consumer.java index ce0e340..94abb69 100644 --- a/src/de/diddiz/LogBlock/Consumer.java +++ b/src/de/diddiz/LogBlock/Consumer.java @@ -30,9 +30,10 @@ import org.bukkit.inventory.ItemStack; public class Consumer extends TimerTask { private final Queue bqueue = new LinkedBlockingQueue(); + private final Queue kqueue = new LinkedBlockingQueue(); + private final Queue cqueue = new LinkedBlockingQueue(); private final Config config; private final Set hiddenPlayers, hiddenBlocks; - private final Queue kqueue = new LinkedBlockingQueue(); private final Map lastAttackedEntity = new HashMap(); private final Map lastAttackTime = new HashMap(); private final Logger log; @@ -231,14 +232,16 @@ public class Consumer extends TimerTask queueSignPlace(playerName, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines()); } + public void queueChat(String player, String message) { + cqueue.add(new ChatRow(player, message.replace("\\", "\\\\").replace("'", "\\'"))); + } + @Override public void run() { if (!lock.tryLock()) return; final Connection conn = logblock.getConnection(); Statement state = null; - BlockChange b; - KillRow k; String table; if (getQueueSize() > 1000) log.info("[LogBlock Consumer] Queue overloaded. Size: " + getQueueSize()); @@ -251,7 +254,7 @@ public class Consumer extends TimerTask int count = 0; if (!bqueue.isEmpty()) { while (!bqueue.isEmpty() && (System.currentTimeMillis() - start < config.timePerRun || count < config.forceToProcessAtLeast)) { - b = bqueue.poll(); + final BlockChange b = bqueue.poll(); if (b == null) continue; final int playerHash = b.playerName.hashCode(); @@ -279,7 +282,7 @@ public class Consumer extends TimerTask } if (!kqueue.isEmpty()) { while (!kqueue.isEmpty() && (System.currentTimeMillis() - start < config.timePerRun || count < config.forceToProcessAtLeast)) { - k = kqueue.poll(); + final KillRow k = kqueue.poll(); if (k == null || k.victim == null) continue; if (k.killer != null && !players.containsKey(k.killer.hashCode())) @@ -297,6 +300,22 @@ public class Consumer extends TimerTask } conn.commit(); } + if (!cqueue.isEmpty()) { + while (!cqueue.isEmpty() && (System.currentTimeMillis() - start < config.timePerRun || count < config.forceToProcessAtLeast)) { + final ChatRow c = cqueue.poll(); + if (c == null) + continue; + final int playerHash = c.player.hashCode(); + if (!players.containsKey(playerHash)) + if (!addPlayer(conn, state, c.player)) { + log.warning("[LogBlock Consumer] Failed to add player " + c.player); + continue; + } + state.execute("INSERT INTO `lb-chat` (date, playerid, message) VALUES (FROM_UNIXTIME(" + c.date + "), " + players.get(playerHash) + ", '" + c.message + "')"); + count++; + } + conn.commit(); + } } catch (final SQLException ex) { log.log(Level.SEVERE, "[LogBlock Consumer] SQL exception", ex); } finally { @@ -312,7 +331,7 @@ public class Consumer extends TimerTask } int getQueueSize() { - return bqueue.size() + kqueue.size(); + return bqueue.size() + kqueue.size() + cqueue.size(); } boolean hide(Player player) { @@ -358,4 +377,16 @@ public class Consumer extends TimerTask this.weapon = weapon; } } + + private static class ChatRow + { + final long date; + final String player, message; + + ChatRow(String player, String message) { + date = System.currentTimeMillis() / 1000; + this.player = player; + this.message = message; + } + } } diff --git a/src/de/diddiz/LogBlock/LogBlock.java b/src/de/diddiz/LogBlock/LogBlock.java index 38aeebb..5b7e381 100644 --- a/src/de/diddiz/LogBlock/LogBlock.java +++ b/src/de/diddiz/LogBlock/LogBlock.java @@ -154,6 +154,11 @@ public class LogBlock extends JavaPlugin pm.registerEvent(Type.PLAYER_INTERACT, lbPlayerListener, Priority.Monitor, this); if (config.logKills) pm.registerEvent(Type.ENTITY_DAMAGE, lbEntityListener, Priority.Monitor, this); + if (config.logChat) { + final LBChatListener lbChatListener = new LBChatListener(this); + pm.registerEvent(Type.PLAYER_CHAT, lbChatListener, Priority.Monitor, this); + pm.registerEvent(Type.PLAYER_COMMAND_PREPROCESS, lbChatListener, Priority.Monitor, this); + } if (config.useBukkitScheduler) { if (getServer().getScheduler().scheduleAsyncRepeatingTask(this, consumer, config.delayBetweenRuns * 20, config.delayBetweenRuns * 20) > 0) log.info("[LogBlock] Scheduled consumer with bukkit scheduler."); diff --git a/src/de/diddiz/LogBlock/Updater.java b/src/de/diddiz/LogBlock/Updater.java index 620aa7e..31df73a 100644 --- a/src/de/diddiz/LogBlock/Updater.java +++ b/src/de/diddiz/LogBlock/Updater.java @@ -61,6 +61,8 @@ class Updater final DatabaseMetaData dbm = conn.getMetaData(); conn.setAutoCommit(true); createTable(dbm, state, "lb-players", "(playerid SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, playername varchar(32) NOT NULL DEFAULT '-', PRIMARY KEY (playerid), UNIQUE (playername))"); + if (logblock.getConfig().logChat) + createTable(dbm, state, "lb-chat", "(id INT NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid SMALLINT UNSIGNED NOT NULL, message VARCHAR(255) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid))"); for (final String table : logblock.getConfig().tables.values()) { if (dbm.getTables(null, null, table + "-chest", null).next() && state.executeQuery("SELECT * FROM `" + table + "-chest` LIMIT 1").getMetaData().getColumnCount() != 4) // Chest table update state.execute("DROP TABLE `" + table + "-chest`"); @@ -76,7 +78,7 @@ class Updater private void createTable(DatabaseMetaData dbm, Statement state, String table, String query) throws SQLException { if (!dbm.getTables(null, null, table, null).next()) { - log.log(Level.INFO, "[LogBlock] Crating table " + table + "."); + log.log(Level.INFO, "[LogBlock] Creating table " + table + "."); state.execute("CREATE TABLE `" + table + "` " + query); if (!dbm.getTables(null, null, table, null).next()) throw new SQLException("Table " + table + " not found and failed to create");