From e26df582be8e6002648fc9727b7d9035f303d553 Mon Sep 17 00:00:00 2001 From: bootswithdefer Date: Tue, 9 Nov 2010 11:04:11 -0700 Subject: [PATCH] v7: changed the db format, show create/destroy block count in /lb commands --- LogBlock.jar | Bin 19962 -> 29166 bytes LogBlock.java | 373 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 260 insertions(+), 113 deletions(-) diff --git a/LogBlock.jar b/LogBlock.jar index 0770bd848a31cdd80fcd9f4c43e923dd7e6fb094..97f5be6ce7954bf5d0f6e10fdf2b6ea876c26852 100755 GIT binary patch delta 22997 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 delta 13694 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 IuzP`c01k|j5C8xG diff --git a/LogBlock.java b/LogBlock.java index c246501..127e341 100755 --- a/LogBlock.java +++ b/LogBlock.java @@ -1,3 +1,6 @@ +import java.util.ArrayList; +import java.util.HashSet; +import java.util.HashMap; import java.util.logging.Logger; import java.util.logging.Level; import java.util.Timer; @@ -11,9 +14,8 @@ import net.minecraft.server.MinecraftServer; public class LogBlock extends Plugin { - private boolean versionCheck = true; private String name = "LogBlock"; - private int version = 6; + private int version = 7; private String dbDriver = "com.mysql.jdbc.Driver"; private String dbUrl = ""; private String dbUsername = ""; @@ -38,7 +40,6 @@ public class LogBlock extends Plugin delay = properties.getInt("delay", 10); toolID = properties.getInt("tool-id", 270); defaultDist = properties.getInt("default-distance", 20); - versionCheck = properties.getBoolean("boots-version-check", true); } catch (Exception ex) { log.log(Level.SEVERE, "Exception while reading from logblock.properties", ex); } @@ -63,7 +64,7 @@ public class LogBlock extends Plugin public void initialize() { - new VersionCheck(name, version, versionCheck); + new VersionCheck(name, version); LBListener listener = new LBListener(); etc.getLoader().addListener(PluginLoader.Hook.COMMAND, listener, this, PluginListener.Priority.LOW); @@ -76,11 +77,9 @@ public class LogBlock extends Plugin return DriverManager.getConnection("jdbc:jdc:jdcpool"); } - private void queueBlock(Player player, String type, Block b) + private void queueBlock(Player player, Block before, Block after) { - if (b.getType() == 0) - return; - BlockRow row = new BlockRow(player.getName(), type, b.getType(), b.getX(), b.getY(), b.getZ()); + BlockRow row = new BlockRow(player.getName(), before.getType(), after.getType(), after.getX(), after.getY(), after.getZ()); boolean result = bqueue.offer(row); if (!result) log.info(name + " failed to queue block for " + player.getName()); @@ -103,7 +102,7 @@ public class LogBlock extends Plugin rs = ps.executeQuery(); while (rs.next()) { - String msg = rs.getString("date") + " " + rs.getString("player") + " " + rs.getString("action") + " " + etc.getDataSource().getItem(rs.getInt("type")); + String msg = rs.getString("date") + " " + rs.getString("player") + " " + etc.getDataSource().getItem(rs.getInt("replaced")) + "-" + etc.getDataSource().getItem(rs.getInt("type")); player.sendMessage(Colors.Gold + msg); hist = true; } @@ -122,115 +121,241 @@ public class LogBlock extends Plugin player.sendMessage(Colors.Blue + "None."); } - private void showAreaStats(Player player, int size) + private class AreaStats implements Runnable { - player.sendMessage(Colors.Blue + "Within " + size + " blocks of you: "); - player.sendMessage(Colors.Gold + String.format("%-6s %s", "#", "Player")); - boolean hist = false; - Connection conn = null; - PreparedStatement ps = null; - ResultSet rs = null; - try { - conn = getConnection(); - conn.setAutoCommit(false); - ps = conn.prepareStatement("SELECT player, count(player) as num from blocks where x > ? and x < ? and z > ? and z < ? group by player order by count(player) desc limit 10", Statement.RETURN_GENERATED_KEYS); - ps.setInt(1, (int)player.getX()-size); - ps.setInt(2, (int)player.getX()+size); - ps.setInt(3, (int)player.getZ()-size); - ps.setInt(4, (int)player.getZ()+size); - rs = ps.executeQuery(); - while (rs.next()) - { - String msg = String.format("%-6d %s", rs.getInt("num"), rs.getString("player")); - player.sendMessage(Colors.Gold + msg); - hist = true; - } - } catch (SQLException ex) { - log.log(Level.SEVERE, name + " SQL exception", ex); - } finally { + private Player player; + private int size; + AreaStats(Player player, int size) + { + this.player = player; + this.size = size; + } + public void run() + { + HashSet players = new HashSet(); + HashMap created = new HashMap(); + HashMap destroyed = new HashMap(); + + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try { + conn = getConnection(); + conn.setAutoCommit(false); + ps = conn.prepareStatement("SELECT player, count(player) as num from blocks where type > 0 and x > ? and x < ? and z > ? and z < ? group by player order by count(player) desc limit 10", Statement.RETURN_GENERATED_KEYS); + ps.setInt(1, (int)player.getX()-size); + ps.setInt(2, (int)player.getX()+size); + ps.setInt(3, (int)player.getZ()-size); + ps.setInt(4, (int)player.getZ()+size); + rs = ps.executeQuery(); + while (rs.next()) + { + players.add(rs.getString("player")); + created.put(rs.getString("player"), rs.getInt("num")); + } rs.close(); ps.close(); - conn.close(); + + ps = conn.prepareStatement("SELECT player, count(player) as num from blocks where replaced > 0 and x > ? and x < ? and z > ? and z < ? group by player order by count(player) desc limit 10", Statement.RETURN_GENERATED_KEYS); + ps.setInt(1, (int)player.getX()-size); + ps.setInt(2, (int)player.getX()+size); + ps.setInt(3, (int)player.getZ()-size); + ps.setInt(4, (int)player.getZ()+size); + rs = ps.executeQuery(); + while (rs.next()) + { + players.add(rs.getString("player")); + destroyed.put(rs.getString("player"), rs.getInt("num")); + } + } catch (SQLException ex) { - log.log(Level.SEVERE, name + " SQL exception on close", ex); + log.log(Level.SEVERE, name + " SQL exception", ex); + } finally { + try { + rs.close(); + ps.close(); + conn.close(); + } catch (SQLException ex) { + log.log(Level.SEVERE, name + " SQL exception on close", ex); + } + } + + player.sendMessage(Colors.Blue + "Within " + size + " blocks of you: "); + if (players.size() == 0) + { + player.sendMessage(Colors.Blue + "No results found."); + return; + } + + player.sendMessage(Colors.Gold + String.format("%-6s %-6s %s", "Creat", "Destr", "Player")); + for (String p: players) + { + Integer c = created.get(p); + Integer d = destroyed.get(p); + if (c == null) + c = 0; + if (d == null) + d = 0; + player.sendMessage(Colors.Gold + String.format("%-6d %-6d %s", c, d, p)); } } - if (!hist) - player.sendMessage(Colors.Blue + "Nothing."); } - private void showPlayerAreaStats(Player player, String name, int size) + private class PlayerAreaStats implements Runnable { - player.sendMessage(Colors.Blue + "Stats for " + name + ", within " + size + " blocks of you: "); - player.sendMessage(Colors.Gold + String.format("%-6s %s", "#", "Block")); - boolean hist = false; - Connection conn = null; - PreparedStatement ps = null; - ResultSet rs = null; - try { - conn = getConnection(); - conn.setAutoCommit(false); - ps = conn.prepareStatement("SELECT type, count(type) as num from blocks where x > ? and x < ? and z > ? and z < ? and player = ? group by type order by count(type) desc limit 10", Statement.RETURN_GENERATED_KEYS); - ps.setInt(1, (int)player.getX()-size); - ps.setInt(2, (int)player.getX()+size); - ps.setInt(3, (int)player.getZ()-size); - ps.setInt(4, (int)player.getZ()+size); - ps.setString(5, name); - rs = ps.executeQuery(); - while (rs.next()) - { - String msg = String.format("%-6d %s", rs.getInt("num"), etc.getDataSource().getItem(rs.getInt("type"))); - player.sendMessage(Colors.Gold + msg); - hist = true; - } - } catch (SQLException ex) { - log.log(Level.SEVERE, name + " SQL exception", ex); - } finally { + private Player player; + private String name; + private int size; + PlayerAreaStats(Player player, String name, int size) + { + this.player = player; + this.name = name; + this.size = size; + } + public void run() + { + HashSet types = new HashSet(); + HashMap created = new HashMap(); + HashMap destroyed = new HashMap(); + + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try { + conn = getConnection(); + conn.setAutoCommit(false); + ps = conn.prepareStatement("SELECT type, count(type) as num from blocks where type > 0 and player = ? and x > ? and x < ? and z > ? and z < ? group by type order by count(replaced) desc limit 10", Statement.RETURN_GENERATED_KEYS); + ps.setString(1, name); + ps.setInt(2, (int)player.getX()-size); + ps.setInt(3, (int)player.getX()+size); + ps.setInt(4, (int)player.getZ()-size); + ps.setInt(5, (int)player.getZ()+size); + rs = ps.executeQuery(); + while (rs.next()) + { + types.add(etc.getDataSource().getItem(rs.getInt("type"))); + created.put(etc.getDataSource().getItem(rs.getInt("type")), rs.getInt("num")); + } rs.close(); ps.close(); - conn.close(); + + ps = conn.prepareStatement("SELECT replaced, count(replaced) as num from blocks where replaced > 0 and player = ? and x > ? and x < ? and z > ? and z < ? group by replaced order by count(replaced) desc limit 10", Statement.RETURN_GENERATED_KEYS); + ps.setString(1, name); + ps.setInt(2, (int)player.getX()-size); + ps.setInt(3, (int)player.getX()+size); + ps.setInt(4, (int)player.getZ()-size); + ps.setInt(5, (int)player.getZ()+size); + rs = ps.executeQuery(); + while (rs.next()) + { + types.add(etc.getDataSource().getItem(rs.getInt("replaced"))); + destroyed.put(etc.getDataSource().getItem(rs.getInt("replaced")), rs.getInt("num")); + } + } catch (SQLException ex) { - log.log(Level.SEVERE, name + " SQL exception on close", ex); + log.log(Level.SEVERE, name + " SQL exception", ex); + } finally { + try { + rs.close(); + ps.close(); + conn.close(); + } catch (SQLException ex) { + log.log(Level.SEVERE, name + " SQL exception on close", ex); + } + } + + player.sendMessage(Colors.Blue + "Player " + name + " within " + size + " blocks of you: "); + if (types.size() == 0) + { + player.sendMessage(Colors.Blue + "No results found."); + return; + } + + player.sendMessage(Colors.Gold + String.format("%-6s %-6s %s", "Creat", "Destr", "Block")); + for (String t: types) + { + Integer c = created.get(t); + Integer d = destroyed.get(t); + if (c == null) + c = 0; + if (d == null) + d = 0; + player.sendMessage(Colors.Gold + String.format("%-6d %-6d %s", c, d, t)); } } - if (!hist) - player.sendMessage(Colors.Blue + "Nothing."); } - private void showPlayerWorldStats(Player player) + private class PlayerWorldStats implements Runnable { - player.sendMessage(Colors.Blue + "Player stats, entire map: "); - player.sendMessage(Colors.Gold + String.format("%-6s %s", "#", "Player")); - boolean hist = false; - Connection conn = null; - PreparedStatement ps = null; - ResultSet rs = null; - try { - conn = getConnection(); - conn.setAutoCommit(false); - ps = conn.prepareStatement("SELECT player, count(player) as num from blocks group by player order by count(player) desc limit 10", Statement.RETURN_GENERATED_KEYS); - rs = ps.executeQuery(); - while (rs.next()) - { - String msg = String.format("%-6d %s", rs.getInt("num"), rs.getString("player")); - player.sendMessage(Colors.Gold + msg); - hist = true; - } - } catch (SQLException ex) { - log.log(Level.SEVERE, name + " SQL exception", ex); - } finally { + private Player player; + PlayerWorldStats(Player player) + { + this.player = player; + } + public void run() + { + HashSet players = new HashSet(); + HashMap created = new HashMap(); + HashMap destroyed = new HashMap(); + + Connection conn = null; + PreparedStatement ps = null; + ResultSet rs = null; + try { + conn = getConnection(); + conn.setAutoCommit(false); + ps = conn.prepareStatement("SELECT player, count(player) as num from blocks where type > 0 group by player order by count(player) desc limit 5", Statement.RETURN_GENERATED_KEYS); + rs = ps.executeQuery(); + while (rs.next()) + { + players.add(rs.getString("player")); + created.put(rs.getString("player"), rs.getInt("num")); + } rs.close(); ps.close(); - conn.close(); + + ps = conn.prepareStatement("SELECT player, count(player) as num from blocks where replaced > 0 group by player order by count(player) desc limit 5", Statement.RETURN_GENERATED_KEYS); + rs = ps.executeQuery(); + while (rs.next()) + { + players.add(rs.getString("player")); + destroyed.put(rs.getString("player"), rs.getInt("num")); + } + } catch (SQLException ex) { - log.log(Level.SEVERE, name + " SQL exception on close", ex); + log.log(Level.SEVERE, name + " SQL exception", ex); + } finally { + try { + rs.close(); + ps.close(); + conn.close(); + } catch (SQLException ex) { + log.log(Level.SEVERE, name + " SQL exception on close", ex); + } + } + + player.sendMessage(Colors.Blue + "Within entire world:"); + if (players.size() == 0) + { + player.sendMessage(Colors.Blue + "No results found."); + return; + } + + player.sendMessage(Colors.Gold + String.format("%-6s %-6s %s", "Creat", "Destr", "Player")); + for (String p: players) + { + Integer c = created.get(p); + Integer d = destroyed.get(p); + if (c == null) + c = 0; + if (d == null) + d = 0; + player.sendMessage(Colors.Gold + String.format("%-6d %-6d %s", c, d, p)); } } - if (!hist) - player.sendMessage(Colors.Blue + "Nothing."); } public class LBListener extends PluginListener // start @@ -242,20 +367,26 @@ public class LogBlock extends Plugin if (split[0].equalsIgnoreCase("/lb")) { if (split.length == 1) { - showAreaStats(player, defaultDist); + AreaStats th = new AreaStats(player, defaultDist); + new Thread(th).start(); return true; } if (split.length == 2) { - if (split[1].equalsIgnoreCase("world")) - showPlayerWorldStats(player); - else + if (split[1].equalsIgnoreCase("world")) { + PlayerWorldStats th = new PlayerWorldStats(player); + new Thread(th).start(); + } else player.sendMessage(Colors.Rose + "Incorrect usage."); return true; } - if (split[1].equalsIgnoreCase("player")) - showPlayerAreaStats(player, split[2], defaultDist); - else if (split[1].equalsIgnoreCase("area")) - showAreaStats(player, Integer.parseInt(split[2])); + if (split[1].equalsIgnoreCase("player")) { + PlayerAreaStats th = new PlayerAreaStats(player, split[2], defaultDist); + new Thread(th).start(); + } + else if (split[1].equalsIgnoreCase("area")) { + AreaStats th = new AreaStats(player, Integer.parseInt(split[2])); + new Thread(th).start(); + } else player.sendMessage(Colors.Rose + "Incorrect usage."); return true; @@ -276,8 +407,7 @@ public class LogBlock extends Plugin if (before.getType() == blockPlaced.getType()) return false; - queueBlock(player, "create", blockPlaced); - queueBlock(player, "destroy", before); + queueBlock(player, before, blockPlaced); return false; } @@ -288,8 +418,7 @@ public class LogBlock extends Plugin if (after.getType() == blockAt.getType()) return false; - queueBlock(player, "destroy", blockAt); - queueBlock(player, "create", after); + queueBlock(player, blockAt, after); return false; } } // end LBListener @@ -316,7 +445,7 @@ public class LogBlock extends Plugin try { conn = getConnection(); conn.setAutoCommit(false); - ps = conn.prepareStatement("INSERT INTO blocks (date, player, action, type, x, y, z) VALUES (now(),?,?,?,?,?,?)", Statement.RETURN_GENERATED_KEYS); + ps = conn.prepareStatement("INSERT INTO blocks (date, player, replaced, type, x, y, z) VALUES (now(),?,?,?,?,?,?)", Statement.RETURN_GENERATED_KEYS); while (count < 100 && start+delay > (System.currentTimeMillis()/1000F)) { @@ -325,7 +454,7 @@ public class LogBlock extends Plugin continue; //b.log(); ps.setString(1, b.name); - ps.setString(2, b.action); + ps.setInt(2, b.replaced); ps.setInt(3, b.type); ps.setInt(4, b.x); ps.setInt(5, b.y); @@ -354,14 +483,13 @@ public class LogBlock extends Plugin private class BlockRow // start { public String name; - public String action; - public int type; + public int replaced, type; public int x, y, z; - BlockRow(String name, String action, int type, int x, int y, int z) + BlockRow(String name, int replaced, int type, int x, int y, int z) { this.name = name; - this.action = action; + this.replaced = replaced; this.type = type; this.x = x; this.y = y; @@ -370,7 +498,26 @@ public class LogBlock extends Plugin public void log() { - log.info("name: " + name + " action: " + action + " type: " + type + " x: " + x + " y: " + y + " z: " + z); + log.info("name: " + name + " before type: " + replaced + " type: " + type + " x: " + x + " y: " + y + " z: " + z); } - } // end MyRow + } // end BlockRow + + private class Result + { + public String player; + public int created; + public int destroyed; + + Result(String player, int c, int d) + { + this.player = player; + this.created = c; + this.destroyed = d; + } + + public String toString() + { + return(String.format("%-6d %-6d %s", created, destroyed, player)); + } + } } // end LogBlock