diff --git a/src/de/diddiz/LogBlock/Config.java b/src/de/diddiz/LogBlock/Config.java index 17aa84c..c9c2a98 100644 --- a/src/de/diddiz/LogBlock/Config.java +++ b/src/de/diddiz/LogBlock/Config.java @@ -42,7 +42,7 @@ public class Config extends LoggingEnabledMapping public final int linesPerPage, linesLimit; public final boolean askRollbacks, askRedos, askClearLogs, askClearLogAfterRollback, askRollbackAfterBan; public final String banPermission; - public final boolean installSpout, checkVersion; + public final boolean checkVersion; public final Set hiddenPlayers, hiddenBlocks; public static enum LogKillsLevel { @@ -88,7 +88,6 @@ public class Config extends LoggingEnabledMapping def.put("questioner.askClearLogAfterRollback", true); def.put("questioner.askRollbackAfterBan", false); def.put("questioner.banPermission", "mcbans.ban.local"); - def.put("updater.installSpout", true); def.put("updater.checkVersion", true); def.put("tools.tool.aliases", Arrays.asList("t")); def.put("tools.tool.leftClickBehavior", "NONE"); @@ -154,7 +153,6 @@ public class Config extends LoggingEnabledMapping askClearLogAfterRollback = config.getBoolean("questioner.askClearLogAfterRollback", true); askRollbackAfterBan = config.getBoolean("questioner.askRollbackAfterBan", false); banPermission = config.getString("questioner.banPermission"); - installSpout = config.getBoolean("updater.installSpout", true); checkVersion = config.getBoolean("updater.checkVersion", true); final List tools = new ArrayList(); final ConfigurationSection toolsSec = config.getConfigurationSection("tools"); diff --git a/src/de/diddiz/LogBlock/LBChestAccessListener.java b/src/de/diddiz/LogBlock/LBChestAccessListener.java index 968aac1..ff4ac5c 100644 --- a/src/de/diddiz/LogBlock/LBChestAccessListener.java +++ b/src/de/diddiz/LogBlock/LBChestAccessListener.java @@ -6,37 +6,90 @@ import static de.diddiz.util.BukkitUtils.rawData; import java.util.HashMap; import java.util.Map; import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.ContainerBlock; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.ItemStack; -import org.getspout.spoutapi.event.inventory.InventoryCloseEvent; -import org.getspout.spoutapi.event.inventory.InventoryListener; -import org.getspout.spoutapi.event.inventory.InventoryOpenEvent; -class LBChestAccessListener extends InventoryListener +class LBChestAccessListener extends PlayerListener { private final Consumer consumer; - private final Map containers = new HashMap(); + private final Map containers = new HashMap(); LBChestAccessListener(LogBlock logblock) { consumer = logblock.getConsumer(); } - @Override - public void onInventoryClose(InventoryCloseEvent event) { - if (!event.isCancelled() && event.getLocation() != null && containers.containsKey(event.getPlayer().getName().hashCode())) { - final String playerName = event.getPlayer().getName(); - final Location loc = event.getLocation(); - final ItemStack[] before = containers.get(playerName.hashCode()); - final ItemStack[] after = compressInventory(event.getInventory().getContents()); + public void checkInventoryClose(Player player) { + final ContainerState cont = containers.get(player); + if (cont != null) { + final ItemStack[] before = cont.items; + final BlockState state = cont.loc.getBlock().getState(); + if (!(state instanceof ContainerBlock)) + return; + final ItemStack[] after = compressInventory(((ContainerBlock)state).getInventory().getContents()); final ItemStack[] diff = compareInventories(before, after); for (final ItemStack item : diff) - consumer.queueChestAccess(playerName, loc, loc.getWorld().getBlockTypeIdAt(loc), (short)item.getTypeId(), (short)item.getAmount(), rawData(item)); - containers.remove(playerName.hashCode()); + consumer.queueChestAccess(player.getName(), cont.loc, state.getTypeId(), (short)item.getTypeId(), (short)item.getAmount(), rawData(item)); + containers.remove(player); } } + public void checkInventoryOpen(Player player, Block block) { + final BlockState state = block.getState(); + if (!(state instanceof ContainerBlock)) + return; + containers.put(player, new ContainerState(block.getLocation(), compressInventory(((ContainerBlock)state).getInventory().getContents()))); + } + @Override - public void onInventoryOpen(InventoryOpenEvent event) { - if (!event.isCancelled() && event.getLocation() != null && event.getLocation().getBlock().getTypeId() != 58) - containers.put(event.getPlayer().getName().hashCode(), compressInventory(event.getInventory().getContents())); + public void onPlayerChat(PlayerChatEvent event) { + checkInventoryClose(event.getPlayer()); + } + + @Override + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + checkInventoryClose(event.getPlayer()); + } + + @Override + public void onPlayerQuit(PlayerQuitEvent event) { + checkInventoryClose(event.getPlayer()); + } + + @Override + public void onPlayerTeleport(PlayerTeleportEvent event) { + checkInventoryClose(event.getPlayer()); + } + + @Override + public void onPlayerInteract(PlayerInteractEvent event) { + final Player player = event.getPlayer(); + checkInventoryClose(player); + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + final Block block = event.getClickedBlock(); + final int type = block.getTypeId(); + if (type == 23 || type == 54 || type == 61 || type == 62) + checkInventoryOpen(player, block); + } + } + + private static class ContainerState + { + public final ItemStack[] items; + public final Location loc; + + private ContainerState(Location loc, ItemStack[] items) { + this.items = items; + this.loc = loc; + } } } diff --git a/src/de/diddiz/LogBlock/LBSpoutChestAccessListener.java b/src/de/diddiz/LogBlock/LBSpoutChestAccessListener.java new file mode 100644 index 0000000..13d72cc --- /dev/null +++ b/src/de/diddiz/LogBlock/LBSpoutChestAccessListener.java @@ -0,0 +1,45 @@ +package de.diddiz.LogBlock; + +import static de.diddiz.util.BukkitUtils.compareInventories; +import static de.diddiz.util.BukkitUtils.compressInventory; +import static de.diddiz.util.BukkitUtils.rawData; +import java.util.HashMap; +import java.util.Map; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.getspout.spoutapi.event.inventory.InventoryCloseEvent; +import org.getspout.spoutapi.event.inventory.InventoryListener; +import org.getspout.spoutapi.event.inventory.InventoryOpenEvent; + +class LBSpoutChestAccessListener extends InventoryListener +{ + private final Consumer consumer; + private final Map containers = new HashMap(); + + LBSpoutChestAccessListener(LogBlock logblock) { + consumer = logblock.getConsumer(); + } + + @Override + public void onInventoryClose(InventoryCloseEvent event) { + if (!event.isCancelled() && event.getLocation() != null) { + final Player player = event.getPlayer(); + final ItemStack[] before = containers.get(player); + if (before != null) { + final ItemStack[] after = compressInventory(event.getInventory().getContents()); + final ItemStack[] diff = compareInventories(before, after); + final Location loc = event.getLocation(); + for (final ItemStack item : diff) + consumer.queueChestAccess(player.getName(), loc, loc.getWorld().getBlockTypeIdAt(loc), (short)item.getTypeId(), (short)item.getAmount(), rawData(item)); + containers.remove(player); + } + } + } + + @Override + public void onInventoryOpen(InventoryOpenEvent event) { + if (!event.isCancelled() && event.getLocation() != null && event.getLocation().getBlock().getTypeId() != 58) + containers.put(event.getPlayer(), compressInventory(event.getInventory().getContents())); + } +} diff --git a/src/de/diddiz/LogBlock/LogBlock.java b/src/de/diddiz/LogBlock/LogBlock.java index 7c2d717..1e6a260 100644 --- a/src/de/diddiz/LogBlock/LogBlock.java +++ b/src/de/diddiz/LogBlock/LogBlock.java @@ -19,6 +19,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.Event.Priority; import org.bukkit.event.Event.Type; +import org.bukkit.event.Listener; import org.bukkit.permissions.Permission; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; @@ -110,20 +111,6 @@ public class LogBlock extends JavaPlugin } catch (final Exception ex) { getLogger().warning("[LogBlock] Failed to download WorldEdit. You may have to download it manually. You don't have to install it, just place the jar in the lib folder."); } - if (config.isLogging(Logging.CHESTACCESS) && pm.getPlugin("Spout") == null) - if (config.installSpout) - try { - download(getLogger(), new URL("http://ci.getspout.org/job/Spout/Recommended/artifact/target/spout-dev-SNAPSHOT.jar"), new File("plugins/Spout.jar")); - pm.loadPlugin(new File("plugins/Spout.jar")); - pm.enablePlugin(pm.getPlugin("Spout")); - } catch (final Exception ex) { - config.setLogging(Logging.CHESTACCESS, false); - getLogger().warning("[LogBlock] Failed to install Spout, you may have to restart your server or install it manually."); - } - else { - config.setLogging(Logging.CHESTACCESS, false); - getLogger().warning("[LogBlock] Spout is not installed. Disabling chest logging."); - } commandsHandler = new CommandsHandler(this); getCommand("lb").setExecutor(commandsHandler); if (pm.getPlugin("Permissions") != null) { @@ -134,10 +121,10 @@ public class LogBlock extends JavaPlugin if (config.enableAutoClearLog) getServer().getScheduler().scheduleAsyncDelayedTask(this, new AutoClearLog(this)); getServer().getScheduler().scheduleAsyncDelayedTask(this, new DumpedLogImporter(this)); - final LBBlockListener lbBlockListener = new LBBlockListener(this); - final LBPlayerListener lbPlayerListener = new LBPlayerListener(this); - final LBEntityListener lbEntityListener = new LBEntityListener(this); - final LBToolListener lbToolListener = new LBToolListener(this); + final Listener lbBlockListener = new LBBlockListener(this); + final Listener lbPlayerListener = new LBPlayerListener(this); + final Listener lbEntityListener = new LBEntityListener(this); + final Listener lbToolListener = new LBToolListener(this); pm.registerEvent(Type.PLAYER_INTERACT, lbToolListener, Priority.Normal, this); pm.registerEvent(Type.PLAYER_CHANGED_WORLD, lbToolListener, Priority.Normal, this); if (config.askRollbackAfterBan) @@ -164,10 +151,18 @@ public class LogBlock extends JavaPlugin if (config.isLogging(Logging.LEAVESDECAY)) pm.registerEvent(Type.LEAVES_DECAY, lbBlockListener, Priority.Monitor, this); if (config.isLogging(Logging.CHESTACCESS)) - if (pm.isPluginEnabled("Spout")) - pm.registerEvent(Type.CUSTOM_EVENT, new LBChestAccessListener(this), Priority.Monitor, this); - else - getLogger().warning("[LogBlock] Spout not found. Can't log chest accesses."); + if (pm.isPluginEnabled("Spout")) { + pm.registerEvent(Type.CUSTOM_EVENT, new LBSpoutChestAccessListener(this), Priority.Monitor, this); + getLogger().info("[LogBlock] Using Spout as chest access API"); + } else { + final Listener chestAccessListener = new LBChestAccessListener(this); + pm.registerEvent(Type.PLAYER_INTERACT, chestAccessListener, Priority.Monitor, this); + pm.registerEvent(Type.PLAYER_CHAT, chestAccessListener, Priority.Monitor, this); + pm.registerEvent(Type.PLAYER_COMMAND_PREPROCESS, chestAccessListener, Priority.Monitor, this); + pm.registerEvent(Type.PLAYER_TELEPORT, chestAccessListener, Priority.Monitor, this); + pm.registerEvent(Type.PLAYER_QUIT, chestAccessListener, Priority.Monitor, this); + getLogger().info("[LogBlock] Using own chest access API"); + } if (config.isLogging(Logging.SWITCHINTERACT) || config.isLogging(Logging.DOORINTERACT) || config.isLogging(Logging.CAKEEAT)) pm.registerEvent(Type.PLAYER_INTERACT, lbPlayerListener, Priority.Monitor, this); if (config.isLogging(Logging.KILL))