forked from LogBlock/LogBlock
Merge branch 'master' into issue-442
- Update PR to use Actor system - Amend actorFromProjectileSource to choose a friendly name when a block is the source of a projectile - Added util method to try to suggest an appropriate item as the "weapon" in a projectile kill Closes #442 Fixes #470 Fixes #471
This commit is contained in:
27
pom.xml
27
pom.xml
@@ -1,4 +1,3 @@
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -28,24 +27,22 @@
|
||||
<url>http://ci.kitteh.org/job/LogBlock</url>
|
||||
</ciManagement>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>kittehReleases</id>
|
||||
<name>Kitteh Releases</name>
|
||||
<url>http://repo.kitteh.org/content/repositories/releases</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>kittehSnapshots</id>
|
||||
<name>Kitteh Snapshots</name>
|
||||
<url>http://repo.kitteh.org/content/repositories/snapshots</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>md_5-releases</id>
|
||||
<url>http://repo.md-5.net/content/repositories/releases/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>md_5-snapshots</id>
|
||||
<url>http://repo.md-5.net/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.6.1-R0.1-SNAPSHOT</version>
|
||||
<version>1.7.2-R0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
@@ -57,7 +54,7 @@
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldedit</artifactId>
|
||||
<version>5.5</version>
|
||||
<version>6.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
99
src/main/java/de/diddiz/LogBlock/Actor.java
Normal file
99
src/main/java/de/diddiz/LogBlock/Actor.java
Normal file
@@ -0,0 +1,99 @@
|
||||
package de.diddiz.LogBlock;
|
||||
|
||||
import static de.diddiz.util.BukkitUtils.entityName;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.projectiles.BlockProjectileSource;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
public class Actor {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 79 * hash + (this.UUID != null ? this.UUID.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Actor other = (Actor) obj;
|
||||
return ((this.UUID == null && other.UUID == null) || this.UUID.equals(other.UUID));
|
||||
}
|
||||
|
||||
final String name;
|
||||
final String UUID;
|
||||
|
||||
public Actor(String name, String UUID) {
|
||||
this.name = name;
|
||||
this.UUID = UUID;
|
||||
|
||||
}
|
||||
|
||||
public Actor(String name, java.util.UUID UUID) {
|
||||
this.name = name;
|
||||
this.UUID = UUID.toString();
|
||||
|
||||
}
|
||||
|
||||
public Actor(String name) {
|
||||
this(name, generateUUID(name));
|
||||
}
|
||||
|
||||
public Actor(ResultSet rs) throws SQLException {
|
||||
this(rs.getString("playername"),rs.getString("UUID"));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getUUID() {
|
||||
return UUID;
|
||||
}
|
||||
|
||||
public static Actor actorFromEntity(Entity entity) {
|
||||
if (entity instanceof Player) {
|
||||
return new Actor(entityName(entity),entity.getUniqueId());
|
||||
} else {
|
||||
return new Actor(entityName(entity));
|
||||
}
|
||||
}
|
||||
|
||||
public static Actor actorFromEntity(EntityType entity) {
|
||||
return new Actor(entity.getName());
|
||||
}
|
||||
|
||||
public static Actor actorFromProjectileSource(ProjectileSource psource) {
|
||||
if (psource instanceof Entity) return actorFromEntity((Entity) psource);
|
||||
if (psource instanceof BlockProjectileSource) return new Actor(((BlockProjectileSource) psource).getBlock().getType().toString());
|
||||
else return new Actor(psource.toString());
|
||||
|
||||
}
|
||||
|
||||
public static boolean isValidUUID(String uuid) {
|
||||
try {
|
||||
java.util.UUID.fromString(uuid);
|
||||
return true;
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String generateUUID(String name) {
|
||||
return "log_" + name;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -8,40 +8,44 @@ import de.diddiz.util.BukkitUtils;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import de.diddiz.LogBlock.config.Config;
|
||||
import static de.diddiz.util.LoggingUtil.checkText;
|
||||
import org.bukkit.Material;
|
||||
|
||||
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 String signtext;
|
||||
public final ChestAccess ca;
|
||||
|
||||
public BlockChange(long date, Location loc, String playerName, int replaced, int type, byte data, String signtext, ChestAccess ca) {
|
||||
public BlockChange(long date, Location loc, Actor actor, int replaced, int type, byte data, String signtext, ChestAccess ca) {
|
||||
id = 0;
|
||||
this.date = date;
|
||||
this.loc = loc;
|
||||
this.playerName = playerName;
|
||||
this.actor = actor;
|
||||
this.replaced = replaced;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
this.signtext = signtext;
|
||||
this.signtext = checkText(signtext);
|
||||
this.ca = ca;
|
||||
this.playerName = actor == null ? null : actor.getName();
|
||||
}
|
||||
|
||||
public BlockChange(ResultSet rs, QueryParams p) throws SQLException {
|
||||
id = p.needId ? rs.getInt("id") : 0;
|
||||
date = p.needDate ? rs.getTimestamp("date").getTime() : 0;
|
||||
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;
|
||||
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.getByte("itemdata")) : null;
|
||||
ca = p.needChestAccess && rs.getShort("itemtype") != 0 && rs.getShort("itemamount") != 0 ? new ChestAccess(rs.getShort("itemtype"), rs.getShort("itemamount"), rs.getShort("itemdata")) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,8 +53,8 @@ public class BlockChange implements LookupCacheElement
|
||||
final StringBuilder msg = new StringBuilder();
|
||||
if (date > 0)
|
||||
msg.append(Config.formatter.format(date)).append(" ");
|
||||
if (playerName != null)
|
||||
msg.append(playerName).append(" ");
|
||||
if (actor != null)
|
||||
msg.append(actor.getName()).append(" ");
|
||||
if (signtext != null) {
|
||||
final String action = type == 0 ? "destroyed " : "created ";
|
||||
if (!signtext.contains("\0"))
|
||||
@@ -64,9 +68,9 @@ public class BlockChange implements LookupCacheElement
|
||||
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));
|
||||
msg.append("took ").append(-ca.itemAmount).append("x ").append(materialName(ca.itemType, ca.itemData)).append(" from ").append(materialName(type));
|
||||
else
|
||||
msg.append("put in ").append(ca.itemAmount).append("x ").append(materialName(ca.itemType, ca.itemData));
|
||||
msg.append("put ").append(ca.itemAmount).append("x ").append(materialName(ca.itemType, ca.itemData)).append(" into ").append(materialName(type));
|
||||
} else if (BukkitUtils.getContainerBlocks().contains(Material.getMaterial(type)))
|
||||
msg.append("opened ").append(materialName(type));
|
||||
else if (type == 64 || type == 71)
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.diddiz.LogBlock;
|
||||
|
||||
import static de.diddiz.util.LoggingUtil.checkText;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import org.bukkit.Location;
|
||||
@@ -8,17 +9,20 @@ public class ChatMessage implements LookupCacheElement
|
||||
{
|
||||
final long id, date;
|
||||
final String playerName, message;
|
||||
final Actor player;
|
||||
|
||||
public ChatMessage(String playerName, String message) {
|
||||
public ChatMessage(Actor player, String message) {
|
||||
id = 0;
|
||||
date = System.currentTimeMillis() / 1000;
|
||||
this.playerName = playerName;
|
||||
this.message = message;
|
||||
this.player = player;
|
||||
this.message = checkText(message);
|
||||
this.playerName = player == null ? null : player.getName();
|
||||
}
|
||||
|
||||
public ChatMessage(ResultSet rs, QueryParams p) throws SQLException {
|
||||
id = p.needId ? rs.getInt("id") : 0;
|
||||
date = p.needDate ? rs.getTimestamp("date").getTime() : 0;
|
||||
player = p.needPlayer ? new Actor(rs) : null;
|
||||
playerName = p.needPlayer ? rs.getString("playername") : null;
|
||||
message = p.needMessage ? rs.getString("message") : null;
|
||||
}
|
||||
@@ -30,6 +34,6 @@ public class ChatMessage implements LookupCacheElement
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return (playerName != null ? "<" + playerName + "> " : "") + (message != null ? message : "");
|
||||
return (player != null ? "<" + player.getName() + "> " : "") + (message != null ? message : "");
|
||||
}
|
||||
}
|
||||
|
@@ -2,10 +2,9 @@ package de.diddiz.LogBlock;
|
||||
|
||||
public class ChestAccess
|
||||
{
|
||||
final short itemType, itemAmount;
|
||||
final byte itemData;
|
||||
final short itemType, itemAmount, itemData;
|
||||
|
||||
public ChestAccess(short itemType, short itemAmount, byte itemData) {
|
||||
public ChestAccess(short itemType, short itemAmount, short itemData) {
|
||||
this.itemType = itemType;
|
||||
this.itemAmount = itemAmount;
|
||||
this.itemData = itemData >= 0 ? itemData : 0;
|
||||
|
@@ -306,6 +306,8 @@ public class CommandsHandler implements CommandExecutor
|
||||
}
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
sender.sendMessage(ChatColor.RED + ex.getMessage());
|
||||
} catch (final ArrayIndexOutOfBoundsException ex) {
|
||||
sender.sendMessage(ChatColor.RED + "Not enough arguments given");
|
||||
} catch (final Exception ex) {
|
||||
sender.sendMessage(ChatColor.RED + "Error, check server.log");
|
||||
getLogger().log(Level.WARNING, "Exception in commands handler: ", ex);
|
||||
@@ -404,7 +406,7 @@ public class CommandsHandler implements CommandExecutor
|
||||
params.needPlayer = true;
|
||||
if (params.types.isEmpty() || Block.inList(params.types, 63) || Block.inList(params.types, 68))
|
||||
params.needSignText = true;
|
||||
if (params.bct == BlockChangeType.CHESTACCESS || params.types.isEmpty() || Block.inList(params.types, 23) || Block.inList(params.types, 54) || Block.inList(params.types, 61) || Block.inList(params.types, 62))
|
||||
if (params.bct == BlockChangeType.CHESTACCESS || params.bct == BlockChangeType.ALL)
|
||||
params.needChestAccess = true;
|
||||
}
|
||||
conn = logblock.getConnection();
|
||||
@@ -464,7 +466,7 @@ public class CommandsHandler implements CommandExecutor
|
||||
params.needPlayer = true;
|
||||
if (params.types.isEmpty() || Block.inList(params.types, 63) || Block.inList(params.types, 68))
|
||||
params.needSignText = true;
|
||||
if (params.types.isEmpty() || Block.inList(params.types, 23) || Block.inList(params.types, 54) || Block.inList(params.types, 61) || Block.inList(params.types, 62))
|
||||
if (params.bct == BlockChangeType.CHESTACCESS || params.bct == BlockChangeType.ALL)
|
||||
params.needChestAccess = true;
|
||||
}
|
||||
conn = logblock.getConnection();
|
||||
@@ -536,9 +538,8 @@ public class CommandsHandler implements CommandExecutor
|
||||
public void run() {
|
||||
try {
|
||||
params.needCoords = true;
|
||||
if (params.bct == BlockChangeType.CHESTACCESS || params.types.isEmpty() || Block.inList(params.types, 23) || Block.inList(params.types, 54) || Block.inList(params.types, 61) || Block.inList(params.types, 62)) {
|
||||
if (params.bct == BlockChangeType.CHESTACCESS || params.bct == BlockChangeType.ALL)
|
||||
params.needChestAccess = true;
|
||||
}
|
||||
params.limit = 1;
|
||||
params.sum = SummarizationMode.NONE;
|
||||
conn = logblock.getConnection();
|
||||
@@ -550,8 +551,8 @@ public class CommandsHandler implements CommandExecutor
|
||||
rs = state.executeQuery(params.getQuery());
|
||||
if (rs.next()) {
|
||||
final Player player = (Player)sender;
|
||||
final int y = rs.getInt(2);
|
||||
final Location loc = new Location(params.world, rs.getInt(1) + 0.5, y, rs.getInt(3) + 0.5, player.getLocation().getYaw(), 90);
|
||||
final int y = rs.getInt("y");
|
||||
final Location loc = new Location(params.world, rs.getInt("x") + 0.5, y, rs.getInt("z") + 0.5, player.getLocation().getYaw(), 90);
|
||||
|
||||
// Teleport the player sync because omg thread safety
|
||||
logblock.getServer().getScheduler().scheduleSyncDelayedTask(logblock, new Runnable() {
|
||||
@@ -606,7 +607,7 @@ 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.getByte("itemdata"));
|
||||
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"));
|
||||
final int changes = editor.getSize();
|
||||
if (changes > 10000) {
|
||||
editor.setSender(sender);
|
||||
@@ -671,7 +672,7 @@ public class CommandsHandler implements CommandExecutor
|
||||
sender.sendMessage(ChatColor.DARK_AQUA + "Searching " + params.getTitle() + ":");
|
||||
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.getByte("itemdata"));
|
||||
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"));
|
||||
final int changes = editor.getSize();
|
||||
if (!params.silent)
|
||||
sender.sendMessage(ChatColor.GREEN.toString() + changes + " blocks found.");
|
||||
|
@@ -26,13 +26,14 @@ import java.util.logging.Level;
|
||||
import static de.diddiz.LogBlock.config.Config.*;
|
||||
import static de.diddiz.util.BukkitUtils.*;
|
||||
import static org.bukkit.Bukkit.getLogger;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
public class Consumer extends TimerTask
|
||||
{
|
||||
private final Queue<Row> queue = new LinkedBlockingQueue<Row>();
|
||||
private final Set<String> failedPlayers = new HashSet<String>();
|
||||
private final Set<Actor> failedPlayers = new HashSet<Actor>();
|
||||
private final LogBlock logblock;
|
||||
private final Map<String, Integer> playerIds = new HashMap<String, Integer>();
|
||||
private final Map<Actor, Integer> playerIds = new HashMap<Actor, Integer>();
|
||||
private final Lock lock = new ReentrantLock();
|
||||
|
||||
Consumer(LogBlock logblock) {
|
||||
@@ -46,8 +47,8 @@ public class Consumer extends TimerTask
|
||||
/**
|
||||
* Logs any block change. Don't try to combine broken and placed blocks. Queue two block changes or use the queueBLockReplace methods.
|
||||
*/
|
||||
public void queueBlock(String playerName, Location loc, int typeBefore, int typeAfter, byte data) {
|
||||
queueBlock(playerName, loc, typeBefore, typeAfter, data, null, null);
|
||||
public void queueBlock(Actor actor, Location loc, int typeBefore, int typeAfter, byte data) {
|
||||
queueBlock(actor, loc, typeBefore, typeAfter, data, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,15 +57,15 @@ public class Consumer extends TimerTask
|
||||
* @param before
|
||||
* Blockstate of the block before actually being destroyed.
|
||||
*/
|
||||
public void queueBlockBreak(String playerName, BlockState before) {
|
||||
queueBlockBreak(playerName, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData());
|
||||
public void queueBlockBreak(Actor actor, BlockState before) {
|
||||
queueBlockBreak(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a block break. The block type afterwards is assumed to be o (air).
|
||||
*/
|
||||
public void queueBlockBreak(String playerName, Location loc, int typeBefore, byte dataBefore) {
|
||||
queueBlock(playerName, loc, typeBefore, 0, dataBefore);
|
||||
public void queueBlockBreak(Actor actor, Location loc, int typeBefore, byte dataBefore) {
|
||||
queueBlock(actor, loc, typeBefore, 0, dataBefore);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,15 +74,15 @@ public class Consumer extends TimerTask
|
||||
* @param after
|
||||
* Blockstate of the block after actually being placed.
|
||||
*/
|
||||
public void queueBlockPlace(String playerName, BlockState after) {
|
||||
queueBlockPlace(playerName, new Location(after.getWorld(), after.getX(), after.getY(), after.getZ()), after.getBlock().getTypeId(), after.getBlock().getData());
|
||||
public void queueBlockPlace(Actor actor, BlockState after) {
|
||||
queueBlockPlace(actor, new Location(after.getWorld(), after.getX(), after.getY(), after.getZ()), after.getBlock().getTypeId(), after.getBlock().getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a block place. The block type before is assumed to be o (air).
|
||||
*/
|
||||
public void queueBlockPlace(String playerName, Location loc, int type, byte data) {
|
||||
queueBlock(playerName, loc, 0, type, data);
|
||||
public void queueBlockPlace(Actor actor, Location loc, int type, byte data) {
|
||||
queueBlock(actor, loc, 0, type, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,93 +91,109 @@ public class Consumer extends TimerTask
|
||||
* @param after
|
||||
* Blockstate of the block after actually being placed.
|
||||
*/
|
||||
public void queueBlockReplace(String playerName, BlockState before, BlockState after) {
|
||||
queueBlockReplace(playerName, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData(), after.getTypeId(), after.getRawData());
|
||||
public void queueBlockReplace(Actor actor, BlockState before, BlockState after) {
|
||||
queueBlockReplace(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData(), after.getTypeId(), after.getRawData());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param before
|
||||
* Blockstate of the block before actually being destroyed.
|
||||
*/
|
||||
public void queueBlockReplace(String playerName, BlockState before, int typeAfter, byte dataAfter) {
|
||||
queueBlockReplace(playerName, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData(), typeAfter, dataAfter);
|
||||
public void queueBlockReplace(Actor actor, BlockState before, int typeAfter, byte dataAfter) {
|
||||
queueBlockReplace(actor, new Location(before.getWorld(), before.getX(), before.getY(), before.getZ()), before.getTypeId(), before.getRawData(), typeAfter, dataAfter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param after
|
||||
* Blockstate of the block after actually being placed.
|
||||
*/
|
||||
public void queueBlockReplace(String playerName, int typeBefore, byte dataBefore, BlockState after) {
|
||||
queueBlockReplace(playerName, new Location(after.getWorld(), after.getX(), after.getY(), after.getZ()), typeBefore, dataBefore, after.getTypeId(), after.getRawData());
|
||||
public void queueBlockReplace(Actor actor, int typeBefore, byte dataBefore, BlockState after) {
|
||||
queueBlockReplace(actor, new Location(after.getWorld(), after.getX(), after.getY(), after.getZ()), typeBefore, dataBefore, after.getTypeId(), after.getRawData());
|
||||
}
|
||||
|
||||
public void queueBlockReplace(String playerName, Location loc, int typeBefore, byte dataBefore, int typeAfter, byte dataAfter) {
|
||||
public void queueBlockReplace(Actor actor, Location loc, int typeBefore, byte dataBefore, int typeAfter, byte dataAfter) {
|
||||
if (dataBefore == 0 && (typeBefore != typeAfter))
|
||||
queueBlock(playerName, loc, typeBefore, typeAfter, dataAfter);
|
||||
queueBlock(actor, loc, typeBefore, typeAfter, dataAfter);
|
||||
else {
|
||||
queueBlockBreak(playerName, loc, typeBefore, dataBefore);
|
||||
queueBlockPlace(playerName, loc, typeAfter, dataAfter);
|
||||
queueBlockBreak(actor, loc, typeBefore, dataBefore);
|
||||
queueBlockPlace(actor, loc, typeAfter, dataAfter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param container
|
||||
* The respective container. Must be an instance of Chest, Dispencer or Furnace.
|
||||
* The respective container. Must be an instance of an InventoryHolder.
|
||||
*/
|
||||
public void queueChestAccess(String playerName, BlockState container, short itemType, short itemAmount, byte itemData) {
|
||||
public void queueChestAccess(Actor actor, BlockState container, short itemType, short itemAmount, short itemData) {
|
||||
if (!(container instanceof InventoryHolder))
|
||||
return;
|
||||
queueChestAccess(playerName, new Location(container.getWorld(), container.getX(), container.getY(), container.getZ()), container.getTypeId(), itemType, itemAmount, itemData);
|
||||
queueChestAccess(actor, new Location(container.getWorld(), container.getX(), container.getY(), container.getZ()), container.getTypeId(), itemType, itemAmount, itemData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type
|
||||
* Type id of the container. Must be 63 or 68.
|
||||
* Type id of the container.
|
||||
*/
|
||||
public void queueChestAccess(String playerName, Location loc, int type, short itemType, short itemAmount, byte itemData) {
|
||||
queueBlock(playerName, loc, type, type, (byte)0, null, new ChestAccess(itemType, itemAmount, itemData));
|
||||
public void queueChestAccess(Actor actor, Location loc, int type, short itemType, short itemAmount, short itemData) {
|
||||
queueBlock(actor, loc, type, type, (byte)0, null, new ChestAccess(itemType, itemAmount, itemData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a container block break. The block type before is assumed to be o (air). All content is assumed to be taken.
|
||||
*
|
||||
* @param container
|
||||
* Must be instanceof InventoryHolder
|
||||
* Must be an instance of InventoryHolder
|
||||
*/
|
||||
public void queueContainerBreak(String playerName, BlockState container) {
|
||||
public void queueContainerBreak(Actor actor, BlockState container) {
|
||||
if (!(container instanceof InventoryHolder))
|
||||
return;
|
||||
queueContainerBreak(playerName, new Location(container.getWorld(), container.getX(), container.getY(), container.getZ()), container.getTypeId(), container.getRawData(), ((InventoryHolder)container).getInventory());
|
||||
queueContainerBreak(actor, new Location(container.getWorld(), container.getX(), container.getY(), container.getZ()), container.getTypeId(), container.getRawData(), ((InventoryHolder)container).getInventory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a container block break. The block type before is assumed to be o (air). All content is assumed to be taken.
|
||||
*/
|
||||
public void queueContainerBreak(String playerName, Location loc, int type, byte data, Inventory inv) {
|
||||
public void queueContainerBreak(Actor actor, Location loc, int type, byte data, Inventory inv) {
|
||||
final ItemStack[] items = compressInventory(inv.getContents());
|
||||
for (final ItemStack item : items)
|
||||
queueChestAccess(playerName, loc, type, (short)item.getTypeId(), (short)(item.getAmount() * -1), rawData(item));
|
||||
queueBlockBreak(playerName, loc, type, data);
|
||||
queueChestAccess(actor, loc, type, (short)item.getTypeId(), (short)(item.getAmount() * -1), rawData(item));
|
||||
queueBlockBreak(actor, loc, type, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param killer
|
||||
* Can' be null
|
||||
* Can't be null
|
||||
* @param victim
|
||||
* Can' be null
|
||||
* Can't be null
|
||||
*/
|
||||
public void queueKill(Entity killer, Entity victim) {
|
||||
if (killer == null || victim == null)
|
||||
return;
|
||||
int weapon = 0;
|
||||
|
||||
if(killer instanceof Projectile)
|
||||
killer = ((Projectile)killer).getShooter();
|
||||
|
||||
Actor killerActor = Actor.actorFromEntity(killer);
|
||||
// If it's a projectile kill we want to manually assign the weapon, so check for player before converting a projectile to its source
|
||||
if (killer instanceof Player && ((Player)killer).getItemInHand() != null)
|
||||
weapon = ((Player)killer).getItemInHand().getTypeId();
|
||||
|
||||
queueKill(victim.getLocation(), entityName(killer), entityName(victim), weapon);
|
||||
if(killer instanceof Projectile) {
|
||||
ProjectileSource ps = ((Projectile)killer).getShooter();
|
||||
killerActor = Actor.actorFromProjectileSource(ps);
|
||||
weapon = itemIDfromProjectileEntity(killer);
|
||||
}
|
||||
|
||||
queueKill(victim.getLocation(), killerActor, Actor.actorFromEntity(victim), weapon);
|
||||
}
|
||||
|
||||
/**
|
||||
* This form should only be used when the killer is not an entity e.g. for fall or suffocation damage
|
||||
* @param killer
|
||||
* Can't be null
|
||||
* @param victim
|
||||
* Can't be null
|
||||
*/
|
||||
public void queueKill(Actor killer, Entity victim) {
|
||||
if (killer == null || victim == null)
|
||||
return;
|
||||
queueKill(victim.getLocation(), killer, Actor.actorFromEntity(victim), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,24 +208,24 @@ public class Consumer extends TimerTask
|
||||
* @deprecated Use {@link #queueKill(Location,String,String,int)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void queueKill(World world, String killerName, String victimName, int weapon) {
|
||||
queueKill(new Location(world, 0, 0, 0), killerName, victimName, weapon);
|
||||
public void queueKill(World world, Actor killer, Actor victim, int weapon) {
|
||||
queueKill(new Location(world, 0, 0, 0), killer, victim, weapon);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param location
|
||||
* Location of the victim.
|
||||
* @param killerName
|
||||
* Name of the killer. Can be null.
|
||||
* @param victimName
|
||||
* Name of the victim. Can't be null.
|
||||
* @param killer
|
||||
* Killer Actor. Can be null.
|
||||
* @param victim
|
||||
* Victim Actor. Can't be null.
|
||||
* @param weapon
|
||||
* Item id of the weapon. 0 for no weapon.
|
||||
*/
|
||||
public void queueKill(Location location, String killerName, String victimName, int weapon) {
|
||||
if (victimName == null || !isLogged(location.getWorld()))
|
||||
public void queueKill(Location location, Actor killer, Actor victim, int weapon) {
|
||||
if (victim == null || !isLogged(location.getWorld()))
|
||||
return;
|
||||
queue.add(new KillRow(location, killerName == null ? null : killerName.replaceAll("[^a-zA-Z0-9_]", ""), victimName.replaceAll("[^a-zA-Z0-9_]", ""), weapon));
|
||||
queue.add(new KillRow(location, killer == null ? null : killer, victim, weapon));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,14 +234,14 @@ public class Consumer extends TimerTask
|
||||
* @param lines
|
||||
* The four lines on the sign.
|
||||
*/
|
||||
public void queueSignBreak(String playerName, Location loc, int type, byte data, String[] lines) {
|
||||
public void queueSignBreak(Actor actor, Location loc, int type, byte data, String[] lines) {
|
||||
if (type != 63 && type != 68 || lines == null || lines.length != 4)
|
||||
return;
|
||||
queueBlock(playerName, loc, type, 0, data, lines[0] + "\0" + lines[1] + "\0" + lines[2] + "\0" + lines[3], null);
|
||||
queueBlock(actor, loc, type, 0, data, lines[0] + "\0" + lines[1] + "\0" + lines[2] + "\0" + lines[3], null);
|
||||
}
|
||||
|
||||
public void queueSignBreak(String playerName, Sign sign) {
|
||||
queueSignBreak(playerName, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines());
|
||||
public void queueSignBreak(Actor actor, Sign sign) {
|
||||
queueSignBreak(actor, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,17 +250,17 @@ public class Consumer extends TimerTask
|
||||
* @param lines
|
||||
* The four lines on the sign.
|
||||
*/
|
||||
public void queueSignPlace(String playerName, Location loc, int type, byte data, String[] lines) {
|
||||
public void queueSignPlace(Actor actor, Location loc, int type, byte data, String[] lines) {
|
||||
if (type != 63 && type != 68 || lines == null || lines.length != 4)
|
||||
return;
|
||||
queueBlock(playerName, loc, 0, type, data, lines[0] + "\0" + lines[1] + "\0" + lines[2] + "\0" + lines[3], null);
|
||||
queueBlock(actor, loc, 0, type, data, lines[0] + "\0" + lines[1] + "\0" + lines[2] + "\0" + lines[3], null);
|
||||
}
|
||||
|
||||
public void queueSignPlace(String playerName, Sign sign) {
|
||||
queueSignPlace(playerName, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines());
|
||||
public void queueSignPlace(Actor actor, Sign sign) {
|
||||
queueSignPlace(actor, new Location(sign.getWorld(), sign.getX(), sign.getY(), sign.getZ()), sign.getTypeId(), sign.getRawData(), sign.getLines());
|
||||
}
|
||||
|
||||
public void queueChat(String player, String message) {
|
||||
public void queueChat(Actor player, String message) {
|
||||
for (String ignored : Config.ignoredChat) {
|
||||
if (message.startsWith(ignored)) {
|
||||
return;
|
||||
@@ -261,7 +278,7 @@ public class Consumer extends TimerTask
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public synchronized void run() {
|
||||
if (queue.isEmpty() || !lock.tryLock())
|
||||
return;
|
||||
final Connection conn = logblock.getConnection();
|
||||
@@ -282,12 +299,12 @@ public class Consumer extends TimerTask
|
||||
final Row r = queue.poll();
|
||||
if (r == null)
|
||||
continue;
|
||||
for (final String player : r.getPlayers()) {
|
||||
if (!playerIds.containsKey(player)) {
|
||||
if (!addPlayer(state, player)) {
|
||||
if (!failedPlayers.contains(player)) {
|
||||
failedPlayers.add(player);
|
||||
getLogger().warning("[Consumer] Failed to add player " + player);
|
||||
for (final Actor actor : r.getActors()) {
|
||||
if (!playerIds.containsKey(actor)) {
|
||||
if (!addPlayer(state, actor)) {
|
||||
if (!failedPlayers.contains(actor)) {
|
||||
failedPlayers.add(actor);
|
||||
getLogger().warning("[Consumer] Failed to add player " + actor.getName());
|
||||
}
|
||||
continue process;
|
||||
}
|
||||
@@ -295,6 +312,24 @@ public class Consumer extends TimerTask
|
||||
}
|
||||
if (r instanceof PreparedStatementRow) {
|
||||
PreparedStatementRow PSRow = (PreparedStatementRow) r;
|
||||
if (r instanceof MergeableRow) {
|
||||
int batchCount=count;
|
||||
// if we've reached our row target but not exceeded our time target, allow merging of up to 50% of our row limit more rows
|
||||
if (count > forceToProcessAtLeast) batchCount = forceToProcessAtLeast / 2;
|
||||
while(!queue.isEmpty()) {
|
||||
MergeableRow mRow = (MergeableRow) PSRow;
|
||||
Row s = queue.peek();
|
||||
if (s == null) break;
|
||||
if (!(s instanceof MergeableRow)) break;
|
||||
MergeableRow mRow2 = (MergeableRow) s;
|
||||
if (mRow.canMerge(mRow2)) {
|
||||
PSRow = mRow.merge((MergeableRow) queue.poll());
|
||||
count++;
|
||||
batchCount++;
|
||||
if (batchCount > forceToProcessAtLeast) break;
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
PSRow.setConnection(conn);
|
||||
try {
|
||||
PSRow.executeStatements();
|
||||
@@ -332,7 +367,7 @@ public class Consumer extends TimerTask
|
||||
|
||||
public void writeToFile() throws FileNotFoundException {
|
||||
final long time = System.currentTimeMillis();
|
||||
final Set<String> insertedPlayers = new HashSet<String>();
|
||||
final Set<Actor> insertedPlayers = new HashSet<Actor>();
|
||||
int counter = 0;
|
||||
new File("plugins/LogBlock/import/").mkdirs();
|
||||
PrintWriter writer = new PrintWriter(new File("plugins/LogBlock/import/queue-" + time + "-0.sql"));
|
||||
@@ -340,10 +375,11 @@ public class Consumer extends TimerTask
|
||||
final Row r = queue.poll();
|
||||
if (r == null)
|
||||
continue;
|
||||
for (final String player : r.getPlayers())
|
||||
if (!playerIds.containsKey(player) && !insertedPlayers.contains(player)) {
|
||||
writer.println("INSERT IGNORE INTO `lb-players` (playername) VALUES ('" + player + "');");
|
||||
insertedPlayers.add(player);
|
||||
for (final Actor actor : r.getActors())
|
||||
if (!playerIds.containsKey(actor) && !insertedPlayers.contains(actor)) {
|
||||
// Odd query contruction is to work around innodb auto increment behaviour - bug #492
|
||||
writer.println("INSERT IGNORE INTO `lb-players` (playername,UUID) SELECT '" + actor.getName() + "','" + actor.getUUID() + "' FROM `lb-players` WHERE NOT EXISTS (SELECT NULL FROM `lb-players` WHERE UUID = '" + actor.getUUID() + "') LIMIT 1;");
|
||||
insertedPlayers.add(actor);
|
||||
}
|
||||
for (final String insert : r.getInserts())
|
||||
writer.println(insert);
|
||||
@@ -370,25 +406,28 @@ public class Consumer extends TimerTask
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean addPlayer(Statement state, String playerName) throws SQLException {
|
||||
state.execute("INSERT IGNORE INTO `lb-players` (playername) VALUES ('" + playerName + "')");
|
||||
final ResultSet rs = state.executeQuery("SELECT playerid FROM `lb-players` WHERE playername = '" + playerName + "'");
|
||||
private boolean addPlayer(Statement state, Actor actor) throws SQLException {
|
||||
// Odd query contruction is to work around innodb auto increment behaviour - bug #492
|
||||
String name = actor.getName();
|
||||
String uuid = actor.getUUID();
|
||||
state.execute("INSERT IGNORE INTO `lb-players` (playername,UUID) SELECT '" + name + "','" + uuid + "' FROM `lb-players` WHERE NOT EXISTS (SELECT NULL FROM `lb-players` WHERE UUID = '" + uuid + "') LIMIT 1;");
|
||||
final ResultSet rs = state.executeQuery("SELECT playerid FROM `lb-players` WHERE UUID = '" + uuid + "'");
|
||||
if (rs.next())
|
||||
playerIds.put(playerName, rs.getInt(1));
|
||||
playerIds.put(actor, rs.getInt(1));
|
||||
rs.close();
|
||||
return playerIds.containsKey(playerName);
|
||||
return playerIds.containsKey(actor);
|
||||
}
|
||||
|
||||
private void queueBlock(String playerName, Location loc, int typeBefore, int typeAfter, byte data, String signtext, ChestAccess ca) {
|
||||
private void queueBlock(Actor actor, Location loc, int typeBefore, int typeAfter, byte data, String signtext, ChestAccess ca) {
|
||||
|
||||
if (Config.fireCustomEvents) {
|
||||
// Create and call the event
|
||||
BlockChangePreLogEvent event = new BlockChangePreLogEvent(playerName, loc, typeBefore, typeAfter, data, signtext, ca);
|
||||
BlockChangePreLogEvent event = new BlockChangePreLogEvent(actor, loc, typeBefore, typeAfter, data, signtext, ca);
|
||||
logblock.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) return;
|
||||
|
||||
// Update variables
|
||||
playerName = event.getOwner();
|
||||
actor = event.getOwnerActor();
|
||||
loc = event.getLocation();
|
||||
typeBefore = event.getTypeBefore();
|
||||
typeAfter = event.getTypeAfter();
|
||||
@@ -397,31 +436,37 @@ public class Consumer extends TimerTask
|
||||
ca = event.getChestAccess();
|
||||
}
|
||||
// Do this last so LogBlock still has final say in what is being added
|
||||
if (playerName == null || loc == null || typeBefore < 0 || typeAfter < 0 || (Config.safetyIdCheck && (typeBefore > 255 || typeAfter > 255)) || hiddenPlayers.contains(playerName.toLowerCase()) || !isLogged(loc.getWorld()) || typeBefore != typeAfter && hiddenBlocks.contains(typeBefore) && hiddenBlocks.contains(typeAfter)) return;
|
||||
queue.add(new BlockRow(loc, playerName.replaceAll("[^a-zA-Z0-9_]", ""), typeBefore, typeAfter, data, signtext, ca));
|
||||
if (actor == null || loc == null || typeBefore < 0 || typeAfter < 0 || (Config.safetyIdCheck && (typeBefore > 255 || typeAfter > 255)) || hiddenPlayers.contains(actor.getName().toLowerCase()) || !isLogged(loc.getWorld()) || typeBefore != typeAfter && hiddenBlocks.contains(typeBefore) && hiddenBlocks.contains(typeAfter)) return;
|
||||
queue.add(new BlockRow(loc, actor, typeBefore, typeAfter, data, signtext, ca));
|
||||
}
|
||||
|
||||
private String playerID(String playerName) {
|
||||
if (playerName == null)
|
||||
private String playerID(Actor actor) {
|
||||
if (actor == null)
|
||||
return "NULL";
|
||||
final Integer id = playerIds.get(playerName);
|
||||
final Integer id = playerIds.get(actor);
|
||||
if (id != null)
|
||||
return id.toString();
|
||||
return "(SELECT playerid FROM `lb-players` WHERE playername = '" + playerName + "')";
|
||||
return "(SELECT playerid FROM `lb-players` WHERE UUID = '" + actor.getUUID() + "')";
|
||||
}
|
||||
|
||||
private Integer playerIDAsInt(String playerName) {
|
||||
if (playerName == null) {
|
||||
private Integer playerIDAsInt(Actor actor) {
|
||||
if (actor == null) {
|
||||
return null;
|
||||
}
|
||||
return playerIds.get(playerName);
|
||||
return playerIds.get(actor);
|
||||
}
|
||||
|
||||
private static interface Row
|
||||
{
|
||||
String[] getInserts();
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated - Names are not guaranteed to be unique. Use {@link #getActors() }
|
||||
*/
|
||||
String[] getPlayers();
|
||||
|
||||
Actor[] getActors();
|
||||
}
|
||||
|
||||
private interface PreparedStatementRow extends Row
|
||||
@@ -429,22 +474,28 @@ public class Consumer extends TimerTask
|
||||
|
||||
abstract void setConnection(Connection connection);
|
||||
abstract void executeStatements() throws SQLException;
|
||||
|
||||
}
|
||||
|
||||
private class BlockRow extends BlockChange implements PreparedStatementRow
|
||||
private interface MergeableRow extends PreparedStatementRow
|
||||
{
|
||||
abstract boolean isUnique();
|
||||
abstract boolean canMerge(MergeableRow row);
|
||||
abstract MergeableRow merge(MergeableRow second);
|
||||
}
|
||||
|
||||
private class BlockRow extends BlockChange implements MergeableRow
|
||||
{
|
||||
private Connection connection;
|
||||
|
||||
public BlockRow(Location loc, String playerName, int replaced, int type, byte data, String signtext, ChestAccess ca) {
|
||||
super(System.currentTimeMillis() / 1000, loc, playerName, replaced, type, data, signtext, ca);
|
||||
public BlockRow(Location loc, Actor actor, int replaced, int type, byte data, String signtext, ChestAccess ca) {
|
||||
super(System.currentTimeMillis() / 1000, loc, actor, replaced, type, data, signtext, ca);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getInserts() {
|
||||
final String table = getWorldConfig(loc.getWorld()).table;
|
||||
final String[] inserts = new String[ca != null || signtext != null ? 2 : 1];
|
||||
inserts[0] = "INSERT INTO `" + table + "` (date, playerid, replaced, type, data, x, y, z) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(playerName) + ", " + replaced + ", " + type + ", " + data + ", '" + loc.getBlockX() + "', " + loc.getBlockY() + ", '" + loc.getBlockZ() + "');";
|
||||
inserts[0] = "INSERT INTO `" + table + "` (date, playerid, replaced, type, data, x, y, z) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(actor) + ", " + replaced + ", " + type + ", " + data + ", '" + loc.getBlockX() + "', " + loc.getBlockY() + ", '" + loc.getBlockZ() + "');";
|
||||
if (signtext != null) {
|
||||
inserts[1] = "INSERT INTO `" + table + "-sign` (id, signtext) values (LAST_INSERT_ID(), '" + signtext.replace("\\", "\\\\").replace("'", "\\'") + "');";
|
||||
}
|
||||
@@ -455,7 +506,12 @@ public class Consumer extends TimerTask
|
||||
|
||||
@Override
|
||||
public String[] getPlayers() {
|
||||
return new String[]{playerName};
|
||||
return new String[]{actor.getName()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actor[] getActors() {
|
||||
return new Actor[]{actor};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -470,7 +526,7 @@ public class Consumer extends TimerTask
|
||||
PreparedStatement ps1 = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps1 = connection.prepareStatement("INSERT INTO `" + table + "` (date, playerid, replaced, type, data, x, y, z) VALUES(FROM_UNIXTIME(?), " + playerID(playerName) + ", ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
|
||||
ps1 = connection.prepareStatement("INSERT INTO `" + table + "` (date, playerid, replaced, type, data, x, y, z) VALUES(FROM_UNIXTIME(?), " + playerID(actor) + ", ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
|
||||
ps1.setLong(1, date );
|
||||
ps1.setInt(2, replaced);
|
||||
ps1.setInt(3, type);
|
||||
@@ -499,7 +555,15 @@ public class Consumer extends TimerTask
|
||||
ps.executeUpdate();
|
||||
}
|
||||
}
|
||||
// we intentionally do not catch SQLException, it is thrown to the caller
|
||||
catch (final SQLException ex) {
|
||||
if (ps1 != null) {
|
||||
getLogger().log(Level.SEVERE, "[Consumer] Troublesome query: " + ps1.toString());
|
||||
}
|
||||
if (ps != null) {
|
||||
getLogger().log(Level.SEVERE, "[Consumer] Troublesome query: " + ps.toString());
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
finally {
|
||||
// individual try/catch here, though ugly, prevents resource leaks
|
||||
if( ps1 != null ) {
|
||||
@@ -524,16 +588,128 @@ public class Consumer extends TimerTask
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnique() {
|
||||
return !(signtext == null && ca == null && playerIds.containsKey(actor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMerge(MergeableRow row) {
|
||||
return !this.isUnique() && !row.isUnique() && row instanceof BlockRow && getWorldConfig(loc.getWorld()).table.equals(getWorldConfig(((BlockRow) row).loc.getWorld()).table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeableRow merge(MergeableRow singleRow) {
|
||||
return new MultiBlockChangeRow(this,(BlockRow) singleRow);
|
||||
}
|
||||
}
|
||||
|
||||
private class MultiBlockChangeRow implements MergeableRow{
|
||||
private List<BlockRow> rows = new ArrayList<BlockRow>();
|
||||
private Connection connection;
|
||||
private Set<String> players = new HashSet<String>();
|
||||
private Set<Actor> actors = new HashSet<Actor>();
|
||||
private String table;
|
||||
|
||||
MultiBlockChangeRow (BlockRow first, BlockRow second) {
|
||||
if (first.isUnique() || second.isUnique()) throw new IllegalArgumentException("Can't merge a unique row");
|
||||
rows.add(first);
|
||||
rows.add(second);
|
||||
actors.addAll(Arrays.asList(first.getActors()));
|
||||
actors.addAll(Arrays.asList(second.getActors()));
|
||||
players.addAll(Arrays.asList(first.getPlayers()));
|
||||
players.addAll(Arrays.asList(second.getPlayers()));
|
||||
table = getWorldConfig(first.loc.getWorld()).table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConnection(Connection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeStatements() throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = connection.prepareStatement("INSERT INTO `" + table + "` (date, playerid, replaced, type, data, x, y, z) VALUES(FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?)");
|
||||
for (BlockRow row : rows) {
|
||||
ps.setLong(1, row.date );
|
||||
ps.setInt(2, playerIds.get(row.actor));
|
||||
ps.setInt(3, row.replaced);
|
||||
ps.setInt(4, row.type);
|
||||
ps.setInt(5, row.data);
|
||||
ps.setInt(6, row.loc.getBlockX());
|
||||
ps.setInt(7, row.loc.getBlockY());
|
||||
ps.setInt(8, row.loc.getBlockZ());
|
||||
ps.addBatch();
|
||||
}
|
||||
ps.executeBatch();
|
||||
} catch (final SQLException ex) {
|
||||
if (ps != null) {
|
||||
getLogger().log(Level.SEVERE, "[Consumer] Troublesome query: " + ps.toString());
|
||||
}
|
||||
throw ex;
|
||||
} finally {
|
||||
// individual try/catch here, though ugly, prevents resource leaks
|
||||
if( ps != null ) {
|
||||
try {
|
||||
ps.close();
|
||||
}
|
||||
catch(SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnique() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMerge(MergeableRow row) {
|
||||
return !row.isUnique() && row instanceof BlockRow && table.equals(getWorldConfig(((BlockRow) row).loc.getWorld()).table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeableRow merge(MergeableRow second) {
|
||||
if (second.isUnique()) throw new IllegalArgumentException("Can't merge a unique row");
|
||||
rows.add((BlockRow) second);
|
||||
actors.addAll(Arrays.asList(second.getActors()));
|
||||
players.addAll(Arrays.asList(second.getPlayers()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getInserts() {
|
||||
List<String> l = new ArrayList<String>();
|
||||
for (BlockRow row : rows) {
|
||||
l.addAll(Arrays.asList(row.getInserts()));
|
||||
}
|
||||
return (String[]) l.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPlayers() {
|
||||
return (String[]) players.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actor[] getActors() {
|
||||
return (Actor[]) actors.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
private class KillRow implements Row
|
||||
{
|
||||
final long date;
|
||||
final String killer, victim;
|
||||
final Actor killer, victim;
|
||||
final int weapon;
|
||||
final Location loc;
|
||||
|
||||
KillRow(Location loc, String attacker, String defender, int weapon) {
|
||||
KillRow(Location loc, Actor attacker, Actor defender, int weapon) {
|
||||
date = System.currentTimeMillis() / 1000;
|
||||
this.loc = loc;
|
||||
killer = attacker;
|
||||
@@ -543,12 +719,17 @@ public class Consumer extends TimerTask
|
||||
|
||||
@Override
|
||||
public String[] getInserts() {
|
||||
return new String[]{"INSERT INTO `" + getWorldConfig(loc.getWorld()).table + "-kills` (date, killer, victim, weapon, x, y, z) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(killer) + ", " + playerID(victim) + ", " + weapon + ", " + loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ() + ");"};
|
||||
return new String[]{"INSERT INTO `" + getWorldConfig(loc.getWorld()).table + "-kills` (date, killer, victim, weapon, x, y, z) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(killer) + ", " + playerID(victim) + ", " + weapon + ", " + loc.getBlockX() + ", " + (loc.getBlockY() < 0 ? 0 : loc.getBlockY()) + ", " + loc.getBlockZ() + ");"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPlayers() {
|
||||
return new String[]{killer, victim};
|
||||
return new String[]{killer.getName(), victim.getName()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actor[] getActors() {
|
||||
return new Actor[]{killer,victim};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,18 +737,23 @@ public class Consumer extends TimerTask
|
||||
{
|
||||
private Connection connection;
|
||||
|
||||
ChatRow(String player, String message) {
|
||||
ChatRow(Actor player, String message) {
|
||||
super(player, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getInserts() {
|
||||
return new String[]{"INSERT INTO `lb-chat` (date, playerid, message) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(playerName) + ", '" + message.replace("\\", "\\\\").replace("'", "\\'") + "');"};
|
||||
return new String[]{"INSERT INTO `lb-chat` (date, playerid, message) VALUES (FROM_UNIXTIME(" + date + "), " + playerID(player) + ", '" + message.replace("\\", "\\\\").replace("'", "\\'") + "');"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPlayers() {
|
||||
return new String[]{playerName};
|
||||
return new String[]{player.getName()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actor[] getActors() {
|
||||
return new Actor[]{player};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -581,9 +767,9 @@ public class Consumer extends TimerTask
|
||||
Integer id;
|
||||
|
||||
String sql = "INSERT INTO `lb-chat` (date, playerid, message) VALUES (FROM_UNIXTIME(?), ";
|
||||
if ((id = playerIDAsInt(playerName)) == null) {
|
||||
if ((id = playerIDAsInt(player)) == null) {
|
||||
noID = true;
|
||||
sql += playerID(playerName) + ", ";
|
||||
sql += playerID(player) + ", ";
|
||||
} else {
|
||||
sql += "?, ";
|
||||
}
|
||||
@@ -618,45 +804,59 @@ public class Consumer extends TimerTask
|
||||
|
||||
private class PlayerJoinRow implements Row
|
||||
{
|
||||
private final String playerName;
|
||||
private final Actor player;
|
||||
private final long lastLogin;
|
||||
private final String ip;
|
||||
|
||||
PlayerJoinRow(Player player) {
|
||||
playerName = player.getName();
|
||||
this.player = Actor.actorFromEntity(player);
|
||||
lastLogin = System.currentTimeMillis() / 1000;
|
||||
ip = player.getAddress().toString().replace("'", "\\'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getInserts() {
|
||||
return new String[]{"UPDATE `lb-players` SET lastlogin = FROM_UNIXTIME(" + lastLogin + "), firstlogin = IF(firstlogin = 0, FROM_UNIXTIME(" + lastLogin + "), firstlogin), ip = '" + ip + "' WHERE " + (playerIds.containsKey(playerName) ? "playerid = " + playerIds.get(playerName) : "playerName = '" + playerName + "'") + ";"};
|
||||
if (logPlayerInfo)
|
||||
return new String[]{"UPDATE `lb-players` SET lastlogin = FROM_UNIXTIME(" + lastLogin + "), firstlogin = IF(firstlogin = 0, FROM_UNIXTIME(" + lastLogin + "), firstlogin), ip = '" + ip + "', playername = '" + player.getName() + "' WHERE UUID = '" + player.getUUID() + "';"};
|
||||
return new String[]{"UPDATE `lb-players` SET playername = '" + player.getName() + "' WHERE UUID = '" + player.getUUID() + "';"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPlayers() {
|
||||
return new String[]{playerName};
|
||||
return new String[]{player.getName()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actor[] getActors() {
|
||||
return new Actor[]{player};
|
||||
}
|
||||
}
|
||||
|
||||
private class PlayerLeaveRow implements Row
|
||||
{
|
||||
private final String playerName;
|
||||
{;
|
||||
private final long leaveTime;
|
||||
private final Actor actor;
|
||||
|
||||
PlayerLeaveRow(Player player) {
|
||||
playerName = player.getName();
|
||||
leaveTime = System.currentTimeMillis() / 1000;
|
||||
actor = Actor.actorFromEntity(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getInserts() {
|
||||
return new String[]{"UPDATE `lb-players` SET onlinetime = onlinetime + TIMESTAMPDIFF(SECOND, lastlogin, FROM_UNIXTIME('" + leaveTime + "')) WHERE lastlogin > 0 && " + (playerIds.containsKey(playerName) ? "playerid = " + playerIds.get(playerName) : "playerName = '" + playerName + "'") + ";"};
|
||||
if (logPlayerInfo)
|
||||
return new String[]{"UPDATE `lb-players` SET onlinetime = onlinetime + TIMESTAMPDIFF(SECOND, lastlogin, FROM_UNIXTIME('" + leaveTime + "')), playername = '" + actor.getName() + "' WHERE lastlogin > 0 && UUID = '" + actor.getUUID() + "';"};
|
||||
return new String[]{"UPDATE `lb-players` SET playername = '" + actor.getName() + "' WHERE UUID = '" + actor.getUUID() + "';"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getPlayers() {
|
||||
return new String[]{playerName};
|
||||
return new String[]{actor.getName()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actor[] getActors() {
|
||||
return new Actor[]{actor};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,30 @@
|
||||
package de.diddiz.LogBlock;
|
||||
|
||||
import de.diddiz.LogBlock.config.Config;
|
||||
import de.diddiz.LogBlock.listeners.*;
|
||||
import de.diddiz.LogBlock.listeners.BanListener;
|
||||
import de.diddiz.LogBlock.listeners.BlockBreakLogging;
|
||||
import de.diddiz.LogBlock.listeners.BlockBurnLogging;
|
||||
import de.diddiz.LogBlock.listeners.BlockPlaceLogging;
|
||||
import de.diddiz.LogBlock.listeners.BlockSpreadLogging;
|
||||
import de.diddiz.LogBlock.listeners.ChatLogging;
|
||||
import de.diddiz.LogBlock.listeners.ChestAccessLogging;
|
||||
import de.diddiz.LogBlock.listeners.CreatureInteractLogging;
|
||||
import de.diddiz.LogBlock.listeners.EndermenLogging;
|
||||
import de.diddiz.LogBlock.listeners.ExplosionLogging;
|
||||
import de.diddiz.LogBlock.listeners.FluidFlowLogging;
|
||||
import de.diddiz.LogBlock.listeners.InteractLogging;
|
||||
import de.diddiz.LogBlock.listeners.KillLogging;
|
||||
import de.diddiz.LogBlock.listeners.LeavesDecayLogging;
|
||||
import de.diddiz.LogBlock.listeners.LockedChestDecayLogging;
|
||||
import de.diddiz.LogBlock.listeners.PlayerInfoLogging;
|
||||
import de.diddiz.LogBlock.listeners.SignChangeLogging;
|
||||
import de.diddiz.LogBlock.listeners.SnowFadeLogging;
|
||||
import de.diddiz.LogBlock.listeners.SnowFormLogging;
|
||||
import de.diddiz.LogBlock.listeners.StructureGrowLogging;
|
||||
import de.diddiz.LogBlock.listeners.ToolListener;
|
||||
import de.diddiz.LogBlock.listeners.WitherLogging;
|
||||
import de.diddiz.util.MySQLConnectionPool;
|
||||
import de.diddiz.worldedit.LogBlockEditSessionFactory;
|
||||
import de.diddiz.worldedit.WorldEditLoggingHook;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -24,6 +45,7 @@ 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
|
||||
@@ -65,6 +87,13 @@ public class LogBlock extends JavaPlugin
|
||||
noDb = true;
|
||||
return;
|
||||
}
|
||||
final Statement st = conn.createStatement();
|
||||
final ResultSet rs = st.executeQuery("SHOW CHARACTER SET where charset='utf8mb4';");
|
||||
if (rs.next()) {
|
||||
Config.mb4=true;
|
||||
// Allegedly JDBC driver since 2010 hasn't needed this. I did.
|
||||
st.executeQuery("SET NAMES utf8mb4;");
|
||||
}
|
||||
conn.close();
|
||||
if (updater.update())
|
||||
load(this);
|
||||
@@ -81,6 +110,7 @@ public class LogBlock extends JavaPlugin
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
materialName(0); // Force static code to run
|
||||
final PluginManager pm = getPluginManager();
|
||||
if (errorAtLoading) {
|
||||
pm.disablePlugin(this);
|
||||
@@ -89,27 +119,32 @@ public class LogBlock extends JavaPlugin
|
||||
if (noDb)
|
||||
return;
|
||||
if (pm.getPlugin("WorldEdit") != null) {
|
||||
LogBlockEditSessionFactory.initialize(this);
|
||||
if(Integer.parseInt(pm.getPlugin("WorldEdit").getDescription().getVersion().substring(0, 1)) > 5) {
|
||||
new WorldEditLoggingHook(this).hook();
|
||||
} else {
|
||||
getLogger().warning("Failed to hook into WorldEdit. Your WorldEdit version seems to be outdated, please make sure WorldEdit is at least version 6.");
|
||||
}
|
||||
}
|
||||
commandsHandler = new CommandsHandler(this);
|
||||
getCommand("lb").setExecutor(commandsHandler);
|
||||
if (enableAutoClearLog && autoClearLogDelay > 0)
|
||||
getServer().getScheduler().scheduleAsyncRepeatingTask(this, new AutoClearLog(this), 6000, autoClearLogDelay * 60 * 20);
|
||||
getServer().getScheduler().scheduleAsyncDelayedTask(this, new DumpedLogImporter(this));
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, new AutoClearLog(this), 6000, autoClearLogDelay * 60 * 20);
|
||||
getServer().getScheduler().runTaskAsynchronously(this, new DumpedLogImporter(this));
|
||||
registerEvents();
|
||||
if (useBukkitScheduler) {
|
||||
if (getServer().getScheduler().scheduleAsyncRepeatingTask(this, consumer, delayBetweenRuns * 20, delayBetweenRuns * 20) > 0)
|
||||
if (getServer().getScheduler().runTaskTimerAsynchronously(this, consumer, delayBetweenRuns < 20 ? 20 : delayBetweenRuns, delayBetweenRuns).getTaskId() > 0)
|
||||
getLogger().info("Scheduled consumer with bukkit scheduler.");
|
||||
else {
|
||||
getLogger().warning("Failed to schedule consumer with bukkit scheduler. Now trying schedule with timer.");
|
||||
timer = new Timer();
|
||||
timer.scheduleAtFixedRate(consumer, delayBetweenRuns * 1000, delayBetweenRuns * 1000);
|
||||
timer.schedule(consumer, delayBetweenRuns < 20 ? 1000 : delayBetweenRuns * 50, delayBetweenRuns * 50);
|
||||
}
|
||||
} else {
|
||||
timer = new Timer();
|
||||
timer.scheduleAtFixedRate(consumer, delayBetweenRuns * 1000, delayBetweenRuns * 1000);
|
||||
timer.schedule(consumer, delayBetweenRuns < 20 ? 1000 : delayBetweenRuns * 50, delayBetweenRuns * 50);
|
||||
getLogger().info("Scheduled consumer with timer.");
|
||||
}
|
||||
getServer().getScheduler().runTaskAsynchronously(this, new Updater.PlayerCountChecker(this));
|
||||
for (final Tool tool : toolsByType.values())
|
||||
if (pm.getPermission("logblock.tools." + tool.name) == null) {
|
||||
final Permission perm = new Permission("logblock.tools." + tool.name, tool.permissionDefault);
|
||||
@@ -126,6 +161,7 @@ public class LogBlock extends JavaPlugin
|
||||
private void registerEvents() {
|
||||
final PluginManager pm = getPluginManager();
|
||||
pm.registerEvents(new ToolListener(this), this);
|
||||
pm.registerEvents(new PlayerInfoLogging(this), this);
|
||||
if (askRollbackAfterBan)
|
||||
pm.registerEvents(new BanListener(this), this);
|
||||
if (isLogging(Logging.BLOCKPLACE))
|
||||
@@ -166,8 +202,8 @@ public class LogBlock extends JavaPlugin
|
||||
pm.registerEvents(new StructureGrowLogging(this), this);
|
||||
if (isLogging(Logging.GRASSGROWTH) || isLogging(Logging.MYCELIUMSPREAD) || isLogging(Logging.VINEGROWTH) || isLogging(Logging.MUSHROOMSPREAD))
|
||||
pm.registerEvents(new BlockSpreadLogging(this), this);
|
||||
if (logPlayerInfo)
|
||||
pm.registerEvents(new PlayerInfoLogging(this), this);
|
||||
if (isLogging(Logging.LOCKEDCHESTDECAY))
|
||||
pm.registerEvents(new LockedChestDecayLogging(this), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -179,9 +215,10 @@ public class LogBlock extends JavaPlugin
|
||||
if (logPlayerInfo && getServer().getOnlinePlayers() != null)
|
||||
for (final Player player : getServer().getOnlinePlayers())
|
||||
consumer.queueLeave(player);
|
||||
getLogger().info("Waiting for consumer ...");
|
||||
consumer.run();
|
||||
if (consumer.getQueueSize() > 0) {
|
||||
getLogger().info("Waiting for consumer ...");
|
||||
int tries = 10;
|
||||
int tries = 9;
|
||||
while (consumer.getQueueSize() > 0) {
|
||||
getLogger().info("Remaining queue size: " + consumer.getQueueSize());
|
||||
if (tries > 0)
|
||||
|
@@ -9,7 +9,7 @@ public enum Logging
|
||||
PRESUREPLATEINTERACT, TRIPWIREINTERACT, CREATURECROPTRAMPLE, CROPTRAMPLE,
|
||||
NATURALSTRUCTUREGROW, GRASSGROWTH, MYCELIUMSPREAD, VINEGROWTH, MUSHROOMSPREAD,
|
||||
WITHER(true), WITHER_SKULL(true), BONEMEALSTRUCTUREGROW,
|
||||
WORLDEDIT, TNTMINECARTEXPLOSION(true);
|
||||
WORLDEDIT, TNTMINECARTEXPLOSION(true), LOCKEDCHESTDECAY;
|
||||
|
||||
public static final int length = Logging.values().length;
|
||||
private final boolean defaultEnabled;
|
||||
|
77
src/main/java/de/diddiz/LogBlock/QueryParams.java
Executable file → Normal file
77
src/main/java/de/diddiz/LogBlock/QueryParams.java
Executable file → Normal file
@@ -20,11 +20,12 @@ 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
|
||||
{
|
||||
private static final Set<Integer> keywords = new HashSet<Integer>(Arrays.asList("player".hashCode(), "area".hashCode(), "selection".hashCode(), "sel".hashCode(), "block".hashCode(), "type".hashCode(), "sum".hashCode(), "destroyed".hashCode(), "created".hashCode(), "chestaccess".hashCode(), "all".hashCode(), "time".hashCode(), "since".hashCode(), "before".hashCode(), "limit".hashCode(), "world".hashCode(), "asc".hashCode(), "desc".hashCode(), "last".hashCode(), "coords".hashCode(), "silent".hashCode(), "chat".hashCode(), "search".hashCode(), "match".hashCode(), "loc".hashCode(), "location".hashCode(), "kills".hashCode(), "killer".hashCode(), "victim".hashCode()));
|
||||
private static final Set<Integer> keywords = new HashSet<Integer>(Arrays.asList("player".hashCode(), "area".hashCode(), "selection".hashCode(), "sel".hashCode(), "block".hashCode(), "type".hashCode(), "sum".hashCode(), "destroyed".hashCode(), "created".hashCode(), "chestaccess".hashCode(), "all".hashCode(), "time".hashCode(), "since".hashCode(), "before".hashCode(), "limit".hashCode(), "world".hashCode(), "asc".hashCode(), "desc".hashCode(), "last".hashCode(), "coords".hashCode(), "silent".hashCode(), "chat".hashCode(), "search".hashCode(), "match".hashCode(), "loc".hashCode(), "location".hashCode(), "kills".hashCode(), "killer".hashCode(), "victim".hashCode(), "both".hashCode()));
|
||||
public BlockChangeType bct = BlockChangeType.BOTH;
|
||||
public int limit = -1, before = 0, since = 0, radius = -1;
|
||||
public Location loc = null;
|
||||
@@ -32,7 +33,7 @@ public final class QueryParams implements Cloneable
|
||||
public List<String> players = new ArrayList<String>();
|
||||
public List<String> killers = new ArrayList<String>();
|
||||
public List<String> victims = new ArrayList<String>();
|
||||
public boolean excludePlayersMode = false, excludeKillersMode = false, excludeVictimsMode = false, prepareToolQuery = false, silent = false;
|
||||
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>();
|
||||
@@ -69,7 +70,7 @@ public final class QueryParams implements Cloneable
|
||||
if (needDate)
|
||||
select += "date, ";
|
||||
if (needPlayer)
|
||||
select += "playername, ";
|
||||
select += "playername, UUID,";
|
||||
if (needMessage)
|
||||
select += "message, ";
|
||||
select = select.substring(0, select.length() - 2);
|
||||
@@ -110,7 +111,7 @@ public final class QueryParams implements Cloneable
|
||||
|
||||
return select + " " + from + getWhere() + "ORDER BY date " + order + ", id " + order + " " + getLimit();
|
||||
} else if (sum == SummarizationMode.PLAYERS)
|
||||
return "SELECT playername, SUM(kills) AS kills, SUM(killed) AS killed FROM ((SELECT killer AS playerid, count(*) AS kills, 0 as killed FROM `" + getTable() + "-kills` INNER JOIN `lb-players` as killers ON (killer=killers.playerid) INNER JOIN `lb-players` as victims ON (victim=victims.playerid) " + getWhere(BlockChangeType.KILLS) + "GROUP BY killer) UNION (SELECT victim AS playerid, 0 as kills, count(*) AS killed FROM `" + getTable() + "-kills` INNER JOIN `lb-players` as killers ON (killer=killers.playerid) INNER JOIN `lb-players` as victims ON (victim=victims.playerid) " + getWhere(BlockChangeType.KILLS) + "GROUP BY victim)) AS t INNER JOIN `lb-players` USING (playerid) GROUP BY playerid ORDER BY SUM(kills) + SUM(killed) " + order + " " + getLimit();
|
||||
return "SELECT playername, UUID, SUM(kills) AS kills, SUM(killed) AS killed FROM ((SELECT killer AS playerid, count(*) AS kills, 0 as killed FROM `" + getTable() + "-kills` INNER JOIN `lb-players` as killers ON (killer=killers.playerid) INNER JOIN `lb-players` as victims ON (victim=victims.playerid) " + getWhere(BlockChangeType.KILLS) + "GROUP BY killer) UNION (SELECT victim AS playerid, 0 as kills, count(*) AS killed FROM `" + getTable() + "-kills` INNER JOIN `lb-players` as killers ON (killer=killers.playerid) INNER JOIN `lb-players` as victims ON (victim=victims.playerid) " + getWhere(BlockChangeType.KILLS) + "GROUP BY victim)) AS t INNER JOIN `lb-players` USING (playerid) GROUP BY playerid ORDER BY SUM(kills) + SUM(killed) " + order + " " + getLimit();
|
||||
}
|
||||
if (sum == SummarizationMode.NONE) {
|
||||
String select = "SELECT ";
|
||||
@@ -126,7 +127,7 @@ public final class QueryParams implements Cloneable
|
||||
if (needData)
|
||||
select += "data, ";
|
||||
if (needPlayer)
|
||||
select += "playername, ";
|
||||
select += "playername, UUID, ";
|
||||
if (needCoords)
|
||||
select += "x, y, z, ";
|
||||
if (needSignText)
|
||||
@@ -141,12 +142,17 @@ public final class QueryParams implements Cloneable
|
||||
if (needSignText)
|
||||
from += "LEFT JOIN `" + getTable() + "-sign` USING (id) ";
|
||||
if (needChestAccess)
|
||||
from += "LEFT JOIN `" + getTable() + "-chest` USING (id) ";
|
||||
// If BlockChangeType is CHESTACCESS, we can use more efficient query
|
||||
if (bct == BlockChangeType.CHESTACCESS) {
|
||||
from += "RIGHT JOIN `" + getTable() + "-chest` USING (id) ";
|
||||
} else {
|
||||
from += "LEFT JOIN `" + getTable() + "-chest` 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();
|
||||
else
|
||||
return "SELECT playername, 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() + "` " + 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();
|
||||
}
|
||||
|
||||
public String getTable() {
|
||||
@@ -163,6 +169,8 @@ public final class QueryParams implements Cloneable
|
||||
title.append("kills ");
|
||||
else {
|
||||
if (!types.isEmpty()) {
|
||||
if (excludeBlocksMode)
|
||||
title.append("all blocks except ");
|
||||
final String[] blocknames = new String[types.size()];
|
||||
for (int i = 0; i < types.size(); i++)
|
||||
blocknames[i] = materialName(types.get(i).getBlock());
|
||||
@@ -198,7 +206,7 @@ public final class QueryParams implements Cloneable
|
||||
title.append("more than ").append(before * -1).append(" minutes ago ");
|
||||
if (loc != null) {
|
||||
if (radius > 0)
|
||||
title.append("within ").append(radius).append(" blocks of ").append(prepareToolQuery ? "clicked block" : "you").append(" ");
|
||||
title.append("within ").append(radius).append(" blocks of ").append(prepareToolQuery ? "clicked block" : "location").append(" ");
|
||||
else if (radius == 0)
|
||||
title.append("at ").append(loc.getBlockX()).append(":").append(loc.getBlockY()).append(":").append(loc.getBlockZ()).append(" ");
|
||||
} else if (sel != null)
|
||||
@@ -299,6 +307,8 @@ public final class QueryParams implements Cloneable
|
||||
switch (blockChangeType) {
|
||||
case ALL:
|
||||
if (!types.isEmpty()) {
|
||||
if (excludeBlocksMode)
|
||||
where.append("NOT ");
|
||||
where.append('(');
|
||||
for (final Block block : types) {
|
||||
where.append("((type = ").append(block.getBlock()).append(" OR replaced = ").append(block.getBlock());
|
||||
@@ -315,6 +325,8 @@ public final class QueryParams implements Cloneable
|
||||
break;
|
||||
case BOTH:
|
||||
if (!types.isEmpty()) {
|
||||
if (excludeBlocksMode)
|
||||
where.append("NOT ");
|
||||
where.append('(');
|
||||
for (final Block block : types) {
|
||||
where.append("((type = ").append(block.getBlock()).append(" OR replaced = ").append(block.getBlock());
|
||||
@@ -332,6 +344,8 @@ public final class QueryParams implements Cloneable
|
||||
break;
|
||||
case CREATED:
|
||||
if (!types.isEmpty()) {
|
||||
if (excludeBlocksMode)
|
||||
where.append("NOT ");
|
||||
where.append('(');
|
||||
for (final Block block : types) {
|
||||
where.append("((type = ").append(block.getBlock());
|
||||
@@ -344,12 +358,13 @@ public final class QueryParams implements Cloneable
|
||||
}
|
||||
where.delete(where.length() - 4, where.length());
|
||||
where.append(") AND ");
|
||||
} else
|
||||
where.append("type != 0 AND ");
|
||||
where.append("type != replaced AND ");
|
||||
}
|
||||
where.append("type != 0 AND type != replaced AND ");
|
||||
break;
|
||||
case DESTROYED:
|
||||
if (!types.isEmpty()) {
|
||||
if (excludeBlocksMode)
|
||||
where.append("NOT ");
|
||||
where.append('(');
|
||||
for (final Block block : types) {
|
||||
where.append("((replaced = ").append(block.getBlock());
|
||||
@@ -362,13 +377,13 @@ public final class QueryParams implements Cloneable
|
||||
}
|
||||
where.delete(where.length() - 4, where.length());
|
||||
where.append(") AND ");
|
||||
} else
|
||||
where.append("replaced != 0 AND ");
|
||||
where.append("type != replaced AND ");
|
||||
}
|
||||
where.append("replaced != 0 AND type != replaced AND ");
|
||||
break;
|
||||
case CHESTACCESS:
|
||||
where.append("(type = 23 OR type = 54 OR type = 61 OR type = 62) AND type = replaced AND ");
|
||||
if (!types.isEmpty()) {
|
||||
if (excludeBlocksMode)
|
||||
where.append("NOT ");
|
||||
where.append('(');
|
||||
for (final Block block : types) {
|
||||
where.append("((itemtype = ").append(block.getBlock());
|
||||
@@ -488,6 +503,7 @@ public final class QueryParams implements Cloneable
|
||||
players.add(matches.size() == 1 ? matches.get(0).getName() : playerName.replaceAll("[^a-zA-Z0-9_]", ""));
|
||||
}
|
||||
}
|
||||
needPlayer = true;
|
||||
} else if (param.equals("killer")) {
|
||||
if (values.length < 1)
|
||||
throw new IllegalArgumentException("No or wrong count of arguments for '" + param + "'");
|
||||
@@ -504,6 +520,7 @@ public final class QueryParams implements Cloneable
|
||||
killers.add(matches.size() == 1 ? matches.get(0).getName() : killerName.replaceAll("[^a-zA-Z0-9_]", ""));
|
||||
}
|
||||
}
|
||||
needKiller = true;
|
||||
} else if (param.equals("victim")) {
|
||||
if (values.length < 1)
|
||||
throw new IllegalArgumentException("No or wrong count of arguments for '" + param + "'");
|
||||
@@ -520,6 +537,7 @@ public final class QueryParams implements Cloneable
|
||||
victims.add(matches.size() == 1 ? matches.get(0).getName() : victimName.replaceAll("[^a-zA-Z0-9_]", ""));
|
||||
}
|
||||
}
|
||||
needVictim = true;
|
||||
} else if (param.equals("weapon")) {
|
||||
if (values.length < 1)
|
||||
throw new IllegalArgumentException("No or wrong count of arguments for '" + param + "'");
|
||||
@@ -535,10 +553,15 @@ public final class QueryParams implements Cloneable
|
||||
throw new IllegalArgumentException("No material matching: '" + weaponName + "'");
|
||||
types.add(new Block(mat.getId(), -1));
|
||||
}
|
||||
needWeapon = true;
|
||||
} else if (param.equals("block") || param.equals("type")) {
|
||||
if (values.length < 1)
|
||||
throw new IllegalArgumentException("No or wrong count of arguments for '" + param + "'");
|
||||
for (final String blockName : values) {
|
||||
for (String blockName : values) {
|
||||
if (blockName.startsWith("!")) {
|
||||
excludeBlocksMode = true;
|
||||
blockName = blockName.substring(1);
|
||||
}
|
||||
if (blockName.contains(":")) {
|
||||
String[] blockNameSplit = blockName.split(":");
|
||||
if (blockNameSplit.length > 2)
|
||||
@@ -557,23 +580,21 @@ public final class QueryParams implements Cloneable
|
||||
types.add(new Block(mat.getId(), data));
|
||||
} else {
|
||||
final Material mat = Material.matchMaterial(blockName);
|
||||
if (mat == null)
|
||||
throw new IllegalArgumentException("No material matching: '" + blockName + "'");
|
||||
types.add(new Block(mat.getId(), -1));
|
||||
types.add(new Block(typeFromName(blockName), -1));
|
||||
}
|
||||
}
|
||||
} else if (param.equals("area")) {
|
||||
if (player == null && !prepareToolQuery)
|
||||
throw new IllegalArgumentException("You have to ba a player to use area");
|
||||
if (player == null && !prepareToolQuery && loc == null)
|
||||
throw new IllegalArgumentException("You have to be a player to use area, or specify a location first");
|
||||
if (values.length == 0) {
|
||||
radius = defaultDist;
|
||||
if (!prepareToolQuery)
|
||||
if (!prepareToolQuery && loc == null)
|
||||
loc = player.getLocation();
|
||||
} else {
|
||||
if (!isInt(values[0]))
|
||||
throw new IllegalArgumentException("Not a number: '" + values[0] + "'");
|
||||
radius = Integer.parseInt(values[0]);
|
||||
if (!prepareToolQuery)
|
||||
if (!prepareToolQuery && loc == null)
|
||||
loc = player.getLocation();
|
||||
}
|
||||
} else if (param.equals("selection") || param.equals("sel")) {
|
||||
@@ -608,6 +629,8 @@ public final class QueryParams implements Cloneable
|
||||
bct = BlockChangeType.CREATED;
|
||||
else if (param.equals("destroyed"))
|
||||
bct = BlockChangeType.DESTROYED;
|
||||
else if (param.equals("both"))
|
||||
bct = BlockChangeType.BOTH;
|
||||
else if (param.equals("chestaccess"))
|
||||
bct = BlockChangeType.CHESTACCESS;
|
||||
else if (param.equals("chat"))
|
||||
@@ -655,8 +678,12 @@ public final class QueryParams implements Cloneable
|
||||
throw new IllegalArgumentException("Not a valid argument: '" + param + "'");
|
||||
i += values.length;
|
||||
}
|
||||
if (bct == BlockChangeType.KILLS && !getWorldConfig(world).isLogging(Logging.KILL))
|
||||
throw new IllegalArgumentException("Kill logging not enabled for world '" + world.getName() + "'");
|
||||
if (bct == BlockChangeType.KILLS) {
|
||||
if (world == null)
|
||||
throw new IllegalArgumentException("No world specified");
|
||||
if (!getWorldConfig(world).isLogging(Logging.KILL))
|
||||
throw new IllegalArgumentException("Kill logging not enabled for world '" + world.getName() + "'");
|
||||
}
|
||||
if (types.size() > 0)
|
||||
for (final Set<Integer> equivalent : getBlockEquivalents()) {
|
||||
boolean found = false;
|
||||
|
@@ -12,11 +12,14 @@ public class SummedBlockChanges implements LookupCacheElement
|
||||
private final String group;
|
||||
private final int created, destroyed;
|
||||
private final float spaceFactor;
|
||||
private final Actor actor;
|
||||
|
||||
public SummedBlockChanges(ResultSet rs, QueryParams p, float spaceFactor) throws SQLException {
|
||||
group = p.sum == SummarizationMode.PLAYERS ? rs.getString(1) : materialName(rs.getInt(1));
|
||||
created = rs.getInt(2);
|
||||
destroyed = rs.getInt(3);
|
||||
// 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();
|
||||
created = rs.getInt("created");
|
||||
destroyed = rs.getInt("destroyed");
|
||||
this.spaceFactor = spaceFactor;
|
||||
}
|
||||
|
||||
|
12
src/main/java/de/diddiz/LogBlock/SummedKills.java
Executable file → Normal file
12
src/main/java/de/diddiz/LogBlock/SummedKills.java
Executable file → Normal file
@@ -1,22 +1,20 @@
|
||||
package de.diddiz.LogBlock;
|
||||
|
||||
import static de.diddiz.util.MaterialName.materialName;
|
||||
import static de.diddiz.util.Utils.spaces;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import org.bukkit.Location;
|
||||
import de.diddiz.LogBlock.QueryParams.SummarizationMode;
|
||||
|
||||
public class SummedKills implements LookupCacheElement
|
||||
{
|
||||
private final String playerName;
|
||||
private final Actor player;
|
||||
private final int kills, killed;
|
||||
private final float spaceFactor;
|
||||
|
||||
public SummedKills(ResultSet rs, QueryParams p, float spaceFactor) throws SQLException {
|
||||
playerName = rs.getString(1);
|
||||
kills = rs.getInt(2);
|
||||
killed = rs.getInt(3);
|
||||
player = new Actor(rs);
|
||||
kills = rs.getInt("kills");
|
||||
killed = rs.getInt("killed");
|
||||
this.spaceFactor = spaceFactor;
|
||||
}
|
||||
|
||||
@@ -27,6 +25,6 @@ public class SummedKills implements LookupCacheElement
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return kills + spaces((int)((6 - String.valueOf(kills).length()) / spaceFactor)) + killed + spaces((int)((7 - String.valueOf(killed).length()) / spaceFactor)) + playerName;
|
||||
return kills + spaces((int)((6 - String.valueOf(kills).length()) / spaceFactor)) + killed + spaces((int)((7 - String.valueOf(killed).length()) / spaceFactor)) + player.getName();
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,11 @@
|
||||
package de.diddiz.LogBlock;
|
||||
|
||||
import static de.diddiz.LogBlock.config.Config.getLoggedWorlds;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import static de.diddiz.util.BukkitUtils.friendlyWorldname;
|
||||
import static org.bukkit.Bukkit.getLogger;
|
||||
import de.diddiz.LogBlock.config.Config;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
@@ -12,14 +14,24 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.logging.Level;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static de.diddiz.LogBlock.config.Config.getLoggedWorlds;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import static de.diddiz.util.BukkitUtils.friendlyWorldname;
|
||||
import de.diddiz.util.UUIDFetcher;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
import static org.bukkit.Bukkit.getLogger;
|
||||
|
||||
class Updater
|
||||
{
|
||||
private final LogBlock logblock;
|
||||
final int UUID_CONVERT_BATCH_SIZE = 100;
|
||||
|
||||
Updater(LogBlock logblock) {
|
||||
this.logblock = logblock;
|
||||
@@ -166,7 +178,7 @@ class Updater
|
||||
final Statement st = conn.createStatement();
|
||||
for (final WorldConfig wcfg : getLoggedWorlds())
|
||||
if (wcfg.isLogging(Logging.KILL))
|
||||
st.execute("ALTER TABLE `" + wcfg.table + "-kills` ADD (x SMALLINT NOT NULL DEFAULT 0, y TINYINT UNSIGNED NOT NULL DEFAULT 0, z SMALLINT NOT NULL DEFAULT 0)");
|
||||
st.execute("ALTER TABLE `" + wcfg.table + "-kills` ADD (x MEDIUMINT NOT NULL DEFAULT 0, y SMALLINT NOT NULL DEFAULT 0, z MEDIUMINT NOT NULL DEFAULT 0)");
|
||||
st.close();
|
||||
conn.close();
|
||||
} catch (final SQLException ex) {
|
||||
@@ -197,6 +209,176 @@ class Updater
|
||||
}
|
||||
config.set("version", "1.52");
|
||||
}
|
||||
if (config.getString("version").compareTo("1.81") < 0) {
|
||||
getLogger().info("Updating tables to 1.81 ...");
|
||||
final Connection conn = logblock.getConnection();
|
||||
try {
|
||||
conn.setAutoCommit(true);
|
||||
final Statement st = conn.createStatement();
|
||||
for (final WorldConfig wcfg : getLoggedWorlds()) {
|
||||
if (wcfg.isLogging(Logging.CHESTACCESS)) {
|
||||
st.execute("ALTER TABLE `"+wcfg.table+"-chest` CHANGE itemdata itemdata SMALLINT NOT NULL");
|
||||
getLogger().info("Table "+wcfg.table+"-chest modified");
|
||||
}
|
||||
}
|
||||
st.close();
|
||||
conn.close();
|
||||
} catch (final SQLException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
|
||||
return false;
|
||||
}
|
||||
config.set("version", "1.81");
|
||||
}
|
||||
|
||||
if (config.getString("version").compareTo("1.90") < 0) {
|
||||
getLogger().info("Updating tables to 1.9 ...");
|
||||
getLogger().info("Importing UUIDs for large databases may take some time");
|
||||
final Connection conn = logblock.getConnection();
|
||||
try {
|
||||
conn.setAutoCommit(true);
|
||||
final Statement st = conn.createStatement();
|
||||
st.execute("ALTER TABLE `lb-players` ADD `UUID` VARCHAR(36) NOT NULL");
|
||||
} catch (final SQLException ex) {
|
||||
// Error 1060 is MySQL error "column already exists". We want to continue with import if we get that error
|
||||
if (ex.getErrorCode() != 1060) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
String unimportedPrefix="noimport_";
|
||||
ResultSet rs;
|
||||
conn.setAutoCommit(true);
|
||||
final Statement st = conn.createStatement();
|
||||
if (config.getBoolean("logging.logPlayerInfo")) {
|
||||
// Start by assuming anything with no onlinetime is not a player
|
||||
st.execute("UPDATE `lb-players` SET UUID = CONCAT ('log_',playername) WHERE onlinetime=0 AND LENGTH(UUID) = 0");
|
||||
} else {
|
||||
// If we can't assume that, we must assume anything we can't look up is not a player
|
||||
unimportedPrefix = "log_";
|
||||
}
|
||||
// Tell people how many are needing converted
|
||||
rs = st.executeQuery("SELECT COUNT(playername) FROM `lb-players` WHERE LENGTH(UUID)=0");
|
||||
rs.next();
|
||||
String total = Integer.toString(rs.getInt(1));
|
||||
getLogger().info(total + " players to convert");
|
||||
int done = 0;
|
||||
|
||||
conn.setAutoCommit(false);
|
||||
Map <String,Integer> players = new HashMap<String,Integer>();
|
||||
List <String> names = new ArrayList<String>(UUID_CONVERT_BATCH_SIZE);
|
||||
Map <String,UUID> response;
|
||||
rs = st.executeQuery("SELECT playerid,playername FROM `lb-players` WHERE LENGTH(UUID)=0 LIMIT " + Integer.toString(UUID_CONVERT_BATCH_SIZE));
|
||||
while (rs.next()) {
|
||||
do {
|
||||
players.put(rs.getString(2),rs.getInt(1));
|
||||
names.add(rs.getString(2));
|
||||
} while (rs.next());
|
||||
if (names.size()>0) {
|
||||
String theUUID;
|
||||
response = UUIDFetcher.getUUIDs(names);
|
||||
for (Map.Entry<String,Integer> entry : players.entrySet()) {
|
||||
if (response.get(entry.getKey()) == null) {
|
||||
theUUID = unimportedPrefix + entry.getKey();
|
||||
getLogger().warning(entry.getKey() + " not found - giving UUID of " + theUUID);
|
||||
} else {
|
||||
theUUID = response.get(entry.getKey()).toString();
|
||||
}
|
||||
String thePID = entry.getValue().toString();
|
||||
st.execute("UPDATE `lb-players` SET UUID = '" + theUUID + "' WHERE playerid = " + thePID);
|
||||
done++;
|
||||
}
|
||||
conn.commit();
|
||||
players.clear();
|
||||
names.clear();
|
||||
getLogger().info("Processed " + Integer.toString(done) + " out of " + total);
|
||||
rs = st.executeQuery("SELECT playerid,playername FROM `lb-players` WHERE LENGTH(UUID)=0 LIMIT " + Integer.toString(UUID_CONVERT_BATCH_SIZE));
|
||||
}
|
||||
}
|
||||
st.close();
|
||||
conn.close();
|
||||
|
||||
} catch (final SQLException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
|
||||
return false;
|
||||
} catch (Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "[UUID importer]", ex);
|
||||
return false;
|
||||
}
|
||||
config.set("version", "1.90");
|
||||
}
|
||||
// Ensure charset for free-text fields is UTF-8, or UTF8-mb4 if possible
|
||||
// As this may be an expensive operation and the database default may already be this, check on a table-by-table basis before converting
|
||||
if (config.getString("version").compareTo("1.92") < 0) {
|
||||
getLogger().info("Updating tables to 1.92 ...");
|
||||
String charset = "utf8";
|
||||
if ( Config.mb4) charset="utf8mb4";
|
||||
final Connection conn = logblock.getConnection();
|
||||
try {
|
||||
conn.setAutoCommit(true);
|
||||
final Statement st = conn.createStatement();
|
||||
if (isLogging(Logging.CHAT)) {
|
||||
final ResultSet rs = st.executeQuery("SHOW FULL COLUMNS FROM `lb-chat` WHERE field = 'message'");
|
||||
if (rs.next() && !rs.getString("Collation").substring(0,4).equalsIgnoreCase(charset)) {
|
||||
st.execute("ALTER TABLE `lb-chat` CONVERT TO CHARSET " + charset);
|
||||
getLogger().info("Table lb-chat modified");
|
||||
} else {
|
||||
getLogger().info("Table lb-chat already fine, skipping it");
|
||||
}
|
||||
}
|
||||
for (final WorldConfig wcfg : getLoggedWorlds()) {
|
||||
if (wcfg.isLogging(Logging.SIGNTEXT)) {
|
||||
final ResultSet rs = st.executeQuery("SHOW FULL COLUMNS FROM `"+wcfg.table+"-sign` WHERE field = 'signtext'");
|
||||
if (rs.next() && !rs.getString("Collation").substring(0,4).equalsIgnoreCase(charset)) {
|
||||
st.execute("ALTER TABLE `"+wcfg.table+"-sign` CONVERT TO CHARSET " + charset);
|
||||
getLogger().info("Table "+wcfg.table+"-sign modified");
|
||||
} else {
|
||||
getLogger().info("Table "+wcfg.table+"-sign already fine, skipping it");
|
||||
}
|
||||
}
|
||||
}
|
||||
st.close();
|
||||
conn.close();
|
||||
} catch (final SQLException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
|
||||
return false;
|
||||
}
|
||||
config.set("version", "1.92");
|
||||
}
|
||||
if (config.getString("version").compareTo("1.93") < 0) {
|
||||
getLogger().info("Updating tables to 1.93 ...");
|
||||
final Connection conn = logblock.getConnection();
|
||||
try {
|
||||
conn.setAutoCommit(true);
|
||||
final Statement st = conn.createStatement();
|
||||
// Need to wrap both these next two inside individual try/catch statements in case index does not exist
|
||||
try {
|
||||
st.execute("DROP INDEX UUID ON `lb-players`");
|
||||
} catch (final SQLException ex) {
|
||||
if (ex.getErrorCode() != 1091) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
st.execute("DROP INDEX playername ON `lb-players`");
|
||||
} catch (final SQLException ex) {
|
||||
if (ex.getErrorCode() != 1091) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
st.execute("CREATE INDEX UUID ON `lb-players` (UUID);");
|
||||
st.execute("CREATE INDEX playername ON `lb-players` (playername);");
|
||||
st.close();
|
||||
conn.close();
|
||||
} catch (final SQLException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
|
||||
return false;
|
||||
}
|
||||
config.set("version", "1.93");
|
||||
}
|
||||
|
||||
logblock.saveConfig();
|
||||
return true;
|
||||
}
|
||||
@@ -208,15 +390,19 @@ class Updater
|
||||
final Statement state = conn.createStatement();
|
||||
final DatabaseMetaData dbm = conn.getMetaData();
|
||||
conn.setAutoCommit(true);
|
||||
createTable(dbm, state, "lb-players", "(playerid SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, playername varchar(32) NOT NULL, firstlogin DATETIME NOT NULL, lastlogin DATETIME NOT NULL, onlinetime INT UNSIGNED NOT NULL, ip varchar(255) NOT NULL, PRIMARY KEY (playerid), UNIQUE (playername))");
|
||||
createTable(dbm, state, "lb-players", "(playerid INT UNSIGNED NOT NULL AUTO_INCREMENT, UUID varchar(36) NOT NULL, playername varchar(32) NOT NULL, firstlogin DATETIME NOT NULL, lastlogin DATETIME NOT NULL, onlinetime INT UNSIGNED NOT NULL, ip varchar(255) NOT NULL, PRIMARY KEY (playerid), INDEX (UUID))");
|
||||
// Players table must not be empty or inserts won't work - bug #492
|
||||
final ResultSet rs = state.executeQuery("SELECT NULL FROM `lb-players` LIMIT 1;");
|
||||
if (!rs.next())
|
||||
state.execute("INSERT IGNORE INTO `lb-players` (UUID,playername) VALUES ('log_dummy_record','dummy_record')");
|
||||
if (isLogging(Logging.CHAT))
|
||||
createTable(dbm, state, "lb-chat", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid SMALLINT UNSIGNED NOT NULL, message VARCHAR(255) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid), FULLTEXT message (message)) ENGINE=MyISAM");
|
||||
createTable(dbm, state, "lb-chat", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid INT UNSIGNED NOT NULL, message VARCHAR(255) NOT NULL, PRIMARY KEY (id), KEY playerid (playerid), FULLTEXT message (message)) ENGINE=MyISAM DEFAULT CHARSET utf8");
|
||||
for (final WorldConfig wcfg : getLoggedWorlds()) {
|
||||
createTable(dbm, state, wcfg.table, "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, playerid SMALLINT UNSIGNED NOT NULL, replaced TINYINT UNSIGNED NOT NULL, type TINYINT UNSIGNED NOT NULL, data TINYINT UNSIGNED NOT NULL, x 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))");
|
||||
createTable(dbm, state, wcfg.table + "-chest", "(id INT UNSIGNED NOT NULL, itemtype SMALLINT UNSIGNED NOT NULL, itemamount SMALLINT NOT NULL, itemdata TINYINT UNSIGNED NOT NULL, PRIMARY KEY (id))");
|
||||
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 + "-sign", "(id INT UNSIGNED NOT NULL, signtext VARCHAR(255) NOT NULL, PRIMARY KEY (id)) DEFAULT CHARSET utf8");
|
||||
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))");
|
||||
if (wcfg.isLogging(Logging.KILL))
|
||||
createTable(dbm, state, wcfg.table + "-kills", "(id INT UNSIGNED NOT NULL AUTO_INCREMENT, date DATETIME NOT NULL, killer SMALLINT UNSIGNED, victim SMALLINT UNSIGNED NOT NULL, weapon SMALLINT UNSIGNED NOT NULL, x SMALLINT NOT NULL, y TINYINT UNSIGNED NOT NULL, z SMALLINT NOT NULL, PRIMARY KEY (id))");
|
||||
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))");
|
||||
}
|
||||
state.close();
|
||||
conn.close();
|
||||
@@ -230,4 +416,32 @@ class Updater
|
||||
throw new SQLException("Table " + table + " not found and failed to create");
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlayerCountChecker implements Runnable {
|
||||
|
||||
private LogBlock logblock;
|
||||
|
||||
public PlayerCountChecker(LogBlock logblock) {
|
||||
this.logblock = logblock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final Connection conn = logblock.getConnection();
|
||||
try {
|
||||
conn.setAutoCommit(true);
|
||||
final Statement st = conn.createStatement();
|
||||
ResultSet rs = st.executeQuery("SELECT auto_increment FROM information_schema.columns AS col join information_schema.tables AS tab ON (col.table_schema=tab.table_schema AND col.table_name=tab.table_name) WHERE col.table_name = 'lb-players' AND col.column_name = 'playerid' AND col.data_type = 'smallint' AND col.table_schema = DATABASE() AND auto_increment > 65000;");
|
||||
if (rs.next()) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
logblock.getLogger().warning("Your server reached 65000 players. You should soon update your database table schema - see FAQ: https://github.com/LogBlock/LogBlock/wiki/FAQ#logblock-your-server-reached-65000-players-");
|
||||
}
|
||||
}
|
||||
st.close();
|
||||
conn.close();
|
||||
} catch (final SQLException ex) {
|
||||
logblock.getLogger().log(Level.SEVERE, "[Updater] Error: ", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ import org.bukkit.block.Sign;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.material.Bed;
|
||||
import org.bukkit.material.PistonBaseMaterial;
|
||||
import org.bukkit.material.PistonExtensionMaterial;
|
||||
@@ -26,6 +27,7 @@ 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.equalTypes;
|
||||
import static de.diddiz.util.BukkitUtils.getContainerBlocks;
|
||||
import static de.diddiz.util.BukkitUtils.modifyContainer;
|
||||
import static de.diddiz.util.MaterialName.materialName;
|
||||
import static org.bukkit.Bukkit.getLogger;
|
||||
@@ -71,7 +73,7 @@ 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, byte itemData) {
|
||||
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)));
|
||||
}
|
||||
|
||||
@@ -145,8 +147,8 @@ public class WorldEditor implements Runnable
|
||||
|
||||
private class Edit extends BlockChange
|
||||
{
|
||||
public Edit(long time, Location loc, String playerName, int replaced, int type, byte data, String signtext, ChestAccess ca) {
|
||||
super(time, loc, playerName, replaced, type, data, signtext, ca);
|
||||
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);
|
||||
}
|
||||
|
||||
PerformResult perform() throws WorldEditorException {
|
||||
@@ -162,21 +164,24 @@ public class WorldEditor implements Runnable
|
||||
if (type == 0) {
|
||||
if (!block.setTypeId(0))
|
||||
throw new WorldEditorException(block.getTypeId(), 0, block.getLocation());
|
||||
} else if (ca != null && (type == 23 || type == 54 || type == 61 || type == 62)) {
|
||||
int leftover;
|
||||
try {
|
||||
leftover = modifyContainer(state, new ItemStack(ca.itemType, -ca.itemAmount, (short)0, ca.itemData));
|
||||
if (leftover > 0)
|
||||
for (final BlockFace face : new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST})
|
||||
if (block.getRelative(face).getTypeId() == 54)
|
||||
leftover = modifyContainer(block.getRelative(face).getState(), new ItemStack(ca.itemType, ca.itemAmount < 0 ? leftover : -leftover, (short)0, ca.itemData));
|
||||
} catch (final Exception ex) {
|
||||
throw new WorldEditorException(ex.getMessage(), block.getLocation());
|
||||
} else if (ca != null) {
|
||||
if (getContainerBlocks().contains(Material.getMaterial(type))) {
|
||||
int leftover;
|
||||
try {
|
||||
leftover = modifyContainer(state, new ItemStack(ca.itemType, -ca.itemAmount, ca.itemData));
|
||||
// Special-case blocks which might be double chests
|
||||
if (leftover > 0 && (type == 54 || type == 146))
|
||||
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));
|
||||
} catch (final Exception ex) {
|
||||
throw new WorldEditorException(ex.getMessage(), block.getLocation());
|
||||
}
|
||||
if (!state.update())
|
||||
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 (!state.update())
|
||||
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());
|
||||
} else
|
||||
return PerformResult.NO_ACTION;
|
||||
return PerformResult.SUCCESS;
|
||||
|
@@ -46,6 +46,9 @@ public class Config
|
||||
public static Set<String> ignoredChat;
|
||||
public static SimpleDateFormat formatter;
|
||||
public static boolean safetyIdCheck;
|
||||
public static boolean logEnvironmentalKills;
|
||||
// Not loaded from config - checked at runtime
|
||||
public static boolean mb4 = false;
|
||||
|
||||
public static enum LogKillsLevel
|
||||
{
|
||||
@@ -82,6 +85,7 @@ public class Config
|
||||
def.put("clearlog.autoClearLogDelay", "6h");
|
||||
def.put("logging.logCreeperExplosionsAsPlayerWhoTriggeredThese", false);
|
||||
def.put("logging.logKillsLevel", "PLAYERS");
|
||||
def.put("logging.logEnvironmentalKills", false);
|
||||
def.put("logging.logPlayerInfo", false);
|
||||
def.put("logging.hiddenPlayers", new ArrayList<String>());
|
||||
def.put("logging.hiddenBlocks", Arrays.asList(0));
|
||||
@@ -129,7 +133,7 @@ public class Config
|
||||
if (!config.contains(e.getKey()))
|
||||
config.set(e.getKey(), e.getValue());
|
||||
logblock.saveConfig();
|
||||
url = "jdbc:mysql://" + config.getString("mysql.host") + ":" + config.getInt("mysql.port") + "/" + getStringIncludingInts(config, "mysql.database") + "?useUnicode=true&characterEncoding=utf-8";
|
||||
url = "jdbc:mysql://" + config.getString("mysql.host") + ":" + config.getInt("mysql.port") + "/" + getStringIncludingInts(config, "mysql.database") + "?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true";
|
||||
user = getStringIncludingInts(config, "mysql.user");
|
||||
password = getStringIncludingInts(config, "mysql.password");
|
||||
delayBetweenRuns = config.getInt("consumer.delayBetweenRuns", 2);
|
||||
@@ -147,8 +151,9 @@ public class Config
|
||||
try {
|
||||
logKillsLevel = LogKillsLevel.valueOf(config.getString("logging.logKillsLevel").toUpperCase());
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
throw new DataFormatException("lookup.toolblockID doesn't appear to be a valid log level. Allowed are 'PLAYERS', 'MONSTERS' and 'ANIMALS'");
|
||||
throw new DataFormatException("logging.logKillsLevel doesn't appear to be a valid log level. Allowed are 'PLAYERS', 'MONSTERS' and 'ANIMALS'");
|
||||
}
|
||||
logEnvironmentalKills = config.getBoolean("logging.logEnvironmentalKills", false);
|
||||
hiddenPlayers = new HashSet<String>();
|
||||
for (final String playerName : config.getStringList("logging.hiddenPlayers"))
|
||||
hiddenPlayers.add(playerName.toLowerCase().trim());
|
||||
|
@@ -14,7 +14,9 @@ public class WorldConfig extends LoggingEnabledMapping
|
||||
|
||||
public WorldConfig(File file) throws IOException {
|
||||
final Map<String, Object> def = new HashMap<String, Object>();
|
||||
def.put("table", "lb-" + file.getName().substring(0, file.getName().length() - 4).replace(' ', '_'));
|
||||
// "Before MySQL 5.1.6, database and table names cannot contain "/", "\", ".", or characters that are not permitted in file names" - MySQL manual
|
||||
// They _can_ contain spaces, but replace them as well
|
||||
def.put("table", "lb-" + file.getName().substring(0, file.getName().length() - 4).replaceAll("[ ./\\\\]", "_"));
|
||||
for (final Logging l : Logging.values())
|
||||
def.put("logging." + l.toString(), l.isDefaultEnabled());
|
||||
final YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
package de.diddiz.LogBlock.events;
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.ChestAccess;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
@@ -13,7 +14,7 @@ public class BlockChangePreLogEvent extends PreLogEvent {
|
||||
private String signText;
|
||||
private ChestAccess chestAccess;
|
||||
|
||||
public BlockChangePreLogEvent(String owner, Location location, int typeBefore, int typeAfter, byte data,
|
||||
public BlockChangePreLogEvent(Actor owner, Location location, int typeBefore, int typeAfter, byte data,
|
||||
String signText, ChestAccess chestAccess) {
|
||||
|
||||
super(owner);
|
||||
|
@@ -1,24 +1,36 @@
|
||||
package de.diddiz.LogBlock.events;
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
public abstract class PreLogEvent extends Event implements Cancellable {
|
||||
|
||||
protected boolean cancelled = false;
|
||||
protected String owner;
|
||||
protected Actor owner;
|
||||
|
||||
public PreLogEvent(String owner) {
|
||||
public PreLogEvent(Actor owner) {
|
||||
|
||||
this.owner = owner.replaceAll("[^a-zA-Z0-9_]", "");
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player/monster/cause involved in this event
|
||||
*
|
||||
* @return Player/monster/cause who is involved in this event
|
||||
* @deprecated {@link #getOwnerActor() } returns an object encapsulating
|
||||
* name and uuid. Names are not guaranteed to be unique.
|
||||
*/
|
||||
public String getOwner() {
|
||||
|
||||
return owner.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player/monster/cause involved in this event
|
||||
*
|
||||
* @return Player/monster/cause who is involved in this event
|
||||
*/
|
||||
public Actor getOwnerActor() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@@ -27,9 +39,9 @@ public abstract class PreLogEvent extends Event implements Cancellable {
|
||||
*
|
||||
* @param owner The player/monster/cause who is involved in this event
|
||||
*/
|
||||
public void setOwner(String owner) {
|
||||
public void setOwner(Actor owner) {
|
||||
|
||||
this.owner = owner.replaceAll("[^a-zA-Z0-9_]", "");
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import static de.diddiz.util.LoggingUtil.smartLogBlockBreak;
|
||||
@@ -29,33 +30,33 @@ public class BlockBreakLogging extends LoggingListener
|
||||
WorldConfig wcfg = getWorldConfig(event.getBlock().getWorld());
|
||||
if (wcfg == null) return;
|
||||
|
||||
final String playerName = event.getPlayer().getName();
|
||||
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)) {
|
||||
consumer.queueSignBreak(playerName, (Sign) origin.getState());
|
||||
consumer.queueSignBreak(actor, (Sign) origin.getState());
|
||||
} else if (wcfg.isLogging(Logging.CHESTACCESS) && BukkitUtils.getContainerBlocks().contains(type)) {
|
||||
consumer.queueContainerBreak(playerName, origin.getState());
|
||||
consumer.queueContainerBreak(actor, origin.getState());
|
||||
} else if (type == Material.ICE) {
|
||||
// When in creative mode ice doesn't form water
|
||||
if (event.getPlayer().getGameMode().equals(GameMode.CREATIVE)) {
|
||||
consumer.queueBlockBreak(playerName, origin.getState());
|
||||
consumer.queueBlockBreak(actor, origin.getState());
|
||||
} else {
|
||||
consumer.queueBlockReplace(playerName, origin.getState(), 9, (byte) 0);
|
||||
consumer.queueBlockReplace(actor, origin.getState(), 9, (byte) 0);
|
||||
}
|
||||
} else {
|
||||
smartLogBlockBreak(consumer, playerName, origin);
|
||||
smartLogBlockBreak(consumer, actor, origin);
|
||||
}
|
||||
smartLogFallables(consumer, playerName, origin);
|
||||
smartLogFallables(consumer, actor, origin);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerBucketFill(PlayerBucketFillEvent event) {
|
||||
if (isLogging(event.getBlockClicked().getWorld(), Logging.BLOCKBREAK)) {
|
||||
consumer.queueBlockBreak(event.getPlayer().getName(), event.getBlockClicked().getState());
|
||||
consumer.queueBlockBreak(Actor.actorFromEntity(event.getPlayer()), event.getBlockClicked().getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,9 +3,18 @@ package de.diddiz.LogBlock.listeners;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import static de.diddiz.util.LoggingUtil.smartLogBlockBreak;
|
||||
import static de.diddiz.util.LoggingUtil.smartLogFallables;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
|
||||
@@ -18,8 +27,21 @@ public class BlockBurnLogging extends LoggingListener
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onBlockBurn(BlockBurnEvent event) {
|
||||
if (isLogging(event.getBlock().getWorld(), Logging.FIRE)) {
|
||||
smartLogBlockBreak(consumer, "Fire", event.getBlock());
|
||||
smartLogFallables(consumer, "Fire", event.getBlock());
|
||||
smartLogBlockBreak(consumer, new Actor("Fire"), event.getBlock());
|
||||
smartLogFallables(consumer, new Actor("Fire"), event.getBlock());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onExtinguish(PlayerInteractEvent event) {
|
||||
if(event.getAction().equals(Action.LEFT_CLICK_BLOCK)){
|
||||
Player player = event.getPlayer();
|
||||
Block block = event.getClickedBlock().getRelative(event.getBlockFace());
|
||||
if (block.getType().equals(Material.FIRE) && isLogging(player.getWorld(), Logging.FIRE)) {
|
||||
Actor actor = Actor.actorFromEntity(player);
|
||||
smartLogBlockBreak(consumer, actor, block);
|
||||
smartLogFallables(consumer, actor, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
|
||||
@@ -29,14 +30,14 @@ public class BlockPlaceLogging extends LoggingListener
|
||||
final Material type = event.getBlock().getType();
|
||||
final BlockState before = event.getBlockReplacedState();
|
||||
final BlockState after = event.getBlockPlaced().getState();
|
||||
final String playerName = event.getPlayer().getName();
|
||||
final Actor actor = Actor.actorFromEntity(event.getPlayer());
|
||||
|
||||
//Handle falling blocks
|
||||
if (BukkitUtils.getRelativeTopFallables().contains(type)) {
|
||||
|
||||
// Catch placed blocks overwriting something
|
||||
if (before.getType() != Material.AIR) {
|
||||
consumer.queueBlockBreak(playerName, before);
|
||||
consumer.queueBlockBreak(actor, before);
|
||||
}
|
||||
|
||||
Location loc = event.getBlock().getLocation();
|
||||
@@ -55,9 +56,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(playerName, finalLoc, type.getId(), event.getBlock().getData());
|
||||
consumer.queueBlockPlace(actor, finalLoc, type.getId(), event.getBlock().getData());
|
||||
} else {
|
||||
consumer.queueBlockReplace(playerName, finalLoc, finalLoc.getBlock().getTypeId(), finalLoc.getBlock().getData(), type.getId(), event.getBlock().getData());
|
||||
consumer.queueBlockReplace(actor, finalLoc, finalLoc.getBlock().getTypeId(), finalLoc.getBlock().getData(), type.getId(), event.getBlock().getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,9 +74,9 @@ public class BlockPlaceLogging extends LoggingListener
|
||||
@Override
|
||||
public void run() {
|
||||
if (before.getTypeId() == 0)
|
||||
consumer.queueBlockPlace(playerName, after);
|
||||
consumer.queueBlockPlace(actor, after);
|
||||
else
|
||||
consumer.queueBlockReplace(playerName, before, after);
|
||||
consumer.queueBlockReplace(actor, before, after);
|
||||
}
|
||||
}, 1L);
|
||||
}
|
||||
@@ -84,6 +85,6 @@ 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(event.getPlayer().getName(), 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(), event.getBucket() == Material.WATER_BUCKET ? 9 : 11, (byte)0);
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,15 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockSpreadEvent;
|
||||
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
|
||||
public class BlockSpreadLogging extends LoggingListener
|
||||
{
|
||||
|
||||
@@ -47,6 +47,6 @@ public class BlockSpreadLogging extends LoggingListener
|
||||
return;
|
||||
}
|
||||
|
||||
consumer.queueBlockReplace(name, event.getBlock().getState(), event.getNewState());
|
||||
consumer.queueBlockReplace(new Actor(name), event.getBlock().getState(), event.getNewState());
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.server.ServerCommandEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
|
||||
public class ChatLogging extends LoggingListener
|
||||
{
|
||||
@@ -18,17 +19,17 @@ public class ChatLogging extends LoggingListener
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
if (isLogging(event.getPlayer().getWorld(), Logging.CHAT))
|
||||
consumer.queueChat(event.getPlayer().getName(), event.getMessage());
|
||||
consumer.queueChat(Actor.actorFromEntity(event.getPlayer()), event.getMessage());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
if (isLogging(event.getPlayer().getWorld(), Logging.CHAT))
|
||||
consumer.queueChat(event.getPlayer().getName(), event.getMessage());
|
||||
consumer.queueChat(Actor.actorFromEntity(event.getPlayer()), event.getMessage());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onServerCommand(ServerCommandEvent event) {
|
||||
consumer.queueChat("Console", "/" + event.getCommand());
|
||||
consumer.queueChat(new Actor("Console"), "/" + event.getCommand());
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import static de.diddiz.util.BukkitUtils.compareInventories;
|
||||
import static de.diddiz.util.BukkitUtils.compressInventory;
|
||||
@@ -43,7 +44,7 @@ public class ChestAccessLogging extends LoggingListener
|
||||
final ItemStack[] diff = compareInventories(before, after);
|
||||
final Location loc = getInventoryHolderLocation(holder);
|
||||
for (final ItemStack item : diff) {
|
||||
consumer.queueChestAccess(player.getName(), loc, loc.getWorld().getBlockTypeIdAt(loc), (short)item.getTypeId(), (short)item.getAmount(), rawData(item));
|
||||
consumer.queueChestAccess(Actor.actorFromEntity(player), loc, loc.getWorld().getBlockTypeIdAt(loc), (short)item.getTypeId(), (short)item.getAmount(), rawData(item));
|
||||
}
|
||||
containers.remove(player);
|
||||
}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
import de.diddiz.util.BukkitUtils;
|
||||
import org.bukkit.Location;
|
||||
@@ -14,8 +16,6 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityInteractEvent;
|
||||
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
|
||||
public class CreatureInteractLogging extends LoggingListener
|
||||
{
|
||||
public CreatureInteractLogging(LogBlock lb) {
|
||||
@@ -42,11 +42,11 @@ public class CreatureInteractLogging extends LoggingListener
|
||||
case SOIL:
|
||||
if (wcfg.isLogging(Logging.CREATURECROPTRAMPLE)) {
|
||||
// 3 = Dirt ID
|
||||
consumer.queueBlock(entityType.getName(), loc, typeId, 3, blockData);
|
||||
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("CreatureTrample", trampledCrop.getState());
|
||||
consumer.queueBlockBreak(new Actor("CreatureTrample"), trampledCrop.getState());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@@ -1,12 +1,13 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import org.bukkit.entity.Enderman;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
|
||||
public class EndermenLogging extends LoggingListener
|
||||
{
|
||||
@@ -17,6 +18,6 @@ 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("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.getTo().getId(), (byte)0); // Figure out how to get the data of the placed block;
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,10 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
import static de.diddiz.LogBlock.config.Config.logCreeperExplosionsAsPlayerWhoTriggeredThese;
|
||||
import static de.diddiz.util.BukkitUtils.getContainerBlocks;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.Creeper;
|
||||
@@ -10,17 +12,20 @@ import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Fireball;
|
||||
import org.bukkit.entity.Ghast;
|
||||
import org.bukkit.entity.minecart.ExplosiveMinecart;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.Wither;
|
||||
import org.bukkit.entity.WitherSkull;
|
||||
import org.bukkit.entity.minecart.ExplosiveMinecart;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
import static de.diddiz.LogBlock.config.Config.logCreeperExplosionsAsPlayerWhoTriggeredThese;
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
|
||||
public class ExplosionLogging extends LoggingListener
|
||||
{
|
||||
@@ -32,7 +37,7 @@ public class ExplosionLogging extends LoggingListener
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
final WorldConfig wcfg = getWorldConfig(event.getLocation().getWorld());
|
||||
if (wcfg != null) {
|
||||
String name = "Explosion";
|
||||
Actor actor = new Actor("Explosion");
|
||||
Entity source = event.getEntity();
|
||||
if (source == null) {
|
||||
if (!wcfg.isLogging(Logging.MISCEXPLOSION))
|
||||
@@ -40,22 +45,22 @@ public class ExplosionLogging extends LoggingListener
|
||||
} else if (source instanceof TNTPrimed) {
|
||||
if (!wcfg.isLogging(Logging.TNTEXPLOSION))
|
||||
return;
|
||||
name = "TNT";
|
||||
actor = new Actor("TNT");
|
||||
} else if (source instanceof ExplosiveMinecart) {
|
||||
if (!wcfg.isLogging(Logging.TNTMINECARTEXPLOSION))
|
||||
return;
|
||||
name = "TNTMinecart";
|
||||
actor = new Actor("TNTMinecart");
|
||||
} else if (source instanceof Creeper) {
|
||||
if (!wcfg.isLogging(Logging.CREEPEREXPLOSION))
|
||||
return;
|
||||
if (logCreeperExplosionsAsPlayerWhoTriggeredThese) {
|
||||
final Entity target = ((Creeper) source).getTarget();
|
||||
name = target instanceof Player ? ((Player)target).getName() : "Creeper";
|
||||
actor = target instanceof Player ? Actor.actorFromEntity(target) : new Actor("Creeper");
|
||||
} else
|
||||
name = "Creeper";
|
||||
new Actor("Creeper");
|
||||
} else if (source instanceof Fireball) {
|
||||
Fireball fireball = (Fireball) source;
|
||||
Entity shooter = fireball.getShooter();
|
||||
ProjectileSource shooter = fireball.getShooter();
|
||||
if (shooter == null) {
|
||||
return;
|
||||
}
|
||||
@@ -63,25 +68,25 @@ public class ExplosionLogging extends LoggingListener
|
||||
if (!wcfg.isLogging(Logging.GHASTFIREBALLEXPLOSION)) {
|
||||
return;
|
||||
}
|
||||
name = "Ghast";
|
||||
actor = Actor.actorFromProjectileSource(shooter);
|
||||
} else if (shooter instanceof Wither) {
|
||||
if (!wcfg.isLogging(Logging.WITHER)) {
|
||||
return;
|
||||
}
|
||||
name = "Wither";
|
||||
actor = Actor.actorFromProjectileSource(shooter);
|
||||
}
|
||||
} else if (source instanceof EnderDragon) {
|
||||
if (!wcfg.isLogging(Logging.ENDERDRAGON))
|
||||
return;
|
||||
name = "EnderDragon";
|
||||
actor = Actor.actorFromEntity(source);
|
||||
} else if (source instanceof Wither) {
|
||||
if(!wcfg.isLogging(Logging.WITHER))
|
||||
return;
|
||||
name = "Wither";
|
||||
actor = Actor.actorFromEntity(source);
|
||||
} else if (source instanceof WitherSkull) {
|
||||
if(!wcfg.isLogging(Logging.WITHER_SKULL))
|
||||
return;
|
||||
name = "WitherSkull";
|
||||
actor = Actor.actorFromEntity(source);
|
||||
} else {
|
||||
if (!wcfg.isLogging(Logging.MISCEXPLOSION))
|
||||
return;
|
||||
@@ -89,11 +94,11 @@ 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))
|
||||
consumer.queueSignBreak(name, (Sign)block.getState());
|
||||
else if (wcfg.isLogging(Logging.CHESTACCESS) && (type == 23 || type == 54 || type == 61))
|
||||
consumer.queueContainerBreak(name, block.getState());
|
||||
consumer.queueSignBreak(actor, (Sign)block.getState());
|
||||
else if (wcfg.isLogging(Logging.CHESTACCESS) && (getContainerBlocks().contains(Material.getMaterial(type))))
|
||||
consumer.queueContainerBreak(actor, block.getState());
|
||||
else
|
||||
consumer.queueBlockBreak(name, block.getState());
|
||||
consumer.queueBlockBreak(actor, block.getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,10 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -9,9 +13,6 @@ import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
|
||||
public class FluidFlowLogging extends LoggingListener
|
||||
{
|
||||
@@ -32,37 +33,37 @@ public class FluidFlowLogging extends LoggingListener
|
||||
if (typeFrom == 10 || typeFrom == 11) {
|
||||
if (canFlow && wcfg.isLogging(Logging.LAVAFLOW)) {
|
||||
if (isSurroundedByWater(to) && event.getBlock().getData() <= 2)
|
||||
consumer.queueBlockReplace("LavaFlow", to.getState(), 4, (byte)0);
|
||||
consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 4, (byte)0);
|
||||
else if (typeTo == 0) {
|
||||
consumer.queueBlockPlace("LavaFlow", to.getLocation(), 10, (byte)(event.getBlock().getData() + 1));
|
||||
consumer.queueBlockPlace(new Actor("LavaFlow"), to.getLocation(), 10, (byte)(event.getBlock().getData() + 1));
|
||||
} else {
|
||||
consumer.queueBlockReplace("LavaFlow", to.getState(), 10, (byte)(event.getBlock().getData() + 1));
|
||||
consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 10, (byte)(event.getBlock().getData() + 1));
|
||||
}
|
||||
} else if (typeTo == 8 || typeTo == 9) {
|
||||
if (event.getFace() == BlockFace.DOWN) {
|
||||
consumer.queueBlockReplace("LavaFlow", to.getState(), 1, (byte)0);
|
||||
consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 1, (byte)0);
|
||||
} else {
|
||||
consumer.queueBlockReplace("LavaFlow", to.getState(), 4, (byte)0);
|
||||
consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 4, (byte)0);
|
||||
}
|
||||
}
|
||||
} else if ((typeFrom == 8 || typeFrom == 9) && wcfg.isLogging(Logging.WATERFLOW)) {
|
||||
if (typeTo == 0) {
|
||||
consumer.queueBlockPlace("WaterFlow", to.getLocation(), 8, (byte)(event.getBlock().getData() + 1));
|
||||
consumer.queueBlockPlace(new Actor("WaterFlow"), to.getLocation(), 8, (byte)(event.getBlock().getData() + 1));
|
||||
} else if (nonFluidProofBlocks.contains(typeTo)) {
|
||||
consumer.queueBlockReplace("WaterFlow", to.getState(), 8, (byte)(event.getBlock().getData() + 1));
|
||||
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("WaterFlow", to.getState(), 49, (byte)0);
|
||||
consumer.queueBlockReplace(new Actor("WaterFlow"), to.getState(), 49, (byte)0);
|
||||
} else if (event.getFace() == BlockFace.DOWN) {
|
||||
consumer.queueBlockReplace("LavaFlow", to.getState(), 1, (byte)0);
|
||||
consumer.queueBlockReplace(new Actor("LavaFlow"), to.getState(), 1, (byte)0);
|
||||
}
|
||||
}
|
||||
if (typeTo == 0 || nonFluidProofBlocks.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("WaterFlow", lower.getState(), lower.getData() == 0 ? 49 : 4, (byte)0);
|
||||
consumer.queueBlockReplace(new Actor("WaterFlow"), lower.getState(), lower.getData() == 0 ? 49 : 4, (byte)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
|
||||
import de.diddiz.util.BukkitUtils;
|
||||
@@ -15,6 +16,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class InteractLogging extends LoggingListener
|
||||
{
|
||||
@@ -27,6 +29,7 @@ public class InteractLogging extends LoggingListener
|
||||
final WorldConfig wcfg = getWorldConfig(event.getPlayer().getWorld());
|
||||
if (wcfg != null) {
|
||||
final Block clicked = event.getClickedBlock();
|
||||
if (clicked == null) return;
|
||||
final Material type = clicked.getType();
|
||||
final int typeId = type.getId();
|
||||
final byte blockData = clicked.getData();
|
||||
@@ -38,31 +41,31 @@ public class InteractLogging extends LoggingListener
|
||||
case WOOD_BUTTON:
|
||||
case STONE_BUTTON:
|
||||
if (wcfg.isLogging(Logging.SWITCHINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
consumer.queueBlock(player.getName(), loc, typeId, typeId, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData);
|
||||
break;
|
||||
case FENCE_GATE:
|
||||
case WOODEN_DOOR:
|
||||
case TRAP_DOOR:
|
||||
if (wcfg.isLogging(Logging.DOORINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
consumer.queueBlock(player.getName(), loc, typeId, typeId, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData);
|
||||
break;
|
||||
case CAKE_BLOCK:
|
||||
if (wcfg.isLogging(Logging.CAKEEAT) && event.getAction() == Action.RIGHT_CLICK_BLOCK && player.getFoodLevel() < 20)
|
||||
consumer.queueBlock(player.getName(), loc, typeId, typeId, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData);
|
||||
break;
|
||||
case NOTE_BLOCK:
|
||||
if (wcfg.isLogging(Logging.NOTEBLOCKINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
consumer.queueBlock(player.getName(), loc, typeId, typeId, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData);
|
||||
break;
|
||||
case DIODE_BLOCK_OFF:
|
||||
case DIODE_BLOCK_ON:
|
||||
if (wcfg.isLogging(Logging.DIODEINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
consumer.queueBlock(player.getName(), loc, typeId, typeId, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData);
|
||||
break;
|
||||
case REDSTONE_COMPARATOR_OFF:
|
||||
case REDSTONE_COMPARATOR_ON:
|
||||
if (wcfg.isLogging(Logging.COMPARATORINTERACT) && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
consumer.queueBlock(player.getName(), loc, typeId, typeId, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData);
|
||||
}
|
||||
break;
|
||||
case WOOD_PLATE:
|
||||
@@ -70,22 +73,22 @@ public class InteractLogging extends LoggingListener
|
||||
case IRON_PLATE:
|
||||
case GOLD_PLATE:
|
||||
if (wcfg.isLogging(Logging.PRESUREPLATEINTERACT) && event.getAction() == Action.PHYSICAL) {
|
||||
consumer.queueBlock(player.getName(), loc, typeId, typeId, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData);
|
||||
}
|
||||
break;
|
||||
case TRIPWIRE:
|
||||
if (wcfg.isLogging(Logging.TRIPWIREINTERACT) && event.getAction() == Action.PHYSICAL) {
|
||||
consumer.queueBlock(player.getName(), loc, typeId, typeId, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), loc, typeId, typeId, blockData);
|
||||
}
|
||||
break;
|
||||
case SOIL:
|
||||
if (wcfg.isLogging(Logging.CROPTRAMPLE) && event.getAction() == Action.PHYSICAL) {
|
||||
// 3 = Dirt ID
|
||||
consumer.queueBlock(player.getName(), loc, typeId, 3, blockData);
|
||||
consumer.queueBlock(Actor.actorFromEntity(player), 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(player.getName(), trampledCrop.getState());
|
||||
consumer.queueBlockBreak(Actor.actorFromEntity(player), trampledCrop.getState());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@@ -1,9 +1,12 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.Config.LogKillsLevel;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import static de.diddiz.LogBlock.config.Config.logEnvironmentalKills;
|
||||
import static de.diddiz.LogBlock.config.Config.logKillsLevel;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Monster;
|
||||
@@ -12,35 +15,36 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.Config.LogKillsLevel;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
|
||||
|
||||
public class KillLogging extends LoggingListener
|
||||
{
|
||||
private final Map<Integer, Integer> lastAttackedEntity = new HashMap<Integer, Integer>();
|
||||
private final Map<Integer, Long> lastAttackTime = new HashMap<Integer, Long>();
|
||||
|
||||
public KillLogging(LogBlock lb) {
|
||||
super(lb);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onEntityDamage(EntityDamageEvent event) {
|
||||
if (isLogging(event.getEntity().getWorld(), Logging.KILL) && event instanceof EntityDamageByEntityEvent && event.getEntity() instanceof LivingEntity) {
|
||||
public void onEntityDeath(EntityDeathEvent deathEvent) {
|
||||
EntityDamageEvent event = deathEvent.getEntity().getLastDamageCause();
|
||||
// For a death event, there should always be a damage event and it should not be cancelled. Check anyway.
|
||||
if (event!= null && event.isCancelled() == false && isLogging(event.getEntity().getWorld(), Logging.KILL) && event.getEntity() instanceof LivingEntity) {
|
||||
final LivingEntity victim = (LivingEntity)event.getEntity();
|
||||
final Entity killer = ((EntityDamageByEntityEvent)event).getDamager();
|
||||
if (victim.getHealth() - event.getDamage() > 0 || victim.getHealth() <= 0)
|
||||
return;
|
||||
if (logKillsLevel == LogKillsLevel.PLAYERS && !(victim instanceof Player && killer instanceof Player))
|
||||
return;
|
||||
else if (logKillsLevel == LogKillsLevel.MONSTERS && !((victim instanceof Player || victim instanceof Monster) && killer instanceof Player || killer instanceof Monster))
|
||||
return;
|
||||
if (lastAttackedEntity.containsKey(killer.getEntityId()) && lastAttackedEntity.get(killer.getEntityId()) == victim.getEntityId() && System.currentTimeMillis() - lastAttackTime.get(killer.getEntityId()) < 5000)
|
||||
return;
|
||||
consumer.queueKill(killer, victim);
|
||||
lastAttackedEntity.put(killer.getEntityId(), victim.getEntityId());
|
||||
lastAttackTime.put(killer.getEntityId(), System.currentTimeMillis());
|
||||
if (event instanceof EntityDamageByEntityEvent) {
|
||||
final Entity killer = ((EntityDamageByEntityEvent)event).getDamager();
|
||||
if (logKillsLevel == LogKillsLevel.PLAYERS && !(victim instanceof Player && killer instanceof Player))
|
||||
return;
|
||||
else if (logKillsLevel == LogKillsLevel.MONSTERS && !((victim instanceof Player || victim instanceof Monster) && killer instanceof Player || killer instanceof Monster))
|
||||
return;
|
||||
consumer.queueKill(killer, victim);
|
||||
} else if (logEnvironmentalKills) {
|
||||
if (logKillsLevel == LogKillsLevel.PLAYERS && !(victim instanceof Player))
|
||||
return;
|
||||
else if (logKillsLevel == LogKillsLevel.MONSTERS && !((victim instanceof Player || victim instanceof Monster)))
|
||||
return;
|
||||
consumer.queueKill(new Actor(event.getCause().toString()),victim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import static de.diddiz.util.LoggingUtil.smartLogBlockBreak;
|
||||
import static de.diddiz.util.LoggingUtil.smartLogFallables;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.LeavesDecayEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
|
||||
public class LeavesDecayLogging extends LoggingListener
|
||||
{
|
||||
@@ -18,8 +19,8 @@ public class LeavesDecayLogging extends LoggingListener
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onLeavesDecay(LeavesDecayEvent event) {
|
||||
if (isLogging(event.getBlock().getWorld(), Logging.LEAVESDECAY)) {
|
||||
smartLogBlockBreak(consumer, "LeavesDecay", event.getBlock());
|
||||
smartLogFallables(consumer, "LeavesDecay", event.getBlock());
|
||||
smartLogBlockBreak(consumer, new Actor("LeavesDecay"), event.getBlock());
|
||||
smartLogFallables(consumer, new Actor("LeavesDecay"), event.getBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,25 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockFadeEvent;
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +1,13 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
|
||||
public class SignChangeLogging extends LoggingListener
|
||||
{
|
||||
@@ -16,6 +18,6 @@ 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(event.getPlayer().getName(), event.getBlock().getLocation(), event.getBlock().getTypeId(), event.getBlock().getData(), event.getLines());
|
||||
consumer.queueSignPlace(Actor.actorFromEntity(event.getPlayer()), event.getBlock().getLocation(), event.getBlock().getTypeId(), event.getBlock().getData(), event.getLines());
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,12 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockFadeEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
|
||||
public class SnowFadeLogging extends LoggingListener
|
||||
{
|
||||
@@ -18,7 +19,7 @@ public class SnowFadeLogging extends LoggingListener
|
||||
if (isLogging(event.getBlock().getWorld(), Logging.SNOWFADE)) {
|
||||
final int type = event.getBlock().getTypeId();
|
||||
if (type == 78 || type == 79)
|
||||
consumer.queueBlockReplace("SnowFade", event.getBlock().getState(), event.getNewState());
|
||||
consumer.queueBlockReplace(new Actor("SnowFade"), event.getBlock().getState(), event.getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +1,13 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.isLogging;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockFormEvent;
|
||||
import org.bukkit.event.block.LeavesDecayEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
|
||||
public class SnowFormLogging extends LoggingListener
|
||||
{
|
||||
@@ -14,18 +15,18 @@ public class SnowFormLogging extends LoggingListener
|
||||
super(lb);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onLeavesDecay(LeavesDecayEvent event) {
|
||||
if (isLogging(event.getBlock().getWorld(), Logging.SNOWFORM))
|
||||
consumer.queueBlockBreak("LeavesDecay", event.getBlock().getState());
|
||||
}
|
||||
// @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
// public void onLeavesDecay(LeavesDecayEvent event) {
|
||||
// if (isLogging(event.getBlock().getWorld(), Logging.SNOWFORM))
|
||||
// consumer.queueBlockBreak("LeavesDecay", event.getBlock().getState());
|
||||
// }
|
||||
|
||||
@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)
|
||||
consumer.queueBlockReplace("SnowForm", event.getBlock().getState(), event.getNewState());
|
||||
consumer.queueBlockReplace(new Actor("SnowForm"), event.getBlock().getState(), event.getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
|
||||
public class StructureGrowLogging extends LoggingListener
|
||||
{
|
||||
@@ -19,18 +20,18 @@ public class StructureGrowLogging extends LoggingListener
|
||||
public void onStructureGrow(StructureGrowEvent event) {
|
||||
final WorldConfig wcfg = getWorldConfig(event.getWorld());
|
||||
if (wcfg != null) {
|
||||
final String playerName;
|
||||
final Actor actor;
|
||||
if (event.getPlayer() != null) {
|
||||
if (!wcfg.isLogging(Logging.BONEMEALSTRUCTUREGROW))
|
||||
return;
|
||||
playerName = event.getPlayer().getName();
|
||||
actor = Actor.actorFromEntity(event.getPlayer());
|
||||
} else {
|
||||
if (!wcfg.isLogging(Logging.NATURALSTRUCTUREGROW))
|
||||
return;
|
||||
playerName = "NaturalGrow";
|
||||
actor = new Actor("NaturalGrow");
|
||||
}
|
||||
for (final BlockState state : event.getBlocks())
|
||||
consumer.queueBlockReplace(playerName, state.getBlock().getState(), state);
|
||||
consumer.queueBlockReplace(actor, state.getBlock().getState(), state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -60,19 +60,19 @@ public class ToolListener implements Listener
|
||||
params.sel = null;
|
||||
if (behavior == ToolBehavior.BLOCK)
|
||||
params.setLocation(block.getRelative(event.getBlockFace()).getLocation());
|
||||
else if (block.getTypeId() != 54 || tool.params.radius != 0)
|
||||
else if ((block.getTypeId() != 54 && block.getTypeId() != 146) || 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() == 54) {
|
||||
if (block.getRelative(face).getTypeId() == block.getTypeId()) {
|
||||
params.setSelection(RegionContainer.fromCorners(event.getPlayer().getWorld(),
|
||||
block.getLocation(), block.getRelative(face).getLocation()));
|
||||
}
|
||||
}
|
||||
if (params.sel == null) {
|
||||
params.setLocation(block.getLocation());
|
||||
}
|
||||
}
|
||||
if (params.sel == null) {
|
||||
params.setLocation(block.getLocation());
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.diddiz.LogBlock.listeners;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import org.bukkit.entity.Wither;
|
||||
@@ -18,6 +19,6 @@ 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("Wither", event.getBlock().getState(), event.getTo().getId(), event.getData()); // Wither walked through a block.
|
||||
consumer.queueBlockReplace(Actor.actorFromEntity(event.getEntity()), event.getBlock().getState(), event.getTo().getId(), event.getData()); // Wither walked through a block.
|
||||
}
|
||||
}
|
||||
|
@@ -6,8 +6,11 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
@@ -18,6 +21,7 @@ import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.DoubleChest;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
@@ -35,6 +39,8 @@ public class BukkitUtils
|
||||
private static final Set<Material> cropBlocks;
|
||||
private static final Set<Material> containerBlocks;
|
||||
|
||||
private static final Map<EntityType,Integer> projectileItems;
|
||||
|
||||
static {
|
||||
blockEquivalents = new HashSet<Set<Integer>>(7);
|
||||
blockEquivalents.add(new HashSet<Integer>(Arrays.asList(2, 3, 60)));
|
||||
@@ -60,7 +66,7 @@ public class BukkitUtils
|
||||
relativeBreakable.add(Material.COCOA);
|
||||
|
||||
// Blocks that break when they are on top of a block
|
||||
relativeTopBreakable = new HashSet<Material>(32);
|
||||
relativeTopBreakable = new HashSet<Material>(33);
|
||||
relativeTopBreakable.add(Material.SAPLING);
|
||||
relativeTopBreakable.add(Material.LONG_GRASS);
|
||||
relativeTopBreakable.add(Material.DEAD_BUSH);
|
||||
@@ -91,8 +97,9 @@ public class BukkitUtils
|
||||
relativeTopBreakable.add(Material.REDSTONE_COMPARATOR_ON);
|
||||
relativeTopBreakable.add(Material.REDSTONE_COMPARATOR_OFF);
|
||||
relativeTopBreakable.add(Material.WOODEN_DOOR);
|
||||
relativeTopBreakable.add(Material.IRON_DOOR);
|
||||
relativeTopBreakable.add(Material.IRON_DOOR_BLOCK);
|
||||
relativeTopBreakable.add(Material.CARPET);
|
||||
relativeTopBreakable.add(Material.DOUBLE_PLANT);
|
||||
|
||||
// Blocks that fall
|
||||
relativeTopFallables = new HashSet<Material>(4);
|
||||
@@ -152,8 +159,25 @@ public class BukkitUtils
|
||||
containerBlocks.add(Material.DROPPER);
|
||||
containerBlocks.add(Material.HOPPER);
|
||||
containerBlocks.add(Material.BREWING_STAND);
|
||||
containerBlocks.add(Material.FURNACE);
|
||||
containerBlocks.add(Material.BURNING_FURNACE);
|
||||
containerBlocks.add(Material.BEACON);
|
||||
// Doesn't actually have a block inventory
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
private static final BlockFace[] relativeBlockFaces = new BlockFace[] {
|
||||
@@ -177,6 +201,19 @@ 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 int getInventoryHolderType(InventoryHolder holder) {
|
||||
if (holder instanceof DoubleChest) {
|
||||
return ((DoubleChest)holder).getLocation().getBlock().getTypeId();
|
||||
@@ -240,7 +277,7 @@ public class BukkitUtils
|
||||
for (final ItemStack item : items)
|
||||
if (item != null) {
|
||||
final int type = item.getTypeId();
|
||||
final byte data = rawData(item);
|
||||
final short data = rawData(item);
|
||||
boolean found = false;
|
||||
for (final ItemStack item2 : compressed)
|
||||
if (type == item2.getTypeId() && data == rawData(item2)) {
|
||||
@@ -249,7 +286,7 @@ public class BukkitUtils
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
compressed.add(new ItemStack(type, item.getAmount(), (short)0, data));
|
||||
compressed.add(new ItemStack(type, item.getAmount(), data));
|
||||
}
|
||||
Collections.sort(compressed, new ItemStackComparator());
|
||||
return compressed.toArray(new ItemStack[compressed.size()]);
|
||||
@@ -320,8 +357,8 @@ public class BukkitUtils
|
||||
}
|
||||
}
|
||||
|
||||
public static byte rawData(ItemStack item) {
|
||||
return item.getType() != null ? item.getData() != null ? item.getData().getData() : 0 : 0;
|
||||
public static short rawData(ItemStack item) {
|
||||
return item.getType() != null ? item.getData() != null ? item.getDurability() : 0 : 0;
|
||||
}
|
||||
|
||||
public static int saveSpawnHeight(Location loc) {
|
||||
@@ -379,7 +416,7 @@ public class BukkitUtils
|
||||
return -1;
|
||||
if (aType > bType)
|
||||
return 1;
|
||||
final byte aData = rawData(a), bData = rawData(b);
|
||||
final short aData = rawData(a), bData = rawData(b);
|
||||
if (aData < bData)
|
||||
return -1;
|
||||
if (aData > bData)
|
||||
@@ -387,4 +424,9 @@ public class BukkitUtils
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int itemIDfromProjectileEntity(Entity e) {
|
||||
Integer i = projectileItems.get(e.getType());
|
||||
return (i == null) ? 0 : i;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,11 @@
|
||||
package de.diddiz.util;
|
||||
|
||||
import de.diddiz.LogBlock.Actor;
|
||||
import de.diddiz.LogBlock.Consumer;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import static de.diddiz.LogBlock.config.Config.getWorldConfig;
|
||||
import static de.diddiz.LogBlock.config.Config.mb4;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -17,13 +22,10 @@ import org.bukkit.material.RedstoneTorch;
|
||||
import org.bukkit.material.Torch;
|
||||
import org.bukkit.material.TrapDoor;
|
||||
import org.bukkit.material.TripwireHook;
|
||||
import de.diddiz.LogBlock.Consumer;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.WorldConfig;
|
||||
|
||||
public class LoggingUtil {
|
||||
|
||||
public static void smartLogFallables(Consumer consumer, String playerName, Block origin) {
|
||||
public static void smartLogFallables(Consumer consumer, Actor actor, Block origin) {
|
||||
|
||||
WorldConfig wcfg = getWorldConfig(origin.getWorld());
|
||||
if (wcfg == null) return;
|
||||
@@ -35,7 +37,7 @@ public class LoggingUtil {
|
||||
while (BukkitUtils.getRelativeTopFallables().contains(checkBlock.getType())) {
|
||||
|
||||
// Record this block as falling
|
||||
consumer.queueBlockBreak(playerName, checkBlock.getState());
|
||||
consumer.queueBlockBreak(actor, checkBlock.getState());
|
||||
|
||||
// Guess where the block is going (This could be thrown of by explosions, but it is better than nothing)
|
||||
Location loc = origin.getLocation();
|
||||
@@ -52,9 +54,9 @@ public class LoggingUtil {
|
||||
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(playerName, finalLoc, checkBlock.getTypeId(), checkBlock.getData());
|
||||
consumer.queueBlockPlace(actor, finalLoc, checkBlock.getTypeId(), checkBlock.getData());
|
||||
} else {
|
||||
consumer.queueBlockReplace(playerName, finalLoc, finalLoc.getBlock().getTypeId(), finalLoc.getBlock().getData(), checkBlock.getTypeId(), checkBlock.getData());
|
||||
consumer.queueBlockReplace(actor, finalLoc, finalLoc.getBlock().getTypeId(), finalLoc.getBlock().getData(), checkBlock.getTypeId(), checkBlock.getData());
|
||||
}
|
||||
up++;
|
||||
}
|
||||
@@ -64,7 +66,7 @@ public class LoggingUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void smartLogBlockBreak(Consumer consumer, String playerName, Block origin) {
|
||||
public static void smartLogBlockBreak(Consumer consumer, Actor actor, Block origin) {
|
||||
|
||||
WorldConfig wcfg = getWorldConfig(origin.getWorld());
|
||||
if (wcfg == null) return;
|
||||
@@ -72,21 +74,33 @@ 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) {
|
||||
consumer.queueSignBreak(playerName, (Sign) checkBlock.getState());
|
||||
} else if (checkBlock.getType() == Material.IRON_DOOR || checkBlock.getType() == Material.WOOD_DOOR) {
|
||||
consumer.queueSignBreak(actor, (Sign) checkBlock.getState());
|
||||
} else if (checkBlock.getType() == Material.IRON_DOOR_BLOCK || checkBlock.getType() == Material.WOODEN_DOOR) {
|
||||
Block doorBlock = checkBlock;
|
||||
// If the doorBlock is the top half a door the player simply punched a door
|
||||
// this will be handled later.
|
||||
if (doorBlock.getData() != 8 && doorBlock.getData() != 9) {
|
||||
if (!BukkitUtils.isTop(doorBlock.getType(), doorBlock.getData())) {
|
||||
doorBlock = doorBlock.getRelative(BlockFace.UP);
|
||||
// Fall back check just in case the top half wasn't a door
|
||||
if (doorBlock.getType() == Material.IRON_DOOR || doorBlock.getType() == Material.WOOD_DOOR) {
|
||||
consumer.queueBlockBreak(playerName, doorBlock.getState());
|
||||
if (doorBlock.getType() == Material.IRON_DOOR_BLOCK || doorBlock.getType() == Material.WOODEN_DOOR) {
|
||||
consumer.queueBlockBreak(actor, doorBlock.getState());
|
||||
}
|
||||
consumer.queueBlockBreak(playerName, checkBlock.getState());
|
||||
consumer.queueBlockBreak(actor, checkBlock.getState());
|
||||
}
|
||||
} else if (checkBlock.getType() == Material.DOUBLE_PLANT) {
|
||||
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())) {
|
||||
plantBlock = plantBlock.getRelative(BlockFace.UP);
|
||||
// Fall back check just in case the top half wasn't a plant
|
||||
if (plantBlock.getType() == Material.DOUBLE_PLANT) {
|
||||
consumer.queueBlockBreak(actor, plantBlock.getState());
|
||||
}
|
||||
consumer.queueBlockBreak(actor, checkBlock.getState());
|
||||
}
|
||||
} else {
|
||||
consumer.queueBlockBreak(playerName, checkBlock.getState());
|
||||
consumer.queueBlockBreak(actor, checkBlock.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,78 +114,97 @@ public class LoggingUtil {
|
||||
case REDSTONE_TORCH_ON:
|
||||
case REDSTONE_TORCH_OFF:
|
||||
if (blockState.getBlock().getRelative(((RedstoneTorch) data).getAttachedFace()).equals(origin)) {
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
consumer.queueBlockBreak(actor, blockState);
|
||||
}
|
||||
break;
|
||||
case TORCH:
|
||||
if (blockState.getBlock().getRelative(((Torch) data).getAttachedFace()).equals(origin)) {
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
consumer.queueBlockBreak(actor, blockState);
|
||||
}
|
||||
break;
|
||||
case COCOA:
|
||||
if (blockState.getBlock().getRelative(((CocoaPlant) data).getAttachedFace()).equals(origin)) {
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
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(playerName, blockState);
|
||||
consumer.queueBlockBreak(actor, blockState);
|
||||
}
|
||||
break;
|
||||
case LEVER:
|
||||
if (blockState.getBlock().getRelative(((Lever) data).getAttachedFace()).equals(origin)) {
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
consumer.queueBlockBreak(actor, blockState);
|
||||
}
|
||||
break;
|
||||
case TRIPWIRE_HOOK:
|
||||
if (blockState.getBlock().getRelative(((TripwireHook) data).getAttachedFace()).equals(origin)) {
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
consumer.queueBlockBreak(actor, blockState);
|
||||
}
|
||||
break;
|
||||
case WOOD_BUTTON:
|
||||
case STONE_BUTTON:
|
||||
if (blockState.getBlock().getRelative(((Button) data).getAttachedFace()).equals(origin)) {
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
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(playerName, (Sign) blockState);
|
||||
consumer.queueSignBreak(actor, (Sign) blockState);
|
||||
} else {
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
consumer.queueBlockBreak(actor, blockState);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TRAP_DOOR:
|
||||
if (blockState.getBlock().getRelative(((TrapDoor) data).getAttachedFace()).equals(origin)) {
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
consumer.queueBlockBreak(actor, blockState);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
consumer.queueBlockBreak(playerName, blockState);
|
||||
consumer.queueBlockBreak(actor, blockState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Special door check
|
||||
if (origin.getType() == Material.IRON_DOOR || origin.getType() == Material.WOOD_DOOR) {
|
||||
if (origin.getType() == Material.IRON_DOOR_BLOCK || origin.getType() == Material.WOODEN_DOOR) {
|
||||
Block doorBlock = origin;
|
||||
|
||||
// Up or down?
|
||||
if (origin.getData() != 8 && origin.getData() != 9) {
|
||||
if (!BukkitUtils.isTop(doorBlock.getType(), doorBlock.getData())) {
|
||||
doorBlock = doorBlock.getRelative(BlockFace.UP);
|
||||
} else {
|
||||
doorBlock = doorBlock.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
|
||||
if (doorBlock.getType() == Material.IRON_DOOR || doorBlock.getType() == Material.WOOD_DOOR) {
|
||||
consumer.queueBlockBreak(playerName, doorBlock.getState());
|
||||
if (doorBlock.getType() == Material.IRON_DOOR_BLOCK || doorBlock.getType() == Material.WOODEN_DOOR) {
|
||||
consumer.queueBlockBreak(actor, doorBlock.getState());
|
||||
}
|
||||
} else if (origin.getType() == Material.DOUBLE_PLANT) { // Special double plant check
|
||||
Block plantBlock = origin;
|
||||
|
||||
// Up or down?
|
||||
if (!BukkitUtils.isTop(origin.getType(), origin.getData())) {
|
||||
plantBlock = plantBlock.getRelative(BlockFace.UP);
|
||||
} else {
|
||||
plantBlock = plantBlock.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
|
||||
if (plantBlock.getType() == Material.DOUBLE_PLANT) {
|
||||
consumer.queueBlockBreak(actor, plantBlock.getState());
|
||||
}
|
||||
}
|
||||
|
||||
// Do this down here so that the block is added after blocks sitting on it
|
||||
consumer.queueBlockBreak(playerName, origin.getState());
|
||||
consumer.queueBlockBreak(actor, origin.getState());
|
||||
}
|
||||
|
||||
public static String checkText(String text) {
|
||||
if (text==null) return text;
|
||||
if (mb4) return text;
|
||||
return text.replaceAll("[^\\u0000-\\uFFFF]", "?");
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package de.diddiz.util;
|
||||
|
||||
import static de.diddiz.util.Utils.isByte;
|
||||
import static de.diddiz.util.Utils.isInt;
|
||||
import static de.diddiz.util.Utils.isShort;
|
||||
import static org.bukkit.Bukkit.getLogger;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -15,8 +15,10 @@ import org.bukkit.material.MaterialData;
|
||||
|
||||
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<Byte, String>> materialDataNames = new HashMap<Integer, Map<Byte, 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
|
||||
@@ -28,23 +30,161 @@ public class MaterialName
|
||||
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("17.1", "redwood log");
|
||||
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("18.1", "redwood leaves");
|
||||
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("31.0", "dead long grass");
|
||||
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");
|
||||
for (byte i = 0; i < 7; i++) {
|
||||
cfg.set("35." + i, toReadable(Material.STEP.getNewData(i)));
|
||||
cfg.set("351." + i, toReadable(Material.DOUBLE_STEP.getNewData(i)));
|
||||
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("35." + i, toReadable(Material.WOOL.getNewData(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 clay");
|
||||
cfg.set("95." + i, COLORS[i] + " stained glass");
|
||||
cfg.set("160." + i, COLORS[i] + " stained glass pane");
|
||||
cfg.set("171." + i, COLORS[i] + " carpet");
|
||||
}
|
||||
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);
|
||||
@@ -52,18 +192,26 @@ public class MaterialName
|
||||
getLogger().log(Level.WARNING, "Unable to save material.yml: ", ex);
|
||||
}
|
||||
}
|
||||
if (cfg.getString("263.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))
|
||||
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<Byte, String> dataNames = new HashMap<Byte, String>();
|
||||
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 (isByte(data)) {
|
||||
if (sec.isString(data))
|
||||
dataNames.put(Byte.valueOf(data), sec.getString(data));
|
||||
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
|
||||
@@ -84,15 +232,27 @@ public class MaterialName
|
||||
/**
|
||||
* @return Name of the material regarding it's data, or if it's unknown, the basic name.
|
||||
*/
|
||||
public static String materialName(int type, byte data) {
|
||||
final Map<Byte, String> dataNames = materialDataNames.get(type);
|
||||
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 ]", "");
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package de.diddiz.util;
|
||||
|
||||
import static de.diddiz.LogBlock.config.Config.mb4;
|
||||
import java.io.Closeable;
|
||||
import java.sql.Array;
|
||||
import java.sql.Blob;
|
||||
@@ -76,6 +77,7 @@ public class MySQLConnectionPool implements Closeable
|
||||
throw new SQLException("Failed to validate a brand new connection");
|
||||
}
|
||||
connections.add(conn);
|
||||
if (mb4) conn.createStatement().executeQuery("SET NAMES utf8mb4");
|
||||
return conn;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
|
79
src/main/java/de/diddiz/util/UUIDFetcher.java
Normal file
79
src/main/java/de/diddiz/util/UUIDFetcher.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package de.diddiz.util;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
// Adapted from https://gist.github.com/evilmidget38/26d70114b834f71fb3b4
|
||||
|
||||
public class UUIDFetcher {
|
||||
|
||||
private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft";
|
||||
private static final JSONParser jsonParser = new JSONParser();
|
||||
|
||||
public static Map<String, UUID> getUUIDs(List<String> names) throws Exception {
|
||||
Map<String, UUID> uuidMap = new HashMap<String, UUID>();
|
||||
HttpURLConnection connection = createConnection();
|
||||
String body = JSONArray.toJSONString(names);
|
||||
writeBody(connection, body);
|
||||
JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream()));
|
||||
for (Object profile : array) {
|
||||
JSONObject jsonProfile = (JSONObject) profile;
|
||||
String id = (String) jsonProfile.get("id");
|
||||
String name = (String) jsonProfile.get("name");
|
||||
UUID uuid = UUIDFetcher.getUUID(id);
|
||||
uuidMap.put(name, uuid);
|
||||
}
|
||||
return uuidMap;
|
||||
}
|
||||
|
||||
private static void writeBody(HttpURLConnection connection, String body) throws Exception {
|
||||
OutputStream stream = connection.getOutputStream();
|
||||
stream.write(body.getBytes());
|
||||
stream.flush();
|
||||
stream.close();
|
||||
}
|
||||
|
||||
private static HttpURLConnection createConnection() throws Exception {
|
||||
URL url = new URL(PROFILE_URL);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setUseCaches(false);
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
return connection;
|
||||
}
|
||||
|
||||
private static UUID getUUID(String id) {
|
||||
return UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" + id.substring(20, 32));
|
||||
}
|
||||
|
||||
public static byte[] toBytes(UUID uuid) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]);
|
||||
byteBuffer.putLong(uuid.getMostSignificantBits());
|
||||
byteBuffer.putLong(uuid.getLeastSignificantBits());
|
||||
return byteBuffer.array();
|
||||
}
|
||||
|
||||
public static UUID fromBytes(byte[] array) {
|
||||
if (array.length != 16) {
|
||||
throw new IllegalArgumentException("Illegal byte array length: " + array.length);
|
||||
}
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(array);
|
||||
long mostSignificant = byteBuffer.getLong();
|
||||
long leastSignificant = byteBuffer.getLong();
|
||||
return new UUID(mostSignificant, leastSignificant);
|
||||
}
|
||||
|
||||
}
|
@@ -19,6 +19,15 @@ public class Utils
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isShort(String str) {
|
||||
try {
|
||||
Short.parseShort(str);
|
||||
return true;
|
||||
} catch (final NumberFormatException ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isByte(String str) {
|
||||
try {
|
||||
Byte.parseByte(str);
|
||||
@@ -76,6 +85,8 @@ public class Utils
|
||||
while (currIndex <= spec[0].length() && isInt(spec[0].substring(lastIndex, currIndex)))
|
||||
currIndex++;
|
||||
if (currIndex - 1 != lastIndex) {
|
||||
if (currIndex > spec[0].length())
|
||||
return -1;
|
||||
final String param = spec[0].substring(currIndex - 1, currIndex).toLowerCase();
|
||||
if (param.equals("d"))
|
||||
days = Integer.parseInt(spec[0].substring(lastIndex, currIndex - 1));
|
||||
|
@@ -1,78 +0,0 @@
|
||||
package de.diddiz.worldedit;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalPlayer;
|
||||
import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.bags.BlockBag;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.Config;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
public class LogBlockEditSession extends EditSession {
|
||||
|
||||
private LocalPlayer player;
|
||||
private LogBlock plugin;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public LogBlockEditSession(LocalWorld world, int maxBlocks, LocalPlayer player, LogBlock lb) {
|
||||
super(world, maxBlocks);
|
||||
this.player = player;
|
||||
this.plugin = lb;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public LogBlockEditSession(LocalWorld world, int maxBlocks, BlockBag blockBag, LocalPlayer player, LogBlock lb) {
|
||||
super(world, maxBlocks, blockBag);
|
||||
this.player = player;
|
||||
this.plugin = lb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean rawSetBlock(Vector pt, BaseBlock block) {
|
||||
if (!(player.getWorld() instanceof BukkitWorld) || !(Config.isLogging(player.getWorld().getName(), Logging.WORLDEDIT))) {
|
||||
return super.rawSetBlock(pt, block);
|
||||
}
|
||||
|
||||
int typeBefore = ((BukkitWorld) player.getWorld()).getWorld().getBlockTypeIdAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
byte dataBefore = ((BukkitWorld) player.getWorld()).getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).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 = ((BukkitWorld) player.getWorld()).getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getState();
|
||||
}
|
||||
boolean success = super.rawSetBlock(pt, block);
|
||||
if (success) {
|
||||
Location location = new Location(((BukkitWorld) player.getWorld()).getWorld(), pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
|
||||
// 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(player.getName(), (Sign) stateBefore);
|
||||
if (block.getType() != Material.AIR.getId()) {
|
||||
plugin.getConsumer().queueBlockPlace(player.getName(), location, block.getType(), (byte) block.getData());
|
||||
}
|
||||
} else {
|
||||
if (dataBefore != 0) {
|
||||
plugin.getConsumer().queueBlockBreak(player.getName(), location, typeBefore, dataBefore);
|
||||
if (block.getType() != Material.AIR.getId()) {
|
||||
plugin.getConsumer().queueBlockPlace(player.getName(), location, block.getType(), (byte) block.getData());
|
||||
}
|
||||
} else {
|
||||
plugin.getConsumer().queueBlock(player.getName(), location, typeBefore, block.getType(), (byte) block.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
package de.diddiz.worldedit;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.EditSessionFactory;
|
||||
import com.sk89q.worldedit.LocalPlayer;
|
||||
import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bags.BlockBag;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
|
||||
public class LogBlockEditSessionFactory extends EditSessionFactory {
|
||||
|
||||
private LogBlock plugin;
|
||||
|
||||
public LogBlockEditSessionFactory(LogBlock lb) {
|
||||
this.plugin = lb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditSession getEditSession(LocalWorld world, int maxBlocks, LocalPlayer player) {
|
||||
return new LogBlockEditSession(world, maxBlocks, player, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditSession getEditSession(LocalWorld world, int maxBlocks, BlockBag blockBag, LocalPlayer player) {
|
||||
return new LogBlockEditSession(world, maxBlocks, blockBag, player, plugin);
|
||||
}
|
||||
|
||||
public static void initialize(LogBlock logBlock) {
|
||||
try {
|
||||
// Check to see if the world edit version is compatible
|
||||
Class.forName("com.sk89q.worldedit.EditSessionFactory").getDeclaredMethod("getEditSession", LocalWorld.class, int.class, BlockBag.class, LocalPlayer.class);
|
||||
WorldEdit.getInstance().setEditSessionFactory(new LogBlockEditSessionFactory(logBlock));
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
114
src/main/java/de/diddiz/worldedit/WorldEditLoggingHook.java
Normal file
114
src/main/java/de/diddiz/worldedit/WorldEditLoggingHook.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package de.diddiz.worldedit;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
//...so they ALSO have a class called Actor... need to fully-qualify when we use ours
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.logging.AbstractLoggingExtent;
|
||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||
import de.diddiz.LogBlock.LogBlock;
|
||||
import de.diddiz.LogBlock.Logging;
|
||||
import de.diddiz.LogBlock.config.Config;
|
||||
import java.util.logging.Level;
|
||||
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;
|
||||
|
||||
public class WorldEditLoggingHook {
|
||||
|
||||
private LogBlock plugin;
|
||||
|
||||
public WorldEditLoggingHook(LogBlock plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
// Convert WE Actor to LB Actor
|
||||
private de.diddiz.LogBlock.Actor AtoA(Actor weActor) {
|
||||
if (weActor.isPlayer()) {
|
||||
return new de.diddiz.LogBlock.Actor(weActor.getName(),weActor.getUniqueId());
|
||||
}
|
||||
return new de.diddiz.LogBlock.Actor(weActor.getName());
|
||||
}
|
||||
|
||||
private World adapt(com.sk89q.worldedit.world.World weWorld) {
|
||||
if (weWorld == null) {
|
||||
throw new NullPointerException("[Logblock-Worldedit] The provided world was null.");
|
||||
}
|
||||
if (weWorld instanceof BukkitWorld) return ((BukkitWorld) weWorld).getWorld();
|
||||
World world = Bukkit.getServer().getWorld(weWorld.getName());
|
||||
if (world == null) throw new IllegalArgumentException("Can't find a Bukkit world for " + weWorld);
|
||||
return world;
|
||||
}
|
||||
|
||||
public void hook() {
|
||||
WorldEdit.getInstance().getEventBus().register(new Object() {
|
||||
@Subscribe
|
||||
public void wrapForLogging(final EditSessionEvent event) {
|
||||
final Actor actor = event.getActor();
|
||||
if (actor == null ) return;
|
||||
final de.diddiz.LogBlock.Actor lbActor = AtoA(actor);
|
||||
|
||||
// Check to ensure the world should be logged
|
||||
final World world;
|
||||
final com.sk89q.worldedit.world.World k = event.getWorld();
|
||||
try {
|
||||
world = adapt(k);
|
||||
} catch (RuntimeException ex) {
|
||||
plugin.getLogger().warning("Failed to register logging for WorldEdit!");
|
||||
plugin.getLogger().log(Level.WARNING, ex.getMessage(),ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// If config becomes reloadable, this check should be moved
|
||||
if (!(Config.isLogging(world, Logging.WORLDEDIT))) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setExtent(new AbstractLoggingExtent(event.getExtent()) {
|
||||
@Override
|
||||
protected void onBlockChange(Vector pt, BaseBlock block) {
|
||||
|
||||
if (event.getStage() != EditSession.Stage.BEFORE_CHANGE) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
name: ${project.name}
|
||||
version: '1.70'
|
||||
version: '1.93'
|
||||
author: DiddiZ
|
||||
authors: [md_5, ammar2]
|
||||
authors: [md_5, ammar2, frymaster]
|
||||
website: http://dev.bukkit.org/server-mods/logblock/
|
||||
main: de.diddiz.LogBlock.LogBlock
|
||||
description: ${project.description}
|
||||
|
Reference in New Issue
Block a user