forked from LogBlock/LogBlock
Sort members
This commit is contained in:
@@ -621,7 +621,7 @@ public class CommandsHandler implements CommandExecutor
|
|||||||
return fillWithSpaces(rs.getInt("created")) + fillWithSpaces(rs.getInt("destroyed")) + BukkitUtils.getMaterialName(rs.getInt("type"));
|
return fillWithSpaces(rs.getInt("created")) + fillWithSpaces(rs.getInt("destroyed")) + BukkitUtils.getMaterialName(rs.getInt("type"));
|
||||||
else
|
else
|
||||||
return fillWithSpaces(rs.getInt("created")) + fillWithSpaces(rs.getInt("destroyed")) + rs.getString("playername");
|
return fillWithSpaces(rs.getInt("created")) + fillWithSpaces(rs.getInt("destroyed")) + rs.getString("playername");
|
||||||
} catch (final Exception ex) {
|
} catch (final SQLException ex) {
|
||||||
log.log(Level.SEVERE, "[LogBlock HistoryFormatter] Error", ex);
|
log.log(Level.SEVERE, "[LogBlock HistoryFormatter] Error", ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -23,15 +23,15 @@ import de.diddiz.util.BukkitUtils;
|
|||||||
|
|
||||||
public class Consumer extends TimerTask
|
public class Consumer extends TimerTask
|
||||||
{
|
{
|
||||||
private final LogBlock logblock;
|
|
||||||
private final Logger log;
|
|
||||||
private final Config config;
|
|
||||||
private final LinkedBlockingQueue<BlockRow> bqueue = new LinkedBlockingQueue<BlockRow>();
|
private final LinkedBlockingQueue<BlockRow> bqueue = new LinkedBlockingQueue<BlockRow>();
|
||||||
private final LinkedBlockingQueue<KillRow> kqueue = new LinkedBlockingQueue<KillRow>();
|
private final Config config;
|
||||||
private final HashSet<Integer> players = new HashSet<Integer>();
|
|
||||||
private final HashSet<Integer> hiddenplayers = new HashSet<Integer>();
|
private final HashSet<Integer> hiddenplayers = new HashSet<Integer>();
|
||||||
|
private final LinkedBlockingQueue<KillRow> kqueue = new LinkedBlockingQueue<KillRow>();
|
||||||
private final HashMap<Integer, Integer> lastAttackedEntity = new HashMap<Integer, Integer>();
|
private final HashMap<Integer, Integer> lastAttackedEntity = new HashMap<Integer, Integer>();
|
||||||
private final HashMap<Integer, Long> lastAttackTime = new HashMap<Integer, Long>();
|
private final HashMap<Integer, Long> lastAttackTime = new HashMap<Integer, Long>();
|
||||||
|
private final Logger log;
|
||||||
|
private final LogBlock logblock;
|
||||||
|
private final HashSet<Integer> players = new HashSet<Integer>();
|
||||||
|
|
||||||
Consumer(LogBlock logblock) {
|
Consumer(LogBlock logblock) {
|
||||||
this.logblock = logblock;
|
this.logblock = logblock;
|
||||||
@@ -40,20 +40,6 @@ public class Consumer extends TimerTask
|
|||||||
readPlayers();
|
readPlayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getQueueSize() {
|
|
||||||
return bqueue.size() + kqueue.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hide(Player player) {
|
|
||||||
final int hash = player.getName().hashCode();
|
|
||||||
if (hiddenplayers.contains(hash)) {
|
|
||||||
hiddenplayers.remove(hash);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
hiddenplayers.add(hash);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs any block change. Don't try to combine broken and placed blocks. Queue two block changes or use the queueBLockReplace methods.
|
* Logs any block change. Don't try to combine broken and placed blocks. Queue two block changes or use the queueBLockReplace methods.
|
||||||
*/
|
*/
|
||||||
@@ -61,16 +47,6 @@ public class Consumer extends TimerTask
|
|||||||
queueBlock(playerName, loc, typeBefore, typeAfter, data, null, null);
|
queueBlock(playerName, loc, typeBefore, typeAfter, data, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queueBlock(String playerName, Location loc, int typeBefore, int typeAfter, byte data, String signtext, ChestAccess ca) {
|
|
||||||
if (playerName == null || loc == null || typeBefore < 0 || typeAfter < 0 || hiddenplayers.contains(playerName.hashCode()) || !config.tables.containsKey(loc.getWorld().getName().hashCode()))
|
|
||||||
return;
|
|
||||||
if (playerName.length() > 32)
|
|
||||||
playerName = playerName.substring(0, 32);
|
|
||||||
if (signtext != null)
|
|
||||||
signtext = signtext.replace("\\", "\\\\").replace("'", "\\'");
|
|
||||||
bqueue.add(new BlockRow(loc.getWorld().getName().hashCode(), playerName, typeBefore, typeAfter, data, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), signtext, ca));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a block break. The type afterwards is assumed to be o (air).
|
* Logs a block break. The type afterwards is assumed to be o (air).
|
||||||
*
|
*
|
||||||
@@ -246,56 +222,6 @@ public class Consumer extends TimerTask
|
|||||||
queueSignPlace(playerName, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines());
|
queueSignPlace(playerName, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addPlayer(String playerName) {
|
|
||||||
final Connection conn = logblock.getConnection();
|
|
||||||
if (conn == null)
|
|
||||||
return false;
|
|
||||||
Statement state = null;
|
|
||||||
try {
|
|
||||||
state = conn.createStatement();
|
|
||||||
conn.setAutoCommit(true);
|
|
||||||
state.execute("INSERT IGNORE INTO `lb-players` (playername) VALUES ('" + playerName + "');");
|
|
||||||
readPlayers();
|
|
||||||
return players.contains(playerName.hashCode());
|
|
||||||
} catch (final SQLException ex) {
|
|
||||||
log.log(Level.SEVERE, "[LogBlock] SQL exception", ex);
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (state != null)
|
|
||||||
state.close();
|
|
||||||
conn.close();
|
|
||||||
} catch (final SQLException ex) {
|
|
||||||
log.log(Level.SEVERE, "[LogBlock] SQL exception on close", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readPlayers() {
|
|
||||||
final Connection conn = logblock.getConnection();
|
|
||||||
if (conn == null)
|
|
||||||
return;
|
|
||||||
Statement state = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
conn.setAutoCommit(false);
|
|
||||||
state = conn.createStatement();
|
|
||||||
rs = state.executeQuery("SELECT playername FROM `lb-players`");
|
|
||||||
while (rs.next())
|
|
||||||
players.add(rs.getString(1).hashCode());
|
|
||||||
} catch (final SQLException ex) {
|
|
||||||
log.log(Level.SEVERE, "[LogBlock Consumer] SQL exception", ex);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (state != null)
|
|
||||||
state.close();
|
|
||||||
conn.close();
|
|
||||||
} catch (final SQLException ex) {
|
|
||||||
log.log(Level.SEVERE, "[LogBlock Consumer] SQL exception on close", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void run() {
|
public synchronized void run() {
|
||||||
final Connection conn = logblock.getConnection();
|
final Connection conn = logblock.getConnection();
|
||||||
@@ -378,15 +304,89 @@ public class Consumer extends TimerTask
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getQueueSize() {
|
||||||
|
return bqueue.size() + kqueue.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hide(Player player) {
|
||||||
|
final int hash = player.getName().hashCode();
|
||||||
|
if (hiddenplayers.contains(hash)) {
|
||||||
|
hiddenplayers.remove(hash);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hiddenplayers.add(hash);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean addPlayer(String playerName) {
|
||||||
|
final Connection conn = logblock.getConnection();
|
||||||
|
if (conn == null)
|
||||||
|
return false;
|
||||||
|
Statement state = null;
|
||||||
|
try {
|
||||||
|
state = conn.createStatement();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
state.execute("INSERT IGNORE INTO `lb-players` (playername) VALUES ('" + playerName + "');");
|
||||||
|
readPlayers();
|
||||||
|
return players.contains(playerName.hashCode());
|
||||||
|
} catch (final SQLException ex) {
|
||||||
|
log.log(Level.SEVERE, "[LogBlock] SQL exception", ex);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (state != null)
|
||||||
|
state.close();
|
||||||
|
conn.close();
|
||||||
|
} catch (final SQLException ex) {
|
||||||
|
log.log(Level.SEVERE, "[LogBlock] SQL exception on close", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void queueBlock(String playerName, Location loc, int typeBefore, int typeAfter, byte data, String signtext, ChestAccess ca) {
|
||||||
|
if (playerName == null || loc == null || typeBefore < 0 || typeAfter < 0 || hiddenplayers.contains(playerName.hashCode()) || !config.tables.containsKey(loc.getWorld().getName().hashCode()))
|
||||||
|
return;
|
||||||
|
if (playerName.length() > 32)
|
||||||
|
playerName = playerName.substring(0, 32);
|
||||||
|
if (signtext != null)
|
||||||
|
signtext = signtext.replace("\\", "\\\\").replace("'", "\\'");
|
||||||
|
bqueue.add(new BlockRow(loc.getWorld().getName().hashCode(), playerName, typeBefore, typeAfter, data, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), signtext, ca));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readPlayers() {
|
||||||
|
final Connection conn = logblock.getConnection();
|
||||||
|
if (conn == null)
|
||||||
|
return;
|
||||||
|
Statement state = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
state = conn.createStatement();
|
||||||
|
rs = state.executeQuery("SELECT playername FROM `lb-players`");
|
||||||
|
while (rs.next())
|
||||||
|
players.add(rs.getString(1).hashCode());
|
||||||
|
} catch (final SQLException ex) {
|
||||||
|
log.log(Level.SEVERE, "[LogBlock Consumer] SQL exception", ex);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (state != null)
|
||||||
|
state.close();
|
||||||
|
conn.close();
|
||||||
|
} catch (final SQLException ex) {
|
||||||
|
log.log(Level.SEVERE, "[LogBlock Consumer] SQL exception on close", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class BlockRow
|
private static class BlockRow
|
||||||
{
|
{
|
||||||
public final int worldHash;
|
public final ChestAccess ca;
|
||||||
|
public final byte data;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final int replaced, type;
|
public final int replaced, type;
|
||||||
public final byte data;
|
|
||||||
public final int x, y, z;
|
|
||||||
public final String signtext;
|
public final String signtext;
|
||||||
public final ChestAccess ca;
|
public final int worldHash;
|
||||||
|
public final int x, y, z;
|
||||||
|
|
||||||
BlockRow(int worldHash, String name, int replaced, int type, byte data, int x, int y, int z, String signtext, ChestAccess ca) {
|
BlockRow(int worldHash, String name, int replaced, int type, byte data, int x, int y, int z, String signtext, ChestAccess ca) {
|
||||||
this.worldHash = worldHash;
|
this.worldHash = worldHash;
|
||||||
@@ -404,8 +404,8 @@ public class Consumer extends TimerTask
|
|||||||
|
|
||||||
private static class ChestAccess
|
private static class ChestAccess
|
||||||
{
|
{
|
||||||
public final short itemType, itemAmount;
|
|
||||||
public final byte itemData;
|
public final byte itemData;
|
||||||
|
public final short itemType, itemAmount;
|
||||||
|
|
||||||
ChestAccess(short itemType, short itemAmount, byte itemData) {
|
ChestAccess(short itemType, short itemAmount, byte itemData) {
|
||||||
this.itemType = itemType;
|
this.itemType = itemType;
|
||||||
@@ -416,10 +416,10 @@ public class Consumer extends TimerTask
|
|||||||
|
|
||||||
private static class KillRow
|
private static class KillRow
|
||||||
{
|
{
|
||||||
public final int worldHash;
|
|
||||||
public final String killer;
|
public final String killer;
|
||||||
public final String victim;
|
public final String victim;
|
||||||
public final int weapon;
|
public final int weapon;
|
||||||
|
public final int worldHash;
|
||||||
|
|
||||||
KillRow(int worldHash, String attacker, String defender, int weapon) {
|
KillRow(int worldHash, String attacker, String defender, int weapon) {
|
||||||
this.worldHash = worldHash;
|
this.worldHash = worldHash;
|
||||||
|
@@ -2,6 +2,7 @@ package de.diddiz.LogBlock;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
@@ -70,7 +71,7 @@ public class LogBlock extends JavaPlugin
|
|||||||
}
|
}
|
||||||
if (!file.exists() || file.length() == 0)
|
if (!file.exists() || file.length() == 0)
|
||||||
throw new FileNotFoundException(file.getAbsolutePath() + file.getName());
|
throw new FileNotFoundException(file.getAbsolutePath() + file.getName());
|
||||||
} catch (final Exception e) {
|
} catch (final IOException e) {
|
||||||
log.log(Level.SEVERE, "[LogBlock] Error while downloading " + file.getName() + ".");
|
log.log(Level.SEVERE, "[LogBlock] Error while downloading " + file.getName() + ".");
|
||||||
errorAtLoading = true;
|
errorAtLoading = true;
|
||||||
return;
|
return;
|
||||||
|
@@ -20,20 +20,20 @@ import de.diddiz.util.Utils;
|
|||||||
public class QueryParams implements Cloneable
|
public class QueryParams implements Cloneable
|
||||||
{
|
{
|
||||||
private static final HashSet<Integer> keywords = new HashSet<Integer>(Arrays.asList("player".hashCode(), "area".hashCode(), "selection".hashCode(), "sel".hashCode(), "block".hashCode(), "type".hashCode(), "sum".hashCode(), "destroyed".hashCode(), "created".hashCode(), "chestaccess".hashCode(), "all".hashCode(), "time".hashCode(), "since".hashCode(), "before".hashCode(), "limit".hashCode(), "world".hashCode(), "asc".hashCode(), "desc".hashCode(), "last".hashCode()));
|
private static final HashSet<Integer> keywords = new HashSet<Integer>(Arrays.asList("player".hashCode(), "area".hashCode(), "selection".hashCode(), "sel".hashCode(), "block".hashCode(), "type".hashCode(), "sum".hashCode(), "destroyed".hashCode(), "created".hashCode(), "chestaccess".hashCode(), "all".hashCode(), "time".hashCode(), "since".hashCode(), "before".hashCode(), "limit".hashCode(), "world".hashCode(), "asc".hashCode(), "desc".hashCode(), "last".hashCode()));
|
||||||
private final LogBlock logblock;
|
|
||||||
List<String> players = new ArrayList<String>();
|
|
||||||
List<Integer> types = new ArrayList<Integer>();
|
|
||||||
Location loc = null;
|
|
||||||
int radius = -1;
|
|
||||||
Selection sel = null;
|
|
||||||
int minutes = 0;
|
|
||||||
SummarizationMode sum = SummarizationMode.NONE;
|
|
||||||
BlockChangeType bct = BlockChangeType.BOTH;
|
BlockChangeType bct = BlockChangeType.BOTH;
|
||||||
int limit = 15;
|
int limit = 15;
|
||||||
World world = null;
|
Location loc = null;
|
||||||
|
int minutes = 0;
|
||||||
Order order = Order.DESC;
|
Order order = Order.DESC;
|
||||||
boolean selectFullBlockData = false;
|
List<String> players = new ArrayList<String>();
|
||||||
boolean prepareToolQuery = false;
|
boolean prepareToolQuery = false;
|
||||||
|
int radius = -1;
|
||||||
|
Selection sel = null;
|
||||||
|
boolean selectFullBlockData = false;
|
||||||
|
SummarizationMode sum = SummarizationMode.NONE;
|
||||||
|
List<Integer> types = new ArrayList<Integer>();
|
||||||
|
World world = null;
|
||||||
|
private final LogBlock logblock;
|
||||||
|
|
||||||
public QueryParams(LogBlock logblock) {
|
public QueryParams(LogBlock logblock) {
|
||||||
this.logblock = logblock;
|
this.logblock = logblock;
|
||||||
@@ -44,19 +44,161 @@ public class QueryParams implements Cloneable
|
|||||||
parseArgs(sender, args);
|
parseArgs(sender, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void merge(QueryParams params) {
|
static boolean isKeyWord(String param) {
|
||||||
players = params.players;
|
if (keywords.contains(param.toLowerCase().hashCode()))
|
||||||
types = params.types;
|
return true;
|
||||||
loc = params.loc;
|
return false;
|
||||||
radius = params.radius;
|
}
|
||||||
sel = params.sel;
|
|
||||||
if (minutes == 0)
|
public String getLimit() {
|
||||||
minutes = params.minutes;
|
if (limit == -1)
|
||||||
sum = params.sum;
|
return "";
|
||||||
bct = params.bct;
|
return "LIMIT " + limit;
|
||||||
limit = params.limit;
|
}
|
||||||
world = params.world;
|
|
||||||
order = params.order;
|
public String getOrderBy() {
|
||||||
|
return "ORDER BY date " + order + ", id " + order + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuery() {
|
||||||
|
if (sum == SummarizationMode.NONE) {
|
||||||
|
final StringBuilder select = new StringBuilder("SELECT ");
|
||||||
|
final StringBuilder from = new StringBuilder("FROM `" + getTable() + "` ");
|
||||||
|
if (selectFullBlockData)
|
||||||
|
select.append("replaced, type, data, x, y, z ");
|
||||||
|
else
|
||||||
|
select.append("date, replaced, type, playername");
|
||||||
|
if (!selectFullBlockData || players.size() > 0)
|
||||||
|
from.append("INNER JOIN `lb-players` USING (playerid) ");
|
||||||
|
if (types.size() == 0 || types.contains(63) || types.contains(68)) {
|
||||||
|
select.append(", signtext");
|
||||||
|
from.append("LEFT JOIN `" + getTable() + "-sign` USING (id) ");
|
||||||
|
}
|
||||||
|
if (types.size() == 0 || types.contains(23) || types.contains(54) || types.contains(61)) {
|
||||||
|
select.append(", itemtype, itemamount, itemdata");
|
||||||
|
from.append("LEFT JOIN `" + getTable() + "-chest` USING (id) ");
|
||||||
|
}
|
||||||
|
return select.toString() + " " + from.toString() + getWhere() + getOrderBy() + getLimit();
|
||||||
|
} else if (sum == SummarizationMode.TYPES)
|
||||||
|
return "SELECT type, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT type, count(type) AS created, 0 AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) " + getWhere() + "AND type > 0 GROUP BY type) UNION (SELECT replaced AS type, 0 AS created, count(replaced) AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) " + getWhere() + "AND replaced > 0 GROUP BY replaced)) AS t GROUP BY type ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit();
|
||||||
|
else
|
||||||
|
return "SELECT playername, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT playerid, count(type) AS created, 0 AS destroyed FROM `" + getTable() + "` " + getWhere() + "AND type > 0 GROUP BY playerid) UNION (SELECT playerid, 0 AS created, count(replaced) AS destroyed FROM `" + getTable() + "` " + getWhere() + "AND replaced > 0 GROUP BY playerid)) AS t INNER JOIN `lb-players` USING (playerid) GROUP BY playerid ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTable() {
|
||||||
|
return logblock.getConfig().tables.get(world.getName().hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
final StringBuilder title = new StringBuilder();
|
||||||
|
if (!types.isEmpty()) {
|
||||||
|
for (int i = 0; i < types.size(); i++)
|
||||||
|
title.append(BukkitUtils.getMaterialName(types.get(i)) + ", ");
|
||||||
|
title.deleteCharAt(title.length() - 2);
|
||||||
|
} else
|
||||||
|
title.append("Block ");
|
||||||
|
if (bct == BlockChangeType.CREATED)
|
||||||
|
title.append("creations ");
|
||||||
|
else if (bct == BlockChangeType.DESTROYED)
|
||||||
|
title.append("destructions ");
|
||||||
|
else
|
||||||
|
title.append("changes ");
|
||||||
|
if (!players.isEmpty()) {
|
||||||
|
title.append("from player ");
|
||||||
|
for (int i = 0; i < players.size(); i++)
|
||||||
|
title.append(players.get(i) + ", ");
|
||||||
|
title.deleteCharAt(title.length() - 2);
|
||||||
|
}
|
||||||
|
if (minutes > 0)
|
||||||
|
title.append("in the last " + minutes + " minutes ");
|
||||||
|
if (minutes < 0)
|
||||||
|
title.append("up to " + minutes + " minutes ago ");
|
||||||
|
if (loc != null && radius > 0)
|
||||||
|
title.append("within " + radius + " blocks of you ");
|
||||||
|
if (loc != null && radius == 0)
|
||||||
|
title.append("at " + loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ() + " ");
|
||||||
|
else if (sel != null)
|
||||||
|
title.append("inside selection ");
|
||||||
|
title.append("in " + getfriendlyWorldname());
|
||||||
|
title.setCharAt(0, String.valueOf(title.charAt(0)).toUpperCase().toCharArray()[0]);
|
||||||
|
return title.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWhere() {
|
||||||
|
return getWhere(bct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWhere(BlockChangeType blockChangeType) {
|
||||||
|
final StringBuilder where = new StringBuilder("WHERE ");
|
||||||
|
switch (blockChangeType) {
|
||||||
|
case ALL:
|
||||||
|
if (!types.isEmpty()) {
|
||||||
|
where.append('(');
|
||||||
|
for (final int type : types)
|
||||||
|
where.append("type = " + type + " OR replaced = " + type + " OR ");
|
||||||
|
where.delete(where.length() - 4, where.length() - 1);
|
||||||
|
where.append(") AND ");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BOTH:
|
||||||
|
where.append("type <> replaced AND ");
|
||||||
|
if (!types.isEmpty()) {
|
||||||
|
where.append('(');
|
||||||
|
for (final int type : types)
|
||||||
|
where.append("type = " + type + " OR replaced = " + type + " OR ");
|
||||||
|
where.delete(where.length() - 4, where.length());
|
||||||
|
where.append(") AND ");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CREATED:
|
||||||
|
where.append("type <> replaced AND ");
|
||||||
|
if (!types.isEmpty()) {
|
||||||
|
where.append('(');
|
||||||
|
for (final int type : types)
|
||||||
|
where.append("type = " + type + " OR ");
|
||||||
|
where.delete(where.length() - 4, where.length());
|
||||||
|
where.append(") AND ");
|
||||||
|
} else
|
||||||
|
where.append("type > 0 AND ");
|
||||||
|
break;
|
||||||
|
case DESTROYED:
|
||||||
|
where.append("type <> replaced AND ");
|
||||||
|
if (!types.isEmpty()) {
|
||||||
|
where.append('(');
|
||||||
|
for (final int type : types)
|
||||||
|
where.append("replaced = " + type + " OR ");
|
||||||
|
where.delete(where.length() - 4, where.length());
|
||||||
|
where.append(") AND ");
|
||||||
|
} else
|
||||||
|
where.append("replaced > 0 AND ");
|
||||||
|
break;
|
||||||
|
case CHESTACCESS:
|
||||||
|
where.append("type = replaced AND (type = 23 OR type = 54 OR type = 61) AND ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!players.isEmpty() && sum != SummarizationMode.PLAYERS) {
|
||||||
|
where.append('(');
|
||||||
|
for (final String playerName : players)
|
||||||
|
where.append("playername = '" + playerName + "' OR ");
|
||||||
|
where.delete(where.length() - 4, where.length());
|
||||||
|
where.append(") AND ");
|
||||||
|
}
|
||||||
|
if (loc != null) {
|
||||||
|
if (radius == 0)
|
||||||
|
where.append("x = '" + loc.getBlockX() + "' AND y = '" + loc.getBlockY() + "' AND z = '" + loc.getBlockZ() + "' AND ");
|
||||||
|
else if (radius > 0)
|
||||||
|
where.append("x > '" + (loc.getBlockX() - radius) + "' AND x < '" + (loc.getBlockX() + radius) + "' AND z > '" + (loc.getBlockZ() - radius) + "' AND z < '" + (loc.getBlockZ() + radius) + "' AND ");
|
||||||
|
} else if (sel != null)
|
||||||
|
where.append("x >= '" + sel.getMinimumPoint().getBlockX() + "' AND x <= '" + sel.getMaximumPoint().getBlockX() + "' AND y >= '" + sel.getMinimumPoint().getBlockY() + "' AND y <= '" + sel.getMaximumPoint().getBlockY() + "' AND z >= '" + sel.getMinimumPoint().getBlockZ() + "' AND z <= '" + sel.getMaximumPoint().getBlockZ() + "' AND ");
|
||||||
|
if (minutes > 0)
|
||||||
|
where.append("date > date_sub(now(), INTERVAL " + minutes + " MINUTE) AND ");
|
||||||
|
if (minutes < 0)
|
||||||
|
where.append("date < date_sub(now(), INTERVAL " + minutes * -1 + " MINUTE) AND ");
|
||||||
|
if (where.length() > 6)
|
||||||
|
where.delete(where.length() - 4, where.length());
|
||||||
|
else
|
||||||
|
where.delete(0, where.length());
|
||||||
|
return where.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseArgs(CommandSender sender, List<String> args) throws IllegalArgumentException {
|
public void parseArgs(CommandSender sender, List<String> args) throws IllegalArgumentException {
|
||||||
@@ -203,155 +345,17 @@ public class QueryParams implements Cloneable
|
|||||||
players.add(playerName);
|
players.add(playerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTable() {
|
protected QueryParams clone() {
|
||||||
return logblock.getConfig().tables.get(world.getName().hashCode());
|
try {
|
||||||
|
return (QueryParams)super.clone();
|
||||||
|
} catch (final CloneNotSupportedException ex) {}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
private String getfriendlyWorldname() {
|
||||||
final StringBuilder title = new StringBuilder();
|
String worldName = world.getName();
|
||||||
if (!types.isEmpty()) {
|
worldName = worldName.substring(worldName.lastIndexOf('/') + 1);
|
||||||
for (int i = 0; i < types.size(); i++)
|
return worldName.substring(worldName.lastIndexOf('\\') + 1);
|
||||||
title.append(BukkitUtils.getMaterialName(types.get(i)) + ", ");
|
|
||||||
title.deleteCharAt(title.length() - 2);
|
|
||||||
} else
|
|
||||||
title.append("Block ");
|
|
||||||
if (bct == BlockChangeType.CREATED)
|
|
||||||
title.append("creations ");
|
|
||||||
else if (bct == BlockChangeType.DESTROYED)
|
|
||||||
title.append("destructions ");
|
|
||||||
else
|
|
||||||
title.append("changes ");
|
|
||||||
if (!players.isEmpty()) {
|
|
||||||
title.append("from player ");
|
|
||||||
for (int i = 0; i < players.size(); i++)
|
|
||||||
title.append(players.get(i) + ", ");
|
|
||||||
title.deleteCharAt(title.length() - 2);
|
|
||||||
}
|
|
||||||
if (minutes > 0)
|
|
||||||
title.append("in the last " + minutes + " minutes ");
|
|
||||||
if (minutes < 0)
|
|
||||||
title.append("up to " + minutes + " minutes ago ");
|
|
||||||
if (loc != null && radius > 0)
|
|
||||||
title.append("within " + radius + " blocks of you ");
|
|
||||||
if (loc != null && radius == 0)
|
|
||||||
title.append("at " + loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ() + " ");
|
|
||||||
else if (sel != null)
|
|
||||||
title.append("inside selection ");
|
|
||||||
title.append("in " + getfriendlyWorldname());
|
|
||||||
title.setCharAt(0, String.valueOf(title.charAt(0)).toUpperCase().toCharArray()[0]);
|
|
||||||
return title.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrderBy() {
|
|
||||||
return "ORDER BY date " + order + ", id " + order + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLimit() {
|
|
||||||
if (limit == -1)
|
|
||||||
return "";
|
|
||||||
return "LIMIT " + limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getWhere() {
|
|
||||||
return getWhere(bct);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getWhere(BlockChangeType blockChangeType) {
|
|
||||||
final StringBuilder where = new StringBuilder("WHERE ");
|
|
||||||
switch (blockChangeType) {
|
|
||||||
case ALL:
|
|
||||||
if (!types.isEmpty()) {
|
|
||||||
where.append('(');
|
|
||||||
for (final int type : types)
|
|
||||||
where.append("type = " + type + " OR replaced = " + type + " OR ");
|
|
||||||
where.delete(where.length() - 4, where.length() - 1);
|
|
||||||
where.append(") AND ");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BOTH:
|
|
||||||
where.append("type <> replaced AND ");
|
|
||||||
if (!types.isEmpty()) {
|
|
||||||
where.append('(');
|
|
||||||
for (final int type : types)
|
|
||||||
where.append("type = " + type + " OR replaced = " + type + " OR ");
|
|
||||||
where.delete(where.length() - 4, where.length());
|
|
||||||
where.append(") AND ");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CREATED:
|
|
||||||
where.append("type <> replaced AND ");
|
|
||||||
if (!types.isEmpty()) {
|
|
||||||
where.append('(');
|
|
||||||
for (final int type : types)
|
|
||||||
where.append("type = " + type + " OR ");
|
|
||||||
where.delete(where.length() - 4, where.length());
|
|
||||||
where.append(") AND ");
|
|
||||||
} else
|
|
||||||
where.append("type > 0 AND ");
|
|
||||||
break;
|
|
||||||
case DESTROYED:
|
|
||||||
where.append("type <> replaced AND ");
|
|
||||||
if (!types.isEmpty()) {
|
|
||||||
where.append('(');
|
|
||||||
for (final int type : types)
|
|
||||||
where.append("replaced = " + type + " OR ");
|
|
||||||
where.delete(where.length() - 4, where.length());
|
|
||||||
where.append(") AND ");
|
|
||||||
} else
|
|
||||||
where.append("replaced > 0 AND ");
|
|
||||||
break;
|
|
||||||
case CHESTACCESS:
|
|
||||||
where.append("type = replaced AND (type = 23 OR type = 54 OR type = 61) AND ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!players.isEmpty() && sum != SummarizationMode.PLAYERS) {
|
|
||||||
where.append('(');
|
|
||||||
for (final String playerName : players)
|
|
||||||
where.append("playername = '" + playerName + "' OR ");
|
|
||||||
where.delete(where.length() - 4, where.length());
|
|
||||||
where.append(") AND ");
|
|
||||||
}
|
|
||||||
if (loc != null) {
|
|
||||||
if (radius == 0)
|
|
||||||
where.append("x = '" + loc.getBlockX() + "' AND y = '" + loc.getBlockY() + "' AND z = '" + loc.getBlockZ() + "' AND ");
|
|
||||||
else if (radius > 0)
|
|
||||||
where.append("x > '" + (loc.getBlockX() - radius) + "' AND x < '" + (loc.getBlockX() + radius) + "' AND z > '" + (loc.getBlockZ() - radius) + "' AND z < '" + (loc.getBlockZ() + radius) + "' AND ");
|
|
||||||
} else if (sel != null)
|
|
||||||
where.append("x >= '" + sel.getMinimumPoint().getBlockX() + "' AND x <= '" + sel.getMaximumPoint().getBlockX() + "' AND y >= '" + sel.getMinimumPoint().getBlockY() + "' AND y <= '" + sel.getMaximumPoint().getBlockY() + "' AND z >= '" + sel.getMinimumPoint().getBlockZ() + "' AND z <= '" + sel.getMaximumPoint().getBlockZ() + "' AND ");
|
|
||||||
if (minutes > 0)
|
|
||||||
where.append("date > date_sub(now(), INTERVAL " + minutes + " MINUTE) AND ");
|
|
||||||
if (minutes < 0)
|
|
||||||
where.append("date < date_sub(now(), INTERVAL " + minutes * -1 + " MINUTE) AND ");
|
|
||||||
if (where.length() > 6)
|
|
||||||
where.delete(where.length() - 4, where.length());
|
|
||||||
else
|
|
||||||
where.delete(0, where.length());
|
|
||||||
return where.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getQuery() {
|
|
||||||
if (sum == SummarizationMode.NONE) {
|
|
||||||
final StringBuilder select = new StringBuilder("SELECT ");
|
|
||||||
final StringBuilder from = new StringBuilder("FROM `" + getTable() + "` ");
|
|
||||||
if (selectFullBlockData)
|
|
||||||
select.append("replaced, type, data, x, y, z ");
|
|
||||||
else
|
|
||||||
select.append("date, replaced, type, playername");
|
|
||||||
if (!selectFullBlockData || players.size() > 0)
|
|
||||||
from.append("INNER JOIN `lb-players` USING (playerid) ");
|
|
||||||
if (types.size() == 0 || types.contains(63) || types.contains(68)) {
|
|
||||||
select.append(", signtext");
|
|
||||||
from.append("LEFT JOIN `" + getTable() + "-sign` USING (id) ");
|
|
||||||
}
|
|
||||||
if (types.size() == 0 || types.contains(23) || types.contains(54) || types.contains(61)) {
|
|
||||||
select.append(", itemtype, itemamount, itemdata");
|
|
||||||
from.append("LEFT JOIN `" + getTable() + "-chest` USING (id) ");
|
|
||||||
}
|
|
||||||
return select.toString() + " " + from.toString() + getWhere() + getOrderBy() + getLimit();
|
|
||||||
} else if (sum == SummarizationMode.TYPES)
|
|
||||||
return "SELECT type, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT type, count(type) AS created, 0 AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) " + getWhere() + "AND type > 0 GROUP BY type) UNION (SELECT replaced AS type, 0 AS created, count(replaced) AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) " + getWhere() + "AND replaced > 0 GROUP BY replaced)) AS t GROUP BY type ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit();
|
|
||||||
else
|
|
||||||
return "SELECT playername, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT playerid, count(type) AS created, 0 AS destroyed FROM `" + getTable() + "` " + getWhere() + "AND type > 0 GROUP BY playerid) UNION (SELECT playerid, 0 AS created, count(replaced) AS destroyed FROM `" + getTable() + "` " + getWhere() + "AND replaced > 0 GROUP BY playerid)) AS t INNER JOIN `lb-players` USING (playerid) GROUP BY playerid ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] getValues(List<String> args, int offset) {
|
private String[] getValues(List<String> args, int offset) {
|
||||||
@@ -367,34 +371,30 @@ public class QueryParams implements Cloneable
|
|||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getfriendlyWorldname() {
|
private void merge(QueryParams params) {
|
||||||
String worldName = world.getName();
|
players = params.players;
|
||||||
worldName = worldName.substring(worldName.lastIndexOf('/') + 1);
|
types = params.types;
|
||||||
return worldName.substring(worldName.lastIndexOf('\\') + 1);
|
loc = params.loc;
|
||||||
}
|
radius = params.radius;
|
||||||
|
sel = params.sel;
|
||||||
protected QueryParams clone() {
|
if (minutes == 0)
|
||||||
try {
|
minutes = params.minutes;
|
||||||
return (QueryParams)super.clone();
|
sum = params.sum;
|
||||||
} catch (final CloneNotSupportedException ex) {}
|
bct = params.bct;
|
||||||
return null;
|
limit = params.limit;
|
||||||
}
|
world = params.world;
|
||||||
|
order = params.order;
|
||||||
static boolean isKeyWord(String param) {
|
|
||||||
if (keywords.contains(param.toLowerCase().hashCode()))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum SummarizationMode {
|
|
||||||
NONE, TYPES, PLAYERS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum BlockChangeType {
|
public static enum BlockChangeType {
|
||||||
BOTH, CREATED, DESTROYED, CHESTACCESS, ALL
|
ALL, BOTH, CHESTACCESS, CREATED, DESTROYED
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum Order {
|
public static enum Order {
|
||||||
ASC, DESC
|
ASC, DESC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum SummarizationMode {
|
||||||
|
NONE, PLAYERS, TYPES
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,24 +18,6 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
public class BukkitUtils
|
public class BukkitUtils
|
||||||
{
|
{
|
||||||
private static class ItemStackComparator implements Comparator<ItemStack>
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public int compare(ItemStack a, ItemStack b) {
|
|
||||||
final int aType = a.getTypeId(), bType = b.getTypeId();
|
|
||||||
if (aType < bType)
|
|
||||||
return -1;
|
|
||||||
if (aType > bType)
|
|
||||||
return 1;
|
|
||||||
final byte aData = rawData(a), bData = rawData(b);
|
|
||||||
if (aData < bData)
|
|
||||||
return -1;
|
|
||||||
if (aData > bData)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static Set<Set<Integer>> blockEquivalents;
|
private final static Set<Set<Integer>> blockEquivalents;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -159,4 +141,22 @@ public class BukkitUtils
|
|||||||
return 0;
|
return 0;
|
||||||
return item.getData().getData();
|
return item.getData().getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ItemStackComparator implements Comparator<ItemStack>
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int compare(ItemStack a, ItemStack b) {
|
||||||
|
final int aType = a.getTypeId(), bType = b.getTypeId();
|
||||||
|
if (aType < bType)
|
||||||
|
return -1;
|
||||||
|
if (aType > bType)
|
||||||
|
return 1;
|
||||||
|
final byte aData = rawData(a), bData = rawData(b);
|
||||||
|
if (aData < bData)
|
||||||
|
return -1;
|
||||||
|
if (aData > bData)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,16 @@ public class ConnectionPool implements Closeable
|
|||||||
reaper.start();
|
reaper.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void close() {
|
||||||
|
final Enumeration<JDCConnection> conns = connections.elements();
|
||||||
|
while (conns.hasMoreElements()) {
|
||||||
|
final JDCConnection conn = conns.nextElement();
|
||||||
|
connections.remove(conn);
|
||||||
|
conn.terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized Connection getConnection() throws SQLException {
|
public synchronized Connection getConnection() throws SQLException {
|
||||||
JDCConnection conn;
|
JDCConnection conn;
|
||||||
for (int i = 0; i < connections.size(); i++) {
|
for (int i = 0; i < connections.size(); i++) {
|
||||||
@@ -68,16 +78,6 @@ public class ConnectionPool implements Closeable
|
|||||||
connections.remove(conn);
|
connections.remove(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void close() {
|
|
||||||
final Enumeration<JDCConnection> conns = connections.elements();
|
|
||||||
while (conns.hasMoreElements()) {
|
|
||||||
final JDCConnection conn = conns.nextElement();
|
|
||||||
connections.remove(conn);
|
|
||||||
conn.terminate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ConnectionReaper extends Thread
|
private class ConnectionReaper extends Thread
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user