diff --git a/appinfo.properties b/appinfo.properties index 3ff0f46d..abdadeb3 100644 --- a/appinfo.properties +++ b/appinfo.properties @@ -1,5 +1,5 @@ -#Tue, 27 Aug 2013 12:35:14 +0200 +#Tue, 27 Aug 2013 16:20:04 +0200 program.VERSION=3.1 -program.BUILDNUM=514 -program.BUILDDATE=08/27/2013 12\:35 PM +program.BUILDNUM=522 +program.BUILDDATE=08/27/2013 04\:20 PM diff --git a/buildnumber.properties b/buildnumber.properties index 00760e04..cbfa6771 100644 --- a/buildnumber.properties +++ b/buildnumber.properties @@ -1,3 +1,3 @@ #Build Number for ANT. Do not edit! -#Tue Aug 27 12:35:14 CEST 2013 -build.number=515 +#Tue Aug 27 16:20:04 CEST 2013 +build.number=523 diff --git a/src/me/StevenLawson/TotalFreedomMod/Commands/Command_rollback.java b/src/me/StevenLawson/TotalFreedomMod/Commands/Command_rollback.java index 5c9785f5..5c10579f 100644 --- a/src/me/StevenLawson/TotalFreedomMod/Commands/Command_rollback.java +++ b/src/me/StevenLawson/TotalFreedomMod/Commands/Command_rollback.java @@ -8,7 +8,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @CommandPermissions(level = AdminLevel.SUPER, source = SourceType.BOTH, block_host_console = true) -@CommandParameters(description = "Issues a rollback on a player", usage = "/ <[partialname] | purge [partialname] | purgeall>", aliases = "rb") +@CommandParameters(description = "Issues a rollback on a player", usage = "/ <[partialname] | undo [partialname] purge [partialname] | purgeall>", aliases = "rb") public class Command_rollback extends TFM_Command { @Override @@ -16,25 +16,58 @@ public class Command_rollback extends TFM_Command { if (args.length == 1) { - if (args[0].equalsIgnoreCase("purgeall")) + if ("purgeall".equalsIgnoreCase(args[0])) { - TFM_Util.adminAction(sender.getName(), "Purging all rollback history.", false); + TFM_Util.adminAction(sender.getName(), "Purging all rollback history", false); playerMsg("Purged all rollback history for " + TFM_RollbackManager.purgeEntries() + " players."); } else { String playerName = getPlayerName(args[0]); + + if (!TFM_RollbackManager.canRollback(playerName)) + { + playerMsg("That player has no entries stored."); + return true; + } + + if (TFM_RollbackManager.canUndoRollback(playerName)) + { + playerMsg("That player has just been rolled back."); + } + TFM_Util.adminAction(sender.getName(), "Rolling back player: " + playerName, false); playerMsg("Rolled back " + TFM_RollbackManager.rollback(playerName) + " edits for " + playerName + "."); + playerMsg("If this rollback was a mistake, use /rollback undo " + playerName + " within 20 seconds to reverse the rollback."); } } else if (args.length == 2) { - if (args[0].equalsIgnoreCase("purge")) + if ("purge".equalsIgnoreCase(args[0])) { String playerName = getPlayerName(args[1]); + + if (!TFM_RollbackManager.canRollback(playerName)) + { + playerMsg("That player has no entries stored."); + return true; + } + playerMsg("Purged " + TFM_RollbackManager.purgeEntries(playerName) + " rollback history entries for " + playerName + "."); } + else if ("undo".equalsIgnoreCase(args[0])) + { + String playerName = getPlayerName(args[1]); + + if (!TFM_RollbackManager.canUndoRollback(playerName)) + { + playerMsg("That player hasn't been rolled back recently."); + return true; + } + + TFM_Util.adminAction(sender.getName(), "Reverting rollback for player: " + playerName, false); + playerMsg("Reverted " + TFM_RollbackManager.undoRollback(playerName) + " edits for " + playerName + "."); + } else { return false; diff --git a/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_PlayerListener.java b/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_PlayerListener.java index f5697fbd..30636cad 100644 --- a/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_PlayerListener.java +++ b/src/me/StevenLawson/TotalFreedomMod/Listener/TFM_PlayerListener.java @@ -115,7 +115,7 @@ public class TFM_PlayerListener implements Listener TFM_Util.playerMsg(player, "Block edits at (" + ChatColor.WHITE + "x" + location.getBlockX() + ", y" + location.getBlockY() + ", z" + location.getBlockZ() + ChatColor.BLUE + ")" + ChatColor.WHITE + ":", ChatColor.BLUE); for (RollbackEntry entry : entries) { - TFM_Util.playerMsg(player, " - " + ChatColor.BLUE + entry.getAuthor() + " " + entry.getType() + " " + StringUtils.capitalize(entry.getMaterial().toString().toLowerCase()) + (entry.getData() == 0 ? "" : ":" + entry.getData())); + TFM_Util.playerMsg(player, " - " + ChatColor.BLUE + entry.author + " " + entry.getType() + " " + StringUtils.capitalize(entry.getMaterial().toString().toLowerCase()) + (entry.data == 0 ? "" : ":" + entry.data)); } break; diff --git a/src/me/StevenLawson/TotalFreedomMod/TFM_RollbackManager.java b/src/me/StevenLawson/TotalFreedomMod/TFM_RollbackManager.java index 421d578e..a8eec753 100644 --- a/src/me/StevenLawson/TotalFreedomMod/TFM_RollbackManager.java +++ b/src/me/StevenLawson/TotalFreedomMod/TFM_RollbackManager.java @@ -1,5 +1,6 @@ package me.StevenLawson.TotalFreedomMod; +import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -10,10 +11,12 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; public class TFM_RollbackManager { - private static final Map> PLAYER_HISTORY_MAP = new HashMap>(); + private static final Map> PLAYER_HISTORY = new HashMap>(); + private static final List REMOVE_ROLLBACK_HISTORY = new ArrayList(); private TFM_RollbackManager() { @@ -33,6 +36,7 @@ public class TFM_RollbackManager private static void storeEntry(Player player, RollbackEntry entry) { List playerEntryList = getEntriesByPlayer(player.getName()); + if (playerEntryList != null) { playerEntryList.add(0, entry); @@ -41,7 +45,7 @@ public class TFM_RollbackManager public static int purgeEntries() { - Iterator> it = PLAYER_HISTORY_MAP.values().iterator(); + Iterator> it = PLAYER_HISTORY.values().iterator(); while (it.hasNext()) { List playerEntryList = it.next(); @@ -50,45 +54,97 @@ public class TFM_RollbackManager playerEntryList.clear(); } } - return PLAYER_HISTORY_MAP.size(); + return PLAYER_HISTORY.size(); } public static int purgeEntries(String playerName) { List playerEntryList = getEntriesByPlayer(playerName); - if (playerEntryList != null) + + if (playerEntryList == null) { - int count = playerEntryList.size(); - playerEntryList.clear(); - return count; + return 0; } - return 0; + + int count = playerEntryList.size(); + playerEntryList.clear(); + return count; + } public static boolean canRollback(String playerName) { - return PLAYER_HISTORY_MAP.containsKey(playerName.toLowerCase()); + return PLAYER_HISTORY.containsKey(playerName.toLowerCase()) && !PLAYER_HISTORY.get(playerName.toLowerCase()).isEmpty(); + } + + public static boolean canUndoRollback(String playerName) + { + return REMOVE_ROLLBACK_HISTORY.contains(playerName.toLowerCase()); } - public static int rollback(String playerName) + public static int rollback(final String playerName) { - List playerEntryList = getEntriesByPlayer(playerName); - if (playerEntryList != null) + final List entries = getEntriesByPlayer(playerName); + if (entries == null) { - int count = playerEntryList.size(); - Iterator it = playerEntryList.iterator(); - while (it.hasNext()) - { - RollbackEntry entry = it.next(); - if (entry != null) - { - entry.restore(); - } - it.remove(); - } - return count; + return 0; } - return 0; + + int count = entries.size(); + for (RollbackEntry entry : entries) + { + if (entry != null) + { + entry.restore(); + } + } + + if (!REMOVE_ROLLBACK_HISTORY.contains(playerName.toLowerCase())) + { + REMOVE_ROLLBACK_HISTORY.add(playerName.toLowerCase()); + } + + new BukkitRunnable() + { + @Override + public void run() + { + if (REMOVE_ROLLBACK_HISTORY.contains(playerName.toLowerCase())) + { + REMOVE_ROLLBACK_HISTORY.remove(playerName.toLowerCase()); + purgeEntries(playerName); + } + } + }.runTaskLater(TotalFreedomMod.plugin, 20L * 20L); + return count; + } + + public static int undoRollback(String playerName) + { + List entries = getEntriesByPlayer(playerName); + + if (entries == null) + { + return 0; + } + + entries = Lists.reverse(entries); + + int count = entries.size(); + for (RollbackEntry entry : entries) + { + if (entry != null) + { + entry.redo(); + } + } + + if (REMOVE_ROLLBACK_HISTORY.contains(playerName.toLowerCase())) + { + REMOVE_ROLLBACK_HISTORY.remove(playerName.toLowerCase()); + } + + return count; } public static List getEntriesAtLocation(final Location location) @@ -99,11 +155,11 @@ public class TFM_RollbackManager final String testWorldName = location.getWorld().getName(); List entries = new ArrayList(); - for (String playername : PLAYER_HISTORY_MAP.keySet()) + for (String playername : PLAYER_HISTORY.keySet()) { - for (RollbackEntry entry : PLAYER_HISTORY_MAP.get(playername)) + for (RollbackEntry entry : PLAYER_HISTORY.get(playername.toLowerCase())) { - if (testX == entry.x && testY == entry.y && testZ == entry.z && testWorldName.equals(entry.getWorldName())) + if (testX == entry.x && testY == entry.y && testZ == entry.z && testWorldName.equals(entry.worldName)) { entries.add(0, entry); } @@ -116,11 +172,11 @@ public class TFM_RollbackManager private static List getEntriesByPlayer(String playerName) { playerName = playerName.toLowerCase(); - List playerEntryList = PLAYER_HISTORY_MAP.get(playerName); + List playerEntryList = PLAYER_HISTORY.get(playerName.toLowerCase()); if (playerEntryList == null) { playerEntryList = new ArrayList(); - PLAYER_HISTORY_MAP.put(playerName, playerEntryList); + PLAYER_HISTORY.put(playerName.toLowerCase(), playerEntryList); } return playerEntryList; } @@ -146,13 +202,13 @@ public class TFM_RollbackManager public static class RollbackEntry { // Use of primitives to decrease overhead - private final String author; - private final String worldName; + public final String author; + public final String worldName; public final int x; public final short y; public final int z; - private final short blockId; - private final byte data; + public final byte data; + public final short blockId; private final boolean isBreak; private RollbackEntry(String author, Block block, EntryType entryType) @@ -173,17 +229,12 @@ public class TFM_RollbackManager } else { - blockId = (short) block.getTypeId(); - data = 0; + this.blockId = (short) block.getTypeId(); + this.data = block.getData(); this.isBreak = false; } } - public String getAuthor() - { - return author; - } - public Location getLocation() { try @@ -202,26 +253,6 @@ public class TFM_RollbackManager return Material.getMaterial(blockId); } - public int getX() - { - return x; - } - - public short getY() - { - return y; - } - - public int getZ() - { - return z; - } - - public byte getData() - { - return data; - } - public EntryType getType() { return (isBreak ? EntryType.BLOCK_BREAK : EntryType.BLOCK_PLACE); @@ -229,7 +260,7 @@ public class TFM_RollbackManager public void restore() { - Block block = Bukkit.getWorld(worldName).getBlockAt(x, y, z); + final Block block = Bukkit.getWorld(worldName).getBlockAt(x, y, z); if (isBreak) { block.setType(getMaterial()); @@ -241,9 +272,19 @@ public class TFM_RollbackManager } } - public String getWorldName() + public void redo() { - return worldName; + final Block block = Bukkit.getWorld(worldName).getBlockAt(x, y, z); + + if (isBreak) + { + block.setType(Material.AIR); + } + else + { + block.setType(getMaterial()); + block.setData(data); + } } } }