forked from LogBlock/LogBlock
Added chat lookup
This commit is contained in:
35
src/de/diddiz/LogBlock/ChatMessage.java
Normal file
35
src/de/diddiz/LogBlock/ChatMessage.java
Normal 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 : "");
|
||||
}
|
||||
}
|
@@ -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();
|
||||
|
@@ -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};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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 {
|
||||
|
@@ -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))");
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user