Update to 1.13 / Logging/Rollbacks work but largely untested

Still missing: Import data from 1.12 and older
This commit is contained in:
Brokkonaut
2018-07-21 02:41:52 +02:00
parent 1ce92e1d3f
commit ce30d33824
41 changed files with 1144 additions and 1381 deletions

10
pom.xml
View File

@ -40,9 +40,9 @@
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.13-pre7-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -136,8 +136,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>

View File

@ -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) {

View File

@ -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());

View File

@ -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;
}
}

View File

@ -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) {

File diff suppressed because it is too large Load Diff

View File

@ -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();
}
}

View File

@ -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

View File

@ -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<String, Integer> materialToID = new HashMap<>();
private static int nextMaterialId;
private static String[] idToBlockState = new String[10];
private static HashMap<String, Integer> 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();
}
}

View File

@ -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<Block> types = new ArrayList<Block>();
public List<Material> types = new ArrayList<Material>();
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<Integer> 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<String>(players);
params.types = new ArrayList<Block>(types);
params.types = new ArrayList<Material>(types);
return params;
} catch (final CloneNotSupportedException ex) {
}

View File

@ -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());
}
}

View File

@ -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<String> 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<String> aliases, ToolBehavior leftClickBehavior, ToolBehavior rightClickBehavior, boolean defaultEnabled, int item, boolean canDrop, QueryParams params, ToolMode mode, PermissionDefault permissionDefault) {
public Tool(String name, List<String> 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;

View File

@ -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))");
}

View File

@ -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) {

View File

@ -32,15 +32,15 @@ public class Config {
public static boolean dumpDeletedLog;
public static boolean logCreeperExplosionsAsPlayerWhoTriggeredThese, logPlayerInfo;
public static LogKillsLevel logKillsLevel;
public static Set<Integer> dontRollback, replaceAnyway;
public static Set<Material> dontRollback, replaceAnyway;
public static int rollbackMaxTime, rollbackMaxArea;
public static Map<String, Tool> toolsByName;
public static Map<Integer, Tool> toolsByType;
public static Map<Material, Tool> 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<Integer> hiddenBlocks;
public static Set<Material> hiddenBlocks;
public static Set<String> hiddenPlayers;
public static Set<String> 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<Integer>();
for (final Object blocktype : config.getList("logging.hiddenBlocks")) {
final Material mat = Material.matchMaterial(String.valueOf(blocktype));
hiddenBlocks = new HashSet<Material>();
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<String>();
for (String chatCommand : config.getStringList("logging.ignoredChat")) {
ignoredChat.add(chatCommand);
}
dontRollback = new HashSet<Integer>(config.getIntegerList("rollback.dontRollback"));
replaceAnyway = new HashSet<Integer>(config.getIntegerList("rollback.replaceAnyway"));
dontRollback = new HashSet<Material>();
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<Material>();
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<String, Tool>();
toolsByType = new HashMap<Integer, Tool>();
toolsByType = new HashMap<Material, Tool>();
for (final Tool tool : tools) {
toolsByType.put(tool.item, tool);
toolsByName.put(tool.name.toLowerCase(), tool);

View File

@ -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;

View File

@ -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()) {

View File

@ -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);

View File

@ -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));
}
}
}

View File

@ -32,7 +32,7 @@ public class BlockSpreadLogging extends LoggingListener {
}
name = "GrassGrowth";
break;
case MYCEL:
case MYCELIUM:
if (!isLogging(world, Logging.MYCELIUMSPREAD)) {
return;
}

View File

@ -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()));
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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());

View File

@ -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<Integer> nonFluidProofBlocks = new HashSet<Integer>(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;
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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());
}
}
}
}

View File

@ -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());
}
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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<Tool, ToolData> 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);

View File

@ -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.
}
}
}

View File

@ -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<Block> types, int blockID) {
for (Block block : types) {
if (block.getBlock() == blockID) {
return true;
}
}
return false;
}
}

View File

@ -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<Set<Integer>> blockEquivalents;
private static final Set<Material> relativeBreakable;
private static final Set<Material> relativeTopBreakable;
private static final Set<Material> relativeTopFallables;
private static final Set<Material> fallingEntityKillers;
private static final Set<Material> cropBlocks;
private static final Set<Material> containerBlocks;
private static final Map<EntityType, Integer> projectileItems;
private static final Set<Material> singleBlockPlants;
private static final Set<Material> doublePlants;
private static final Set<Material> nonFluidProofBlocks;
private static final Map<EntityType, Material> 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<Set<Integer>>(7);
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(2, 3, 60)));
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(8, 9, 79)));
@ -40,108 +72,93 @@ public class BukkitUtils {
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(93, 94)));
// Blocks that break when they are attached to a block
relativeBreakable = new HashSet<Material>(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<Material>(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<Material>(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<Material>(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<Material>(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<Material>(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, Integer>(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, Material>(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<ItemStack> diff = new ArrayList<ItemStack>();
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<ItemStack> compressed = new ArrayList<ItemStack>();
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<Material> getRelativeTopFallables() {
return relativeTopFallables;
}
public static Set<Material> getFallingEntityKillers() {
return fallingEntityKillers;
}
public static Set<Material> getNonFluidProofBlocks() {
return nonFluidProofBlocks;
}
public static Set<Material> 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<ItemStack> {
@Override
public int compare(ItemStack a, ItemStack b) {
final int aType = a.getTypeId(), bType = b.getTypeId();
if (aType < bType) {
return -1;
}
if (aType > bType) {
return 1;
}
final 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);
}
}

View File

@ -257,6 +257,8 @@ public class ComparableVersion
extends ArrayList<Item>
implements Item
{
private static final long serialVersionUID = 5914575811857700009L;
public int getType()
{
return LIST_ITEM;

View File

@ -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<Location> 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());
}
}

View File

@ -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<Integer, String> materialNames = new HashMap<Integer, String>();
private static final Map<Integer, Map<Short, String>> materialDataNames = new HashMap<Integer, Map<Short, String>>();
private static final Map<String, Integer> nameTypes = new HashMap<String, Integer>();
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<Short, String> dataNames = new HashMap<Short, String>();
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<Short, String> 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 ]", "");
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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());
// }
// }
}
});
}

View File

@ -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'