Added /lb tp <number> to teleport to a lookup element

Made rollback errors viewable ingame
This commit is contained in:
Robin Kupper
2011-08-10 14:02:25 +02:00
parent b6f703a42c
commit e8b6640534
7 changed files with 69 additions and 25 deletions

View File

@@ -6,7 +6,7 @@ import java.sql.SQLException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import org.bukkit.Location; import org.bukkit.Location;
public class BlockChange public class BlockChange implements LookupCacheElement
{ {
private final static SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss"); private final static SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss");
public final long id, date; public final long id, date;
@@ -32,7 +32,7 @@ public class BlockChange
public BlockChange(ResultSet rs, QueryParams p) throws SQLException { public BlockChange(ResultSet rs, QueryParams p) throws SQLException {
id = p.needId ? rs.getInt("id") : 0; id = p.needId ? rs.getInt("id") : 0;
date = p.needDate ? rs.getTimestamp("date").getTime() : 0; date = p.needDate ? rs.getTimestamp("date").getTime() : 0;
loc = p.needCoords ? new Location(null, rs.getInt("x"), rs.getInt("y"), rs.getInt("z")) : null; loc = p.needCoords ? new Location(p.world, rs.getInt("x"), rs.getInt("y"), rs.getInt("z")) : null;
playerName = p.needPlayer ? rs.getString("playername") : null; playerName = p.needPlayer ? rs.getString("playername") : null;
replaced = p.needType ? rs.getInt("replaced") : 0; replaced = p.needType ? rs.getInt("replaced") : 0;
type = p.needType ? rs.getInt("type") : 0; type = p.needType ? rs.getInt("type") : 0;
@@ -80,4 +80,14 @@ public class BlockChange
msg.append(" at " + loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ()); msg.append(" at " + loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ());
return msg.toString(); return msg.toString();
} }
@Override
public Location getLocation() {
return loc;
}
@Override
public String getMessage() {
return toString();
}
} }

View File

@@ -313,7 +313,24 @@ public class CommandsHandler implements CommandExecutor
} else if (command.equals("tp")) { } else if (command.equals("tp")) {
if (sender instanceof Player) { if (sender instanceof Player) {
if (logblock.hasPermission(sender, "logblock.tp")) if (logblock.hasPermission(sender, "logblock.tp"))
new CommandTeleport(sender, new QueryParams(logblock, sender, argsToList(args, 1)), true); if (args.length == 2 || isInt(args[1])) {
final int pos = Integer.parseInt(args[1]) - 1;
final Player player = (Player)sender;
final Session session = logblock.getSession(player.getName());
if (session.lookupCache != null)
if (pos >= 0 && pos < session.lookupCache.length) {
final Location loc = session.lookupCache[pos].getLocation();
if (loc != null) {
player.teleport(new Location(loc.getWorld(), loc.getX() + 0.5, saveSpawnHeight(loc), loc.getZ() + 0.5, player.getLocation().getYaw(), 90));
player.sendMessage(ChatColor.LIGHT_PURPLE + "Teleported to " + loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ());
} else
sender.sendMessage(ChatColor.RED + "There is no location associated with that");
} else
sender.sendMessage(ChatColor.RED + "'" + args[1] + " is out of range");
else
sender.sendMessage(ChatColor.RED + "You havn't done a lookup yet");
} else
new CommandTeleport(sender, new QueryParams(logblock, sender, argsToList(args, 1)), true);
else else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this"); sender.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else } else
@@ -329,6 +346,9 @@ public class CommandsHandler implements CommandExecutor
} else } else
sender.sendMessage(ChatColor.RED + "Unknown command '" + args[0] + "'"); sender.sendMessage(ChatColor.RED + "Unknown command '" + args[0] + "'");
} }
} catch (final NullPointerException ex) {
sender.sendMessage(ChatColor.RED + "Error, check log");
log.log(Level.WARNING, "NPE in commandshandler: ", ex);
} catch (final Exception ex) { } catch (final Exception ex) {
sender.sendMessage(ChatColor.RED + ex.getMessage()); sender.sendMessage(ChatColor.RED + ex.getMessage());
} }
@@ -345,7 +365,7 @@ public class CommandsHandler implements CommandExecutor
if (numberOfPages != 1) if (numberOfPages != 1)
sender.sendMessage(ChatColor.DARK_AQUA + "Page " + page + "/" + numberOfPages); sender.sendMessage(ChatColor.DARK_AQUA + "Page " + page + "/" + numberOfPages);
for (int i = startpos; i <= stoppos; i++) for (int i = startpos; i <= stoppos; i++)
sender.sendMessage(ChatColor.GOLD + session.lookupCache[i].toString()); sender.sendMessage(ChatColor.GOLD + (session.lookupCache[i].getLocation() != null ? "(" + (i + 1) + ") " : "") + session.lookupCache[i].getMessage());
session.page = page; session.page = page;
} else } else
sender.sendMessage(ChatColor.RED + "There isn't a page '" + page + "'"); sender.sendMessage(ChatColor.RED + "There isn't a page '" + page + "'");
@@ -590,6 +610,7 @@ public class CommandsHandler implements CommandExecutor
return; return;
} }
editor.start(); editor.start();
logblock.getSession(senderName(sender)).lookupCache = editor.errors;
sender.sendMessage(ChatColor.GREEN + "Rollback finished successfully (" + editor.getElapsedTime() + " ms, " + editor.getSuccesses() + "/" + changes + " blocks" + (editor.getErrors() > 0 ? ", " + ChatColor.RED + editor.getErrors() + " errors" + ChatColor.GREEN : "") + (editor.getBlacklistCollisions() > 0 ? ", " + editor.getBlacklistCollisions() + " blacklist collisions" : "") + ")"); sender.sendMessage(ChatColor.GREEN + "Rollback finished successfully (" + editor.getElapsedTime() + " ms, " + editor.getSuccesses() + "/" + changes + " blocks" + (editor.getErrors() > 0 ? ", " + ChatColor.RED + editor.getErrors() + " errors" + ChatColor.GREEN : "") + (editor.getBlacklistCollisions() > 0 ? ", " + editor.getBlacklistCollisions() + " blacklist collisions" : "") + ")");
if (!params.silent && config.askClearLogAfterRollback && logblock.hasPermission(sender, "logblock.clearlog") && questioner != null && sender instanceof Player) { if (!params.silent && config.askClearLogAfterRollback && logblock.hasPermission(sender, "logblock.clearlog") && questioner != null && sender instanceof Player) {
Thread.sleep(1000); Thread.sleep(1000);

View File

@@ -28,10 +28,10 @@ import org.bukkit.material.MaterialData;
class LBBlockListener extends BlockListener class LBBlockListener extends BlockListener
{ {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss"); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss");
private static final Set<Integer> nonFluidProofBlocks = new HashSet<Integer>(Arrays.asList(27, 28, 31, 32, 37, 38, 39, 40, 50, 51, 55, 59, 66, 69, 70, 75, 76, 78, 93, 94));
private final Consumer consumer; private final Consumer consumer;
private final Map<Integer, WorldConfig> worlds; private final Map<Integer, WorldConfig> worlds;
private final List<String> errors = new ArrayList<String>(20); private final List<String> errors = new ArrayList<String>(20);
private final Set<Integer> nonFluidProofBlocks = new HashSet<Integer>(Arrays.asList(27, 28, 31, 32, 37, 38, 39, 40, 50, 51, 55, 59, 66, 69, 70, 75, 76, 78, 93, 94));
LBBlockListener(LogBlock logblock) { LBBlockListener(LogBlock logblock) {
consumer = logblock.getConsumer(); consumer = logblock.getConsumer();

View File

@@ -0,0 +1,10 @@
package de.diddiz.LogBlock;
import org.bukkit.Location;
public interface LookupCacheElement
{
public Location getLocation();
public String getMessage();
}

View File

@@ -9,7 +9,7 @@ public class Session
public boolean toolBlockEnabled = true; public boolean toolBlockEnabled = true;
public QueryParams toolBlockQuery; public QueryParams toolBlockQuery;
public ToolMode toolBlockMode; public ToolMode toolBlockMode;
public BlockChange[] lookupCache = null; public LookupCacheElement[] lookupCache = null;
public int page = 1; public int page = 1;
Session(LogBlock logblock) { Session(LogBlock logblock) {

View File

@@ -32,9 +32,9 @@ public class WorldEditor implements Runnable
private final Queue<Edit> edits = new LinkedBlockingQueue<Edit>(); private final Queue<Edit> edits = new LinkedBlockingQueue<Edit>();
private final World world; private final World world;
private int taskID; private int taskID;
private int successes = 0, errors = 0, blacklistCollisions = 0; private int successes = 0, blacklistCollisions = 0;
private long elapsedTime = 0; private long elapsedTime = 0;
final List<String> errorList = new ArrayList<String>(); public LookupCacheElement[] errors;
public WorldEditor(LogBlock logblock, World world) { public WorldEditor(LogBlock logblock, World world) {
log = logblock.getServer().getLogger(); log = logblock.getServer().getLogger();
@@ -52,7 +52,7 @@ public class WorldEditor implements Runnable
} }
public int getErrors() { public int getErrors() {
return errors; return errors.length;
} }
public int getBlacklistCollisions() { public int getBlacklistCollisions() {
@@ -67,21 +67,22 @@ public class WorldEditor implements Runnable
return elapsedTime; return elapsedTime;
} }
synchronized public void start() throws WorldEditorException { synchronized public void start() throws Exception {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
taskID = logblock.getServer().getScheduler().scheduleSyncRepeatingTask(logblock, this, 0, 1); taskID = logblock.getServer().getScheduler().scheduleSyncRepeatingTask(logblock, this, 0, 1);
if (taskID == -1) if (taskID == -1)
throw new WorldEditorException("Failed to schedule task"); throw new Exception("Failed to schedule task");
try { try {
this.wait(); this.wait();
} catch (final InterruptedException ex) { } catch (final InterruptedException ex) {
throw new WorldEditorException("Interrupted"); throw new Exception("Interrupted");
} }
elapsedTime = System.currentTimeMillis() - start; elapsedTime = System.currentTimeMillis() - start;
} }
@Override @Override
public synchronized void run() { public synchronized void run() {
final List<WorldEditorException> errorList = new ArrayList<WorldEditorException>();
int counter = 0; int counter = 0;
while (!edits.isEmpty() && counter < 1000) { while (!edits.isEmpty() && counter < 1000) {
try { try {
@@ -94,11 +95,8 @@ public class WorldEditor implements Runnable
break; break;
} }
} catch (final WorldEditorException ex) { } catch (final WorldEditorException ex) {
errors++; errorList.add(ex);
errorList.add(ex.getMessage());
} catch (final Exception ex) { } catch (final Exception ex) {
errors++;
errorList.add(ex.getMessage());
log.log(Level.WARNING, "[LogBlock WorldEditor] Exeption: ", ex); log.log(Level.WARNING, "[LogBlock WorldEditor] Exeption: ", ex);
} }
counter++; counter++;
@@ -110,10 +108,11 @@ public class WorldEditor implements Runnable
final File file = new File("plugins/LogBlock/error/WorldEditor-" + new SimpleDateFormat("yy-MM-dd-HH-mm-ss").format(System.currentTimeMillis()) + ".log"); final File file = new File("plugins/LogBlock/error/WorldEditor-" + new SimpleDateFormat("yy-MM-dd-HH-mm-ss").format(System.currentTimeMillis()) + ".log");
file.getParentFile().mkdirs(); file.getParentFile().mkdirs();
final PrintWriter writer = new PrintWriter(file); final PrintWriter writer = new PrintWriter(file);
for (final String err : errorList) for (final LookupCacheElement err : errorList)
writer.println(err); writer.println(err.getMessage());
writer.close(); writer.close();
} catch (final Exception ex) {} } catch (final Exception ex) {}
errors = errorList.toArray(new WorldEditorException[errorList.size()]);
notify(); notify();
} }
} }
@@ -210,18 +209,22 @@ public class WorldEditor implements Runnable
} }
@SuppressWarnings("serial") @SuppressWarnings("serial")
public static class WorldEditorException extends Exception public static class WorldEditorException extends Exception implements LookupCacheElement
{ {
public WorldEditorException(String msg) { private final Location loc;
super(msg);
}
public WorldEditorException(int typeBefore, int typeAfter, Location loc) { public WorldEditorException(int typeBefore, int typeAfter, Location loc) {
this("Failed to replace " + materialName(typeBefore) + " with " + materialName(typeAfter), loc); this("Failed to replace " + materialName(typeBefore) + " with " + materialName(typeAfter), loc);
} }
public WorldEditorException(String msg, Location loc) { public WorldEditorException(String msg, Location loc) {
super(msg + " at " + loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ()); super(msg + " at " + loc.getWorld().getName() + ":" + loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ());
this.loc = loc;
}
@Override
public Location getLocation() {
return loc;
} }
} }
} }

View File

@@ -164,7 +164,7 @@ public class BukkitUtils
} }
public static byte rawData(ItemStack item) { public static byte rawData(ItemStack item) {
return item.getType() != null ? (item.getData() != null ? item.getData().getData() : 0) : 0; return item.getType() != null ? item.getData() != null ? item.getData().getData() : 0 : 0;
} }
public static int saveSpawnHeight(Location loc) { public static int saveSpawnHeight(Location loc) {
@@ -186,7 +186,7 @@ public class BukkitUtils
public static int modifyContainer(BlockState b, ItemStack item) throws Exception { public static int modifyContainer(BlockState b, ItemStack item) throws Exception {
if (!(b instanceof ContainerBlock)) if (!(b instanceof ContainerBlock))
throw new Exception("No container at " + b.getBlock().getLocation().toString()); throw new Exception("No container");
final Inventory inv = ((ContainerBlock)b).getInventory(); final Inventory inv = ((ContainerBlock)b).getInventory();
if (item.getAmount() < 0) { if (item.getAmount() < 0) {
item.setAmount(-item.getAmount()); item.setAmount(-item.getAmount());