Added /rollback undo

This commit is contained in:
JeromSar 2013-08-27 16:22:46 +02:00
parent ee6b93e208
commit 0b146943ff
5 changed files with 148 additions and 74 deletions

View File

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

View File

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

View File

@ -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 = "/<command> <[partialname] | purge [partialname] | purgeall>", aliases = "rb")
@CommandParameters(description = "Issues a rollback on a player", usage = "/<command> <[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;

View File

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

View File

@ -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<String, List<RollbackEntry>> PLAYER_HISTORY_MAP = new HashMap<String, List<RollbackEntry>>();
private static final Map<String, List<RollbackEntry>> PLAYER_HISTORY = new HashMap<String, List<RollbackEntry>>();
private static final List<String> REMOVE_ROLLBACK_HISTORY = new ArrayList<String>();
private TFM_RollbackManager()
{
@ -33,6 +36,7 @@ public class TFM_RollbackManager
private static void storeEntry(Player player, RollbackEntry entry)
{
List<RollbackEntry> playerEntryList = getEntriesByPlayer(player.getName());
if (playerEntryList != null)
{
playerEntryList.add(0, entry);
@ -41,7 +45,7 @@ public class TFM_RollbackManager
public static int purgeEntries()
{
Iterator<List<RollbackEntry>> it = PLAYER_HISTORY_MAP.values().iterator();
Iterator<List<RollbackEntry>> it = PLAYER_HISTORY.values().iterator();
while (it.hasNext())
{
List<RollbackEntry> playerEntryList = it.next();
@ -50,47 +54,99 @@ public class TFM_RollbackManager
playerEntryList.clear();
}
}
return PLAYER_HISTORY_MAP.size();
return PLAYER_HISTORY.size();
}
public static int purgeEntries(String playerName)
{
List<RollbackEntry> playerEntryList = getEntriesByPlayer(playerName);
if (playerEntryList != null)
if (playerEntryList == null)
{
return 0;
}
int count = playerEntryList.size();
playerEntryList.clear();
return count;
}
return 0;
}
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 int rollback(String playerName)
public static boolean canUndoRollback(String playerName)
{
List<RollbackEntry> playerEntryList = getEntriesByPlayer(playerName);
if (playerEntryList != null)
return REMOVE_ROLLBACK_HISTORY.contains(playerName.toLowerCase());
}
public static int rollback(final String playerName)
{
int count = playerEntryList.size();
Iterator<RollbackEntry> it = playerEntryList.iterator();
while (it.hasNext())
final List<RollbackEntry> entries = getEntriesByPlayer(playerName);
if (entries == null)
{
return 0;
}
int count = entries.size();
for (RollbackEntry entry : entries)
{
RollbackEntry entry = it.next();
if (entry != null)
{
entry.restore();
}
it.remove();
}
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<RollbackEntry> 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<RollbackEntry> getEntriesAtLocation(final Location location)
{
final int testX = location.getBlockX();
@ -99,11 +155,11 @@ public class TFM_RollbackManager
final String testWorldName = location.getWorld().getName();
List<RollbackEntry> entries = new ArrayList<RollbackEntry>();
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<RollbackEntry> getEntriesByPlayer(String playerName)
{
playerName = playerName.toLowerCase();
List<RollbackEntry> playerEntryList = PLAYER_HISTORY_MAP.get(playerName);
List<RollbackEntry> playerEntryList = PLAYER_HISTORY.get(playerName.toLowerCase());
if (playerEntryList == null)
{
playerEntryList = new ArrayList<RollbackEntry>();
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);
}
}
}
}