Added chat lookup

This commit is contained in:
Robin Kupper
2011-08-20 22:07:15 +02:00
parent d662d5ee47
commit 939c98c90b
8 changed files with 205 additions and 108 deletions

View File

@@ -0,0 +1,35 @@
package de.diddiz.LogBlock;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.bukkit.Location;
public class ChatMessage implements LookupCacheElement
{
final long id, date;
final String playerName, message;
public ChatMessage(String playerName, String message) {
id = 0;
date = System.currentTimeMillis() / 1000;
this.playerName = playerName;
this.message = message;
}
public ChatMessage(ResultSet rs, QueryParams p) throws SQLException {
id = p.needId ? rs.getInt("id") : 0;
date = p.needDate ? rs.getTimestamp("date").getTime() : 0;
playerName = p.needPlayer ? rs.getString("playername") : null;
message = p.needMessage ? rs.getString("message") : null;
}
@Override
public Location getLocation() {
return null;
}
@Override
public String getMessage() {
return (playerName != null ? "<" + playerName + "> " : "") + (message != null ? message : "");
}
}

View File

@@ -429,16 +429,20 @@ public class CommandsHandler implements CommandExecutor
@Override
public void run() {
try {
params.needDate = true;
params.needType = true;
params.needData = true;
params.needPlayer = true;
if (params.types.size() == 0 || params.types.contains(63) || params.types.contains(68))
params.needSignText = true;
if (params.types.size() == 0 || params.types.contains(23) || params.types.contains(54) || params.types.contains(61) || params.types.contains(62) || params.bct == BlockChangeType.CHESTACCESS)
params.needChestAccess = true;
if (params.limit < 0 && params.sum == SummarizationMode.NONE)
params.limit = config.linesLimit;
if (params.bct == BlockChangeType.CHAT) {
params.needDate = true;
params.needPlayer = true;
params.needMessage = true;
} else {
params.needDate = true;
params.needType = true;
params.needData = true;
params.needPlayer = true;
if (params.types.size() == 0 || params.types.contains(63) || params.types.contains(68))
params.needSignText = true;
if (params.types.size() == 0 || params.types.contains(23) || params.types.contains(54) || params.types.contains(61) || params.types.contains(62))
params.needChestAccess = true;
}
conn = logblock.getConnection();
state = conn.createStatement();
rs = state.executeQuery(params.getQuery());
@@ -478,14 +482,20 @@ public class CommandsHandler implements CommandExecutor
public void run() {
File file = null;
try {
params.needDate = true;
params.needType = true;
params.needData = true;
params.needPlayer = true;
if (params.types.size() == 0 || params.types.contains(63) || params.types.contains(68))
params.needSignText = true;
if (params.types.size() == 0 || params.types.contains(23) || params.types.contains(54) || params.types.contains(61) || params.types.contains(62))
params.needChestAccess = true;
if (params.bct == BlockChangeType.CHAT) {
params.needDate = true;
params.needPlayer = true;
params.needMessage = true;
} else {
params.needDate = true;
params.needType = true;
params.needData = true;
params.needPlayer = true;
if (params.types.size() == 0 || params.types.contains(63) || params.types.contains(68))
params.needSignText = true;
if (params.types.size() == 0 || params.types.contains(23) || params.types.contains(54) || params.types.contains(61) || params.types.contains(62))
params.needChestAccess = true;
}
conn = logblock.getConnection();
state = conn.createStatement();
file = new File("plugins/LogBlock/log/" + params.getTitle().replace(":", ".") + ".log");
@@ -501,7 +511,7 @@ public class CommandsHandler implements CommandExecutor
writer.write("Created - Destroyed - " + (params.sum == SummarizationMode.TYPES ? "Block" : "Player") + newline);
final LookupCacheElementFactory factory = new LookupCacheElementFactory(params, sender instanceof Player ? 2 / 3f : 1);
while (rs.next()) {
writer.write(factory.getLookupCacheElement(rs).getMessage()+ newline);
writer.write(factory.getLookupCacheElement(rs).getMessage() + newline);
counter++;
}
writer.close();

View File

@@ -416,25 +416,20 @@ public class Consumer extends TimerTask
}
}
private class ChatRow implements Row
private class ChatRow extends ChatMessage implements Row
{
final long date;
final String player, message;
ChatRow(String player, String message) {
date = System.currentTimeMillis() / 1000;
this.player = player;
this.message = message;
super(player, message);
}
@Override
public String[] getInserts() {
return new String[]{"INSERT INTO `lb-chat` (date, playerid, message) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(player) + ", '" + message + "');"};
return new String[]{"INSERT INTO `lb-chat` (date, playerid, message) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(playerName) + ", '" + message + "');"};
}
@Override
public String[] getPlayers() {
return new String[]{player};
return new String[]{playerName};
}
}
}

View File

@@ -2,6 +2,7 @@ package de.diddiz.LogBlock;
import java.sql.ResultSet;
import java.sql.SQLException;
import de.diddiz.LogBlock.QueryParams.BlockChangeType;
import de.diddiz.LogBlock.QueryParams.SummarizationMode;
public class LookupCacheElementFactory
@@ -15,6 +16,8 @@ public class LookupCacheElementFactory
}
public LookupCacheElement getLookupCacheElement(ResultSet rs) throws SQLException {
if (params.bct == BlockChangeType.CHAT)
return new ChatMessage(rs, params);
if (params.sum == SummarizationMode.NONE)
return new BlockChange(rs, params);
return new SummedBlockChanges(rs, params, spaceFactor);

View File

@@ -5,6 +5,7 @@ import static de.diddiz.util.BukkitUtils.getBlockEquivalents;
import static de.diddiz.util.BukkitUtils.materialName;
import static de.diddiz.util.BukkitUtils.senderName;
import static de.diddiz.util.Utils.isInt;
import static de.diddiz.util.Utils.join;
import static de.diddiz.util.Utils.listing;
import static de.diddiz.util.Utils.parseTimeSpec;
import java.util.ArrayList;
@@ -24,7 +25,7 @@ import com.sk89q.worldedit.bukkit.selections.Selection;
public class QueryParams implements Cloneable
{
private static final Set<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(), "coords".hashCode(), "silent".hashCode()));
private static final Set<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(), "coords".hashCode(), "silent".hashCode(), "chat".hashCode(), "search".hashCode(), "match".hashCode()));
public BlockChangeType bct = BlockChangeType.BOTH;
public int limit = -1, minutes = 0, radius = -1;
public Location loc = null;
@@ -35,7 +36,8 @@ public class QueryParams implements Cloneable
public SummarizationMode sum = SummarizationMode.NONE;
public List<Integer> types = new ArrayList<Integer>();
public World world = null;
public boolean needId = false, needDate = false, needType = false, needData = false, needPlayer = false, needCoords = false, needSignText = false, needChestAccess = false;
public String match = null;
public boolean needId = false, needDate = false, needType = false, needData = false, needPlayer = false, needCoords = false, needSignText = false, needChestAccess = false, needMessage = false;
private final LogBlock logblock;
public QueryParams(LogBlock logblock) {
@@ -56,6 +58,21 @@ public class QueryParams implements Cloneable
}
public String getQuery() {
if (bct == BlockChangeType.CHAT) {
String select = "SELECT ";
String from = "FROM `lb-chat` ";
if (needId)
select += "id, ";
if (needDate)
select += "date, ";
if (needPlayer)
select += "playername, ";
if (needPlayer || players.size() > 0)
from += "INNER JOIN `lb-players` USING (playerid) ";
if (needMessage)
select += "message, ";
return select.substring(0, select.length() - 2) + " " + from + getWhere() + "ORDER BY date " + order + ", id " + order + " " + getLimit();
}
if (sum == SummarizationMode.NONE) {
String select = "SELECT ";
String from = "FROM `" + getTable() + "` ";
@@ -96,6 +113,8 @@ public class QueryParams implements Cloneable
final StringBuilder title = new StringBuilder();
if (bct == BlockChangeType.CHESTACCESS)
title.append("chest accesses ");
else if (bct == BlockChangeType.CHAT)
title.append("chat messages ");
else {
if (!types.isEmpty()) {
final String[] blocknames = new String[types.size()];
@@ -115,10 +134,12 @@ public class QueryParams implements Cloneable
title.append((excludePlayersMode ? "without" : "from") + " many players ");
else if (!players.isEmpty())
title.append((excludePlayersMode ? "without" : "from") + " player" + (players.size() != 1 ? "s" : "") + " " + listing(players.toArray(new String[players.size()]), ", ", " and ") + " ");
if (match != null && match.length() > 0)
title.append("matching '" + match + "' ");
if (minutes > 0)
title.append("in the last " + minutes + " minutes ");
if (minutes < 0)
title.append("up to " + minutes * -1 + " minutes ago ");
title.append("more than " + minutes * -1 + " minutes ago ");
if (loc != null) {
if (radius > 0)
title.append("within " + radius + " blocks of " + (prepareToolQuery ? "clicked block" : "you") + " ");
@@ -146,58 +167,70 @@ public class QueryParams implements Cloneable
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 OR type = 62) AND ");
if (!types.isEmpty()) {
where.append('(');
for (final int type : types)
where.append("itemtype = " + type + " OR ");
where.delete(where.length() - 4, where.length());
where.append(") AND ");
}
break;
if (blockChangeType == BlockChangeType.CHAT) {
if (match != null && match.length() > 0)
where.append("MATCH (message) AGAINST ('" + match + "' IN BOOLEAN MODE) AND ");
} else {
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 OR type = 62) AND ");
if (!types.isEmpty()) {
where.append('(');
for (final int type : types)
where.append("itemtype = " + type + " OR ");
where.delete(where.length() - 4, where.length());
where.append(") AND ");
}
break;
}
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 (!players.isEmpty() && sum != SummarizationMode.PLAYERS)
if (!excludePlayersMode) {
@@ -209,13 +242,6 @@ public class QueryParams implements Cloneable
} else
for (final String playerName : players)
where.append("playername != '" + playerName + "' 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)
@@ -323,6 +349,8 @@ public class QueryParams implements Cloneable
bct = BlockChangeType.DESTROYED;
else if (param.equals("chestaccess"))
bct = BlockChangeType.CHESTACCESS;
else if (param.equals("chat"))
bct = BlockChangeType.CHAT;
else if (param.equals("all"))
bct = BlockChangeType.ALL;
else if (param.equals("limit")) {
@@ -346,7 +374,11 @@ public class QueryParams implements Cloneable
needCoords = true;
else if (param.equals("silent"))
silent = true;
else
else if (param.equals("search") || param.equals("match")) {
if (values.length == 0)
throw new IllegalArgumentException("No arguments for '" + param + "'");
match = join(values, " ").replace("\\", "\\\\").replace("'", "\\'");
} else
throw new IllegalArgumentException("Not a valid argument: '" + param + "'");
if (values != null)
i += values.length;
@@ -413,24 +445,25 @@ public class QueryParams implements Cloneable
return values;
}
public void merge(QueryParams params) {
players = params.players;
excludePlayersMode = params.excludePlayersMode;
types = params.types;
loc = params.loc;
radius = params.radius;
sel = params.sel;
if (params.minutes != 0 || minutes != logblock.getConfig().defaultTime)
minutes = params.minutes;
sum = params.sum;
bct = params.bct;
limit = params.limit;
world = params.world;
order = params.order;
public void merge(QueryParams p) {
players = p.players;
excludePlayersMode = p.excludePlayersMode;
types = p.types;
loc = p.loc;
radius = p.radius;
sel = p.sel;
if (p.minutes != 0 || minutes != logblock.getConfig().defaultTime)
minutes = p.minutes;
sum = p.sum;
bct = p.bct;
limit = p.limit;
world = p.world;
order = p.order;
match = p.match;
}
public static enum BlockChangeType {
ALL, BOTH, CHESTACCESS, CREATED, DESTROYED
ALL, BOTH, CHESTACCESS, CREATED, DESTROYED, CHAT
}
public static enum Order {

View File

@@ -79,6 +79,17 @@ class Updater
config.removeProperty("tables");
config.setProperty("version", "1.23");
}
if (config.getString("version").compareTo("1.27") < 0) {
log.info("[LogBlock] Updating tables to 1.27 ...");
final Connection conn = logblock.getConnection();
try {
conn.setAutoCommit(true);
final Statement st = conn.createStatement();
st.execute("ALTER TABLE `lb-chat` ENGINE = MyISAM, ADD FULLTEXT message (message)");
st.close();
conn.close();
} catch (final SQLException ex) {}
}
config.save();
return true;
}
@@ -92,7 +103,7 @@ class Updater
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 UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid SMALLINT UNSIGNED NOT NULL, message VARCHAR(255) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid))");
createTable(dbm, state, "lb-chat", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid SMALLINT UNSIGNED NOT NULL, message VARCHAR(255) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid), FULLTEXT message (message)) ENGINE=MyISAM");
for (final WorldConfig wcfg : logblock.getConfig().worlds.values()) {
createTable(dbm, state, wcfg.table, "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid SMALLINT UNSIGNED NOT NULL, replaced TINYINT UNSIGNED NOT NULL, type TINYINT UNSIGNED NOT NULL, data TINYINT UNSIGNED NOT NULL, x SMALLINT NOT NULL, y TINYINT UNSIGNED NOT NULL, z SMALLINT NOT NULL, PRIMARY KEY (id), KEY coords (x, z, y), KEY date (date), KEY playerid (playerid))");
createTable(dbm, state, wcfg.table + "-sign", "(id INT UNSIGNED NOT NULL, signtext VARCHAR(255) NOT NULL, PRIMARY KEY (id))");

View File

@@ -131,4 +131,14 @@ public class Utils
filled.append(' ');
return filled.toString();
}
public static String join(String[] s, String delimiter) {
if (s == null || s.length == 0)
return "";
final int len = s.length;
final StringBuffer buffer = new StringBuffer(s[0]);
for (int i = 1; i < len; i++)
buffer.append(delimiter).append(s[i]);
return buffer.toString();
}
}

View File

@@ -1,5 +1,5 @@
name: LogBlock
version: '1.26'
version: '1.27'
author: DiddiZ
website: http://www.diddiz.de/minecraft/
main: de.diddiz.LogBlock.LogBlock