forked from LogBlock/LogBlock
Update to 1.13 / Logging/Rollbacks work but largely untested
Still missing: Import data from 1.12 and older
This commit is contained in:
10
pom.xml
10
pom.xml
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
129
src/main/java/de/diddiz/LogBlock/MaterialConverter.java
Normal file
129
src/main/java/de/diddiz/LogBlock/MaterialConverter.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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) {
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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))");
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class BlockSpreadLogging extends LoggingListener {
|
||||
}
|
||||
name = "GrassGrowth";
|
||||
break;
|
||||
case MYCEL:
|
||||
case MYCELIUM:
|
||||
if (!isLogging(world, Logging.MYCELIUMSPREAD)) {
|
||||
return;
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -257,6 +257,8 @@ public class ComparableVersion
|
||||
extends ArrayList<Item>
|
||||
implements Item
|
||||
{
|
||||
private static final long serialVersionUID = 5914575811857700009L;
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return LIST_ITEM;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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 ]", "");
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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'
|
||||
|
Reference in New Issue
Block a user