diff --git a/pom.xml b/pom.xml index faf7209..93108f9 100644 --- a/pom.xml +++ b/pom.xml @@ -40,9 +40,9 @@ - org.bukkit - bukkit - 1.12-R0.1-SNAPSHOT + org.spigotmc + spigot-api + 1.13-pre7-R0.1-SNAPSHOT provided @@ -136,8 +136,8 @@ maven-compiler-plugin 3.2 - 1.7 - 1.7 + 1.8 + 1.8 diff --git a/src/main/java/de/diddiz/LogBlock/Actor.java b/src/main/java/de/diddiz/LogBlock/Actor.java index b739739..95d0f96 100644 --- a/src/main/java/de/diddiz/LogBlock/Actor.java +++ b/src/main/java/de/diddiz/LogBlock/Actor.java @@ -74,7 +74,7 @@ public class Actor { } public static Actor actorFromEntity(EntityType entity) { - return new Actor(entity.getName()); + return new Actor(entity.name()); } public static Actor actorFromProjectileSource(ProjectileSource psource) { diff --git a/src/main/java/de/diddiz/LogBlock/BlockChange.java b/src/main/java/de/diddiz/LogBlock/BlockChange.java index a5803df..caa282e 100644 --- a/src/main/java/de/diddiz/LogBlock/BlockChange.java +++ b/src/main/java/de/diddiz/LogBlock/BlockChange.java @@ -2,33 +2,40 @@ package de.diddiz.LogBlock; import de.diddiz.LogBlock.config.Config; import de.diddiz.util.BukkitUtils; +import de.diddiz.util.Utils; + import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Openable; +import org.bukkit.block.data.Powerable; +import org.bukkit.block.data.type.Switch; +import org.bukkit.inventory.ItemStack; import java.sql.ResultSet; import java.sql.SQLException; import static de.diddiz.util.LoggingUtil.checkText; -import static de.diddiz.util.MaterialName.materialName; public class BlockChange implements LookupCacheElement { public final long id, date; public final Location loc; public final Actor actor; public final String playerName; - public final int replaced, type; - public final byte data; + // public final BlockData replaced, type; + public final int replacedMaterial, replacedData, typeMaterial, typeData; public final String signtext; public final ChestAccess ca; - public BlockChange(long date, Location loc, Actor actor, int replaced, int type, byte data, String signtext, ChestAccess ca) { + public BlockChange(long date, Location loc, Actor actor, int replaced, int replacedData, int type, int typeData, String signtext, ChestAccess ca) { id = 0; this.date = date; this.loc = loc; this.actor = actor; - this.replaced = replaced; - this.type = type; - this.data = data; + this.replacedMaterial = replaced; + this.replacedData = replacedData; + this.typeMaterial = type; + this.typeData = typeData; this.signtext = checkText(signtext); this.ca = ca; this.playerName = actor == null ? null : actor.getName(); @@ -40,15 +47,25 @@ public class BlockChange implements LookupCacheElement { loc = p.needCoords ? new Location(p.world, rs.getInt("x"), rs.getInt("y"), rs.getInt("z")) : null; actor = p.needPlayer ? new Actor(rs) : null; playerName = p.needPlayer ? rs.getString("playername") : null; - replaced = p.needType ? rs.getInt("replaced") : 0; - type = p.needType ? rs.getInt("type") : 0; - data = p.needData ? rs.getByte("data") : (byte) 0; + replacedMaterial = p.needType ? rs.getInt("replaced") : 0; + replacedData = p.needType ? rs.getInt("replacedData") : -1; + typeMaterial = p.needType ? rs.getInt("type") : 0; + typeData = p.needType ? rs.getInt("typeData") : -1; signtext = p.needSignText ? rs.getString("signtext") : null; - ca = p.needChestAccess && rs.getShort("itemtype") != 0 && rs.getShort("itemamount") != 0 ? new ChestAccess(rs.getShort("itemtype"), rs.getShort("itemamount"), rs.getShort("itemdata")) : null; + ChestAccess catemp = null; + if (p.needChestAccess) { + ItemStack stack = Utils.loadItemStack(rs.getBytes("item")); + if (stack != null) { + catemp = new ChestAccess(stack, rs.getBoolean("itemremove")); + } + } + ca = catemp; } @Override public String toString() { + BlockData type = MaterialConverter.getBlockData(typeMaterial, typeData); + BlockData replaced = MaterialConverter.getBlockData(replacedMaterial, replacedData); final StringBuilder msg = new StringBuilder(); if (date > 0) { msg.append(Config.formatter.format(date)).append(" "); @@ -57,58 +74,47 @@ public class BlockChange implements LookupCacheElement { msg.append(actor.getName()).append(" "); } if (signtext != null) { - final String action = type == 0 ? "destroyed " : "created "; + final String action = type.getMaterial() == Material.AIR ? "destroyed " : "created "; if (!signtext.contains("\0")) { msg.append(action).append(signtext); } else { - msg.append(action).append(materialName(type != 0 ? type : replaced)).append(" [").append(signtext.replace("\0", "] [")).append("]"); + msg.append(action).append((type.getMaterial() != Material.AIR ? type : replaced).getMaterial().name()).append(" [").append(signtext.replace("\0", "] [")).append("]"); } - } else if (type == replaced) { - if (type == 0) { + } else if (type.equals(replaced)) { + if (type.getMaterial() == Material.AIR) { msg.append("did an unspecified action"); } else if (ca != null) { - if (ca.itemType == 0 || ca.itemAmount == 0) { - msg.append("looked inside ").append(materialName(type)); - } else if (ca.itemAmount < 0) { - msg.append("took ").append(-ca.itemAmount).append("x ").append(materialName(ca.itemType, ca.itemData)).append(" from ").append(materialName(type)); + if (ca.itemStack == null) { + msg.append("looked inside ").append(type.getMaterial().name()); + } else if (ca.remove) { + msg.append("took ").append(ca.itemStack.getAmount()).append("x ").append(ca.itemStack.getType().name()).append(" from ").append(type.getMaterial().name()); } else { - msg.append("put ").append(ca.itemAmount).append("x ").append(materialName(ca.itemType, ca.itemData)).append(" into ").append(materialName(type)); + msg.append("put ").append(ca.itemStack.getAmount()).append("x ").append(ca.itemStack.getType().name()).append(" into ").append(type.getMaterial().name()); } - } else if (BukkitUtils.getContainerBlocks().contains(Material.getMaterial(type))) { - msg.append("opened ").append(materialName(type)); - } else if (type == 64 || type == 71) - // This is a problem that will have to be addressed in LB 2, - // there is no way to tell from the top half of the block if - // the door is opened or closed. - { - msg.append("moved ").append(materialName(type)); + } else if (BukkitUtils.getContainerBlocks().contains(type.getMaterial())) { + msg.append("opened ").append(type.getMaterial().name()); + } else if (type instanceof Openable) { + // Door, Trapdoor, Fence gate + msg.append(((Openable)type).isOpen() ? "opened" : "closed").append(" ").append(type.getMaterial().name()); + } else if (type.getMaterial() == Material.LEVER) { + msg.append("switched ").append(type.getMaterial().name()); + } else if (type instanceof Switch) { + msg.append("pressed ").append(type.getMaterial().name()); + } else if (type.getMaterial() == Material.CAKE) { + msg.append("ate a piece of ").append(type.getMaterial().name()); + } else if (type.getMaterial() == Material.NOTE_BLOCK || type.getMaterial() == Material.REPEATER || type.getMaterial() == Material.COMPARATOR || type.getMaterial() == Material.DAYLIGHT_DETECTOR) { + msg.append("changed ").append(type.getMaterial().name()); + } else if (type instanceof Powerable) { + msg.append("stepped on ").append(type.getMaterial().name()); + } else if (type.getMaterial() == Material.TRIPWIRE) { + msg.append("ran into ").append(type.getMaterial().name()); } - // Trapdoor - else if (type == 96) { - msg.append((data < 8 || data > 11) ? "opened" : "closed").append(" ").append(materialName(type)); - } - // Fence gate - else if (type == 107) { - msg.append(data > 3 ? "opened" : "closed").append(" ").append(materialName(type)); - } else if (type == 69) { - msg.append("switched ").append(materialName(type)); - } else if (type == 77 || type == 143) { - msg.append("pressed ").append(materialName(type)); - } else if (type == 92) { - msg.append("ate a piece of ").append(materialName(type)); - } else if (type == 25 || type == 93 || type == 94 || type == 149 || type == 150) { - msg.append("changed ").append(materialName(type)); - } else if (type == 70 || type == 72 || type == 147 || type == 148) { - msg.append("stepped on ").append(materialName(type)); - } else if (type == 132) { - msg.append("ran into ").append(materialName(type)); - } - } else if (type == 0) { - msg.append("destroyed ").append(materialName(replaced, data)); - } else if (replaced == 0) { - msg.append("created ").append(materialName(type, data)); + } else if (type.getMaterial() == Material.AIR) { + msg.append("destroyed ").append(replaced.getMaterial().name()); + } else if (replaced.getMaterial() == Material.AIR) { + msg.append("created ").append(type.getMaterial().name()); } else { - msg.append("replaced ").append(materialName(replaced, (byte) 0)).append(" with ").append(materialName(type, data)); + msg.append("replaced ").append(replaced.getMaterial().name()).append(" with ").append(type.getMaterial().name()); } if (loc != null) { msg.append(" at ").append(loc.getBlockX()).append(":").append(loc.getBlockY()).append(":").append(loc.getBlockZ()); diff --git a/src/main/java/de/diddiz/LogBlock/ChestAccess.java b/src/main/java/de/diddiz/LogBlock/ChestAccess.java index 10260e5..f492662 100644 --- a/src/main/java/de/diddiz/LogBlock/ChestAccess.java +++ b/src/main/java/de/diddiz/LogBlock/ChestAccess.java @@ -1,11 +1,13 @@ package de.diddiz.LogBlock; -public class ChestAccess { - final short itemType, itemAmount, itemData; +import org.bukkit.inventory.ItemStack; - public ChestAccess(short itemType, short itemAmount, short itemData) { - this.itemType = itemType; - this.itemAmount = itemAmount; - this.itemData = itemData >= 0 ? itemData : 0; +public class ChestAccess { + final ItemStack itemStack; + final boolean remove; + + public ChestAccess(ItemStack itemStack, boolean remove) { + this.itemStack = itemStack; + this.remove = remove; } } diff --git a/src/main/java/de/diddiz/LogBlock/CommandsHandler.java b/src/main/java/de/diddiz/LogBlock/CommandsHandler.java index 78bbf2a..4fca25d 100755 --- a/src/main/java/de/diddiz/LogBlock/CommandsHandler.java +++ b/src/main/java/de/diddiz/LogBlock/CommandsHandler.java @@ -6,9 +6,11 @@ import de.diddiz.LogBlock.QueryParams.SummarizationMode; import de.diddiz.LogBlock.config.Config; import de.diddiz.LogBlock.config.WorldConfig; import de.diddiz.LogBlockQuestioner.LogBlockQuestioner; -import de.diddiz.util.Block; +import de.diddiz.util.Utils; + import org.bukkit.ChatColor; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -17,7 +19,6 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitScheduler; -import java.io.Closeable; import java.io.File; import java.io.FileWriter; import java.sql.Connection; @@ -398,7 +399,7 @@ public class CommandsHandler implements CommandExecutor { return true; } - public abstract class AbstractCommand implements Runnable, Closeable { + public abstract class AbstractCommand implements Runnable { protected CommandSender sender; protected QueryParams params; protected Connection conn = null; @@ -409,15 +410,12 @@ public class CommandsHandler implements CommandExecutor { this.sender = sender; this.params = params; if (async) { - if (scheduler.scheduleAsyncDelayedTask(logblock, this) == -1) { - throw new Exception("Failed to schedule the command"); - } + scheduler.runTaskAsynchronously(logblock, this); } else { run(); } } - @Override public final void close() { try { if (conn != null) { @@ -458,7 +456,7 @@ public class CommandsHandler implements CommandExecutor { params.needType = true; params.needData = true; params.needPlayer = true; - if (params.types.isEmpty() || Block.inList(params.types, 63) || Block.inList(params.types, 68)) { + if (params.types.isEmpty() || params.types.contains(Material.SIGN) || params.types.contains(Material.WALL_SIGN)) { params.needSignText = true; } if (params.bct == BlockChangeType.CHESTACCESS || params.bct == BlockChangeType.ALL) { @@ -523,7 +521,7 @@ public class CommandsHandler implements CommandExecutor { params.needType = true; params.needData = true; params.needPlayer = true; - if (params.types.isEmpty() || Block.inList(params.types, 63) || Block.inList(params.types, 68)) { + if (params.types.isEmpty() || params.types.contains(Material.SIGN) || params.types.contains(Material.WALL_SIGN)) { params.needSignText = true; } if (params.bct == BlockChangeType.CHESTACCESS || params.bct == BlockChangeType.ALL) { @@ -671,7 +669,12 @@ public class CommandsHandler implements CommandExecutor { final WorldEditor editor = new WorldEditor(logblock, params.world); while (rs.next()) { - editor.queueEdit(rs.getInt("x"), rs.getInt("y"), rs.getInt("z"), rs.getInt("replaced"), rs.getInt("type"), rs.getByte("data"), rs.getString("signtext"), rs.getShort("itemtype"), rs.getShort("itemamount"), rs.getShort("itemdata")); + ChestAccess chestaccess = null; + ItemStack stack = Utils.loadItemStack(rs.getBytes("item")); + if (stack != null) { + chestaccess = new ChestAccess(stack, rs.getBoolean("itemremove")); + } + editor.queueEdit(rs.getInt("x"), rs.getInt("y"), rs.getInt("z"), rs.getInt("replaced"), rs.getInt("replacedData"), rs.getInt("type"), rs.getByte("typeData"), rs.getString("signtext"), chestaccess); } final int changes = editor.getSize(); if (changes > 10000) { @@ -741,7 +744,12 @@ public class CommandsHandler implements CommandExecutor { } final WorldEditor editor = new WorldEditor(logblock, params.world); while (rs.next()) { - editor.queueEdit(rs.getInt("x"), rs.getInt("y"), rs.getInt("z"), rs.getInt("type"), rs.getInt("replaced"), rs.getByte("data"), rs.getString("signtext"), rs.getShort("itemtype"), (short) -rs.getShort("itemamount"), rs.getShort("itemdata")); + ChestAccess chestaccess = null; + ItemStack stack = Utils.loadItemStack(rs.getBytes("item")); + if (stack != null) { + chestaccess = new ChestAccess(stack, !rs.getBoolean("itemremove")); + } + editor.queueEdit(rs.getInt("x"), rs.getInt("y"), rs.getInt("z"), rs.getInt("type"), rs.getInt("typeData"), rs.getInt("replaced"), rs.getByte("replacedData"), rs.getString("signtext"), chestaccess); } final int changes = editor.getSize(); if (!params.silent) { @@ -793,7 +801,7 @@ public class CommandsHandler implements CommandExecutor { int deleted; final String table = params.getTable(); final String join = params.players.size() > 0 ? "INNER JOIN `lb-players` USING (playerid) " : ""; - rs = state.executeQuery("SELECT count(*) FROM `" + table + "` " + join + params.getWhere()); + rs = state.executeQuery("SELECT count(*) FROM `" + table + "-blocks` " + join + params.getWhere()); rs.next(); if ((deleted = rs.getInt(1)) > 0) { if (!params.silent && askClearLogs && sender instanceof Player && questioner != null) { @@ -806,32 +814,32 @@ public class CommandsHandler implements CommandExecutor { } if (dumpDeletedLog) { try { - state.execute("SELECT * FROM `" + table + "` " + join + params.getWhere() + "INTO OUTFILE '" + new File(dumpFolder, time + " " + table + " " + params.getTitle().replace(":", ".") + ".csv").getAbsolutePath().replace("\\", "\\\\") + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'"); + state.execute("SELECT * FROM `" + table + "-blocks` " + join + params.getWhere() + "INTO OUTFILE '" + new File(dumpFolder, time + " " + table + " " + params.getTitle().replace(":", ".") + ".csv").getAbsolutePath().replace("\\", "\\\\") + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'"); } catch (final SQLException ex) { sender.sendMessage(ChatColor.RED + "Error while dumping log. Make sure your MySQL user has access to the LogBlock folder, or disable clearlog.dumpDeletedLog"); getLogger().log(Level.SEVERE, "[ClearLog] Exception while dumping log: ", ex); return; } } - state.execute("DELETE `" + table + "` FROM `" + table + "` " + join + params.getWhere()); + state.execute("DELETE `" + table + "` FROM `" + table + "-blocks` " + join + params.getWhere()); sender.sendMessage(ChatColor.GREEN + "Cleared out table " + table + ". Deleted " + deleted + " entries."); } - rs = state.executeQuery("SELECT COUNT(*) FROM `" + table + "-sign` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL"); + rs = state.executeQuery("SELECT COUNT(*) FROM `" + table + "-sign` LEFT JOIN `" + table + "-blocks` USING (id) WHERE `" + table + "-blocks`.id IS NULL"); rs.next(); if ((deleted = rs.getInt(1)) > 0) { if (dumpDeletedLog) { - state.execute("SELECT id, signtext FROM `" + table + "-sign` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL INTO OUTFILE '" + new File(dumpFolder, time + " " + table + "-sign " + params.getTitle() + ".csv").getAbsolutePath().replace("\\", "\\\\") + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'"); + state.execute("SELECT id, signtext FROM `" + table + "-sign` LEFT JOIN `" + table + "-blocks` USING (id) WHERE `" + table + "-blocks`.id IS NULL INTO OUTFILE '" + new File(dumpFolder, time + " " + table + "-sign " + params.getTitle() + ".csv").getAbsolutePath().replace("\\", "\\\\") + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'"); } - state.execute("DELETE `" + table + "-sign` FROM `" + table + "-sign` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL;"); + state.execute("DELETE `" + table + "-sign` FROM `" + table + "-sign` LEFT JOIN `" + table + "-blocks` USING (id) WHERE `" + table + "-blocks`.id IS NULL;"); sender.sendMessage(ChatColor.GREEN + "Cleared out table " + table + "-sign. Deleted " + deleted + " entries."); } - rs = state.executeQuery("SELECT COUNT(*) FROM `" + table + "-chest` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL"); + rs = state.executeQuery("SELECT COUNT(*) FROM `" + table + "-chestdata` LEFT JOIN `" + table + "-blocks` USING (id) WHERE `" + table + "-blocks`.id IS NULL"); rs.next(); if ((deleted = rs.getInt(1)) > 0) { if (dumpDeletedLog) { - state.execute("SELECT id, itemtype, itemamount, itemdata FROM `" + table + "-chest` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL INTO OUTFILE '" + new File(dumpFolder, time + " " + table + "-chest " + params.getTitle() + ".csv").getAbsolutePath().replace("\\", "\\\\") + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'"); + state.execute("SELECT id, item, itemremove FROM `" + table + "-chest` LEFT JOIN `" + table + "-blocks` USING (id) WHERE `" + table + "-blocks`.id IS NULL INTO OUTFILE '" + new File(dumpFolder, time + " " + table + "-chest " + params.getTitle() + ".csv").getAbsolutePath().replace("\\", "\\\\") + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'"); } - state.execute("DELETE `" + table + "-chest` FROM `" + table + "-chest` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL;"); + state.execute("DELETE `" + table + "-chest` FROM `" + table + "-chest` LEFT JOIN `" + table + "-blocks` USING (id) WHERE `" + table + "-blocks`.id IS NULL;"); sender.sendMessage(ChatColor.GREEN + "Cleared out table " + table + "-chest. Deleted " + deleted + " entries."); } } catch (final Exception ex) { diff --git a/src/main/java/de/diddiz/LogBlock/Consumer.java b/src/main/java/de/diddiz/LogBlock/Consumer.java index aa84004..7f8afbf 100644 --- a/src/main/java/de/diddiz/LogBlock/Consumer.java +++ b/src/main/java/de/diddiz/LogBlock/Consumer.java @@ -1,12 +1,15 @@ package de.diddiz.LogBlock; -import static de.diddiz.LogBlock.Actor.actorFromString; import de.diddiz.LogBlock.config.Config; import de.diddiz.LogBlock.events.BlockChangePreLogEvent; +import de.diddiz.util.Utils; + +import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.World; +import org.bukkit.Material; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; @@ -48,180 +51,224 @@ public class Consumer extends TimerTask { /** * Logs any block change. Don't try to combine broken and placed blocks. Queue two block changes or use the queueBLockReplace methods. * - * @param actor Actor responsible for making the change - * @param loc Location of the block change - * @param typeBefore Type of the block before the change - * @param typeAfter Type of the block after the change - * @param data Data of the block after the change + * @param actor + * Actor responsible for making the change + * @param loc + * Location of the block change + * @param typeBefore + * Type of the block before the change + * @param typeAfter + * Type of the block after the change + * @param data + * Data of the block after the change */ - public void queueBlock(Actor actor, Location loc, int typeBefore, int typeAfter, byte data) { - queueBlock(actor, loc, typeBefore, typeAfter, data, null, null); + public void queueBlock(Actor actor, Location loc, BlockData typeBefore, BlockData typeAfter) { + queueBlock(actor, loc, typeBefore, typeAfter, null, null); } /** * Logs a block break. The type afterwards is assumed to be 0 (air). * - * @param actor Actor responsible for breaking the block - * @param before Blockstate of the block before actually being destroyed. + * @param actor + * Actor responsible for breaking the block + * @param before + * Blockstate of the block before actually being destroyed. */ public void queueBlockBreak(Actor actor, BlockState before) { - queueBlockBreak(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData()); + queueBlockBreak(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getBlockData()); } /** * Logs a block break. The block type afterwards is assumed to be 0 (air). * - * @param actor Actor responsible for the block break - * @param loc Location of the broken block - * @param typeBefore Type of the block before the break - * @param dataBefore Data of the block before the break + * @param actor + * Actor responsible for the block break + * @param loc + * Location of the broken block + * @param typeBefore + * Type of the block before the break + * @param dataBefore + * Data of the block before the break */ - public void queueBlockBreak(Actor actor, Location loc, int typeBefore, byte dataBefore) { - queueBlock(actor, loc, typeBefore, 0, dataBefore); + public void queueBlockBreak(Actor actor, Location loc, BlockData typeBefore) { + queueBlock(actor, loc, typeBefore, null); } /** * Logs a block place. The block type before is assumed to be 0 (air). * - * @param actor Actor responsible for placing the block - * @param after Blockstate of the block after actually being placed. + * @param actor + * Actor responsible for placing the block + * @param after + * Blockstate of the block after actually being placed. */ public void queueBlockPlace(Actor actor, BlockState after) { - queueBlockPlace(actor, new Location(after.getWorld(), after.getX(), after.getY(), after.getZ()), after.getBlock().getTypeId(), after.getBlock().getData()); + queueBlockPlace(actor, new Location(after.getWorld(), after.getX(), after.getY(), after.getZ()), after.getBlockData()); } /** * Logs a block place. The block type before is assumed to be 0 (air). * - * @param actor Actor responsible for placing the block - * @param loc Location of the placed block - * @param type Type of the placed block - * @param data Data of the placed block + * @param actor + * Actor responsible for placing the block + * @param loc + * Location of the placed block + * @param type + * Type of the placed block + * @param data + * Data of the placed block */ - public void queueBlockPlace(Actor actor, Location loc, int type, byte data) { - queueBlock(actor, loc, 0, type, data); + public void queueBlockPlace(Actor actor, Location loc, BlockData type) { + queueBlock(actor, loc, null, type); } /** * Logs a block being replaced from the before and after {@link org.bukkit.block.BlockState}s * - * @param actor Actor responsible for replacing the block - * @param before Blockstate of the block before actually being destroyed. - * @param after Blockstate of the block after actually being placed. + * @param actor + * Actor responsible for replacing the block + * @param before + * Blockstate of the block before actually being destroyed. + * @param after + * Blockstate of the block after actually being placed. */ public void queueBlockReplace(Actor actor, BlockState before, BlockState after) { - queueBlockReplace(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData(), after.getTypeId(), after.getRawData()); + queueBlockReplace(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getBlockData(), after.getBlockData()); } /** * Logs a block being replaced from the before {@link org.bukkit.block.BlockState} and the type and data after * - * @param actor Actor responsible for replacing the block - * @param before Blockstate of the block before being replaced. - * @param typeAfter Type of the block after being replaced - * @param dataAfter Data of the block after being replaced + * @param actor + * Actor responsible for replacing the block + * @param before + * Blockstate of the block before being replaced. + * @param typeAfter + * Type of the block after being replaced + * @param dataAfter + * Data of the block after being replaced */ - public void queueBlockReplace(Actor actor, BlockState before, int typeAfter, byte dataAfter) { - queueBlockReplace(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData(), typeAfter, dataAfter); + public void queueBlockReplace(Actor actor, BlockState before, BlockData typeAfter) { + queueBlockReplace(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getBlockData(), typeAfter); } /** * Logs a block being replaced from the type and data before and the {@link org.bukkit.block.BlockState} after * - * @param actor Actor responsible for replacing the block - * @param typeBefore Type of the block before being replaced - * @param dataBefore Data of the block before being replaced - * @param after Blockstate of the block after actually being placed. + * @param actor + * Actor responsible for replacing the block + * @param typeBefore + * Type of the block before being replaced + * @param dataBefore + * Data of the block before being replaced + * @param after + * Blockstate of the block after actually being placed. */ - public void queueBlockReplace(Actor actor, int typeBefore, byte dataBefore, BlockState after) { - queueBlockReplace(actor, new Location(after.getWorld(), after.getX(), after.getY(), after.getZ()), typeBefore, dataBefore, after.getTypeId(), after.getRawData()); + public void queueBlockReplace(Actor actor, BlockData typeBefore, BlockState after) { + queueBlockReplace(actor, new Location(after.getWorld(), after.getX(), after.getY(), after.getZ()), typeBefore, after.getBlockData()); } - public void queueBlockReplace(Actor actor, Location loc, int typeBefore, byte dataBefore, int typeAfter, byte dataAfter) { - if (dataBefore == 0 && (typeBefore != typeAfter)) { - queueBlock(actor, loc, typeBefore, typeAfter, dataAfter); - } else { - queueBlockBreak(actor, loc, typeBefore, dataBefore); - queueBlockPlace(actor, loc, typeAfter, dataAfter); - } + public void queueBlockReplace(Actor actor, Location loc, BlockData typeBefore, BlockData typeAfter) { + queueBlockBreak(actor, loc, typeBefore); + queueBlockPlace(actor, loc, typeAfter); } /** * Logs an actor interacting with a container block's inventory * - * @param actor The actor interacting with the container - * @param container The respective container. Must be an instance of an InventoryHolder. - * @param itemType Type of the item taken/stored - * @param itemAmount Amount of the item taken/stored - * @param itemData Data of the item taken/stored + * @param actor + * The actor interacting with the container + * @param container + * The respective container. Must be an instance of an InventoryHolder. + * @param itemType + * Type of the item taken/stored + * @param itemAmount + * Amount of the item taken/stored + * @param itemData + * Data of the item taken/stored */ - public void queueChestAccess(Actor actor, BlockState container, short itemType, short itemAmount, short itemData) { + public void queueChestAccess(Actor actor, BlockState container, ItemStack itemStack, boolean remove) { if (!(container instanceof InventoryHolder)) { throw new IllegalArgumentException("Container must be instanceof InventoryHolder"); } - queueChestAccess(actor, new Location(container.getWorld(), container.getX(), container.getY(), container.getZ()), container.getTypeId(), itemType, itemAmount, itemData); + queueChestAccess(actor, new Location(container.getWorld(), container.getX(), container.getY(), container.getZ()), container.getBlockData(), itemStack, remove); } /** * Logs an actor interacting with a container block's inventory * - * @param actor The actor interacting with the container - * @param loc The location of the container block - * @param type Type id of the container. - * @param itemType Type of the item taken/stored - * @param itemAmount Amount of the item taken/stored - * @param itemData Data of the item taken/stored + * @param actor + * The actor interacting with the container + * @param loc + * The location of the container block + * @param type + * Type id of the container. + * @param itemType + * Type of the item taken/stored + * @param itemAmount + * Amount of the item taken/stored + * @param itemData + * Data of the item taken/stored */ - public void queueChestAccess(Actor actor, Location loc, int type, short itemType, short itemAmount, short itemData) { - queueBlock(actor, loc, type, type, (byte) 0, null, new ChestAccess(itemType, itemAmount, itemData)); + public void queueChestAccess(Actor actor, Location loc, BlockData type, ItemStack itemStack, boolean remove) { + queueBlock(actor, loc, type, type, null, new ChestAccess(itemStack, remove)); } /** * Logs a container block break. The block type before is assumed to be o (air). All content is assumed to be taken. * - * @param actor The actor breaking the container - * @param container Must be an instance of InventoryHolder + * @param actor + * The actor breaking the container + * @param container + * Must be an instance of InventoryHolder */ public void queueContainerBreak(Actor actor, BlockState container) { if (!(container instanceof InventoryHolder)) { return; } - queueContainerBreak(actor, new Location(container.getWorld(), container.getX(), container.getY(), container.getZ()), container.getTypeId(), container.getRawData(), ((InventoryHolder) container).getInventory()); + queueContainerBreak(actor, new Location(container.getWorld(), container.getX(), container.getY(), container.getZ()), container.getBlockData(), ((InventoryHolder) container).getInventory()); } /** * Logs a container block break. The block type before is assumed to be o (air). All content is assumed to be taken. * - * @param actor The actor responsible for breaking the container - * @param loc The location of the inventory block - * @param type The type of the container block - * @param data The data of the container block - * @param inv The inventory of the container block + * @param actor + * The actor responsible for breaking the container + * @param loc + * The location of the inventory block + * @param type + * The type of the container block + * @param data + * The data of the container block + * @param inv + * The inventory of the container block */ - public void queueContainerBreak(Actor actor, Location loc, int type, byte data, Inventory inv) { + public void queueContainerBreak(Actor actor, Location loc, BlockData type, Inventory inv) { final ItemStack[] items = compressInventory(inv.getContents()); for (final ItemStack item : items) { - queueChestAccess(actor, loc, type, (short) item.getTypeId(), (short) (item.getAmount() * -1), rawData(item)); + queueChestAccess(actor, loc, type, item, true); } - queueBlockBreak(actor, loc, type, data); + queueBlockBreak(actor, loc, type); } /** - * @param killer Can't be null - * @param victim Can't be null + * @param killer + * Can't be null + * @param victim + * Can't be null */ public void queueKill(Entity killer, Entity victim) { if (killer == null || victim == null) { return; } - int weapon = 0; + ItemStack weapon = null; Actor killerActor = Actor.actorFromEntity(killer); // If it's a projectile kill we want to manually assign the weapon, so check for player before converting a projectile to its source - if (killer instanceof Player && ((Player) killer).getItemInHand() != null) { - weapon = ((Player) killer).getItemInHand().getTypeId(); + if (killer instanceof Player && ((Player) killer).getInventory().getItemInMainHand() != null) { + weapon = ((Player) killer).getInventory().getItemInMainHand(); } if (killer instanceof Projectile) { - weapon = itemIDfromProjectileEntity(killer); + weapon = new ItemStack(itemIDfromProjectileEntity(killer)); ProjectileSource ps = ((Projectile) killer).getShooter(); if (ps == null) { killerActor = Actor.actorFromEntity(killer); @@ -236,92 +283,99 @@ public class Consumer extends TimerTask { /** * This form should only be used when the killer is not an entity e.g. for fall or suffocation damage * - * @param killer Can't be null - * @param victim Can't be null + * @param killer + * Can't be null + * @param victim + * Can't be null */ public void queueKill(Actor killer, Entity victim) { if (killer == null || victim == null) { return; } - queueKill(victim.getLocation(), killer, Actor.actorFromEntity(victim), 0); + queueKill(victim.getLocation(), killer, Actor.actorFromEntity(victim), null); } /** - * @param world World the victim was inside. - * @param killer Name of the killer. Can be null. - * @param victim Name of the victim. Can't be null. - * @param weapon Item id of the weapon. 0 for no weapon. - * @deprecated Use {@link #queueKill(org.bukkit.Location, de.diddiz.LogBlock.Actor, de.diddiz.LogBlock.Actor, int)} - * instead + * @param location + * Location of the victim. + * @param killer + * Killer Actor. Can be null. + * @param victim + * Victim Actor. Can't be null. + * @param weapon + * Item id of the weapon. 0 for no weapon. */ - @Deprecated - public void queueKill(World world, Actor killer, Actor victim, int weapon) { - queueKill(new Location(world, 0, 0, 0), killer, victim, weapon); - } - - /** - * @param location Location of the victim. - * @param killer Killer Actor. Can be null. - * @param victim Victim Actor. Can't be null. - * @param weapon Item id of the weapon. 0 for no weapon. - */ - public void queueKill(Location location, Actor killer, Actor victim, int weapon) { + public void queueKill(Location location, Actor killer, Actor victim, ItemStack weapon) { if (victim == null || !isLogged(location.getWorld())) { return; } - queue.add(new KillRow(location, killer == null ? null : killer, victim, weapon)); + queue.add(new KillRow(location, killer == null ? null : killer, victim, MaterialConverter.getOrAddMaterialId(weapon.getType().getKey().toString()))); } /** * Logs an actor breaking a sign along with its contents * - * @param actor Actor responsible for breaking the sign - * @param loc Location of the broken sign - * @param type Type of the sign. Must be 63 or 68. - * @param data Data of the sign being broken - * @param lines The four lines on the sign. + * @param actor + * Actor responsible for breaking the sign + * @param loc + * Location of the broken sign + * @param type + * Type of the sign. Must be 63 or 68. + * @param data + * Data of the sign being broken + * @param lines + * The four lines on the sign. */ - public void queueSignBreak(Actor actor, Location loc, int type, byte data, String[] lines) { - if (type != 63 && type != 68 || lines == null || lines.length != 4) { + public void queueSignBreak(Actor actor, Location loc, BlockData type, String[] lines) { + if ((type.getMaterial() != Material.SIGN && type.getMaterial() != Material.WALL_SIGN) || lines == null || lines.length != 4) { return; } - queueBlock(actor, loc, type, 0, data, lines[0] + "\0" + lines[1] + "\0" + lines[2] + "\0" + lines[3], null); + queueBlock(actor, loc, type, null, lines[0] + "\0" + lines[1] + "\0" + lines[2] + "\0" + lines[3], null); } /** * Logs an actor breaking a sign along with its contents * - * @param actor Actor responsible for breaking the sign - * @param sign The sign being broken + * @param actor + * Actor responsible for breaking the sign + * @param sign + * The sign being broken */ public void queueSignBreak(Actor actor, Sign sign) { - queueSignBreak(actor, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines()); + queueSignBreak(actor, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getBlockData(), sign.getLines()); } /** * Logs an actor placing a sign along with its contents * - * @param actor Actor placing the sign - * @param loc Location of the placed sign - * @param type Type of the sign. Must be 63 or 68. - * @param data Data of the placed sign block - * @param lines The four lines on the sign. + * @param actor + * Actor placing the sign + * @param loc + * Location of the placed sign + * @param type + * Type of the sign. Must be 63 or 68. + * @param data + * Data of the placed sign block + * @param lines + * The four lines on the sign. */ - public void queueSignPlace(Actor actor, Location loc, int type, byte data, String[] lines) { - if (type != 63 && type != 68 || lines == null || lines.length != 4) { + public void queueSignPlace(Actor actor, Location loc, BlockData type, String[] lines) { + if ((type.getMaterial() != Material.SIGN && type.getMaterial() != Material.WALL_SIGN) || lines == null || lines.length != 4) { return; } - queueBlock(actor, loc, 0, type, data, lines[0] + "\0" + lines[1] + "\0" + lines[2] + "\0" + lines[3], null); + queueBlock(actor, loc, null, type, lines[0] + "\0" + lines[1] + "\0" + lines[2] + "\0" + lines[3], null); } /** * Logs an actor placing a sign along with its contents * - * @param actor Actor placing the sign - * @param sign The palced sign object + * @param actor + * Actor placing the sign + * @param sign + * The palced sign object */ public void queueSignPlace(Actor actor, Sign sign) { - queueSignPlace(actor, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines()); + queueSignPlace(actor, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getBlockData(), sign.getLines()); } public void queueChat(Actor player, String message) { @@ -344,218 +398,12 @@ public class Consumer extends TimerTask { queue.add(new PlayerLeaveRow(player)); } - // Deprecated methods re-added for API compatability - - /** - * Logs any block change. Don't try to combine broken and placed blocks. - * Queue two block changes or use the queueBLockReplace methods. - * - * @deprecated Use - * {@link #queueBlock(de.diddiz.LogBlock.Actor, org.bukkit.Location, int, int, byte)} - * which supports UUIDs - */ - public void queueBlock(String playerName, Location loc, int typeBefore, int typeAfter, byte data) { - queueBlock(actorFromString(playerName), loc, typeBefore, typeAfter, data); + public void queueAddMaterialMapping(int key, String material) { + queue.add(new AddMaterialRow(key, material)); } - /** - * Logs a block break. The type afterwards is assumed to be 0 (air). - * - * @param before Blockstate of the block before actually being destroyed. - * @deprecated Use - * {@link #queueBlockBreak(de.diddiz.LogBlock.Actor, org.bukkit.block.BlockState)} - * which supports UUIDs - */ - public void queueBlockBreak(String playerName, BlockState before) { - queueBlockBreak(actorFromString(playerName), before); - - } - - /** - * Logs a block break. The block type afterwards is assumed to be 0 (air). - * - * @deprecated Use {@link #queueBlockBreak(de.diddiz.LogBlock.Actor, org.bukkit.Location, int, byte)} - * which supports UUIDs - */ - public void queueBlockBreak(String playerName, Location loc, int typeBefore, byte dataBefore) { - queueBlockBreak(actorFromString(playerName), loc, typeBefore, dataBefore); - } - - /** - * Logs a block place. The block type before is assumed to be 0 (air). - * - * @param after Blockstate of the block after actually being placed. - * @depracated Use {@link #queueBlockPlace(de.diddiz.LogBlock.Actor, org.bukkit.block.BlockState)} - * which supports UUIDs - */ - public void queueBlockPlace(String playerName, BlockState after) { - queueBlockPlace(actorFromString(playerName), after); - } - - /** - * Logs a block place. The block type before is assumed to be 0 (air). - * @deprecated Use {@link #queueBlockPlace(de.diddiz.LogBlock.Actor, org.bukkit.Location, int, byte)} - * which supports UUIDs - */ - public void queueBlockPlace(String playerName, Location loc, int type, byte data) { - queueBlockPlace(actorFromString(playerName), loc, type, data); - } - - /** - * @param before Blockstate of the block before actually being destroyed. - * @param after Blockstate of the block after actually being placed. - * @deprecated Use {@link #queueBlockReplace(de.diddiz.LogBlock.Actor, org.bukkit.block.BlockState, org.bukkit.block.BlockState)} - * which supports UUIDs - */ - public void queueBlockReplace(String playerName, BlockState before, BlockState after) { - queueBlockReplace(actorFromString(playerName), before, after); - } - - /** - * @param before Blockstate of the block before actually being destroyed. - * @deprecated Use {@link #queueBlockReplace(de.diddiz.LogBlock.Actor, org.bukkit.block.BlockState, int, byte)} - * which supports UUIDs - */ - public void queueBlockReplace(String playerName, BlockState before, int typeAfter, byte dataAfter) { - queueBlockReplace(actorFromString(playerName), before, typeAfter, dataAfter); - } - - /** - * @param after Blockstate of the block after actually being placed. - * @deprecated {@link #queueBlockReplace(de.diddiz.LogBlock.Actor, int, byte, org.bukkit.block.BlockState)} - * which supports UUIDs - */ - public void queueBlockReplace(String playerName, int typeBefore, byte dataBefore, BlockState after) { - queueBlockReplace(actorFromString(playerName), typeBefore, dataBefore, after); - } - - /** - * @deprecated use {@link #queueBlockReplace(de.diddiz.LogBlock.Actor, org.bukkit.Location, int, byte, int, byte)} - * which supports UUIDs - */ - public void queueBlockReplace(String playerName, Location loc, int typeBefore, byte dataBefore, int typeAfter, byte dataAfter) { - queueBlockReplace(actorFromString(playerName),loc,typeBefore,dataBefore,typeAfter,dataAfter); - } - - /** - * @param container The respective container. Must be an instance of an - * InventoryHolder. - * @deprecated Use {@link #queueChestAccess(de.diddiz.LogBlock.Actor, org.bukkit.block.BlockState, short, short, short)} - * which supports UUIDs - */ - public void queueChestAccess(String playerName, BlockState container, short itemType, short itemAmount, short itemData) { - queueChestAccess(actorFromString(playerName),container,itemType,itemAmount,itemData); - } - - /** - * @param type Type id of the container. - * @deprecated Use {@link #queueChestAccess(de.diddiz.LogBlock.Actor, org.bukkit.Location, int, short, short, short)} - * which supports UUIDs - */ - public void queueChestAccess(String playerName, Location loc, int type, short itemType, short itemAmount, short itemData) { - queueChestAccess(actorFromString(playerName), loc, type, itemType, itemAmount, itemData); - } - - /** - * Logs a container block break. The block type before is assumed to be o - * (air). All content is assumed to be taken. - * - * @param container Must be an instance of InventoryHolder - * @deprecated Use {@link #queueContainerBreak(de.diddiz.LogBlock.Actor, org.bukkit.block.BlockState)} - * which supports UUIDs - */ - public void queueContainerBreak(String playerName, BlockState container) { - queueContainerBreak(actorFromString(playerName), container); - } - - /** - * Logs a container block break. The block type before is assumed to be o - * (air). All content is assumed to be taken. - * @deprecated Use {@link #queueContainerBreak(de.diddiz.LogBlock.Actor, org.bukkit.Location, int, byte, org.bukkit.inventory.Inventory)} - * which supports UUIDs - */ - public void queueContainerBreak(String playerName, Location loc, int type, byte data, Inventory inv) { - queueContainerBreak(actorFromString(playerName),loc,type,data,inv); - } - - /** - * This form should only be used when the killer is not an entity e.g. for - * fall or suffocation damage - * - * @param killer Can't be null - * @param victim Can't be null - * @deprecated Use {@link #queueKill(de.diddiz.LogBlock.Actor, org.bukkit.entity.Entity)} - * which supports UUIDs - */ - public void queueKill(String killer, Entity victim) { - queueKill(actorFromString(killer),victim); - } - - /** - * @param world World the victim was inside. - * @param killerName Name of the killer. Can be null. - * @param victimName Name of the victim. Can't be null. - * @param weapon Item id of the weapon. 0 for no weapon. - * @deprecated Use {@link #queueKill(org.bukkit.Location, de.diddiz.LogBlock.Actor, de.diddiz.LogBlock.Actor, int)} instead - */ - @Deprecated - public void queueKill(World world, String killerName, String victimName, int weapon) { - queueKill(world,actorFromString(killerName),actorFromString(victimName),weapon); - } - - /** - * @param location Location of the victim. - * @param killerName Name of the killer. Can be null. - * @param victimName Name of the victim. Can't be null. - * @param weapon Item id of the weapon. 0 for no weapon. - * @deprecated Use {@link #queueKill(org.bukkit.Location, de.diddiz.LogBlock.Actor, de.diddiz.LogBlock.Actor, int)} - * which supports UUIDs - */ - public void queueKill(Location location, String killerName, String victimName, int weapon) { - queueKill(location,actorFromString(killerName),actorFromString(victimName),weapon); - } - - /** - * @param type Type of the sign. Must be 63 or 68. - * @param lines The four lines on the sign. - * @deprecated Use {@link #queueSignBreak(de.diddiz.LogBlock.Actor, org.bukkit.Location, int, byte, java.lang.String[])} - * which supports UUIDs - */ - public void queueSignBreak(String playerName, Location loc, int type, byte data, String[] lines) { - queueSignBreak(actorFromString(playerName),loc,type,data,lines); - } - - /** - * @deprecated Use {@link #queueSignBreak(de.diddiz.LogBlock.Actor, org.bukkit.block.Sign)} - * which supports UUIDs - */ - public void queueSignBreak(String playerName, Sign sign) { - queueSignBreak(actorFromString(playerName),sign); - } - - /** - * @param type Type of the sign. Must be 63 or 68. - * @param lines The four lines on the sign. - * @deprecated Use {@link #queueSignPlace(de.diddiz.LogBlock.Actor, org.bukkit.Location, int, byte, java.lang.String[])} - * which supports UUIDs - */ - public void queueSignPlace(String playerName, Location loc, int type, byte data, String[] lines) { - queueSignPlace(actorFromString(playerName),loc,type,data,lines); - } - - /** - * @deprecated Use {@link #queueSignPlace(de.diddiz.LogBlock.Actor, org.bukkit.block.Sign)} - * which supports UUIDs - */ - public void queueSignPlace(String playerName, Sign sign) { - queueSignPlace(actorFromString(playerName),sign); - } -/** - * @deprecated Use {@link #queueChat(de.diddiz.LogBlock.Actor, java.lang.String)} - * which supports UUIDs - */ - public void queueChat(String player, String message) { - queueChat(actorFromString(player),message); + public void queueAddBlockStateMapping(int key, String blockState) { + queue.add(new AddBlockStateRow(key, blockState)); } @Override @@ -564,25 +412,24 @@ public class Consumer extends TimerTask { return; } long startTime = System.currentTimeMillis(); - int startSize = queue.size(); - - final Connection conn = logblock.getConnection(); - Statement state = null; - if (Config.queueWarningSize > 0 && queue.size() >= Config.queueWarningSize) { - getLogger().info("[Consumer] Queue overloaded. Size: " + getQueueSize()); - } - + // int startSize = queue.size(); int count = 0; - + Connection conn = null; + Statement state = null; try { + + conn = logblock.getConnection(); + if (Config.queueWarningSize > 0 && queue.size() >= Config.queueWarningSize) { + getLogger().info("[Consumer] Queue overloaded. Size: " + getQueueSize()); + } + if (conn == null) { return; } conn.setAutoCommit(false); state = conn.createStatement(); final long start = System.currentTimeMillis(); - process: - while (!queue.isEmpty() && (System.currentTimeMillis() - start < timePerRun || count < forceToProcessAtLeast)) { + process: while (!queue.isEmpty() && (System.currentTimeMillis() - start < timePerRun || count < forceToProcessAtLeast)) { final Row r = queue.poll(); if (r == null) { continue; @@ -738,11 +585,16 @@ public class Consumer extends TimerTask { return playerIds.containsKey(actor); } - private void queueBlock(Actor actor, Location loc, int typeBefore, int typeAfter, byte data, String signtext, ChestAccess ca) { - + private void queueBlock(Actor actor, Location loc, BlockData typeBefore, BlockData typeAfter, String signtext, ChestAccess ca) { + if (typeBefore == null) { + typeBefore = Bukkit.createBlockData(Material.AIR); + } + if (typeAfter == null) { + typeAfter = Bukkit.createBlockData(Material.AIR); + } if (Config.fireCustomEvents) { // Create and call the event - BlockChangePreLogEvent event = new BlockChangePreLogEvent(actor, loc, typeBefore, typeAfter, data, signtext, ca); + BlockChangePreLogEvent event = new BlockChangePreLogEvent(actor, loc, typeBefore, typeAfter, signtext, ca); logblock.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return; @@ -753,15 +605,22 @@ public class Consumer extends TimerTask { loc = event.getLocation(); typeBefore = event.getTypeBefore(); typeAfter = event.getTypeAfter(); - data = event.getData(); signtext = event.getSignText(); ca = event.getChestAccess(); } // Do this last so LogBlock still has final say in what is being added - if (actor == null || loc == null || typeBefore < 0 || typeAfter < 0 || (Config.safetyIdCheck && (typeBefore > 255 || typeAfter > 255)) || hiddenPlayers.contains(actor.getName().toLowerCase()) || !isLogged(loc.getWorld()) || typeBefore != typeAfter && hiddenBlocks.contains(typeBefore) && hiddenBlocks.contains(typeAfter)) { + if (actor == null || loc == null || typeBefore == null || typeAfter == null || hiddenPlayers.contains(actor.getName().toLowerCase()) || !isLogged(loc.getWorld()) || typeBefore != typeAfter && hiddenBlocks.contains(typeBefore.getMaterial()) && hiddenBlocks.contains(typeAfter.getMaterial())) { return; } - queue.add(new BlockRow(loc, actor, typeBefore, typeAfter, data, signtext, ca)); + + String replacedString = typeBefore.getAsString(); + int replacedMaterialId = MaterialConverter.getOrAddMaterialId(replacedString); + int replacedStateId = MaterialConverter.getOrAddBlockStateId(replacedString); + String typeString = typeAfter.getAsString(); + int typeMaterialId = MaterialConverter.getOrAddMaterialId(typeString); + int typeStateId = MaterialConverter.getOrAddBlockStateId(typeString); + + queue.add(new BlockRow(loc, actor, replacedMaterialId, replacedStateId, typeMaterialId, typeStateId, signtext, ca)); } private String playerID(Actor actor) { @@ -811,31 +670,33 @@ public class Consumer extends TimerTask { private class BlockRow extends BlockChange implements MergeableRow { private Connection connection; - public BlockRow(Location loc, Actor actor, int replaced, int type, byte data, String signtext, ChestAccess ca) { - super(System.currentTimeMillis() / 1000, loc, actor, replaced, type, data, signtext, ca); + public BlockRow(Location loc, Actor actor, int replaced, int replacedData, int type, int typeData, String signtext, ChestAccess ca) { + super(System.currentTimeMillis() / 1000, loc, actor, replaced, replacedData, type, typeData, signtext, ca); } @Override public String[] getInserts() { final String table = getWorldConfig(loc.getWorld()).table; final String[] inserts = new String[ca != null || signtext != null ? 2 : 1]; - inserts[0] = "INSERT INTO `" + table + "` (date, playerid, replaced, type, data, x, y, z) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(actor) + ", " + replaced + ", " + type + ", " + data + ", '" + loc.getBlockX() + "', " + safeY(loc) + ", '" + loc.getBlockZ() + "');"; + + inserts[0] = "INSERT INTO `" + table + "-blocks` (date, playerid, replaced, replaceddata, type, typedata, x, y, z) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(actor) + ", " + replacedMaterial + ", " + replacedData + ", " + typeMaterial + ", " + typeData + ", '" + loc.getBlockX() + + "', " + safeY(loc) + ", '" + loc.getBlockZ() + "');"; if (signtext != null) { inserts[1] = "INSERT INTO `" + table + "-sign` (id, signtext) values (LAST_INSERT_ID(), '" + mysqlTextEscape(signtext) + "');"; } else if (ca != null) { - inserts[1] = "INSERT INTO `" + table + "-chest` (id, itemtype, itemamount, itemdata) values (LAST_INSERT_ID(), " + ca.itemType + ", " + ca.itemAmount + ", " + ca.itemData + ");"; + inserts[1] = "INSERT INTO `" + table + "-chestdata` (id, item, itemremoved) values (LAST_INSERT_ID(), '" + Utils.mysqlEscapeBytes(Utils.saveItemStack(ca.itemStack)) + "', " + (ca.remove ? 1 : 0) + ");"; } return inserts; } @Override public String[] getPlayers() { - return new String[]{actor.getName()}; + return new String[] { actor.getName() }; } @Override public Actor[] getActors() { - return new Actor[]{actor}; + return new Actor[] { actor }; } @Override @@ -850,14 +711,15 @@ public class Consumer extends TimerTask { PreparedStatement ps1 = null; PreparedStatement ps = null; try { - ps1 = connection.prepareStatement("INSERT INTO `" + table + "` (date, playerid, replaced, type, data, x, y, z) VALUES(FROM_UNIXTIME(?), " + playerID(actor) + ", ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS); + ps1 = connection.prepareStatement("INSERT INTO `" + table + "-blocks` (date, playerid, replaced, replacedData, type, typeData, x, y, z) VALUES(FROM_UNIXTIME(?), " + playerID(actor) + ", ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS); ps1.setLong(1, date); - ps1.setInt(2, replaced); - ps1.setInt(3, type); - ps1.setInt(4, data); - ps1.setInt(5, loc.getBlockX()); - ps1.setInt(6, safeY(loc)); - ps1.setInt(7, loc.getBlockZ()); + ps1.setInt(2, replacedMaterial); + ps1.setInt(3, replacedData); + ps1.setInt(4, typeMaterial); + ps1.setInt(5, typeData); + ps1.setInt(6, loc.getBlockX()); + ps1.setInt(7, safeY(loc)); + ps1.setInt(8, loc.getBlockZ()); ps1.executeUpdate(); int id; @@ -871,11 +733,10 @@ public class Consumer extends TimerTask { ps.setInt(2, id); ps.executeUpdate(); } else if (ca != null) { - ps = connection.prepareStatement("INSERT INTO `" + table + "-chest` (itemtype, itemamount, itemdata, id) values (?, ?, ?, ?)"); - ps.setInt(1, ca.itemType); - ps.setInt(2, ca.itemAmount); - ps.setInt(3, ca.itemData); - ps.setInt(4, id); + ps = connection.prepareStatement("INSERT INTO `" + table + "-chestdata` (item, itemremove, id) values (?, ?, ?)"); + ps.setBytes(1, Utils.saveItemStack(ca.itemStack)); + ps.setInt(2, ca.remove ? 1 : 0); + ps.setInt(3, id); ps.executeUpdate(); } } catch (final SQLException ex) { @@ -954,16 +815,17 @@ public class Consumer extends TimerTask { public void executeStatements() throws SQLException { PreparedStatement ps = null; try { - ps = connection.prepareStatement("INSERT INTO `" + table + "` (date, playerid, replaced, type, data, x, y, z) VALUES(FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?)"); + ps = connection.prepareStatement("INSERT INTO `" + table + "-blocks` (date, playerid, replaced, replacedData, type, typeData, x, y, z) VALUES(FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?, ?)"); for (BlockRow row : rows) { ps.setLong(1, row.date); ps.setInt(2, playerIds.get(row.actor)); - ps.setInt(3, row.replaced); - ps.setInt(4, row.type); - ps.setInt(5, row.data); - ps.setInt(6, row.loc.getBlockX()); - ps.setInt(7, safeY(row.loc)); - ps.setInt(8, row.loc.getBlockZ()); + ps.setInt(3, row.replacedMaterial); + ps.setInt(4, row.replacedData); + ps.setInt(5, row.typeMaterial); + ps.setInt(6, row.typeData); + ps.setInt(7, row.loc.getBlockX()); + ps.setInt(8, safeY(row.loc)); + ps.setInt(9, row.loc.getBlockZ()); ps.addBatch(); } ps.executeBatch(); @@ -1041,17 +903,18 @@ public class Consumer extends TimerTask { @Override public String[] getInserts() { - return new String[]{"INSERT INTO `" + getWorldConfig(loc.getWorld()).table + "-kills` (date, killer, victim, weapon, x, y, z) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(killer) + ", " + playerID(victim) + ", " + weapon + ", " + loc.getBlockX() + ", " + safeY(loc) + ", " + loc.getBlockZ() + ");"}; + return new String[] { "INSERT INTO `" + getWorldConfig(loc.getWorld()).table + "-kills` (date, killer, victim, weapon, x, y, z) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(killer) + ", " + playerID(victim) + ", " + weapon + ", " + loc.getBlockX() + ", " + safeY(loc) + ", " + + loc.getBlockZ() + ");" }; } @Override public String[] getPlayers() { - return new String[]{killer.getName(), victim.getName()}; + return new String[] { killer.getName(), victim.getName() }; } @Override public Actor[] getActors() { - return new Actor[]{killer, victim}; + return new Actor[] { killer, victim }; } } @@ -1064,17 +927,17 @@ public class Consumer extends TimerTask { @Override public String[] getInserts() { - return new String[]{"INSERT INTO `lb-chat` (date, playerid, message) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(player) + ", '" + mysqlTextEscape(message) + "');"}; + return new String[] { "INSERT INTO `lb-chat` (date, playerid, message) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(player) + ", '" + mysqlTextEscape(message) + "');" }; } @Override public String[] getPlayers() { - return new String[]{player.getName()}; + return new String[] { player.getName() }; } @Override public Actor[] getActors() { - return new Actor[]{player}; + return new Actor[] { player }; } @Override @@ -1136,24 +999,24 @@ public class Consumer extends TimerTask { @Override public String[] getInserts() { if (logPlayerInfo) { - return new String[]{"UPDATE `lb-players` SET lastlogin = FROM_UNIXTIME(" + lastLogin + "), firstlogin = IF(firstlogin = 0, FROM_UNIXTIME(" + lastLogin + "), firstlogin), ip = '" + ip + "', playername = '" + mysqlTextEscape(player.getName()) + "' WHERE UUID = '" + player.getUUID() + "';"}; + return new String[] { + "UPDATE `lb-players` SET lastlogin = FROM_UNIXTIME(" + lastLogin + "), firstlogin = IF(firstlogin = 0, FROM_UNIXTIME(" + lastLogin + "), firstlogin), ip = '" + ip + "', playername = '" + mysqlTextEscape(player.getName()) + "' WHERE UUID = '" + player.getUUID() + "';" }; } - return new String[]{"UPDATE `lb-players` SET playername = '" + mysqlTextEscape(player.getName()) + "' WHERE UUID = '" + player.getUUID() + "';"}; + return new String[] { "UPDATE `lb-players` SET playername = '" + mysqlTextEscape(player.getName()) + "' WHERE UUID = '" + player.getUUID() + "';" }; } @Override public String[] getPlayers() { - return new String[]{player.getName()}; + return new String[] { player.getName() }; } @Override public Actor[] getActors() { - return new Actor[]{player}; + return new Actor[] { player }; } } private class PlayerLeaveRow implements Row { - ; private final long leaveTime; private final Actor actor; @@ -1165,26 +1028,78 @@ public class Consumer extends TimerTask { @Override public String[] getInserts() { if (logPlayerInfo) { - return new String[]{"UPDATE `lb-players` SET onlinetime = onlinetime + TIMESTAMPDIFF(SECOND, lastlogin, FROM_UNIXTIME('" + leaveTime + "')), playername = '" + mysqlTextEscape(actor.getName()) + "' WHERE lastlogin > 0 && UUID = '" + actor.getUUID() + "';"}; + return new String[] { "UPDATE `lb-players` SET onlinetime = onlinetime + TIMESTAMPDIFF(SECOND, lastlogin, FROM_UNIXTIME('" + leaveTime + "')), playername = '" + mysqlTextEscape(actor.getName()) + "' WHERE lastlogin > 0 && UUID = '" + actor.getUUID() + "';" }; } - return new String[]{"UPDATE `lb-players` SET playername = '" + mysqlTextEscape(actor.getName()) + "' WHERE UUID = '" + actor.getUUID() + "';"}; + return new String[] { "UPDATE `lb-players` SET playername = '" + mysqlTextEscape(actor.getName()) + "' WHERE UUID = '" + actor.getUUID() + "';" }; } @Override public String[] getPlayers() { - return new String[]{actor.getName()}; + return new String[] { actor.getName() }; } @Override public Actor[] getActors() { - return new Actor[]{actor}; + return new Actor[] { actor }; } } - - private int safeY(Location loc) { + + private class AddMaterialRow implements Row { + private final int key; + private final String material; + + AddMaterialRow(int key, String material) { + this.key = key; + this.material = material; + } + + @Override + public String[] getInserts() { + return new String[] { "INSERT INTO `lb-materials` (id, name) VALUES (" + key + ",'" + mysqlTextEscape(material) + "');" }; + } + + @Override + public String[] getPlayers() { + return new String[0]; + } + + @Override + public Actor[] getActors() { + return new Actor[0]; + } + } + + private class AddBlockStateRow implements Row { + private final int key; + private final String blockstate; + + AddBlockStateRow(int key, String blockstate) { + this.key = key; + this.blockstate = blockstate; + } + + @Override + public String[] getInserts() { + return new String[] { "INSERT INTO `lb-blockstates` (id, name) VALUES (" + key + ",'" + mysqlTextEscape(blockstate) + "');" }; + } + + @Override + public String[] getPlayers() { + return new String[0]; + } + + @Override + public Actor[] getActors() { + return new Actor[0]; + } + } + + private int safeY(Location loc) { int safeY = loc.getBlockY(); - if (safeY<0) safeY = 0; - if (safeY>65535) safeY=65535; + if (safeY < 0) + safeY = 0; + if (safeY > 65535) + safeY = 65535; return safeY; } } diff --git a/src/main/java/de/diddiz/LogBlock/Kill.java b/src/main/java/de/diddiz/LogBlock/Kill.java index 3e58631..11ea97f 100755 --- a/src/main/java/de/diddiz/LogBlock/Kill.java +++ b/src/main/java/de/diddiz/LogBlock/Kill.java @@ -2,7 +2,7 @@ package de.diddiz.LogBlock; import de.diddiz.LogBlock.config.Config; import org.bukkit.Location; -import org.bukkit.inventory.ItemStack; +import org.bukkit.Material; import java.sql.ResultSet; import java.sql.SQLException; @@ -41,7 +41,7 @@ public class Kill implements LookupCacheElement { if (loc != null) { msg.append(" at ").append(loc.getBlockX()).append(":").append(loc.getBlockY()).append(":").append(loc.getBlockZ()); } - String weaponName = prettyItemName(new ItemStack(weapon)); + String weaponName = prettyItemName(MaterialConverter.getMaterial(weapon)); msg.append(" with " + weaponName); // + ("aeiou".contains(weaponName.substring(0, 1)) ? "an " : "a " ) return msg.toString(); } @@ -56,11 +56,10 @@ public class Kill implements LookupCacheElement { return toString(); } - public String prettyItemName(ItemStack i) { - String item = i.getType().toString().replace('_', ' ').toLowerCase(); - if (item.equals("air")) { - item = "fist"; + public String prettyItemName(Material t) { + if (t == null || t == Material.AIR) { + return "fist"; } - return item; + return t.toString().replace('_', ' ').toLowerCase(); } } diff --git a/src/main/java/de/diddiz/LogBlock/LogBlock.java b/src/main/java/de/diddiz/LogBlock/LogBlock.java index d1a319b..2567c19 100644 --- a/src/main/java/de/diddiz/LogBlock/LogBlock.java +++ b/src/main/java/de/diddiz/LogBlock/LogBlock.java @@ -2,9 +2,11 @@ package de.diddiz.LogBlock; import de.diddiz.LogBlock.config.Config; import de.diddiz.LogBlock.listeners.*; +import de.diddiz.util.BukkitUtils; import de.diddiz.util.MySQLConnectionPool; import de.diddiz.worldedit.WorldEditLoggingHook; import org.bukkit.ChatColor; +import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -24,7 +26,6 @@ import java.util.Timer; import java.util.logging.Level; import static de.diddiz.LogBlock.config.Config.*; -import static de.diddiz.util.MaterialName.materialName; import static org.bukkit.Bukkit.getPluginManager; public class LogBlock extends JavaPlugin { @@ -77,6 +78,7 @@ public class LogBlock extends JavaPlugin { load(this); } updater.checkTables(); + MaterialConverter.initializeMaterials(getConnection()); } catch (final NullPointerException ex) { getLogger().log(Level.SEVERE, "Error while loading: ", ex); } catch (final Exception ex) { @@ -89,7 +91,8 @@ public class LogBlock extends JavaPlugin { @Override public void onEnable() { - materialName(0); // Force static code to run + MaterialConverter.getOrAddMaterialId(Material.AIR.getKey()); // AIR must be the first entry + BukkitUtils.isDoublePlant(Material.AIR); // Force static code to run final PluginManager pm = getPluginManager(); if (errorAtLoading) { pm.disablePlugin(this); @@ -201,9 +204,6 @@ public class LogBlock extends JavaPlugin { if (isLogging(Logging.GRASSGROWTH) || isLogging(Logging.MYCELIUMSPREAD) || isLogging(Logging.VINEGROWTH) || isLogging(Logging.MUSHROOMSPREAD)) { pm.registerEvents(new BlockSpreadLogging(this), this); } - if (isLogging(Logging.LOCKEDCHESTDECAY)) { - pm.registerEvents(new LockedChestDecayLogging(this), this); - } } @Override diff --git a/src/main/java/de/diddiz/LogBlock/MaterialConverter.java b/src/main/java/de/diddiz/LogBlock/MaterialConverter.java new file mode 100644 index 0000000..57cef28 --- /dev/null +++ b/src/main/java/de/diddiz/LogBlock/MaterialConverter.java @@ -0,0 +1,129 @@ +package de.diddiz.LogBlock; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Arrays; +import java.util.HashMap; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.block.data.BlockData; + +public class MaterialConverter { + private static String[] idToMaterial = new String[10]; + private static HashMap materialToID = new HashMap<>(); + private static int nextMaterialId; + + private static String[] idToBlockState = new String[10]; + private static HashMap blockStateToID = new HashMap<>(); + private static int nextBlockStateId; + + public synchronized static int getOrAddMaterialId(NamespacedKey nameSpaceKey) { + return getOrAddMaterialId(nameSpaceKey.toString()); + } + + public synchronized static int getOrAddMaterialId(String blockDataString) { + String materialString = blockDataString; + int dataPart = blockDataString.indexOf("["); + if (dataPart >= 0) { + materialString = blockDataString.substring(0, dataPart); + } + Integer key = materialToID.get(materialString); + if (key == null) { + key = nextMaterialId++; + materialToID.put(materialString, key); + int length = idToMaterial.length; + while (length <= key) { + length = (length * 3 / 2) + 5; + } + if (length > idToMaterial.length) { + idToMaterial = Arrays.copyOf(idToMaterial, length); + } + idToMaterial[key] = materialString; + LogBlock.getInstance().getConsumer().queueAddMaterialMapping(key, materialString); + } + return key.intValue(); + } + + public synchronized static int getOrAddBlockStateId(String blockDataString) { + int dataPart = blockDataString.indexOf("["); + if (dataPart < 0) { + return -1; + } + String materialString = blockDataString.substring(dataPart); + Integer key = blockStateToID.get(materialString); + if (key == null) { + key = nextBlockStateId++; + blockStateToID.put(materialString, key); + int length = idToBlockState.length; + while (length <= key) { + length = (length * 3 / 2) + 5; + } + if (length > idToBlockState.length) { + idToBlockState = Arrays.copyOf(idToBlockState, length); + } + idToBlockState[key] = materialString; + LogBlock.getInstance().getConsumer().queueAddBlockStateMapping(key, materialString); + } + return key.intValue(); + } + + public synchronized static BlockData getBlockData(int materialId, int blockStateId) { + String material = idToMaterial[materialId]; + if (blockStateId >= 0) { + material = material + idToBlockState[blockStateId]; + } + return Bukkit.createBlockData(material); + } + + public static Material getMaterial(int materialId) { + return getBlockData(materialId, -1).getMaterial(); + } + + public static void initializeMaterials(Connection connection) throws SQLException { + Statement smt = connection.createStatement(); + ResultSet rs = smt.executeQuery("SELECT id, name FROM `lb-materials`"); + while (rs.next()) { + int key = rs.getInt(1); + String materialString = rs.getString(2); + + materialToID.put(materialString, key); + int length = idToMaterial.length; + while (length <= key) { + length = (length * 3 / 2) + 5; + } + if (length > idToMaterial.length) { + idToMaterial = Arrays.copyOf(idToMaterial, length); + } + idToMaterial[key] = materialString; + if (nextMaterialId <= key) { + nextMaterialId = key + 1; + } + } + rs.close(); + rs = smt.executeQuery("SELECT id, name FROM `lb-blockstates`"); + while (rs.next()) { + int key = rs.getInt(1); + String materialString = rs.getString(2); + + blockStateToID.put(materialString, key); + int length = idToBlockState.length; + while (length <= key) { + length = (length * 3 / 2) + 5; + } + if (length > idToBlockState.length) { + idToBlockState = Arrays.copyOf(idToBlockState, length); + } + idToBlockState[key] = materialString; + if (nextBlockStateId <= key) { + nextBlockStateId = key + 1; + } + } + rs.close(); + smt.close(); + connection.close(); + } +} diff --git a/src/main/java/de/diddiz/LogBlock/QueryParams.java b/src/main/java/de/diddiz/LogBlock/QueryParams.java index d72ae77..43571ef 100644 --- a/src/main/java/de/diddiz/LogBlock/QueryParams.java +++ b/src/main/java/de/diddiz/LogBlock/QueryParams.java @@ -1,6 +1,5 @@ package de.diddiz.LogBlock; -import de.diddiz.util.Block; import de.diddiz.util.Utils; import de.diddiz.worldedit.RegionContainer; import org.bukkit.Location; @@ -15,9 +14,6 @@ import java.util.*; import static de.diddiz.LogBlock.Session.getSession; import static de.diddiz.LogBlock.config.Config.*; import static de.diddiz.util.BukkitUtils.friendlyWorldname; -import static de.diddiz.util.BukkitUtils.getBlockEquivalents; -import static de.diddiz.util.MaterialName.materialName; -import static de.diddiz.util.MaterialName.typeFromName; import static de.diddiz.util.Utils.*; public final class QueryParams implements Cloneable { @@ -32,7 +28,7 @@ public final class QueryParams implements Cloneable { public boolean excludePlayersMode = false, excludeKillersMode = false, excludeVictimsMode = false, excludeBlocksMode = false, prepareToolQuery = false, silent = false; public RegionContainer sel = null; public SummarizationMode sum = SummarizationMode.NONE; - public List types = new ArrayList(); + public List types = new ArrayList(); public World world = null; public String match = null; public boolean needCount = false, needId = false, needDate = false, needType = false, needData = false, needPlayer = false, needCoords = false, needSignText = false, needChestAccess = false, needMessage = false, needKiller = false, needVictim = false, needWeapon = false; @@ -129,7 +125,7 @@ public final class QueryParams implements Cloneable { select += "COUNT(*) AS count"; } else { if (needId) { - select += "`" + getTable() + "`.id, "; + select += "`" + getTable() + "`-blocks.id, "; } if (needDate) { select += "date, "; @@ -138,7 +134,7 @@ public final class QueryParams implements Cloneable { select += "replaced, type, "; } if (needData) { - select += "data, "; + select += "replacedData, typeData, "; } if (needPlayer) { select += "playername, UUID, "; @@ -150,11 +146,11 @@ public final class QueryParams implements Cloneable { select += "signtext, "; } if (needChestAccess) { - select += "itemtype, itemamount, itemdata, "; + select += "item, itemremove, "; } select = select.substring(0, select.length() - 2); } - String from = "FROM `" + getTable() + "` "; + String from = "FROM `" + getTable() + "-blocks` "; if (needPlayer || players.size() > 0) { from += "INNER JOIN `lb-players` USING (playerid) "; } @@ -165,16 +161,16 @@ public final class QueryParams implements Cloneable { // If BlockChangeType is CHESTACCESS, we can use more efficient query { if (bct == BlockChangeType.CHESTACCESS) { - from += "RIGHT JOIN `" + getTable() + "-chest` USING (id) "; + from += "RIGHT JOIN `" + getTable() + "-chestdata` USING (id) "; } else { - from += "LEFT JOIN `" + getTable() + "-chest` USING (id) "; + from += "LEFT JOIN `" + getTable() + "-chestdata` USING (id) "; } } return select + " " + from + getWhere() + "ORDER BY date " + order + ", id " + order + " " + getLimit(); } else if (sum == SummarizationMode.TYPES) { - return "SELECT type, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT type, count(*) AS created, 0 AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) " + getWhere(BlockChangeType.CREATED) + "GROUP BY type) UNION (SELECT replaced AS type, 0 AS created, count(*) AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) " + getWhere(BlockChangeType.DESTROYED) + "GROUP BY replaced)) AS t GROUP BY type ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit(); + return "SELECT type, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT type, count(*) AS created, 0 AS destroyed FROM `" + getTable() + "-blocks` INNER JOIN `lb-players` USING (playerid) " + getWhere(BlockChangeType.CREATED) + "GROUP BY type) UNION (SELECT replaced AS type, 0 AS created, count(*) AS destroyed FROM `" + getTable() + "-blocks` INNER JOIN `lb-players` USING (playerid) " + getWhere(BlockChangeType.DESTROYED) + "GROUP BY replaced)) AS t GROUP BY type ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit(); } else { - return "SELECT playername, UUID, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT playerid, count(*) AS created, 0 AS destroyed FROM `" + getTable() + "` " + getWhere(BlockChangeType.CREATED) + "GROUP BY playerid) UNION (SELECT playerid, 0 AS created, count(*) AS destroyed FROM `" + getTable() + "` " + getWhere(BlockChangeType.DESTROYED) + "GROUP BY playerid)) AS t INNER JOIN `lb-players` USING (playerid) GROUP BY playerid ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit(); + return "SELECT playername, UUID, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT playerid, count(*) AS created, 0 AS destroyed FROM `" + getTable() + "-blocks` " + getWhere(BlockChangeType.CREATED) + "GROUP BY playerid) UNION (SELECT playerid, 0 AS created, count(*) AS destroyed FROM `" + getTable() + "-blocks` " + getWhere(BlockChangeType.DESTROYED) + "GROUP BY playerid)) AS t INNER JOIN `lb-players` USING (playerid) GROUP BY playerid ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit(); } } @@ -197,7 +193,7 @@ public final class QueryParams implements Cloneable { } final String[] blocknames = new String[types.size()]; for (int i = 0; i < types.size(); i++) { - blocknames[i] = materialName(types.get(i).getBlock()); + blocknames[i] = types.get(i).name(); } title.append(listing(blocknames, ", ", " and ")).append(" "); } else { @@ -363,13 +359,9 @@ public final class QueryParams implements Cloneable { where.append("NOT "); } where.append('('); - for (final Block block : types) { - where.append("((type = ").append(block.getBlock()).append(" OR replaced = ").append(block.getBlock()); - if (block.getData() != -1) { - where.append(") AND data = ").append(block.getData()); - } else { - where.append(")"); - } + for (final Material block : types) { + where.append("((type = ").append(MaterialConverter.getOrAddMaterialId(block.getKey())).append(" OR replaced = ").append(MaterialConverter.getOrAddMaterialId(block.getKey())); + where.append(")"); where.append(") OR "); } where.delete(where.length() - 4, where.length() - 1); @@ -382,13 +374,9 @@ public final class QueryParams implements Cloneable { where.append("NOT "); } where.append('('); - for (final Block block : types) { - where.append("((type = ").append(block.getBlock()).append(" OR replaced = ").append(block.getBlock()); - if (block.getData() != -1) { - where.append(") AND data = ").append(block.getData()); - } else { - where.append(")"); - } + for (final Material block : types) { + where.append("((type = ").append(MaterialConverter.getOrAddMaterialId(block.getKey())).append(" OR replaced = ").append(MaterialConverter.getOrAddMaterialId(block.getKey())); + where.append(")"); where.append(") OR "); } where.delete(where.length() - 4, where.length()); @@ -402,13 +390,9 @@ public final class QueryParams implements Cloneable { where.append("NOT "); } where.append('('); - for (final Block block : types) { - where.append("((type = ").append(block.getBlock()); - if (block.getData() != -1) { - where.append(") AND data = ").append(block.getData()); - } else { - where.append(")"); - } + for (final Material block : types) { + where.append("((type = ").append(MaterialConverter.getOrAddMaterialId(block.getKey())); + where.append(")"); where.append(") OR "); } where.delete(where.length() - 4, where.length()); @@ -422,13 +406,9 @@ public final class QueryParams implements Cloneable { where.append("NOT "); } where.append('('); - for (final Block block : types) { - where.append("((replaced = ").append(block.getBlock()); - if (block.getData() != -1) { - where.append(") AND data = ").append(block.getData()); - } else { - where.append(")"); - } + for (final Material block : types) { + where.append("((replaced = ").append(MaterialConverter.getOrAddMaterialId(block.getKey())); + where.append(")"); where.append(") OR "); } where.delete(where.length() - 4, where.length()); @@ -442,19 +422,17 @@ public final class QueryParams implements Cloneable { where.append("NOT "); } where.append('('); - for (final Block block : types) { - where.append("((itemtype = ").append(block.getBlock()); - if (block.getData() != -1) { - where.append(") AND itemdata = ").append(block.getData()); - } else { - where.append(")"); - } + for (final Material block : types) { + where.append("((itemtype = ").append(MaterialConverter.getOrAddMaterialId(block.getKey())); + where.append(")"); where.append(") OR "); } where.delete(where.length() - 4, where.length()); where.append(") AND "); } break; + default: + break; } if (loc != null) { if (radius == 0) { @@ -625,17 +603,10 @@ public final class QueryParams implements Cloneable { } for (final String weaponName : values) { Material mat = Material.matchMaterial(weaponName); - if (mat == null) { - try { - mat = Material.getMaterial(Integer.parseInt(weaponName)); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Data type not a valid number: '" + weaponName + "'"); - } - } if (mat == null) { throw new IllegalArgumentException("No material matching: '" + weaponName + "'"); } - types.add(new Block(mat.getId(), -1)); + types.add(mat); } needWeapon = true; } else if (param.equals("block") || param.equals("type")) { @@ -647,29 +618,9 @@ public final class QueryParams implements Cloneable { excludeBlocksMode = true; blockName = blockName.substring(1); } - if (blockName.contains(":")) { - String[] blockNameSplit = blockName.split(":"); - if (blockNameSplit.length > 2) { - throw new IllegalArgumentException("No material matching: '" + blockName + "'"); - } - final int data; - try { - data = Integer.parseInt(blockNameSplit[1]); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Data type not a valid number: '" + blockNameSplit[1] + "'"); - } - if (data > 255 || data < 0) { - throw new IllegalArgumentException("Data type out of range (0-255): '" + data + "'"); - } - final Material mat = Material.matchMaterial(blockNameSplit[0]); - if (mat == null) { - throw new IllegalArgumentException("No material matching: '" + blockName + "'"); - } - types.add(new Block(mat.getId(), data)); - } else { - final Material mat = Material.matchMaterial(blockName); - types.add(new Block(typeFromName(blockName), -1)); - } + + final Material mat = Material.matchMaterial(blockName); + types.add(mat); } } else if (param.equals("area")) { if (player == null && !prepareToolQuery && loc == null) { @@ -791,24 +742,6 @@ public final class QueryParams implements Cloneable { throw new IllegalArgumentException("Kill logging not enabled for world '" + world.getName() + "'"); } } - if (types.size() > 0) { - for (final Set equivalent : getBlockEquivalents()) { - boolean found = false; - for (final Block block : types) { - if (equivalent.contains(block.getBlock())) { - found = true; - break; - } - } - if (found) { - for (final Integer type : equivalent) { - if (!Block.inList(types, type)) { - types.add(new Block(type, -1)); - } - } - } - } - } if (!prepareToolQuery && bct != BlockChangeType.CHAT) { if (world == null) { throw new IllegalArgumentException("No world specified"); @@ -842,7 +775,7 @@ public final class QueryParams implements Cloneable { try { final QueryParams params = (QueryParams) super.clone(); params.players = new ArrayList(players); - params.types = new ArrayList(types); + params.types = new ArrayList(types); return params; } catch (final CloneNotSupportedException ex) { } diff --git a/src/main/java/de/diddiz/LogBlock/SummedBlockChanges.java b/src/main/java/de/diddiz/LogBlock/SummedBlockChanges.java index f6dfa0d..919949a 100644 --- a/src/main/java/de/diddiz/LogBlock/SummedBlockChanges.java +++ b/src/main/java/de/diddiz/LogBlock/SummedBlockChanges.java @@ -6,11 +6,10 @@ import org.bukkit.Location; import java.sql.ResultSet; import java.sql.SQLException; -import static de.diddiz.util.MaterialName.materialName; import static de.diddiz.util.Utils.spaces; public class SummedBlockChanges implements LookupCacheElement { - private final String group; + private final int type; private final int created, destroyed; private final float spaceFactor; private final Actor actor; @@ -18,7 +17,7 @@ public class SummedBlockChanges implements LookupCacheElement { public SummedBlockChanges(ResultSet rs, QueryParams p, float spaceFactor) throws SQLException { // Actor currently useless here as we don't yet output UUID in results anywhere actor = p.sum == SummarizationMode.PLAYERS ? new Actor(rs) : null; - group = actor == null ? materialName(rs.getInt("type")) : actor.getName(); + type = p.sum == SummarizationMode.TYPES ? rs.getInt("type") : 0; created = rs.getInt("created"); destroyed = rs.getInt("destroyed"); this.spaceFactor = spaceFactor; @@ -31,6 +30,6 @@ public class SummedBlockChanges implements LookupCacheElement { @Override public String getMessage() { - return created + spaces((int) ((10 - String.valueOf(created).length()) / spaceFactor)) + destroyed + spaces((int) ((10 - String.valueOf(destroyed).length()) / spaceFactor)) + group; + return created + spaces((int) ((10 - String.valueOf(created).length()) / spaceFactor)) + destroyed + spaces((int) ((10 - String.valueOf(destroyed).length()) / spaceFactor)) + (actor != null ? actor.getName() : MaterialConverter.getMaterial(type).toString()); } } diff --git a/src/main/java/de/diddiz/LogBlock/Tool.java b/src/main/java/de/diddiz/LogBlock/Tool.java index e84c982..17055b9 100644 --- a/src/main/java/de/diddiz/LogBlock/Tool.java +++ b/src/main/java/de/diddiz/LogBlock/Tool.java @@ -1,5 +1,6 @@ package de.diddiz.LogBlock; +import org.bukkit.Material; import org.bukkit.permissions.PermissionDefault; import java.util.List; @@ -9,13 +10,13 @@ public class Tool { public final List aliases; public final ToolBehavior leftClickBehavior, rightClickBehavior; public final boolean defaultEnabled; - public final int item; + public final Material item; public final boolean canDrop; public final QueryParams params; public final ToolMode mode; public final PermissionDefault permissionDefault; - public Tool(String name, List aliases, ToolBehavior leftClickBehavior, ToolBehavior rightClickBehavior, boolean defaultEnabled, int item, boolean canDrop, QueryParams params, ToolMode mode, PermissionDefault permissionDefault) { + public Tool(String name, List aliases, ToolBehavior leftClickBehavior, ToolBehavior rightClickBehavior, boolean defaultEnabled, Material item, boolean canDrop, QueryParams params, ToolMode mode, PermissionDefault permissionDefault) { this.name = name; this.aliases = aliases; this.leftClickBehavior = leftClickBehavior; diff --git a/src/main/java/de/diddiz/LogBlock/Updater.java b/src/main/java/de/diddiz/LogBlock/Updater.java index d7dffdf..b0950ff 100644 --- a/src/main/java/de/diddiz/LogBlock/Updater.java +++ b/src/main/java/de/diddiz/LogBlock/Updater.java @@ -312,9 +312,11 @@ class Updater { players.clear(); names.clear(); getLogger().info("Processed " + Integer.toString(done) + " out of " + total); + rs.close(); rs = st.executeQuery("SELECT playerid,playername FROM `lb-players` WHERE LENGTH(UUID)=0 LIMIT " + Integer.toString(UUID_CONVERT_BATCH_SIZE)); } } + rs.close(); st.close(); conn.close(); @@ -443,10 +445,13 @@ class Updater { if (isLogging(Logging.CHAT)) { createTable(dbm, state, "lb-chat", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, message VARCHAR(256) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid), FULLTEXT message (message)) ENGINE=MyISAM DEFAULT CHARSET " + charset); } + createTable(dbm, state, "lb-materials", "(id INT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM DEFAULT CHARSET " + charset); + createTable(dbm, state, "lb-blockstates", "(id INT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM DEFAULT CHARSET " + charset); + for (final WorldConfig wcfg : getLoggedWorlds()) { - createTable(dbm, state, wcfg.table, "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, replaced TINYINT UNSIGNED NOT NULL, type TINYINT UNSIGNED NOT NULL, data TINYINT UNSIGNED NOT NULL, x MEDIUMINT NOT NULL, y SMALLINT UNSIGNED NOT NULL, z MEDIUMINT NOT NULL, PRIMARY KEY (id), KEY coords (x, z, y), KEY date (date), KEY playerid (playerid))"); + createTable(dbm, state, wcfg.table + "-blocks", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, replaced SMALLINT UNSIGNED NOT NULL, replacedData SMALLINT NOT NULL, type SMALLINT UNSIGNED NOT NULL, typeData SMALLINT NOT NULL, x MEDIUMINT NOT NULL, y SMALLINT UNSIGNED NOT NULL, z MEDIUMINT 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)) DEFAULT CHARSET " + charset); - createTable(dbm, state, wcfg.table + "-chest", "(id INT UNSIGNED NOT NULL, itemtype SMALLINT UNSIGNED NOT NULL, itemamount SMALLINT NOT NULL, itemdata SMALLINT NOT NULL, PRIMARY KEY (id))"); + createTable(dbm, state, wcfg.table + "-chestdata", "(id INT UNSIGNED NOT NULL, item MEDIUMBLOB, itemremove TINYINT, PRIMARY KEY (id))"); if (wcfg.isLogging(Logging.KILL)) { createTable(dbm, state, wcfg.table + "-kills", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, killer INT UNSIGNED, victim INT UNSIGNED NOT NULL, weapon SMALLINT UNSIGNED NOT NULL, x MEDIUMINT NOT NULL, y SMALLINT NOT NULL, z MEDIUMINT NOT NULL, PRIMARY KEY (id))"); } diff --git a/src/main/java/de/diddiz/LogBlock/WorldEditor.java b/src/main/java/de/diddiz/LogBlock/WorldEditor.java index 7ddc83d..8f11909 100644 --- a/src/main/java/de/diddiz/LogBlock/WorldEditor.java +++ b/src/main/java/de/diddiz/LogBlock/WorldEditor.java @@ -8,12 +8,15 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Bed; +import org.bukkit.block.data.type.Bed.Part; +import org.bukkit.block.data.type.Piston; +import org.bukkit.block.data.type.PistonHead; +import org.bukkit.block.data.type.TechnicalPiston.Type; import org.bukkit.command.CommandSender; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; -import org.bukkit.material.Bed; -import org.bukkit.material.PistonBaseMaterial; -import org.bukkit.material.PistonExtensionMaterial; import java.io.File; import java.io.PrintWriter; @@ -27,7 +30,6 @@ import java.util.logging.Level; import static de.diddiz.LogBlock.config.Config.dontRollback; import static de.diddiz.LogBlock.config.Config.replaceAnyway; import static de.diddiz.util.BukkitUtils.*; -import static de.diddiz.util.MaterialName.materialName; import static org.bukkit.Bukkit.getLogger; public class WorldEditor implements Runnable { @@ -70,8 +72,8 @@ public class WorldEditor implements Runnable { this.sender = sender; } - public void queueEdit(int x, int y, int z, int replaced, int type, byte data, String signtext, short itemType, short itemAmount, short itemData) { - edits.add(new Edit(0, new Location(world, x, y, z), null, replaced, type, data, signtext, new ChestAccess(itemType, itemAmount, itemData))); + public void queueEdit(int x, int y, int z, int replaced, int replaceData, int type, int typeData, String signtext, ChestAccess item) { + edits.add(new Edit(0, new Location(world, x, y, z), null, replaced, replaceData, type, typeData, signtext, item)); } public long getElapsedTime() { @@ -106,6 +108,8 @@ public class WorldEditor implements Runnable { case BLACKLISTED: blacklistCollisions++; break; + case NO_ACTION: + break; } } catch (final WorldEditorException ex) { errorList.add(ex); @@ -145,48 +149,49 @@ public class WorldEditor implements Runnable { } private class Edit extends BlockChange { - public Edit(long time, Location loc, Actor actor, int replaced, int type, byte data, String signtext, ChestAccess ca) { - super(time, loc, actor, replaced, type, data, signtext, ca); + public Edit(long time, Location loc, Actor actor, int replaced, int replaceData, int type, int typeData, String signtext, ChestAccess ca) { + super(time, loc, actor, replaced, replaceData, type, typeData, signtext, ca); } PerformResult perform() throws WorldEditorException { - if (dontRollback.contains(replaced)) { + BlockData replacedBlock = MaterialConverter.getBlockData(this.replacedMaterial, replacedData); + BlockData setBlock = MaterialConverter.getBlockData(this.typeMaterial, typeData); + // action: set to replaced + + if (dontRollback.contains(replacedBlock.getMaterial())) { return PerformResult.BLACKLISTED; } final Block block = loc.getBlock(); - if (replaced == 0 && block.getTypeId() == 0) { + if (replacedBlock.getMaterial() == Material.AIR && block.getType() == Material.AIR) { return PerformResult.NO_ACTION; } final BlockState state = block.getState(); if (!world.isChunkLoaded(block.getChunk())) { world.loadChunk(block.getChunk()); } - if (type == replaced) { - if (type == 0) { - if (!block.setTypeId(0)) { - throw new WorldEditorException(block.getTypeId(), 0, block.getLocation()); - } + if (setBlock.equals(replacedBlock)) { + if (setBlock.getMaterial() == Material.AIR) { + block.setType(Material.AIR); } else if (ca != null) { - if (getContainerBlocks().contains(Material.getMaterial(type))) { + if (state instanceof InventoryHolder) { int leftover; try { - leftover = modifyContainer(state, new ItemStack(ca.itemType, -ca.itemAmount, ca.itemData)); + leftover = modifyContainer(state, new ItemStack(ca.itemStack), !ca.remove); // Special-case blocks which might be double chests - if (leftover > 0 && (type == 54 || type == 146)) { + if (leftover > 0 && (setBlock.getMaterial() == Material.CHEST || setBlock.getMaterial() == Material.TRAPPED_CHEST)) { for (final BlockFace face : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}) { - if (block.getRelative(face).getTypeId() == type) { - leftover = modifyContainer(block.getRelative(face).getState(), new ItemStack(ca.itemType, ca.itemAmount < 0 ? leftover : -leftover, ca.itemData)); + if (block.getRelative(face).getType() == setBlock.getMaterial()) { + ItemStack remaining = new ItemStack(ca.itemStack); + remaining.setAmount(leftover); + leftover = modifyContainer(block.getRelative(face).getState(), remaining, !ca.remove); } } } } catch (final Exception ex) { throw new WorldEditorException(ex.getMessage(), block.getLocation()); } - if (false /*!state.update()*/) { // Raw inventory doesn't need update, really should be using snapshot inventory however. Do this for backwards compat with < 1.12.1 - throw new WorldEditorException("Failed to update inventory of " + materialName(block.getTypeId()), block.getLocation()); - } - if (leftover > 0 && ca.itemAmount < 0) { - throw new WorldEditorException("Not enough space left in " + materialName(block.getTypeId()), block.getLocation()); + if (leftover > 0 && ca.remove) { + throw new WorldEditorException("Not enough space left in " + block.getType(), block.getLocation()); } } } else { @@ -194,24 +199,18 @@ public class WorldEditor implements Runnable { } return PerformResult.SUCCESS; } - if (!(equalTypes(block.getTypeId(), type) || replaceAnyway.contains(block.getTypeId()))) { + if (block.getType() != setBlock.getMaterial() && !replaceAnyway.contains(block.getType())) { return PerformResult.NO_ACTION; } if (state instanceof InventoryHolder) { ((InventoryHolder) state).getInventory().clear(); state.update(); } - if (block.getTypeId() == replaced) { - if (block.getData() != (type == 0 ? data : (byte) 0)) { - block.setData(type == 0 ? data : (byte) 0, true); - } else { - return PerformResult.NO_ACTION; - } - } else if (!block.setTypeIdAndData(replaced, type == 0 ? data : (byte) 0, true)) { - throw new WorldEditorException(block.getTypeId(), replaced, block.getLocation()); - } - final int curtype = block.getTypeId(); - if (signtext != null && (curtype == 63 || curtype == 68)) { + block.setBlockData(replacedBlock); + BlockData newData = block.getBlockData(); + + final Material curtype = block.getType(); + if (signtext != null && (curtype == Material.SIGN || curtype == Material.WALL_SIGN)) { final Sign sign = (Sign) block.getState(); final String[] lines = signtext.split("\0", 4); if (lines.length < 4) { @@ -221,28 +220,36 @@ public class WorldEditor implements Runnable { sign.setLine(i, lines[i]); } if (!sign.update()) { - throw new WorldEditorException("Failed to update signtext of " + materialName(block.getTypeId()), block.getLocation()); + throw new WorldEditorException("Failed to update signtext of " + block.getType(), block.getLocation()); } - } else if (curtype == 26) { - final Bed bed = (Bed) block.getState().getData(); - final Block secBlock = bed.isHeadOfBed() ? block.getRelative(bed.getFacing().getOppositeFace()) : block.getRelative(bed.getFacing()); - if (secBlock.getTypeId() == 0 && !secBlock.setTypeIdAndData(26, (byte) (bed.getData() | 8), true)) { - throw new WorldEditorException(secBlock.getTypeId(), 26, secBlock.getLocation()); + } else if (newData instanceof Bed) { + final Bed bed = (Bed) newData; + final Block secBlock = bed.getPart() == Part.HEAD ? block.getRelative(bed.getFacing().getOppositeFace()) : block.getRelative(bed.getFacing()); + if (secBlock.isEmpty()) { + Bed bed2 = (Bed) bed.clone(); + bed2.setPart(bed.getPart() == Part.HEAD ? Part.FOOT : Part.HEAD); + secBlock.setBlockData(bed2); } - } else if ((curtype == 29 || curtype == 33) && (block.getData() & 8) > 0) { - final PistonBaseMaterial piston = (PistonBaseMaterial) block.getState().getData(); - final Block secBlock = block.getRelative(piston.getFacing()); - if (secBlock.getTypeId() == 0 && !secBlock.setTypeIdAndData(34, curtype == 29 ? (byte) (block.getData() | 8) : (byte) (block.getData() & ~8), true)) { - throw new WorldEditorException(secBlock.getTypeId(), 34, secBlock.getLocation()); + } else if ((curtype == Material.PISTON || curtype == Material.STICKY_PISTON)) { + Piston piston = (Piston) newData; + if (piston.isExtended()) { + final Block secBlock = block.getRelative(piston.getFacing()); + if (secBlock.isEmpty()) { + PistonHead head = (PistonHead) Material.PISTON_HEAD.createBlockData(); + head.setFacing(piston.getFacing()); + head.setType(curtype == Material.PISTON ? Type.NORMAL : Type.STICKY); + secBlock.setBlockData(head); + } } - } else if (curtype == 34) { - final PistonExtensionMaterial piston = (PistonExtensionMaterial) block.getState().getData(); - final Block secBlock = block.getRelative(piston.getFacing().getOppositeFace()); - if (secBlock.getTypeId() == 0 && !secBlock.setTypeIdAndData(piston.isSticky() ? 29 : 33, (byte) (block.getData() | 8), true)) { - throw new WorldEditorException(secBlock.getTypeId(), piston.isSticky() ? 29 : 33, secBlock.getLocation()); + } else if (curtype == Material.PISTON_HEAD) { + PistonHead head = (PistonHead) newData; + final Block secBlock = block.getRelative(head.getFacing().getOppositeFace()); + if (secBlock.isEmpty()) { + Piston piston = (Piston) (head.getType() == Type.NORMAL ? Material.PISTON : Material.STICKY_PISTON).createBlockData(); + piston.setFacing(head.getFacing()); + piston.setExtended(true); + secBlock.setBlockData(piston); } - } else if (curtype == 18 && (block.getData() & 8) > 0) { - block.setData((byte) (block.getData() & 0xF7)); } return PerformResult.SUCCESS; } @@ -252,8 +259,8 @@ public class WorldEditor implements Runnable { public static class WorldEditorException extends Exception implements LookupCacheElement { private final Location loc; - public WorldEditorException(int typeBefore, int typeAfter, Location loc) { - this("Failed to replace " + materialName(typeBefore) + " with " + materialName(typeAfter), loc); + public WorldEditorException(Material typeBefore, Material typeAfter, Location loc) { + this("Failed to replace " + typeBefore.name() + " with " + typeAfter.name(), loc); } public WorldEditorException(String msg, Location loc) { diff --git a/src/main/java/de/diddiz/LogBlock/config/Config.java b/src/main/java/de/diddiz/LogBlock/config/Config.java index ed6cbae..cc4e4bb 100644 --- a/src/main/java/de/diddiz/LogBlock/config/Config.java +++ b/src/main/java/de/diddiz/LogBlock/config/Config.java @@ -32,15 +32,15 @@ public class Config { public static boolean dumpDeletedLog; public static boolean logCreeperExplosionsAsPlayerWhoTriggeredThese, logPlayerInfo; public static LogKillsLevel logKillsLevel; - public static Set dontRollback, replaceAnyway; + public static Set dontRollback, replaceAnyway; public static int rollbackMaxTime, rollbackMaxArea; public static Map toolsByName; - public static Map toolsByType; + public static Map toolsByType; public static int defaultDist, defaultTime; public static int linesPerPage, linesLimit; public static boolean askRollbacks, askRedos, askClearLogs, askClearLogAfterRollback, askRollbackAfterBan; public static String banPermission; - public static Set hiddenBlocks; + public static Set hiddenBlocks; public static Set hiddenPlayers; public static Set ignoredChat; public static SimpleDateFormat formatter; @@ -161,21 +161,37 @@ public class Config { for (final String playerName : config.getStringList("logging.hiddenPlayers")) { hiddenPlayers.add(playerName.toLowerCase().trim()); } - hiddenBlocks = new HashSet(); - for (final Object blocktype : config.getList("logging.hiddenBlocks")) { - final Material mat = Material.matchMaterial(String.valueOf(blocktype)); + hiddenBlocks = new HashSet(); + for (final String blocktype : config.getStringList("logging.hiddenBlocks")) { + final Material mat = Material.matchMaterial(blocktype); if (mat != null) { - hiddenBlocks.add(mat.getId()); + hiddenBlocks.add(mat); } else { - throw new DataFormatException("Not a valid material: '" + blocktype + "'"); + throw new DataFormatException("Not a valid material in hiddenBlocks: '" + blocktype + "'"); } } ignoredChat = new HashSet(); for (String chatCommand : config.getStringList("logging.ignoredChat")) { ignoredChat.add(chatCommand); } - dontRollback = new HashSet(config.getIntegerList("rollback.dontRollback")); - replaceAnyway = new HashSet(config.getIntegerList("rollback.replaceAnyway")); + dontRollback = new HashSet(); + for (String e : config.getStringList("rollback.dontRollback")) { + Material mat = Material.matchMaterial(e); + if (mat != null) { + dontRollback.add(mat); + } else { + throw new DataFormatException("Not a valid material in dontRollback: '" + e + "'"); + } + } + replaceAnyway = new HashSet(); + for (String e : config.getStringList("rollback.replaceAnyway")) { + Material mat = Material.matchMaterial(e); + if (mat != null) { + replaceAnyway.add(mat); + } else { + throw new DataFormatException("Not a valid material in replaceAnyway: '" + e + "'"); + } + } rollbackMaxTime = parseTimeSpec(config.getString("rollback.maxTime").split(" ")); rollbackMaxArea = config.getInt("rollback.maxArea", 50); defaultDist = config.getInt("lookup.defaultDist", 20); @@ -199,7 +215,7 @@ public class Config { final ToolBehavior leftClickBehavior = ToolBehavior.valueOf(tSec.getString("leftClickBehavior").toUpperCase()); final ToolBehavior rightClickBehavior = ToolBehavior.valueOf(tSec.getString("rightClickBehavior").toUpperCase()); final boolean defaultEnabled = tSec.getBoolean("defaultEnabled", false); - final int item = tSec.getInt("item", 0); + final Material item = Material.matchMaterial(tSec.getString("item","OAK_LOG")); final boolean canDrop = tSec.getBoolean("canDrop", false); final QueryParams params = new QueryParams(logblock); params.prepareToolQuery = true; @@ -212,7 +228,7 @@ public class Config { } } toolsByName = new HashMap(); - toolsByType = new HashMap(); + toolsByType = new HashMap(); for (final Tool tool : tools) { toolsByType.put(tool.item, tool); toolsByName.put(tool.name.toLowerCase(), tool); diff --git a/src/main/java/de/diddiz/LogBlock/events/BlockChangePreLogEvent.java b/src/main/java/de/diddiz/LogBlock/events/BlockChangePreLogEvent.java index 5decd89..ade7807 100644 --- a/src/main/java/de/diddiz/LogBlock/events/BlockChangePreLogEvent.java +++ b/src/main/java/de/diddiz/LogBlock/events/BlockChangePreLogEvent.java @@ -3,26 +3,27 @@ package de.diddiz.LogBlock.events; import de.diddiz.LogBlock.Actor; import de.diddiz.LogBlock.ChestAccess; import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.data.BlockData; import org.bukkit.event.HandlerList; public class BlockChangePreLogEvent extends PreLogEvent { private static final HandlerList handlers = new HandlerList(); private Location location; - private int typeBefore, typeAfter; - private byte data; + private BlockData typeBefore, typeAfter; private String signText; private ChestAccess chestAccess; - public BlockChangePreLogEvent(Actor owner, Location location, int typeBefore, int typeAfter, byte data, + public BlockChangePreLogEvent(Actor owner, Location location, BlockData typeBefore, BlockData typeAfter, String signText, ChestAccess chestAccess) { super(owner); this.location = location; this.typeBefore = typeBefore; this.typeAfter = typeAfter; - this.data = data; this.signText = signText; this.chestAccess = chestAccess; } @@ -37,36 +38,30 @@ public class BlockChangePreLogEvent extends PreLogEvent { this.location = location; } - public int getTypeBefore() { + public BlockData getTypeBefore() { return typeBefore; } - public void setTypeBefore(int typeBefore) { - + public void setTypeBefore(BlockData typeBefore) { + if (typeBefore == null) { + typeBefore = Bukkit.createBlockData(Material.AIR); + } this.typeBefore = typeBefore; } - public int getTypeAfter() { + public BlockData getTypeAfter() { return typeAfter; } - public void setTypeAfter(int typeAfter) { - + public void setTypeAfter(BlockData typeAfter) { + if (typeAfter == null) { + typeAfter = Bukkit.createBlockData(Material.AIR); + } this.typeAfter = typeAfter; } - public byte getData() { - - return data; - } - - public void setData(byte data) { - - this.data = data; - } - public String getSignText() { return signText; @@ -90,13 +85,13 @@ public class BlockChangePreLogEvent extends PreLogEvent { private boolean isValidSign() { - if ((typeAfter == 63 || typeAfter == 68) && typeBefore == 0) { + if ((typeAfter.getMaterial() == Material.SIGN || typeAfter.getMaterial() == Material.WALL_SIGN) && typeBefore.getMaterial() == Material.AIR) { return true; } - if ((typeBefore == 63 || typeBefore == 68) && typeAfter == 0) { + if ((typeBefore.getMaterial() == Material.SIGN || typeBefore.getMaterial() == Material.WALL_SIGN) && typeAfter.getMaterial() == Material.AIR) { return true; } - if ((typeAfter == 63 || typeAfter == 68) && typeBefore == typeAfter) { + if ((typeAfter.getMaterial() == Material.SIGN || typeAfter.getMaterial() == Material.WALL_SIGN) && typeBefore.equals(typeAfter)) { return true; } return false; diff --git a/src/main/java/de/diddiz/LogBlock/listeners/BanListener.java b/src/main/java/de/diddiz/LogBlock/listeners/BanListener.java index f7c2969..9f50afb 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/BanListener.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/BanListener.java @@ -29,7 +29,7 @@ public class BanListener implements Listener { p.setPlayer(split[1].equalsIgnoreCase("g") ? split[2] : split[1]); p.since = 0; p.silent = false; - getScheduler().scheduleAsyncDelayedTask(logblock, new Runnable() { + getScheduler().runTaskAsynchronously(logblock, new Runnable() { @Override public void run() { for (final World world : logblock.getServer().getWorlds()) { diff --git a/src/main/java/de/diddiz/LogBlock/listeners/BlockBreakLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/BlockBreakLogging.java index b27db53..e89d0a6 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/BlockBreakLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/BlockBreakLogging.java @@ -5,6 +5,8 @@ import de.diddiz.LogBlock.LogBlock; import de.diddiz.LogBlock.Logging; import de.diddiz.LogBlock.config.WorldConfig; import de.diddiz.util.BukkitUtils; + +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.block.Block; @@ -34,10 +36,9 @@ public class BlockBreakLogging extends LoggingListener { final Actor actor = Actor.actorFromEntity(event.getPlayer()); final Block origin = event.getBlock(); - final int typeId = origin.getTypeId(); final Material type = origin.getType(); - if (wcfg.isLogging(Logging.SIGNTEXT) && (typeId == 63 || typeId == 68)) { + if (wcfg.isLogging(Logging.SIGNTEXT) && (type == Material.SIGN || type == Material.WALL_SIGN)) { consumer.queueSignBreak(actor, (Sign) origin.getState()); } else if (wcfg.isLogging(Logging.CHESTACCESS) && BukkitUtils.getContainerBlocks().contains(type)) { consumer.queueContainerBreak(actor, origin.getState()); @@ -46,7 +47,7 @@ public class BlockBreakLogging extends LoggingListener { if (event.getPlayer().getGameMode().equals(GameMode.CREATIVE)) { consumer.queueBlockBreak(actor, origin.getState()); } else { - consumer.queueBlockReplace(actor, origin.getState(), 9, (byte) 0); + consumer.queueBlockReplace(actor, origin.getState(), Bukkit.createBlockData(Material.WATER)); } } else { smartLogBlockBreak(consumer, actor, origin); diff --git a/src/main/java/de/diddiz/LogBlock/listeners/BlockPlaceLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/BlockPlaceLogging.java index c532537..1324319 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/BlockPlaceLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/BlockPlaceLogging.java @@ -5,6 +5,8 @@ import de.diddiz.LogBlock.LogBlock; import de.diddiz.LogBlock.Logging; import de.diddiz.LogBlock.config.WorldConfig; import de.diddiz.util.BukkitUtils; + +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.BlockFace; @@ -32,7 +34,7 @@ public class BlockPlaceLogging extends LoggingListener { final Actor actor = Actor.actorFromEntity(event.getPlayer()); //Handle falling blocks - if (BukkitUtils.getRelativeTopFallables().contains(type)) { + if (type.hasGravity()) { // Catch placed blocks overwriting something if (before.getType() != Material.AIR) { @@ -55,9 +57,9 @@ public class BlockPlaceLogging extends LoggingListener { // Run this check to avoid false positives if (!BukkitUtils.getFallingEntityKillers().contains(finalLoc.getBlock().getType())) { if (finalLoc.getBlock().getType() == Material.AIR || finalLoc.equals(event.getBlock().getLocation())) { - consumer.queueBlockPlace(actor, finalLoc, type.getId(), event.getBlock().getData()); + consumer.queueBlockPlace(actor, finalLoc, event.getBlock().getBlockData()); } else { - consumer.queueBlockReplace(actor, finalLoc, finalLoc.getBlock().getTypeId(), finalLoc.getBlock().getData(), type.getId(), event.getBlock().getData()); + consumer.queueBlockReplace(actor, finalLoc, finalLoc.getBlock().getBlockData(), event.getBlock().getBlockData()); } } } @@ -65,7 +67,7 @@ public class BlockPlaceLogging extends LoggingListener { } //Sign logging is handled elsewhere - if (wcfg.isLogging(Logging.SIGNTEXT) && (type.getId() == 63 || type.getId() == 68)) { + if (wcfg.isLogging(Logging.SIGNTEXT) && (type == Material.SIGN || type == Material.WALL_SIGN)) { return; } @@ -73,7 +75,7 @@ public class BlockPlaceLogging extends LoggingListener { LogBlock.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(LogBlock.getInstance(), new Runnable() { @Override public void run() { - if (before.getTypeId() == 0) { + if (before.getType() == Material.AIR) { consumer.queueBlockPlace(actor, after); } else { consumer.queueBlockReplace(actor, before, after); @@ -86,7 +88,7 @@ public class BlockPlaceLogging extends LoggingListener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) { if (isLogging(event.getPlayer().getWorld(), Logging.BLOCKPLACE)) { - consumer.queueBlockPlace(Actor.actorFromEntity(event.getPlayer()), event.getBlockClicked().getRelative(event.getBlockFace()).getLocation(), event.getBucket() == Material.WATER_BUCKET ? 9 : 11, (byte) 0); + consumer.queueBlockPlace(Actor.actorFromEntity(event.getPlayer()), event.getBlockClicked().getRelative(event.getBlockFace()).getLocation(), Bukkit.createBlockData(event.getBucket() == Material.WATER_BUCKET ? Material.WATER : Material.LAVA)); } } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/BlockSpreadLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/BlockSpreadLogging.java index ca3d923..0293718 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/BlockSpreadLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/BlockSpreadLogging.java @@ -32,7 +32,7 @@ public class BlockSpreadLogging extends LoggingListener { } name = "GrassGrowth"; break; - case MYCEL: + case MYCELIUM: if (!isLogging(world, Logging.MYCELIUMSPREAD)) { return; } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/ChestAccessLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/ChestAccessLogging.java index 3ada3b9..50527ad 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/ChestAccessLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/ChestAccessLogging.java @@ -4,6 +4,7 @@ import de.diddiz.LogBlock.Actor; import de.diddiz.LogBlock.LogBlock; import de.diddiz.LogBlock.Logging; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.BlockState; import org.bukkit.block.DoubleChest; import org.bukkit.entity.HumanEntity; @@ -42,7 +43,9 @@ public class ChestAccessLogging extends LoggingListener { final ItemStack[] diff = compareInventories(before, after); final Location loc = getInventoryHolderLocation(holder); for (final ItemStack item : diff) { - consumer.queueChestAccess(Actor.actorFromEntity(player), loc, loc.getWorld().getBlockTypeIdAt(loc), (short) item.getTypeId(), (short) item.getAmount(), rawData(item)); + ItemStack item2 = item.clone(); + item2.setAmount(Math.abs(item.getAmount())); + consumer.queueChestAccess(Actor.actorFromEntity(player), loc, loc.getWorld().getBlockAt(loc).getBlockData(), item2, item.getAmount() < 0); } containers.remove(player); } @@ -58,7 +61,7 @@ public class ChestAccessLogging extends LoggingListener { if (event.getInventory() != null) { InventoryHolder holder = event.getInventory().getHolder(); if (holder instanceof BlockState || holder instanceof DoubleChest) { - if (getInventoryHolderType(holder) != 58) { + if (getInventoryHolderType(holder) != Material.CRAFTING_TABLE) { containers.put(event.getPlayer(), compressInventory(event.getInventory().getContents())); } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/CreatureInteractLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/CreatureInteractLogging.java index ea0cab0..b4bfc60 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/CreatureInteractLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/CreatureInteractLogging.java @@ -36,22 +36,18 @@ public class CreatureInteractLogging extends LoggingListener { if (wcfg != null) { final Block clicked = event.getBlock(); final Material type = clicked.getType(); - final int typeId = type.getId(); - final byte blockData = clicked.getData(); final Location loc = clicked.getLocation(); - switch (type) { - case SOIL: - if (wcfg.isLogging(Logging.CREATURECROPTRAMPLE)) { - // 3 = Dirt ID - consumer.queueBlock(Actor.actorFromEntity(entityType), loc, typeId, 3, blockData); - // Log the crop on top as being broken - Block trampledCrop = clicked.getRelative(BlockFace.UP); - if (BukkitUtils.getCropBlocks().contains(trampledCrop.getType())) { - consumer.queueBlockBreak(new Actor("CreatureTrample"), trampledCrop.getState()); - } + if (type == Material.FARMLAND) { + if (wcfg.isLogging(Logging.CREATURECROPTRAMPLE)) { + // 3 = Dirt ID + consumer.queueBlock(Actor.actorFromEntity(entityType), loc, type.createBlockData(), Material.DIRT.createBlockData()); + // Log the crop on top as being broken + Block trampledCrop = clicked.getRelative(BlockFace.UP); + if (BukkitUtils.getCropBlocks().contains(trampledCrop.getType())) { + consumer.queueBlockBreak(new Actor("CreatureTrample"), trampledCrop.getState()); } - break; + } } } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/EndermenLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/EndermenLogging.java index 9fc14ba..5b89ad4 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/EndermenLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/EndermenLogging.java @@ -18,7 +18,7 @@ public class EndermenLogging extends LoggingListener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEntityChangeBlock(EntityChangeBlockEvent event) { if (event.getEntity() instanceof Enderman && isLogging(event.getBlock().getWorld(), Logging.ENDERMEN)) { - consumer.queueBlockReplace(new Actor("Enderman"), event.getBlock().getState(), event.getTo().getId(), (byte) 0); // Figure out how to get the data of the placed block; + consumer.queueBlockReplace(new Actor("Enderman"), event.getBlock().getState(), event.getBlockData()); // Figure out how to get the data of the placed block; } } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/ExplosionLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/ExplosionLogging.java index e53b556..a9d7d31 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/ExplosionLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/ExplosionLogging.java @@ -99,10 +99,10 @@ public class ExplosionLogging extends LoggingListener { } } for (final Block block : event.blockList()) { - final int type = block.getTypeId(); - if (wcfg.isLogging(Logging.SIGNTEXT) & (type == 63 || type == 68)) { + final Material type = block.getType(); + if (wcfg.isLogging(Logging.SIGNTEXT) & (type == Material.SIGN || type == Material.WALL_SIGN)) { consumer.queueSignBreak(actor, (Sign) block.getState()); - } else if (wcfg.isLogging(Logging.CHESTACCESS) && (getContainerBlocks().contains(Material.getMaterial(type)))) { + } else if (wcfg.isLogging(Logging.CHESTACCESS) && (getContainerBlocks().contains(type))) { consumer.queueContainerBreak(actor, block.getState()); } else { consumer.queueBlockBreak(actor, block.getState()); @@ -122,10 +122,10 @@ public class ExplosionLogging extends LoggingListener { } Actor actor = new Actor("Explosion"); - final int type = block.getTypeId(); - if (wcfg.isLogging(Logging.SIGNTEXT) & (type == 63 || type == 68)) { + final Material type = block.getType(); + if (wcfg.isLogging(Logging.SIGNTEXT) & (type == Material.SIGN || type == Material.WALL_SIGN)) { consumer.queueSignBreak(actor, (Sign) block.getState()); - } else if (wcfg.isLogging(Logging.CHESTACCESS) && (getContainerBlocks().contains(Material.getMaterial(type)))) { + } else if (wcfg.isLogging(Logging.CHESTACCESS) && (getContainerBlocks().contains(type))) { consumer.queueContainerBreak(actor, block.getState()); } else { consumer.queueBlockBreak(actor, block.getState()); diff --git a/src/main/java/de/diddiz/LogBlock/listeners/FluidFlowLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/FluidFlowLogging.java index ec1efc5..750b73d 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/FluidFlowLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/FluidFlowLogging.java @@ -4,20 +4,20 @@ import de.diddiz.LogBlock.Actor; import de.diddiz.LogBlock.LogBlock; import de.diddiz.LogBlock.Logging; import de.diddiz.LogBlock.config.WorldConfig; +import de.diddiz.util.BukkitUtils; + +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Levelled; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockFromToEvent; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - import static de.diddiz.LogBlock.config.Config.getWorldConfig; public class FluidFlowLogging extends LoggingListener { - private static final Set nonFluidProofBlocks = new HashSet(Arrays.asList(27, 28, 31, 32, 37, 38, 39, 40, 50, 51, 55, 59, 66, 69, 70, 75, 76, 78, 93, 94, 104, 105, 106)); public FluidFlowLogging(LogBlock lb) { super(lb); @@ -27,43 +27,59 @@ public class FluidFlowLogging extends LoggingListener { public void onBlockFromTo(BlockFromToEvent event) { final WorldConfig wcfg = getWorldConfig(event.getBlock().getWorld()); if (wcfg != null) { + final BlockData blockDataFrom = event.getBlock().getBlockData(); + final Material typeFrom = blockDataFrom.getMaterial(); + final Block to = event.getToBlock(); - final int typeFrom = event.getBlock().getTypeId(); - final int typeTo = to.getTypeId(); - final boolean canFlow = typeTo == 0 || nonFluidProofBlocks.contains(typeTo); - if (typeFrom == 10 || typeFrom == 11) { + final Material typeTo = to.getType(); + final boolean canFlow = typeTo == Material.AIR || BukkitUtils.getNonFluidProofBlocks().contains(typeTo); + if (typeFrom == Material.LAVA) { + Levelled levelledFrom = (Levelled)blockDataFrom; if (canFlow && wcfg.isLogging(Logging.LAVAFLOW)) { - if (isSurroundedByWater(to) && event.getBlock().getData() <= 2) { - consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 4, (byte) 0); - } else if (typeTo == 0) { - consumer.queueBlockPlace(new Actor("LavaFlow"), to.getLocation(), 10, (byte) (event.getBlock().getData() + 1)); + if (isSurroundedByWater(to) && levelledFrom.getLevel() <= 2) { + consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), Material.COBBLESTONE.createBlockData()); } else { - consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 10, (byte) (event.getBlock().getData() + 1)); + Levelled newBlock = (Levelled) blockDataFrom.clone(); + newBlock.setLevel(levelledFrom.getLevel() + 1); + if (typeTo == Material.AIR) { + consumer.queueBlockPlace(new Actor("LavaFlow"), to.getLocation(), newBlock); + } else { + consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), newBlock); + } } - } else if (typeTo == 8 || typeTo == 9) { + } else if (typeTo == Material.WATER) { if (event.getFace() == BlockFace.DOWN) { - consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 1, (byte) 0); + consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), Material.STONE.createBlockData()); } else { - consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 4, (byte) 0); + consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), Material.COBBLESTONE.createBlockData()); } } - } else if ((typeFrom == 8 || typeFrom == 9) && wcfg.isLogging(Logging.WATERFLOW)) { - if (typeTo == 0) { - consumer.queueBlockPlace(new Actor("WaterFlow"), to.getLocation(), 8, (byte) (event.getBlock().getData() + 1)); - } else if (nonFluidProofBlocks.contains(typeTo)) { - consumer.queueBlockReplace(new Actor("WaterFlow"), to.getState(), 8, (byte) (event.getBlock().getData() + 1)); - } else if (typeTo == 10 || typeTo == 11) { - if (to.getData() == 0) { - consumer.queueBlockReplace(new Actor("WaterFlow"), to.getState(), 49, (byte) 0); + } else if ((typeFrom == Material.WATER) && wcfg.isLogging(Logging.WATERFLOW)) { + Levelled levelledFrom = (Levelled)blockDataFrom; + Levelled newBlock = (Levelled) blockDataFrom.clone(); + newBlock.setLevel(levelledFrom.getLevel() + 1); + if (typeTo == Material.AIR) { + consumer.queueBlockPlace(new Actor("WaterFlow"), to.getLocation(), newBlock); + } else if (BukkitUtils.getNonFluidProofBlocks().contains(typeTo)) { + consumer.queueBlockReplace(new Actor("WaterFlow"), to.getState(), newBlock); + } else if (typeTo == Material.LAVA) { + int toLevel = ((Levelled)to.getBlockData()).getLevel(); + if (toLevel == 0) { + consumer.queueBlockReplace(new Actor("WaterFlow"), to.getState(), Material.OBSIDIAN.createBlockData()); } else if (event.getFace() == BlockFace.DOWN) { - consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 1, (byte) 0); + consumer.queueBlockReplace(new Actor("WaterFlow"), to.getState(), Material.STONE.createBlockData()); } } - if (typeTo == 0 || nonFluidProofBlocks.contains(typeTo)) { + if (typeTo == Material.AIR || BukkitUtils.getNonFluidProofBlocks().contains(typeTo)) { for (final BlockFace face : new BlockFace[]{BlockFace.DOWN, BlockFace.NORTH, BlockFace.WEST, BlockFace.EAST, BlockFace.SOUTH}) { final Block lower = to.getRelative(face); - if (lower.getTypeId() == 10 || lower.getTypeId() == 11) { - consumer.queueBlockReplace(new Actor("WaterFlow"), lower.getState(), lower.getData() == 0 ? 49 : 4, (byte) 0); + if (lower.getType() == Material.LAVA) { + int toLevel = ((Levelled)lower.getBlockData()).getLevel(); + if (toLevel == 0) { + consumer.queueBlockReplace(new Actor("WaterFlow"), lower.getState(), Material.OBSIDIAN.createBlockData()); + } else if (event.getFace() == BlockFace.DOWN) { + consumer.queueBlockReplace(new Actor("WaterFlow"), lower.getState(), Material.STONE.createBlockData()); + } } } } @@ -73,8 +89,7 @@ public class FluidFlowLogging extends LoggingListener { private static boolean isSurroundedByWater(Block block) { for (final BlockFace face : new BlockFace[]{BlockFace.NORTH, BlockFace.WEST, BlockFace.EAST, BlockFace.SOUTH}) { - final int type = block.getRelative(face).getTypeId(); - if (type == 8 || type == 9) { + if(block.getRelative(face).getType() == Material.WATER) { return true; } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/InteractLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/InteractLogging.java index dd3e350..8bfc211 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/InteractLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/InteractLogging.java @@ -7,8 +7,10 @@ import de.diddiz.LogBlock.config.WorldConfig; import de.diddiz.util.BukkitUtils; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -30,66 +32,70 @@ public class InteractLogging extends LoggingListener { if (clicked == null) { return; } - final Material type = clicked.getType(); - final int typeId = type.getId(); - final byte blockData = clicked.getData(); + final BlockData blockData = clicked.getBlockData(); + final Material type = blockData.getMaterial(); final Player player = event.getPlayer(); final Location loc = clicked.getLocation(); switch (type) { - case LEVER: - case WOOD_BUTTON: - case STONE_BUTTON: - if (wcfg.isLogging(Logging.SWITCHINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK) { - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData); - } - break; - case FENCE_GATE: - case WOODEN_DOOR: - case TRAP_DOOR: + case OAK_FENCE_GATE: + case SPRUCE_FENCE_GATE: + case BIRCH_FENCE_GATE: + case JUNGLE_FENCE_GATE: + case ACACIA_FENCE_GATE: + case DARK_OAK_FENCE_GATE: + case OAK_TRAPDOOR: + case SPRUCE_TRAPDOOR: + case BIRCH_TRAPDOOR: + case JUNGLE_TRAPDOOR: + case ACACIA_TRAPDOOR: + case DARK_OAK_TRAPDOOR: if (wcfg.isLogging(Logging.DOORINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK) { - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData); + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); } break; - case CAKE_BLOCK: + case CAKE: if (wcfg.isLogging(Logging.CAKEEAT) && event.getAction() == Action.RIGHT_CLICK_BLOCK && player.getFoodLevel() < 20) { - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData); + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); } break; case NOTE_BLOCK: if (wcfg.isLogging(Logging.NOTEBLOCKINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK) { - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData); + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); } break; - case DIODE_BLOCK_OFF: - case DIODE_BLOCK_ON: + case REPEATER: if (wcfg.isLogging(Logging.DIODEINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK) { - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData); + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); } break; - case REDSTONE_COMPARATOR_OFF: - case REDSTONE_COMPARATOR_ON: + case COMPARATOR: if (wcfg.isLogging(Logging.COMPARATORINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK) { - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData); + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); } break; - case WOOD_PLATE: - case STONE_PLATE: - case IRON_PLATE: - case GOLD_PLATE: + case OAK_PRESSURE_PLATE: + case SPRUCE_PRESSURE_PLATE: + case BIRCH_PRESSURE_PLATE: + case JUNGLE_PRESSURE_PLATE: + case ACACIA_PRESSURE_PLATE: + case DARK_OAK_PRESSURE_PLATE: + case STONE_PRESSURE_PLATE: + case HEAVY_WEIGHTED_PRESSURE_PLATE: + case LIGHT_WEIGHTED_PRESSURE_PLATE: if (wcfg.isLogging(Logging.PRESUREPLATEINTERACT) && event.getAction() == Action.PHYSICAL) { - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData); + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); } break; case TRIPWIRE: if (wcfg.isLogging(Logging.TRIPWIREINTERACT) && event.getAction() == Action.PHYSICAL) { - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData); + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); } break; - case SOIL: + case FARMLAND: if (wcfg.isLogging(Logging.CROPTRAMPLE) && event.getAction() == Action.PHYSICAL) { // 3 = Dirt ID - consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, 3, blockData); + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, Material.DIRT.createBlockData()); // Log the crop on top as being broken Block trampledCrop = clicked.getRelative(BlockFace.UP); if (BukkitUtils.getCropBlocks().contains(trampledCrop.getType())) { @@ -97,6 +103,17 @@ public class InteractLogging extends LoggingListener { } } break; + default: + if (Tag.BUTTONS.isTagged(type) || type == Material.LEVER) { + if (wcfg.isLogging(Logging.SWITCHINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK) { + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); + } + } + if (Tag.WOODEN_DOORS.isTagged(type)) { + if (wcfg.isLogging(Logging.DOORINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK) { + consumer.queueBlock(Actor.actorFromEntity(player), loc, blockData, blockData); + } + } } } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/LockedChestDecayLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/LockedChestDecayLogging.java deleted file mode 100644 index 159d12b..0000000 --- a/src/main/java/de/diddiz/LogBlock/listeners/LockedChestDecayLogging.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.diddiz.LogBlock.listeners; - -import de.diddiz.LogBlock.Actor; -import de.diddiz.LogBlock.LogBlock; -import de.diddiz.LogBlock.Logging; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.block.BlockFadeEvent; - -import static de.diddiz.LogBlock.config.Config.isLogging; - -public class LockedChestDecayLogging extends LoggingListener { - public LockedChestDecayLogging(LogBlock lb) { - super(lb); - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onBlockFade(BlockFadeEvent event) { - if (isLogging(event.getBlock().getWorld(), Logging.LOCKEDCHESTDECAY)) { - final int type = event.getBlock().getTypeId(); - if (type == 95) { - consumer.queueBlockReplace(new Actor("LockedChestDecay"), event.getBlock().getState(), event.getNewState()); - } - } - } -} diff --git a/src/main/java/de/diddiz/LogBlock/listeners/SignChangeLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/SignChangeLogging.java index 4d808dd..593dbcf 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/SignChangeLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/SignChangeLogging.java @@ -17,7 +17,7 @@ public class SignChangeLogging extends LoggingListener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onSignChange(SignChangeEvent event) { if (isLogging(event.getBlock().getWorld(), Logging.SIGNTEXT)) { - consumer.queueSignPlace(Actor.actorFromEntity(event.getPlayer()), event.getBlock().getLocation(), event.getBlock().getTypeId(), event.getBlock().getData(), event.getLines()); + consumer.queueSignPlace(Actor.actorFromEntity(event.getPlayer()), event.getBlock().getLocation(), event.getBlock().getBlockData(), event.getLines()); } } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/SnowFadeLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/SnowFadeLogging.java index 8acc3eb..1223893 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/SnowFadeLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/SnowFadeLogging.java @@ -3,6 +3,8 @@ package de.diddiz.LogBlock.listeners; import de.diddiz.LogBlock.Actor; import de.diddiz.LogBlock.LogBlock; import de.diddiz.LogBlock.Logging; + +import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockFadeEvent; @@ -17,8 +19,8 @@ public class SnowFadeLogging extends LoggingListener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockFade(BlockFadeEvent event) { if (isLogging(event.getBlock().getWorld(), Logging.SNOWFADE)) { - final int type = event.getBlock().getTypeId(); - if (type == 78 || type == 79) { + final Material type = event.getBlock().getType(); + if (type == Material.SNOW || type == Material.ICE) { consumer.queueBlockReplace(new Actor("SnowFade"), event.getBlock().getState(), event.getNewState()); } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/SnowFormLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/SnowFormLogging.java index d3c4146..d9abcef 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/SnowFormLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/SnowFormLogging.java @@ -3,6 +3,8 @@ package de.diddiz.LogBlock.listeners; import de.diddiz.LogBlock.Actor; import de.diddiz.LogBlock.LogBlock; import de.diddiz.LogBlock.Logging; + +import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.block.BlockFormEvent; @@ -23,8 +25,8 @@ public class SnowFormLogging extends LoggingListener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockForm(BlockFormEvent event) { if (isLogging(event.getBlock().getWorld(), Logging.SNOWFORM)) { - final int type = event.getNewState().getTypeId(); - if (type == 78 || type == 79) { + final Material type = event.getNewState().getType(); + if (type == Material.SNOW || type == Material.ICE) { consumer.queueBlockReplace(new Actor("SnowForm"), event.getBlock().getState(), event.getNewState()); } } diff --git a/src/main/java/de/diddiz/LogBlock/listeners/ToolListener.java b/src/main/java/de/diddiz/LogBlock/listeners/ToolListener.java index 06dcab8..af4073f 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/ToolListener.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/ToolListener.java @@ -3,6 +3,7 @@ package de.diddiz.LogBlock.listeners; import de.diddiz.LogBlock.*; import de.diddiz.worldedit.RegionContainer; import org.bukkit.ChatColor; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; @@ -34,7 +35,7 @@ public class ToolListener implements Listener { public void onPlayerInteract(PlayerInteractEvent event) { if (event.getMaterial() != null) { final Action action = event.getAction(); - final int type = event.getMaterial().getId(); + final Material type = event.getMaterial(); final Tool tool = toolsByType.get(type); final Player player = event.getPlayer(); if (tool != null && (action == Action.RIGHT_CLICK_BLOCK || action == Action.LEFT_CLICK_BLOCK) && logblock.hasPermission(player, "logblock.tools." + tool.name)) { @@ -52,12 +53,12 @@ public class ToolListener implements Listener { params.sel = null; if (behavior == ToolBehavior.BLOCK) { params.setLocation(block.getRelative(event.getBlockFace()).getLocation()); - } else if ((block.getTypeId() != 54 && block.getTypeId() != 146) || tool.params.radius != 0) { + } else if ((block.getType() != Material.CHEST && block.getType() != Material.TRAPPED_CHEST) || tool.params.radius != 0) { params.setLocation(block.getLocation()); } else { if (logblock.getServer().getPluginManager().isPluginEnabled("WorldEdit")) { for (final BlockFace face : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}) { - if (block.getRelative(face).getTypeId() == block.getTypeId()) { + if (block.getRelative(face).getType() == block.getType()) { params.setSelection(RegionContainer.fromCorners(event.getPlayer().getWorld(), block.getLocation(), block.getRelative(face).getLocation())); } @@ -113,7 +114,7 @@ public class ToolListener implements Listener { for (final Entry entry : session.toolData.entrySet()) { final Tool tool = entry.getKey(); final ToolData toolData = entry.getValue(); - final int item = event.getItemDrop().getItemStack().getTypeId(); + final Material item = event.getItemDrop().getItemStack().getType(); if (item == tool.item && toolData.enabled && !tool.canDrop) { player.sendMessage(ChatColor.RED + "You cannot drop this tool."); event.setCancelled(true); diff --git a/src/main/java/de/diddiz/LogBlock/listeners/WitherLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/WitherLogging.java index fa74c93..3f8c9a8 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/WitherLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/WitherLogging.java @@ -18,7 +18,7 @@ public class WitherLogging extends LoggingListener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEntityChangeBlock(EntityChangeBlockEvent event) { if (event.getEntity() instanceof Wither && isLogging(event.getBlock().getWorld(), Logging.WITHER)) { - consumer.queueBlockReplace(Actor.actorFromEntity(event.getEntity()), event.getBlock().getState(), event.getTo().getId(), event.getData()); // Wither walked through a block. + consumer.queueBlockReplace(Actor.actorFromEntity(event.getEntity()), event.getBlock().getState(), event.getBlockData()); // Wither walked through a block. } } } diff --git a/src/main/java/de/diddiz/util/Block.java b/src/main/java/de/diddiz/util/Block.java deleted file mode 100644 index e59fce7..0000000 --- a/src/main/java/de/diddiz/util/Block.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.diddiz.util; - -import java.util.List; - -public class Block { - private int block; - private int data; - - /** - * @param block The id of the block - * @param data The data for the block, -1 for any data - */ - public Block(int block, int data) { - this.block = block; - this.data = data; - } - - public int getBlock() { - return this.block; - } - - public int getData() { - return this.data; - } - - public static boolean inList(List types, int blockID) { - for (Block block : types) { - if (block.getBlock() == blockID) { - return true; - } - } - return false; - } -} diff --git a/src/main/java/de/diddiz/util/BukkitUtils.java b/src/main/java/de/diddiz/util/BukkitUtils.java index 4fedab3..6a43c9a 100644 --- a/src/main/java/de/diddiz/util/BukkitUtils.java +++ b/src/main/java/de/diddiz/util/BukkitUtils.java @@ -4,6 +4,10 @@ import org.bukkit.*; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.DoubleChest; +import org.bukkit.block.data.Bisected; +import org.bukkit.block.data.Bisected.Half; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Stairs; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; @@ -15,21 +19,49 @@ import org.bukkit.inventory.ItemStack; import java.io.File; import java.util.*; -import static de.diddiz.util.MaterialName.materialName; - public class BukkitUtils { private static final Set> blockEquivalents; private static final Set relativeBreakable; private static final Set relativeTopBreakable; - private static final Set relativeTopFallables; private static final Set fallingEntityKillers; private static final Set cropBlocks; private static final Set containerBlocks; - - private static final Map projectileItems; + + private static final Set singleBlockPlants; + private static final Set doublePlants; + + private static final Set nonFluidProofBlocks; + + private static final Map projectileItems; static { + singleBlockPlants = EnumSet.noneOf(Material.class); + singleBlockPlants.add(Material.GRASS); + singleBlockPlants.add(Material.FERN); + singleBlockPlants.add(Material.DEAD_BUSH); + singleBlockPlants.add(Material.DANDELION); + singleBlockPlants.add(Material.POPPY); + singleBlockPlants.add(Material.BLUE_ORCHID); + singleBlockPlants.add(Material.ALLIUM); + singleBlockPlants.add(Material.AZURE_BLUET); + singleBlockPlants.add(Material.ORANGE_TULIP); + singleBlockPlants.add(Material.WHITE_TULIP); + singleBlockPlants.add(Material.PINK_TULIP); + singleBlockPlants.add(Material.RED_TULIP); + singleBlockPlants.add(Material.OXEYE_DAISY); + singleBlockPlants.add(Material.BROWN_MUSHROOM); + singleBlockPlants.add(Material.RED_MUSHROOM); + + doublePlants = EnumSet.noneOf(Material.class); + doublePlants.add(Material.TALL_GRASS); + doublePlants.add(Material.LARGE_FERN); + doublePlants.add(Material.TALL_SEAGRASS); + doublePlants.add(Material.ROSE_BUSH); + doublePlants.add(Material.LILAC); + doublePlants.add(Material.SUNFLOWER); + doublePlants.add(Material.PEONY); + blockEquivalents = new HashSet>(7); blockEquivalents.add(new HashSet(Arrays.asList(2, 3, 60))); blockEquivalents.add(new HashSet(Arrays.asList(8, 9, 79))); @@ -40,108 +72,93 @@ public class BukkitUtils { blockEquivalents.add(new HashSet(Arrays.asList(93, 94))); // Blocks that break when they are attached to a block - relativeBreakable = new HashSet(11); + relativeBreakable = EnumSet.noneOf(Material.class); relativeBreakable.add(Material.WALL_SIGN); relativeBreakable.add(Material.LADDER); relativeBreakable.add(Material.STONE_BUTTON); - relativeBreakable.add(Material.WOOD_BUTTON); - relativeBreakable.add(Material.REDSTONE_TORCH_ON); - relativeBreakable.add(Material.REDSTONE_TORCH_OFF); + relativeBreakable.addAll(Tag.WOODEN_BUTTONS.getValues()); + relativeBreakable.add(Material.REDSTONE_WALL_TORCH); relativeBreakable.add(Material.LEVER); - relativeBreakable.add(Material.TORCH); - relativeBreakable.add(Material.TRAP_DOOR); + relativeBreakable.add(Material.WALL_TORCH); relativeBreakable.add(Material.TRIPWIRE_HOOK); relativeBreakable.add(Material.COCOA); // Blocks that break when they are on top of a block - relativeTopBreakable = new HashSet(33); - relativeTopBreakable.add(Material.SAPLING); - relativeTopBreakable.add(Material.LONG_GRASS); - relativeTopBreakable.add(Material.DEAD_BUSH); - relativeTopBreakable.add(Material.YELLOW_FLOWER); - relativeTopBreakable.add(Material.RED_ROSE); - relativeTopBreakable.add(Material.BROWN_MUSHROOM); - relativeTopBreakable.add(Material.RED_MUSHROOM); - relativeTopBreakable.add(Material.CROPS); + relativeTopBreakable = EnumSet.noneOf(Material.class); + relativeTopBreakable.addAll(Tag.SAPLINGS.getValues()); + relativeTopBreakable.addAll(singleBlockPlants); + relativeTopBreakable.add(Material.WHEAT); relativeTopBreakable.add(Material.POTATO); relativeTopBreakable.add(Material.CARROT); - relativeTopBreakable.add(Material.WATER_LILY); + relativeTopBreakable.add(Material.LILY_PAD); relativeTopBreakable.add(Material.CACTUS); - relativeTopBreakable.add(Material.SUGAR_CANE_BLOCK); + relativeTopBreakable.add(Material.SUGAR_CANE); relativeTopBreakable.add(Material.FLOWER_POT); relativeTopBreakable.add(Material.POWERED_RAIL); relativeTopBreakable.add(Material.DETECTOR_RAIL); relativeTopBreakable.add(Material.ACTIVATOR_RAIL); - relativeTopBreakable.add(Material.RAILS); + relativeTopBreakable.add(Material.RAIL); relativeTopBreakable.add(Material.REDSTONE_WIRE); - relativeTopBreakable.add(Material.SIGN_POST); - relativeTopBreakable.add(Material.STONE_PLATE); - relativeTopBreakable.add(Material.WOOD_PLATE); - relativeTopBreakable.add(Material.IRON_PLATE); - relativeTopBreakable.add(Material.GOLD_PLATE); + relativeTopBreakable.add(Material.SIGN); + relativeTopBreakable.add(Material.STONE_PRESSURE_PLATE); + relativeTopBreakable.addAll(Tag.WOODEN_PRESSURE_PLATES.getValues()); + relativeTopBreakable.add(Material.LIGHT_WEIGHTED_PRESSURE_PLATE); + relativeTopBreakable.add(Material.HEAVY_WEIGHTED_PRESSURE_PLATE); relativeTopBreakable.add(Material.SNOW); - relativeTopBreakable.add(Material.DIODE_BLOCK_ON); - relativeTopBreakable.add(Material.DIODE_BLOCK_OFF); - relativeTopBreakable.add(Material.REDSTONE_COMPARATOR_ON); - relativeTopBreakable.add(Material.REDSTONE_COMPARATOR_OFF); - relativeTopBreakable.add(Material.WOODEN_DOOR); - relativeTopBreakable.add(Material.IRON_DOOR_BLOCK); - relativeTopBreakable.add(Material.CARPET); - relativeTopBreakable.add(Material.DOUBLE_PLANT); - - // Blocks that fall - relativeTopFallables = new HashSet(4); - relativeTopFallables.add(Material.SAND); - relativeTopFallables.add(Material.GRAVEL); - relativeTopFallables.add(Material.DRAGON_EGG); - relativeTopFallables.add(Material.ANVIL); - relativeTopFallables.add(Material.CONCRETE_POWDER); + relativeTopBreakable.add(Material.REPEATER); + relativeTopBreakable.add(Material.COMPARATOR); + relativeTopBreakable.add(Material.TORCH); + relativeTopBreakable.add(Material.WALL_TORCH); + relativeTopBreakable.add(Material.REDSTONE_TORCH); + relativeTopBreakable.add(Material.REDSTONE_WALL_TORCH); + relativeTopBreakable.addAll(Tag.WOODEN_DOORS.getValues()); + relativeTopBreakable.add(Material.IRON_DOOR); + relativeTopBreakable.addAll(Tag.CARPETS.getValues()); + relativeTopBreakable.addAll(doublePlants); // Blocks that break falling entities - fallingEntityKillers = new HashSet(32); - fallingEntityKillers.add(Material.SIGN_POST); + fallingEntityKillers = EnumSet.noneOf(Material.class); + fallingEntityKillers.add(Material.SIGN); fallingEntityKillers.add(Material.WALL_SIGN); - fallingEntityKillers.add(Material.STONE_PLATE); - fallingEntityKillers.add(Material.WOOD_PLATE); - fallingEntityKillers.add(Material.IRON_PLATE); - fallingEntityKillers.add(Material.GOLD_PLATE); - fallingEntityKillers.add(Material.SAPLING); - fallingEntityKillers.add(Material.YELLOW_FLOWER); - fallingEntityKillers.add(Material.RED_ROSE); - fallingEntityKillers.add(Material.CROPS); + fallingEntityKillers.addAll(Tag.WOODEN_PRESSURE_PLATES.getValues()); + fallingEntityKillers.add(Material.STONE_PRESSURE_PLATE); + fallingEntityKillers.add(Material.LIGHT_WEIGHTED_PRESSURE_PLATE); + fallingEntityKillers.add(Material.HEAVY_WEIGHTED_PRESSURE_PLATE); + fallingEntityKillers.addAll(Tag.SAPLINGS.getValues()); + fallingEntityKillers.addAll(singleBlockPlants); + fallingEntityKillers.add(Material.WHEAT); fallingEntityKillers.add(Material.CARROT); fallingEntityKillers.add(Material.POTATO); - fallingEntityKillers.add(Material.RED_MUSHROOM); - fallingEntityKillers.add(Material.BROWN_MUSHROOM); - fallingEntityKillers.add(Material.STEP); - fallingEntityKillers.add(Material.WOOD_STEP); + fallingEntityKillers.add(Material.BEETROOT); + fallingEntityKillers.add(Material.NETHER_WART); + fallingEntityKillers.addAll(Tag.SLABS.getValues()); fallingEntityKillers.add(Material.TORCH); + fallingEntityKillers.add(Material.WALL_TORCH); fallingEntityKillers.add(Material.FLOWER_POT); fallingEntityKillers.add(Material.POWERED_RAIL); fallingEntityKillers.add(Material.DETECTOR_RAIL); fallingEntityKillers.add(Material.ACTIVATOR_RAIL); - fallingEntityKillers.add(Material.RAILS); + fallingEntityKillers.add(Material.RAIL); fallingEntityKillers.add(Material.LEVER); fallingEntityKillers.add(Material.REDSTONE_WIRE); - fallingEntityKillers.add(Material.REDSTONE_TORCH_ON); - fallingEntityKillers.add(Material.REDSTONE_TORCH_OFF); - fallingEntityKillers.add(Material.DIODE_BLOCK_ON); - fallingEntityKillers.add(Material.DIODE_BLOCK_OFF); - fallingEntityKillers.add(Material.REDSTONE_COMPARATOR_ON); - fallingEntityKillers.add(Material.REDSTONE_COMPARATOR_OFF); + fallingEntityKillers.add(Material.REDSTONE_TORCH); + fallingEntityKillers.add(Material.REDSTONE_WALL_TORCH); + fallingEntityKillers.add(Material.REPEATER); + fallingEntityKillers.add(Material.COMPARATOR); fallingEntityKillers.add(Material.DAYLIGHT_DETECTOR); - fallingEntityKillers.add(Material.CARPET); + fallingEntityKillers.addAll(Tag.CARPETS.getValues()); // Crop Blocks - cropBlocks = new HashSet(5); - cropBlocks.add(Material.CROPS); + cropBlocks = EnumSet.noneOf(Material.class); + cropBlocks.add(Material.WHEAT); cropBlocks.add(Material.MELON_STEM); cropBlocks.add(Material.PUMPKIN_STEM); cropBlocks.add(Material.CARROT); cropBlocks.add(Material.POTATO); + cropBlocks.add(Material.BEETROOT); // Container Blocks - containerBlocks = new HashSet(6); + containerBlocks = EnumSet.noneOf(Material.class); containerBlocks.add(Material.CHEST); containerBlocks.add(Material.TRAPPED_CHEST); containerBlocks.add(Material.DISPENSER); @@ -149,11 +166,10 @@ public class BukkitUtils { containerBlocks.add(Material.HOPPER); containerBlocks.add(Material.BREWING_STAND); containerBlocks.add(Material.FURNACE); - containerBlocks.add(Material.BURNING_FURNACE); containerBlocks.add(Material.BEACON); containerBlocks.add(Material.BLACK_SHULKER_BOX); containerBlocks.add(Material.BLUE_SHULKER_BOX); - containerBlocks.add(Material.SILVER_SHULKER_BOX); + containerBlocks.add(Material.LIGHT_GRAY_SHULKER_BOX); containerBlocks.add(Material.BROWN_SHULKER_BOX); containerBlocks.add(Material.CYAN_SHULKER_BOX); containerBlocks.add(Material.GRAY_SHULKER_BOX); @@ -171,17 +187,49 @@ public class BukkitUtils { // containerBlocks.add(Material.ENDER_CHEST); // It doesn't seem like you could injure people with some of these, but they exist, so.... - projectileItems = new EnumMap(EntityType.class); - projectileItems.put(EntityType.ARROW, 262); - projectileItems.put(EntityType.EGG, 344); - projectileItems.put(EntityType.ENDER_PEARL, 368); - projectileItems.put(EntityType.SMALL_FIREBALL, 385); // Fire charge - projectileItems.put(EntityType.FIREBALL, 385); // Fire charge - projectileItems.put(EntityType.FISHING_HOOK, 346); - projectileItems.put(EntityType.SNOWBALL, 332); - projectileItems.put(EntityType.SPLASH_POTION, 373); - projectileItems.put(EntityType.THROWN_EXP_BOTTLE, 384); - projectileItems.put(EntityType.WITHER_SKULL, 397); + projectileItems = new EnumMap(EntityType.class); + projectileItems.put(EntityType.ARROW, Material.ARROW); + projectileItems.put(EntityType.EGG, Material.EGG); + projectileItems.put(EntityType.ENDER_PEARL, Material.ENDER_PEARL); + projectileItems.put(EntityType.SMALL_FIREBALL, Material.FIRE_CHARGE); // Fire charge + projectileItems.put(EntityType.FIREBALL, Material.FIRE_CHARGE); // Fire charge + projectileItems.put(EntityType.FISHING_HOOK, Material.FISHING_ROD); + projectileItems.put(EntityType.SNOWBALL, Material.SNOWBALL); + projectileItems.put(EntityType.SPLASH_POTION, Material.SPLASH_POTION); + projectileItems.put(EntityType.THROWN_EXP_BOTTLE, Material.EXPERIENCE_BOTTLE); + projectileItems.put(EntityType.WITHER_SKULL, Material.WITHER_SKELETON_SKULL); + + nonFluidProofBlocks = EnumSet.noneOf(Material.class); + nonFluidProofBlocks.addAll(singleBlockPlants); + nonFluidProofBlocks.addAll(doublePlants); + nonFluidProofBlocks.add(Material.REDSTONE_WALL_TORCH); + nonFluidProofBlocks.add(Material.LEVER); + nonFluidProofBlocks.add(Material.WALL_TORCH); + nonFluidProofBlocks.add(Material.TRIPWIRE_HOOK); + nonFluidProofBlocks.add(Material.COCOA); + nonFluidProofBlocks.addAll(Tag.WOODEN_PRESSURE_PLATES.getValues()); + nonFluidProofBlocks.add(Material.STONE_PRESSURE_PLATE); + nonFluidProofBlocks.add(Material.LIGHT_WEIGHTED_PRESSURE_PLATE); + nonFluidProofBlocks.add(Material.HEAVY_WEIGHTED_PRESSURE_PLATE); + nonFluidProofBlocks.addAll(Tag.SAPLINGS.getValues()); + nonFluidProofBlocks.add(Material.WHEAT); + nonFluidProofBlocks.add(Material.CARROT); + nonFluidProofBlocks.add(Material.POTATO); + nonFluidProofBlocks.add(Material.BEETROOT); + nonFluidProofBlocks.add(Material.NETHER_WART); + nonFluidProofBlocks.add(Material.TORCH); + nonFluidProofBlocks.add(Material.FLOWER_POT); + nonFluidProofBlocks.add(Material.POWERED_RAIL); + nonFluidProofBlocks.add(Material.DETECTOR_RAIL); + nonFluidProofBlocks.add(Material.ACTIVATOR_RAIL); + nonFluidProofBlocks.add(Material.RAIL); + nonFluidProofBlocks.add(Material.LEVER); + nonFluidProofBlocks.add(Material.REDSTONE_WIRE); + nonFluidProofBlocks.add(Material.REDSTONE_TORCH); + nonFluidProofBlocks.add(Material.REPEATER); + nonFluidProofBlocks.add(Material.COMPARATOR); + nonFluidProofBlocks.add(Material.DAYLIGHT_DETECTOR); + nonFluidProofBlocks.addAll(Tag.CARPETS.getValues()); } @@ -206,26 +254,20 @@ public class BukkitUtils { return blocks; } - public static boolean isTop(Material mat, byte data) { - - switch (mat) { - case DOUBLE_PLANT: - return data > 5; - case IRON_DOOR_BLOCK: - case WOODEN_DOOR: - return data == 8 || data == 9; - default: - return false; + public static boolean isTop(BlockData data) { + if (data instanceof Bisected && !(data instanceof Stairs)) { + return ((Bisected) data).getHalf() == Half.TOP; } + return false; } - public static int getInventoryHolderType(InventoryHolder holder) { + public static Material getInventoryHolderType(InventoryHolder holder) { if (holder instanceof DoubleChest) { return getInventoryHolderType(((DoubleChest) holder).getLeftSide()); } else if (holder instanceof BlockState) { - return ((BlockState) holder).getTypeId(); + return ((BlockState) holder).getType(); } else { - return -1; + return null; } } @@ -243,6 +285,16 @@ public class BukkitUtils { final ItemStackComparator comperator = new ItemStackComparator(); final ArrayList diff = new ArrayList(); final int l1 = items1.length, l2 = items2.length; + for (int i = 0; i < l1; i++) { + if (items1[i] != null) { + items1[i] = new ItemStack(items1[i]); + } + } + for (int i = 0; i < l2; i++) { + if (items2[i] != null) { + items2[i] = new ItemStack(items2[i]); + } + } int c1 = 0, c2 = 0; while (c1 < l1 || c2 < l2) { if (c1 >= l1) { @@ -281,18 +333,16 @@ public class BukkitUtils { final ArrayList compressed = new ArrayList(); for (final ItemStack item : items) { if (item != null) { - final int type = item.getTypeId(); - final short data = rawData(item); boolean found = false; for (final ItemStack item2 : compressed) { - if (type == item2.getTypeId() && data == rawData(item2)) { + if (item2.isSimilar(item)) { item2.setAmount(item2.getAmount() + item.getAmount()); found = true; break; } } if (!found) { - compressed.add(new ItemStack(type, item.getAmount(), data)); + compressed.add(item.clone()); } } } @@ -328,13 +378,13 @@ public class BukkitUtils { return relativeTopBreakable; } - public static Set getRelativeTopFallables() { - return relativeTopFallables; - } - public static Set getFallingEntityKillers() { return fallingEntityKillers; } + + public static Set getNonFluidProofBlocks() { + return nonFluidProofBlocks; + } public static Set getCropBlocks() { return cropBlocks; @@ -354,18 +404,18 @@ public class BukkitUtils { return entity.getClass().getSimpleName().substring(5); } - public static void giveTool(Player player, int type) { + public static void giveTool(Player player, Material type) { final Inventory inv = player.getInventory(); if (inv.contains(type)) { - player.sendMessage(ChatColor.RED + "You have already a " + materialName(type)); + player.sendMessage(ChatColor.RED + "You have already a " + type.name()); } else { final int free = inv.firstEmpty(); if (free >= 0) { - if (player.getItemInHand() != null && player.getItemInHand().getTypeId() != 0) { - inv.setItem(free, player.getItemInHand()); + if (player.getInventory().getItemInMainHand() != null && player.getInventory().getItemInMainHand().getType() != Material.AIR) { + inv.setItem(free, player.getInventory().getItemInMainHand()); } - player.setItemInHand(new ItemStack(type, 1)); - player.sendMessage(ChatColor.GREEN + "Here's your " + materialName(type)); + player.getInventory().setItemInMainHand(new ItemStack(type)); + player.sendMessage(ChatColor.GREEN + "Here's your " + type.name()); } else { player.sendMessage(ChatColor.RED + "You have no empty slot in your inventory"); } @@ -384,22 +434,21 @@ public class BukkitUtils { } final int x = loc.getBlockX(), z = loc.getBlockZ(); int y = loc.getBlockY(); - boolean lower = world.getBlockTypeIdAt(x, y, z) == 0, upper = world.getBlockTypeIdAt(x, y + 1, z) == 0; + boolean lower = world.getBlockAt(x, y, z).isEmpty(), upper = world.getBlockAt(x, y + 1, z).isEmpty(); while ((!lower || !upper) && y != 127) { lower = upper; - upper = world.getBlockTypeIdAt(x, ++y, z) == 0; + upper = world.getBlockAt(x, ++y, z).isEmpty(); } - while (world.getBlockTypeIdAt(x, y - 1, z) == 0 && y != 0) { + while (world.getBlockAt(x, y - 1, z).isEmpty() && y != 0) { y--; } return y; } - public static int modifyContainer(BlockState b, ItemStack item) { + public static int modifyContainer(BlockState b, ItemStack item, boolean remove) { if (b instanceof InventoryHolder) { final Inventory inv = ((InventoryHolder) b).getInventory(); - if (item.getAmount() < 0) { - item.setAmount(-item.getAmount()); + if (remove) { final ItemStack tmp = inv.removeItem(item).get(0); return tmp != null ? tmp.getAmount() : 0; } else if (item.getAmount() > 0) { @@ -416,9 +465,9 @@ public class BukkitUtils { // Air if (mat == Material.AIR) { return true; - } else if (mat == Material.WATER || mat == Material.STATIONARY_WATER || mat == Material.LAVA || mat == Material.STATIONARY_LAVA) { // Fluids + } else if (mat == Material.WATER || mat == Material.LAVA) { // Fluids return true; - } else if (getFallingEntityKillers().contains(mat) || mat == Material.FIRE || mat == Material.VINE || mat == Material.LONG_GRASS || mat == Material.DEAD_BUSH) { // Misc. + } else if (getFallingEntityKillers().contains(mat) || mat == Material.FIRE || mat == Material.VINE || doublePlants.contains(mat) || mat == Material.DEAD_BUSH) { // Misc. return true; } return false; @@ -427,26 +476,15 @@ public class BukkitUtils { public static class ItemStackComparator implements Comparator { @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 short aData = rawData(a), bData = rawData(b); - if (aData < bData) { - return -1; - } - if (aData > bData) { - return 1; - } - return 0; + return a.getType().name().compareTo(b.getType().name()); } } - public static int itemIDfromProjectileEntity(Entity e) { - Integer i = projectileItems.get(e.getType()); - return (i == null) ? 0 : i; + public static Material itemIDfromProjectileEntity(Entity e) { + return projectileItems.get(e.getType()); + } + + public static boolean isDoublePlant(Material m) { + return doublePlants.contains(m); } } diff --git a/src/main/java/de/diddiz/util/ComparableVersion.java b/src/main/java/de/diddiz/util/ComparableVersion.java index 46ac027..406b009 100644 --- a/src/main/java/de/diddiz/util/ComparableVersion.java +++ b/src/main/java/de/diddiz/util/ComparableVersion.java @@ -257,6 +257,8 @@ public class ComparableVersion extends ArrayList implements Item { + private static final long serialVersionUID = 5914575811857700009L; + public int getType() { return LIST_ITEM; diff --git a/src/main/java/de/diddiz/util/LoggingUtil.java b/src/main/java/de/diddiz/util/LoggingUtil.java index 51a0e44..6a58d92 100644 --- a/src/main/java/de/diddiz/util/LoggingUtil.java +++ b/src/main/java/de/diddiz/util/LoggingUtil.java @@ -6,11 +6,12 @@ import de.diddiz.LogBlock.Logging; import de.diddiz.LogBlock.config.WorldConfig; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; import org.bukkit.block.Sign; -import org.bukkit.material.*; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; import java.util.List; @@ -30,7 +31,7 @@ public class LoggingUtil { Block checkBlock = origin.getRelative(BlockFace.UP); int up = 0; final int highestBlock = checkBlock.getWorld().getHighestBlockYAt(checkBlock.getLocation()); - while (BukkitUtils.getRelativeTopFallables().contains(checkBlock.getType())) { + while (checkBlock.getType().hasGravity()) { // Record this block as falling consumer.queueBlockBreak(actor, checkBlock.getState()); @@ -49,10 +50,10 @@ public class LoggingUtil { // Run this check to avoid false positives if (!BukkitUtils.getFallingEntityKillers().contains(finalLoc.getBlock().getType())) { finalLoc.add(0, up, 0); // Add this here after checking for block breakers - if (finalLoc.getBlock().getType() == Material.AIR || BukkitUtils.getRelativeTopFallables().contains(finalLoc.getBlock().getType())) { - consumer.queueBlockPlace(actor, finalLoc, checkBlock.getTypeId(), checkBlock.getData()); + if (finalLoc.getBlock().getType() == Material.AIR) { + consumer.queueBlockPlace(actor, finalLoc, checkBlock.getBlockData()); } else { - consumer.queueBlockReplace(actor, finalLoc, finalLoc.getBlock().getTypeId(), finalLoc.getBlock().getData(), checkBlock.getTypeId(), checkBlock.getData()); + consumer.queueBlockReplace(actor, finalLoc, finalLoc.getBlock().getBlockData(), checkBlock.getBlockData()); } up++; } @@ -73,28 +74,28 @@ public class LoggingUtil { Block checkBlock = origin.getRelative(BlockFace.UP); if (BukkitUtils.getRelativeTopBreakabls().contains(checkBlock.getType())) { - if (wcfg.isLogging(Logging.SIGNTEXT) && checkBlock.getType() == Material.SIGN_POST) { + if (wcfg.isLogging(Logging.SIGNTEXT) && checkBlock.getType() == Material.SIGN) { consumer.queueSignBreak(actor, (Sign) checkBlock.getState()); - } else if (checkBlock.getType() == Material.IRON_DOOR_BLOCK || checkBlock.getType() == Material.WOODEN_DOOR) { + } else if (checkBlock.getType() == Material.IRON_DOOR || Tag.WOODEN_DOORS.isTagged(checkBlock.getType())) { Block doorBlock = checkBlock; // If the doorBlock is the top half a door the player simply punched a door // this will be handled later. - if (!BukkitUtils.isTop(doorBlock.getType(), doorBlock.getData())) { + if (!BukkitUtils.isTop(doorBlock.getBlockData())) { doorBlock = doorBlock.getRelative(BlockFace.UP); // Fall back check just in case the top half wasn't a door - if (doorBlock.getType() == Material.IRON_DOOR_BLOCK || doorBlock.getType() == Material.WOODEN_DOOR) { + if (doorBlock.getType() == Material.IRON_DOOR || Tag.WOODEN_DOORS.isTagged(doorBlock.getType())) { consumer.queueBlockBreak(actor, doorBlock.getState()); } consumer.queueBlockBreak(actor, checkBlock.getState()); } - } else if (checkBlock.getType() == Material.DOUBLE_PLANT) { + } else if (BukkitUtils.isDoublePlant(checkBlock.getType())) { Block plantBlock = checkBlock; // If the plantBlock is the top half of a double plant the player simply // punched the plant this will be handled later. - if (!BukkitUtils.isTop(plantBlock.getType(), plantBlock.getData())) { + if (!BukkitUtils.isTop(plantBlock.getBlockData())) { plantBlock = plantBlock.getRelative(BlockFace.UP); // Fall back check just in case the top half wasn't a plant - if (plantBlock.getType() == Material.DOUBLE_PLANT) { + if (BukkitUtils.isDoublePlant(plantBlock.getType())) { consumer.queueBlockBreak(actor, plantBlock.getState()); } consumer.queueBlockBreak(actor, checkBlock.getState()); @@ -107,93 +108,45 @@ public class LoggingUtil { List relativeBreakables = BukkitUtils.getBlocksNearby(origin, BukkitUtils.getRelativeBreakables()); if (relativeBreakables.size() != 0) { for (Location location : relativeBreakables) { - final Material blockType = location.getBlock().getType(); - final BlockState blockState = location.getBlock().getState(); - final MaterialData data = blockState.getData(); - switch (blockType) { - case REDSTONE_TORCH_ON: - case REDSTONE_TORCH_OFF: - if (blockState.getBlock().getRelative(((RedstoneTorch) data).getAttachedFace()).equals(origin)) { - consumer.queueBlockBreak(actor, blockState); + Block block = location.getBlock(); + BlockData blockData = block.getBlockData(); + if (blockData instanceof Directional) { + if (block.getRelative(((Directional) blockData).getFacing()).equals(origin)) { + if (wcfg.isLogging(Logging.SIGNTEXT) && block.getType() == Material.WALL_SIGN) { + consumer.queueSignBreak(actor, (Sign) block.getState()); + } else { + consumer.queueBlockBreak(actor, block.getState()); } - break; - case TORCH: - if (blockState.getBlock().getRelative(((Torch) data).getAttachedFace()).equals(origin)) { - consumer.queueBlockBreak(actor, blockState); - } - break; - case COCOA: - if (blockState.getBlock().getRelative(((CocoaPlant) data).getAttachedFace().getOppositeFace()).equals(origin)) { - consumer.queueBlockBreak(actor, blockState); - } - break; - case LADDER: - if (blockState.getBlock().getRelative(((Ladder) data).getAttachedFace()).equals(origin)) { - consumer.queueBlockBreak(actor, blockState); - } - break; - case LEVER: - if (blockState.getBlock().getRelative(((Lever) data).getAttachedFace()).equals(origin)) { - consumer.queueBlockBreak(actor, blockState); - } - break; - case TRIPWIRE_HOOK: - if (blockState.getBlock().getRelative(((TripwireHook) data).getAttachedFace()).equals(origin)) { - consumer.queueBlockBreak(actor, blockState); - } - break; - case WOOD_BUTTON: - case STONE_BUTTON: - if (blockState.getBlock().getRelative(((Button) data).getAttachedFace()).equals(origin)) { - consumer.queueBlockBreak(actor, blockState); - } - break; - case WALL_SIGN: - if (blockState.getBlock().getRelative(((org.bukkit.material.Sign) data).getAttachedFace()).equals(origin)) { - if (wcfg.isLogging(Logging.SIGNTEXT)) { - consumer.queueSignBreak(actor, (Sign) blockState); - } else { - consumer.queueBlockBreak(actor, blockState); - } - } - break; - case TRAP_DOOR: - if (blockState.getBlock().getRelative(((TrapDoor) data).getAttachedFace()).equals(origin)) { - consumer.queueBlockBreak(actor, blockState); - } - break; - default: - consumer.queueBlockBreak(actor, blockState); - break; + } } } } // Special door check - if (origin.getType() == Material.IRON_DOOR_BLOCK || origin.getType() == Material.WOODEN_DOOR) { + if (origin.getType() == Material.IRON_DOOR || Tag.WOODEN_DOORS.isTagged(origin.getType())) { Block doorBlock = origin; // Up or down? - if (!BukkitUtils.isTop(doorBlock.getType(), doorBlock.getData())) { + if (!BukkitUtils.isTop(doorBlock.getBlockData())) { doorBlock = doorBlock.getRelative(BlockFace.UP); } else { doorBlock = doorBlock.getRelative(BlockFace.DOWN); } - if (doorBlock.getType() == Material.IRON_DOOR_BLOCK || doorBlock.getType() == Material.WOODEN_DOOR) { + if (doorBlock.getType() == Material.IRON_DOOR || Tag.WOODEN_DOORS.isTagged(doorBlock.getType())) { consumer.queueBlockBreak(actor, doorBlock.getState()); } - } else if (origin.getType() == Material.DOUBLE_PLANT) { // Special double plant check + } else if (BukkitUtils.isDoublePlant(origin.getType())) { // Special double plant check Block plantBlock = origin; // Up or down? - if (!BukkitUtils.isTop(origin.getType(), origin.getData())) { + if (!BukkitUtils.isTop(origin.getBlockData())) { plantBlock = plantBlock.getRelative(BlockFace.UP); } else { plantBlock = plantBlock.getRelative(BlockFace.DOWN); } - if (plantBlock.getType() == Material.DOUBLE_PLANT) { + if (BukkitUtils.isDoublePlant(plantBlock.getType())) { consumer.queueBlockBreak(actor, plantBlock.getState()); } } diff --git a/src/main/java/de/diddiz/util/MaterialName.java b/src/main/java/de/diddiz/util/MaterialName.java deleted file mode 100644 index 9d6fe22..0000000 --- a/src/main/java/de/diddiz/util/MaterialName.java +++ /dev/null @@ -1,280 +0,0 @@ -package de.diddiz.util; - -import de.diddiz.LogBlock.LogBlock; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.material.MaterialData; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; - -import static de.diddiz.util.Utils.isInt; -import static de.diddiz.util.Utils.isShort; -import static org.bukkit.Bukkit.getLogger; - -public class MaterialName { - private static final String[] COLORS = {"white", "orange", "magenta", "light blue", "yellow", "lime", "pink", "gray", "silver", "cyan", "purple", "blue", "brown", "green", "red", "black"}; - private static final Map materialNames = new HashMap(); - private static final Map> materialDataNames = new HashMap>(); - private static final Map nameTypes = new HashMap(); - - static { - // Add all known materials - for (final Material mat : Material.values()) { - materialNames.put(mat.getId(), mat.toString().replace('_', ' ').toLowerCase()); - } - // Load config - final File file = new File(LogBlock.getInstance().getDataFolder(), "materials.yml"); - final YamlConfiguration cfg = YamlConfiguration.loadConfiguration(file); - if (cfg.getKeys(false).isEmpty()) { - // Generate defaults - cfg.options().header("Add block or item names you want to be overridden or also names for custom blocks"); - cfg.set("1.1", "granite"); - cfg.set("1.2", "polished granite"); - cfg.set("1.3", "diorite"); - cfg.set("1.4", "polished diorite"); - cfg.set("1.5", "andesite"); - cfg.set("1.6", "polished andesite"); - cfg.set("5.0", "oak wood"); - cfg.set("5.1", "spruce wood"); - cfg.set("5.2", "birch wood"); - cfg.set("5.3", "jungle wood"); - cfg.set("5.4", "acacia wood"); - cfg.set("5.5", "dark oak wood"); - cfg.set("3.1", "coarse dirt"); - cfg.set("3.2", "podzol"); - cfg.set("6.1", "redwood sapling"); - cfg.set("6.2", "birch sapling"); - cfg.set("6.3", "jungle sapling"); - cfg.set("6.4", "acacia sapling"); - cfg.set("6.5", "dark oak sapling"); - cfg.set("9", "water"); - cfg.set("11", "lava"); - cfg.set("12.1", "red sand"); - cfg.set("17.0", "oak log"); - cfg.set("17.1", "spruce log"); - cfg.set("17.2", "birch log"); - cfg.set("17.3", "jungle log"); - cfg.set("17.4", "oak log"); - cfg.set("17.5", "spruce log"); - cfg.set("17.6", "birch log"); - cfg.set("17.7", "jungle log"); - cfg.set("17.8", "oak log"); - cfg.set("17.9", "spruce log"); - cfg.set("17.10", "birch log"); - cfg.set("17.11", "jungle log"); - cfg.set("17.12", "oak log"); - cfg.set("17.13", "spruce log"); - cfg.set("17.14", "birch log"); - cfg.set("17.15", "jungle log"); - cfg.set("18.1", "spruce leaves"); - cfg.set("18.2", "birch leaves"); - cfg.set("18.3", "jungle leaves"); - cfg.set("18.4", "oak leaves"); - cfg.set("18.5", "spruce leaves"); - cfg.set("18.6", "birch leaves"); - cfg.set("18.7", "jungle leaves"); - cfg.set("18.8", "oak leaves"); - cfg.set("18.9", "spruce leaves"); - cfg.set("18.10", "birch leaves"); - cfg.set("18.11", "jungle leaves"); - cfg.set("18.12", "oak leaves"); - cfg.set("18.13", "spruce leaves"); - cfg.set("18.14", "birch leaves"); - cfg.set("18.15", "jungle leaves"); - cfg.set("19.1", "wet sponge"); - cfg.set("37.0", "dandelion"); - cfg.set("38.0", "poppy"); - cfg.set("38.1", "blue orchid"); - cfg.set("38.2", "allium"); - cfg.set("38.3", "azure bluet"); - cfg.set("38.4", "red tulip"); - cfg.set("38.5", "orange tulip"); - cfg.set("38.6", "white tulip"); - cfg.set("38.7", "pink tulip"); - cfg.set("38.8", "oxeye daisy"); - cfg.set("24.1", "chiseled sandstone"); - cfg.set("24.2", "smooth sandstone"); - cfg.set("31.0", "dead bush"); - cfg.set("31.1", "tall grass"); - cfg.set("31.2", "fern"); - cfg.set("98.0", "stone brick"); - cfg.set("98.1", "mossy stone brick"); - cfg.set("98.2", "cracked stone brick"); - cfg.set("98.3", "chiseled stone brick"); - cfg.set("125.0", "oak double step"); - cfg.set("125.1", "spruce double step"); - cfg.set("125.2", "birch double step"); - cfg.set("125.3", "jungle double step"); - cfg.set("125.4", "acacia double step"); - cfg.set("125.5", "dark oak double step"); - cfg.set("126.0", "oak step"); - cfg.set("126.1", "spruce step"); - cfg.set("126.2", "birch step"); - cfg.set("126.3", "jungle step"); - cfg.set("126.4", "acacia step"); - cfg.set("126.5", "dark oak step"); - cfg.set("126.8", "oak step"); - cfg.set("126.9", "spruce step"); - cfg.set("126.10", "birch step"); - cfg.set("126.11", "jungle step"); - cfg.set("126.12", "acacia step"); - cfg.set("126.13", "dark oak step"); - cfg.set("139.1", "mossy cobble wall"); - cfg.set("155.1", "chiseled quartz block"); - cfg.set("155.2", "pillar quartz block"); - cfg.set("155.3", "pillar quartz block"); - cfg.set("155.4", "pillar quartz block"); - cfg.set("161.0", "acacia leaves"); - cfg.set("161.1", "dark oak leaves"); - cfg.set("161.4", "acacia leaves"); - cfg.set("161.5", "dark oak leaves"); - cfg.set("161.8", "acacia leaves"); - cfg.set("161.9", "dark oak leaves"); - cfg.set("161.12", "acacia leaves"); - cfg.set("161.13", "dark oak leaves"); - cfg.set("162.0", "acacia log"); - cfg.set("162.1", "dark oak log"); - cfg.set("162.4", "acacia log"); - cfg.set("162.5", "dark oak log"); - cfg.set("162.8", "acacia log"); - cfg.set("162.9", "dark oak log"); - cfg.set("162.12", "acacia log"); - cfg.set("162.13", "dark oak log"); - cfg.set("168.1", "prismarine brick"); - cfg.set("168.2", "dark prismarine"); - cfg.set("181.0", "red sandstone double step"); - cfg.set("181.8", "smooth red sandstone double step"); - cfg.set("162.13", "dark oak log"); - cfg.set("175.0", "sunflower"); - cfg.set("175.1", "lilac"); - cfg.set("175.2", "double tall grass"); - cfg.set("175.3", "large fern"); - cfg.set("175.4", "rose bush"); - cfg.set("175.5", "peony"); - cfg.set("175.8", "sunflower"); - cfg.set("175.9", "lilac"); - cfg.set("175.10", "double tall grass"); - cfg.set("175.11", "large fern"); - cfg.set("175.12", "rose bush"); - cfg.set("175.13", "peony"); - cfg.set("179.1", "chiseled sandstone"); - cfg.set("179.2", "smooth sandstone"); - cfg.set("263.1", "charcoal"); - for (byte i = 0; i < 10; i++) { - cfg.set("43." + i, toReadable(Material.DOUBLE_STEP.getNewData(i))); - } - cfg.set("43.8", "stone double step"); - cfg.set("43.9", "sandstone double step"); - cfg.set("43.15", "quartz double step"); - for (byte i = 0; i < 8; i++) { - cfg.set("44." + i, toReadable(Material.STEP.getNewData(i))); - // The second half of this data list should read the same as the first half - cfg.set("44." + (i + 7), toReadable(Material.STEP.getNewData(i))); - } - for (byte i = 0; i < 16; i++) { - cfg.set("351." + i, toReadable(Material.INK_SACK.getNewData(i))); - cfg.set("35." + i, COLORS[i] + " wool"); - cfg.set("159." + i, COLORS[i] + " stained terracotta"); - cfg.set("95." + i, COLORS[i] + " stained glass"); - cfg.set("160." + i, COLORS[i] + " stained glass pane"); - cfg.set("171." + i, COLORS[i] + " carpet"); - cfg.set("251." + i, COLORS[i] + " concrete"); - cfg.set("252." + i, COLORS[i] + " concrete powder"); - } - for (byte i = 0; i < 6; i++) { - cfg.set("125." + i, toReadable(Material.WOOD_DOUBLE_STEP.getNewData(i))); - cfg.set("126." + i, toReadable(Material.WOOD_STEP.getNewData(i))); - cfg.set("126." + i + 8, toReadable(Material.WOOD_STEP.getNewData(i))); - } - try { - cfg.save(file); - } catch (final IOException ex) { - getLogger().log(Level.WARNING, "Unable to save material.yml: ", ex); - } - } - if (cfg.getString("252.1") == null) { - getLogger().info("[Logblock-names] Logblock's default materials.yml file has been updated with more names"); - getLogger().info("[Logblock-names] Consider deleting your current materials.yml file to allow it to be recreated"); - } - for (final String entry : cfg.getKeys(false)) { - if (isInt(entry)) { - if (cfg.isString(entry)) { - materialNames.put(Integer.valueOf(entry), cfg.getString(entry)); - nameTypes.put(cfg.getString(entry), Integer.valueOf(entry)); - } else if (cfg.isConfigurationSection(entry)) { - final Map dataNames = new HashMap(); - materialDataNames.put(Integer.valueOf(entry), dataNames); - final ConfigurationSection sec = cfg.getConfigurationSection(entry); - for (final String data : sec.getKeys(false)) { - if (isShort(data)) { - if (sec.isString(data)) { - dataNames.put(Short.valueOf(data), sec.getString(data)); - nameTypes.put(sec.getString(data), Integer.valueOf(entry)); - } else { - getLogger().warning("Parsing materials.yml: '" + data + "' is not a string."); - } - } else { - getLogger().warning("Parsing materials.yml: '" + data + "' is no valid material data"); - } - } - } else { - getLogger().warning("Parsing materials.yml: '" + entry + "' is neither a string nor a section."); - } - } else { - getLogger().warning("Parsing materials.yml: '" + entry + "' is no valid material id"); - } - } - } - - /** - * Returns the name of a material based on its id - * - * @param type The type of the material - * @return Name of the material, or if it's unknown, the id. - */ - public static String materialName(int type) { - return materialNames.containsKey(type) ? materialNames.get(type) : String.valueOf(type); - } - - /** - * Returns the name of a material based on its id and data - * - * @param type The type of the material - * @param data The data of the material - * @return Name of the material regarding it's data, or if it's unknown, the basic name. - */ - public static String materialName(int type, short data) { - final Map dataNames = materialDataNames.get(type); - if (dataNames != null) { - if (dataNames.containsKey(data)) { - return dataNames.get(data); - } - } - return materialName(type); - } - - public static Integer typeFromName(String name) { - Integer answer = nameTypes.get(toReadable(name)); - if (answer != null) { - return answer; - } - final Material mat = Material.matchMaterial(name); - if (mat == null) { - throw new IllegalArgumentException("No material matching: '" + name + "'"); - } - return mat.getId(); - } - - private static String toReadable(MaterialData matData) { - return matData.toString().toLowerCase().replace('_', ' ').replaceAll("[^a-z ]", ""); - } - - private static String toReadable(String matData) { - return matData.toLowerCase().replace('_', ' ').replaceAll("[^a-z ]", ""); - } -} diff --git a/src/main/java/de/diddiz/util/MySQLConnectionPool.java b/src/main/java/de/diddiz/util/MySQLConnectionPool.java index 0f7c976..b7e944c 100644 --- a/src/main/java/de/diddiz/util/MySQLConnectionPool.java +++ b/src/main/java/de/diddiz/util/MySQLConnectionPool.java @@ -11,7 +11,7 @@ public class MySQLConnectionPool implements Closeable { private final HikariDataSource ds; - public MySQLConnectionPool(String url, String user, String password) throws ClassNotFoundException { + public MySQLConnectionPool(String url, String user, String password) { this.ds = new HikariDataSource(); ds.setJdbcUrl(url); ds.setUsername(user); diff --git a/src/main/java/de/diddiz/util/Utils.java b/src/main/java/de/diddiz/util/Utils.java index 12349af..849d56f 100644 --- a/src/main/java/de/diddiz/util/Utils.java +++ b/src/main/java/de/diddiz/util/Utils.java @@ -1,13 +1,25 @@ package de.diddiz.util; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import org.bukkit.Material; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; public class Utils { public static String newline = System.getProperty("line.separator"); @@ -192,8 +204,55 @@ public class Utils { } } + private final static char[] hexArray = "0123456789ABCDEF".toCharArray(); + + public static String mysqlEscapeBytes(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2 + 2]; + hexChars[0] = '0'; + hexChars[1] = 'x'; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2 + 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 3] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + public static String mysqlTextEscape(String untrusted) { return untrusted.replace("\\", "\\\\").replace("'", "\\'"); } + public static ItemStack loadItemStack(byte[] data) { + if (data == null || data.length == 0) { + return null; + } + YamlConfiguration conf = new YamlConfiguration(); + try { + InputStreamReader reader = new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(data)), "UTF-8"); + conf.load(reader); + reader.close(); + return conf.getItemStack("stack"); + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + } + return null; + } + + public static byte[] saveItemStack(ItemStack stack) { + if (stack == null || stack.getType() == Material.AIR) { + return null; + } + try { + YamlConfiguration conf = new YamlConfiguration(); + conf.set("stack", stack); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + OutputStreamWriter writer = new OutputStreamWriter(new GZIPOutputStream(baos), "UTF-8"); + writer.write(conf.saveToString()); + writer.close(); + return baos.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } } diff --git a/src/main/java/de/diddiz/worldedit/WorldEditLoggingHook.java b/src/main/java/de/diddiz/worldedit/WorldEditLoggingHook.java index 0bdef23..976f05b 100644 --- a/src/main/java/de/diddiz/worldedit/WorldEditLoggingHook.java +++ b/src/main/java/de/diddiz/worldedit/WorldEditLoggingHook.java @@ -13,12 +13,7 @@ import de.diddiz.LogBlock.LogBlock; import de.diddiz.LogBlock.Logging; import de.diddiz.LogBlock.config.Config; import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.Sign; import java.util.logging.Level; @@ -88,32 +83,33 @@ public class WorldEditLoggingHook { return; } - Location location = new Location(world, pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); - Block origin = location.getBlock(); - int typeBefore = origin.getTypeId(); - byte dataBefore = origin.getData(); - // If we're dealing with a sign, store the block state to read the text off - BlockState stateBefore = null; - if (typeBefore == Material.SIGN_POST.getId() || typeBefore == Material.SIGN.getId()) { - stateBefore = origin.getState(); - } - - // Check to see if we've broken a sign - if (Config.isLogging(location.getWorld().getName(), Logging.SIGNTEXT) && (typeBefore == Material.SIGN_POST.getId() || typeBefore == Material.SIGN.getId())) { - plugin.getConsumer().queueSignBreak(lbActor, (Sign) stateBefore); - if (block.getType() != Material.AIR.getId()) { - plugin.getConsumer().queueBlockPlace(lbActor, location, block.getType(), (byte) block.getData()); - } - } else { - if (dataBefore != 0) { - plugin.getConsumer().queueBlockBreak(lbActor, location, typeBefore, dataBefore); - if (block.getType() != Material.AIR.getId()) { - plugin.getConsumer().queueBlockPlace(lbActor, location, block.getType(), (byte) block.getData()); - } - } else { - plugin.getConsumer().queueBlock(lbActor, location, typeBefore, block.getType(), (byte) block.getData()); - } - } + // FIXME wait for updated worldedit + // Location location = new Location(world, pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); + // Block origin = location.getBlock(); + // Material typeBefore = origin.getType(); + // byte dataBefore = origin.getData(); + // // If we're dealing with a sign, store the block state to read the text off + // BlockState stateBefore = null; + // if (typeBefore == Material.SIGN || typeBefore == Material.WALL_SIGN) { + // stateBefore = origin.getState(); + // } + // + // // Check to see if we've broken a sign + // if (Config.isLogging(location.getWorld().getName(), Logging.SIGNTEXT) && (typeBefore == Material.SIGN || typeBefore == Material.WALL_SIGN)) { + // plugin.getConsumer().queueSignBreak(lbActor, (Sign) stateBefore); + // if (block.getType() != Material.AIR.getId()) { + // plugin.getConsumer().queueBlockPlace(lbActor, location, block.getType(), (byte) block.getData()); + // } + // } else { + // if (dataBefore != 0) { + // plugin.getConsumer().queueBlockBreak(lbActor, location, typeBefore, dataBefore); + // if (block.getType() != Material.AIR.getId()) { + // plugin.getConsumer().queueBlockPlace(lbActor, location, block.getType(), (byte) block.getData()); + // } + // } else { + // plugin.getConsumer().queueBlock(lbActor, location, typeBefore, block.getType(), (byte) block.getData()); + // } + // } } }); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7b908bb..f3dcab9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -6,6 +6,7 @@ website: http://dev.bukkit.org/server-mods/logblock/ main: de.diddiz.LogBlock.LogBlock description: ${project.description} softdepend: [LogBlockQuestioner, WorldEdit] +api-version: 1.13 commands: lb: description: 'LogBlock plugin commands'