First implementation of new commands system

This commit is contained in:
Robin Kupper
2011-05-06 15:46:49 +02:00
parent c94537b498
commit c1781d995a
5 changed files with 1015 additions and 279 deletions

View File

@@ -0,0 +1,470 @@
package de.diddiz.LogBlock;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import de.diddiz.LogBlock.QueryParams.BlockChangeType;
import de.diddiz.LogBlock.QueryParams.SummarizationMode;
public class CommandsHandler implements CommandExecutor
{
private final Logger log;
private final LogBlock logblock;
private final Config config;
public CommandsHandler(LogBlock logblock) {
this.logblock = logblock;
log = logblock.getServer().getLogger();
config = logblock.getConfig();
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (!cmd.getName().equalsIgnoreCase("lb"))
return false;
if (args.length == 0) {
sender.sendMessage(ChatColor.LIGHT_PURPLE + "LogBlock v" + logblock.getDescription().getVersion() + " by DiddiZ");
sender.sendMessage(ChatColor.LIGHT_PURPLE + "Type /lb help for help");
} else if (args[0].equalsIgnoreCase("help")) {
sender.sendMessage(ChatColor.LIGHT_PURPLE + "LogBlock Commands:");
if (logblock.checkPermission(sender, "logblock.me"))
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb me");
if (logblock.checkPermission(sender, "logblock.area")) {
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb area <radius>");
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb world");
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb player [name] <radius>");
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb block [type] <radius>");
}
if (logblock.checkPermission(sender, "logblock.rollback")) {
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb rollback [rollback mode]");
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb redo [redo mode]");
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb writelogfile [player]");
}
if (logblock.checkPermission(sender, "logblock.hide"))
sender.sendMessage(ChatColor.LIGHT_PURPLE + "/lb hide");
} else if (args[0].equalsIgnoreCase("tool")) {
if (sender instanceof Player) {
if (logblock.checkPermission(sender, "logblock.tool"))
giveTool((Player)sender, config.toolID);
else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else
sender.sendMessage(ChatColor.RED + "You have to be a player.");
} else if (args[0].equalsIgnoreCase("toolblock")) {
if (sender instanceof Player) {
if (logblock.checkPermission(sender, "logblock.toolblockID"))
giveTool((Player)sender, config.toolblockID);
else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else
sender.sendMessage(ChatColor.RED + "You have to be a player.");
} else if (args[0].equalsIgnoreCase("hide")) {
if (sender instanceof Player) {
if (logblock.checkPermission(sender, "logblock.hide")) {
if (logblock.getConsumer().hide((Player)sender))
sender.sendMessage(ChatColor.GREEN + "You are now hided and won't appear in any log. Type '/lb hide' again to unhide");
else
sender.sendMessage(ChatColor.GREEN + "You aren't hided anylonger.");
} else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else
sender.sendMessage(ChatColor.RED + "You have to be a player.");
} else if (args[0].equalsIgnoreCase("savequeue")) {
if (logblock.checkPermission(sender, "logblock.rollback"))
try {
new Thread(new CommandSaveQueue(sender, null)).run();
} catch (Exception ex) {
sender.sendMessage(ex.getMessage());
}
else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else if (args[0].equalsIgnoreCase("rollback") || args[0].equalsIgnoreCase("undo")) {
if (logblock.checkPermission(sender, "logblock.rollback")) {
try {
final List<String> argsList = Arrays.asList(args);
argsList.remove(1);
final QueryParams params = new QueryParams(logblock);
params.parseArgs(sender, argsList);
params.setLimit(-1);
params.setOrder(QueryParams.Order.DESC);
params.setSummarizationMode(QueryParams.SummarizationMode.NONE);
new Thread(new CommandRollback(sender, params)).run();
} catch (final Exception ex) {
sender.sendMessage(ex.getMessage());
}
} else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else if (args[0].equalsIgnoreCase("redo")) {
if (logblock.checkPermission(sender, "logblock.rollback")) {
try {
final List<String> argsList = Arrays.asList(args);
argsList.remove(1);
final QueryParams params = new QueryParams(logblock);
params.parseArgs(sender, argsList);
params.setLimit(-1);
params.setOrder(QueryParams.Order.ASC);
params.setSummarizationMode(QueryParams.SummarizationMode.NONE);
new Thread(new CommandRedo(sender, params)).run();
} catch (final Exception ex) {
sender.sendMessage(ex.getMessage());
}
} else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else if (args[0].equalsIgnoreCase("me")) {
if (sender instanceof Player) {
if (logblock.checkPermission(sender, "logblock.rollback")) {
final QueryParams params = new QueryParams(logblock);
params.setPlayer(((Player)sender).getName());
params.setSummarizationMode(SummarizationMode.TYPES);
} else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else
sender.sendMessage(ChatColor.RED + "You have to be a player.");
} else if (args[0].equalsIgnoreCase("writelogfile")) {
if (logblock.checkPermission(sender,"logblock.rollback")) {
try {
final List<String> argsList = Arrays.asList(args);
argsList.remove(1);
final QueryParams params = new QueryParams(logblock);
params.parseArgs(sender, argsList);
params.setLimit(-1);
params.setBlockChangeType(BlockChangeType.ALL);
params.setSummarizationMode(SummarizationMode.NONE);
new Thread(new CommandWriteLogFile(sender, params)).run();
} catch (final Exception ex) {
sender.sendMessage(ex.getMessage());
}
} else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("tp")) {
if (sender instanceof Player) {
if (logblock.checkPermission(sender,"logblock.tp")) {
try {
final List<String> argsList = Arrays.asList(args);
argsList.remove(1);
final QueryParams params = new QueryParams(logblock);
params.parseArgs(sender, argsList);
params.setLimit(1);
new Thread(new CommandTeleport(sender, null)).run();
} catch (final Exception ex) {
sender.sendMessage(ex.getMessage());
}
} else
sender.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else
sender.sendMessage(ChatColor.RED + "You have to be a player.");
} else if (QueryParams.isKeyWord(args[0])) {
try {
final QueryParams params = new QueryParams(logblock);
params.parseArgs(sender, Arrays.asList(args));
new Thread(new CommandLookup(sender, params)).run();
} catch (final Exception ex) {
log.log(Level.SEVERE, "Error at Command", ex);
sender.sendMessage(ex.getMessage());
}
}
return true;
}
private abstract class LBCommand implements Runnable
{
protected final CommandSender sender;
protected final QueryParams params;
protected Connection conn = null;
protected Statement state = null;
protected ResultSet rs = null;
LBCommand(CommandSender sender, QueryParams params) throws Exception {
this.sender = sender;
this.params = params;
try {
conn = logblock.getConnection();
conn.setAutoCommit(false);
state = conn.createStatement();
rs = state.executeQuery(params.getQuery());
} catch (SQLException ex) {
close();
log.log(Level.SEVERE, "[LogBlock CommandsHandler] Error while executing query", ex);
throw new Exception("Error while executing query");
}
}
protected void close() {
try {
if (conn != null)
conn.close();
if (state != null)
state.close();
if (rs != null)
rs.close();
} catch (final SQLException ex) {
log.log(Level.SEVERE, "[LogBlock CommandHandler] SQL exception on close", ex);
}
}
}
private class CommandLookup extends LBCommand
{
CommandLookup(CommandSender sender, QueryParams params) throws Exception {
super(sender, params);
}
@Override
public void run() {
try {
final SummarizationMode sum = params.getSummarizationMode();
final HistoryFormatter histformatter = new HistoryFormatter(sum);
sender.sendMessage(ChatColor.DARK_AQUA + params.getTitle());
if (rs.next()) {
rs.beforeFirst();
if (sum == SummarizationMode.TYPES)
sender.sendMessage(ChatColor.GOLD + String.format("%-6s %-6s %s", "Creat", "Destr", "Block"));
else if (sum == SummarizationMode.PLAYERS)
sender.sendMessage(ChatColor.GOLD + String.format("%-6d %-6d %s", rs.getInt("created"), rs.getInt("destroyed"), rs.getString("playername")));
while (rs.next())
sender.sendMessage(ChatColor.GOLD + histformatter.format(rs));
} else
sender.sendMessage(ChatColor.DARK_AQUA + "No results found.");
} catch (final SQLException ex) {
sender.sendMessage(ChatColor.RED + "SQL exception");
log.log(Level.SEVERE, "[LogBlock Lookup] SQL exception", ex);
} finally {
close();
}
}
}
private class CommandWriteLogFile extends LBCommand
{
CommandWriteLogFile(CommandSender sender, QueryParams params) throws Exception {
super(sender, params);
}
@Override
public void run() {
try {
final File file = new File ("plugins/LogBlock/log/" + params.getTitle() + ".log");
final FileWriter writer = new FileWriter(file);
final String newline = System.getProperty("line.separator");
final HistoryFormatter histformatter = new HistoryFormatter(params.getSummarizationMode());
file.getParentFile().mkdirs();
sender.sendMessage(ChatColor.GREEN + "Creating " + file.getName());
while (rs.next()) {
writer.write(histformatter.format(rs) + newline);
}
writer.close();
sender.sendMessage(ChatColor.GREEN + "Done");
} catch (final SQLException ex) {
sender.sendMessage(ChatColor.RED + "SQL exception");
log.log(Level.SEVERE, "[LogBlock WriteLogFile] SQL exception", ex);
} catch (final IOException ex) {
sender.sendMessage(ChatColor.RED + "IO exception");
log.log(Level.SEVERE, "[LogBlock WriteLogFile] IO exception", ex);
} finally {
close();
}
}
}
private class CommandSaveQueue extends LBCommand
{
CommandSaveQueue(CommandSender sender, QueryParams params) throws Exception {
super(sender, params);
}
@Override
public void run() {
final Consumer consumer = logblock.getConsumer();
sender.sendMessage(ChatColor.DARK_AQUA + "Current queue size: " + consumer.getQueueSize());
while (consumer.getQueueSize() > 0) {
consumer.run();
}
sender.sendMessage(ChatColor.GREEN + "Queue saved successfully");
}
}
private class CommandTeleport extends LBCommand
{
CommandTeleport(CommandSender sender, QueryParams params) throws Exception {
super(sender, params);
}
@Override
public void run() {
try {
if (rs.next()) {
final Player player = (Player)sender;
player.teleport(new Location(params.getWorld(), rs.getInt("x"), rs.getInt("y"), rs.getInt("z")));
} else
sender.sendMessage(ChatColor.RED + "Query returned no result");
} catch (final SQLException ex) {
sender.sendMessage(ChatColor.RED + "SQL exception");
log.log(Level.SEVERE, "[LogBlock WriteLogFile] SQL exception", ex);
} finally {
close();
}
}
}
private class CommandRollback extends LBCommand
{
CommandRollback(CommandSender sender, QueryParams params) throws Exception {
super(sender, params);
}
@Override
public void run() {
try {
final WorldEditor editor = new WorldEditor(logblock, this, params.getWorld());
while (rs.next()) {
editor.queueBlockChange(rs.getInt("type"), rs.getInt("replaced"), rs.getByte("data"), rs.getInt("x"), rs.getInt("y"), rs.getInt("z"));
}
final int changes = editor.getSize();
sender.sendMessage(ChatColor.GREEN + "" + changes + " Changes found.");
final long start = System.currentTimeMillis();
if (!editor.start()) {
sender.sendMessage(ChatColor.RED + "Failed to schedule rollback task");
return;
}
synchronized (this) {
try {
this.wait();
} catch (final InterruptedException e) {
sender.sendMessage(ChatColor.RED + "Rollback Interrupted");
log.severe("[LogBlock Rollback] Interrupted");
}
}
sender.sendMessage(ChatColor.GREEN + "Rollback finished successfully");
sender.sendMessage(ChatColor.GREEN + "Undid " + editor.getSuccesses() + " of " + changes + " changes (" + editor.getErrors() + " errors, " + editor.getBlacklistCollisions() + " blacklist collisions)");
sender.sendMessage(ChatColor.GREEN + "Took: " + (System.currentTimeMillis() - start) + "ms");
} catch (final SQLException ex) {
sender.sendMessage(ChatColor.RED + "SQL exception");
log.log(Level.SEVERE, "[LogBlock Rollback] SQL exception", ex);
} finally {
close();
}
}
}
private class CommandRedo extends LBCommand
{
CommandRedo(CommandSender sender, QueryParams params) throws Exception {
super(sender, params);
}
@Override
public void run() {
try {
final WorldEditor editor = new WorldEditor(logblock, this, params.getWorld());
while (rs.next()) {
editor.queueBlockChange(rs.getInt("replaced"), rs.getInt("type"), rs.getByte("data"), rs.getInt("x"), rs.getInt("y"), rs.getInt("z"));
}
final int changes = editor.getSize();
sender.sendMessage(ChatColor.GREEN + "" + changes + " Changes found.");
final long start = System.currentTimeMillis();
if (!editor.start()) {
sender.sendMessage(ChatColor.RED + "Failed to schedule redo task");
return;
}
synchronized (this) {
try {
this.wait();
} catch (final InterruptedException e) {
sender.sendMessage(ChatColor.RED + "Redo Interrupted");
log.severe("[LogBlock Redo] Interrupted");
}
}
sender.sendMessage(ChatColor.GREEN + "Redo finished successfully");
sender.sendMessage(ChatColor.GREEN + "Redid " + editor.getSuccesses() + " of " + changes + " changes (" + editor.getErrors() + " errors, " + editor.getBlacklistCollisions() + " blacklist collisions)");
sender.sendMessage(ChatColor.GREEN + "Took: " + (System.currentTimeMillis() - start) + "ms");
} catch (final SQLException ex) {
sender.sendMessage(ChatColor.RED + "SQL exception");
log.log(Level.SEVERE, "[LogBlock Redo] SQL exception", ex);
} finally {
close();
}
}
}
private String getMaterialName(int type) {
return Material.getMaterial(type).toString().toLowerCase().replace('_', ' ');
}
private class HistoryFormatter
{
private final SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss");
private final SummarizationMode sum;
HistoryFormatter(SummarizationMode sum) {
this.sum = sum;
}
String format(ResultSet rs) {
try {
if (sum == SummarizationMode.NONE) {
final StringBuffer msg = new StringBuffer(formatter.format(rs.getTimestamp("date")) + " " + rs.getString("playername") + " ");
final int type = rs.getInt("type");
final int replaced = rs.getInt("replaced");
if ((type == 63 || type == 68) && rs.getString("signtext") != null)
msg.append("created " + rs.getString("signtext"));
else if (type == replaced) {
if (type == 23 || type == 54 || type == 61)
msg.append("looked inside " + getMaterialName(type));
} else if (type == 0)
msg.append("destroyed " + getMaterialName(replaced));
else if (replaced == 0)
msg.append("created " + getMaterialName(type));
else
msg.append("replaced " + getMaterialName(replaced) + " with " + getMaterialName(type));
return msg.toString();
} else if (sum == SummarizationMode.TYPES)
return fillWithSpaces(rs.getInt("created")) + fillWithSpaces(rs.getInt("destroyed")) + Material.getMaterial(rs.getInt("type")).toString().toLowerCase().replace('_', ' ');
else
return fillWithSpaces(rs.getInt("created")) + fillWithSpaces(rs.getInt("destroyed")) + rs.getString("playername");
} catch (final Exception ex) {
return null;
}
}
private String fillWithSpaces(Integer number) {
final StringBuffer filled = new StringBuffer(number.toString());
final int neededSpaces = (36 - filled.length() * 6) / 4;
for (int i = 0; i < neededSpaces; i++)
filled.append(' ');;
return filled.toString();
}
}
private void giveTool(Player player, int tool) {
if (player.getInventory().contains(config.toolID))
player.sendMessage(ChatColor.RED + "You have alredy a tool");
else {
final int free = player.getInventory().firstEmpty();
if (free >= 0) {
player.getInventory().setItem(free, player.getItemInHand());
player.setItemInHand(new ItemStack(config.toolID, 1));
player.sendMessage(ChatColor.GREEN + "Here is your tool.");
} else
player.sendMessage(ChatColor.RED + "You have no empty slot in your inventory");
}
}
}

View File

@@ -13,23 +13,15 @@ import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
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.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import com.nijiko.permissions.PermissionHandler;
import com.nijikokun.bukkit.Permissions.Permissions;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
import com.sk89q.worldedit.bukkit.selections.Selection;
import de.diddiz.util.ConnectionPool;
import de.diddiz.util.Download;
@@ -100,6 +92,7 @@ public class LogBlock extends JavaPlugin
getServer().getPluginManager().disablePlugin(this);
return;
}
getCommand("lb").setExecutor(new CommandsHandler(this));
if (getServer().getPluginManager().getPlugin("Permissions") != null) {
permissions = ((Permissions)getServer().getPluginManager().getPlugin("Permissions")).getHandler();
log.info("[LogBlock] Permissions enabled");
@@ -168,268 +161,6 @@ public class LogBlock extends JavaPlugin
log.info("LogBlock disabled.");
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (!cmd.getName().equalsIgnoreCase("lb"))
return false;
if (!(sender instanceof Player)) {
sender.sendMessage("You aren't a player");
return true;
}
final Player player = (Player)sender;
if (args.length == 0) {
player.sendMessage(ChatColor.LIGHT_PURPLE + "LogBlock v" + getDescription().getVersion() + " by DiddiZ");
player.sendMessage(ChatColor.LIGHT_PURPLE + "Type /lb help for help");
} else if (args[0].equalsIgnoreCase("tool")) {
if (checkPermission(player, "logblock.tool")) {
if (player.getInventory().contains(config.toolID))
player.sendMessage(ChatColor.RED + "You have alredy a tool");
else {
final int free = player.getInventory().firstEmpty();
if (free >= 0) {
player.getInventory().setItem(free, player.getItemInHand());
player.setItemInHand(new ItemStack(config.toolID, 1));
player.sendMessage(ChatColor.GREEN + "Here is your tool.");
} else
player.sendMessage(ChatColor.RED + "You have no empty slot in your inventory");
}
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else if (args[0].equalsIgnoreCase("toolblock")) {
if (checkPermission(player, "logblock.toolblock")) {
if (player.getInventory().contains(config.toolblockID))
player.sendMessage(ChatColor.RED + "You have alredy a tool");
else {
final int free = player.getInventory().firstEmpty();
if (free >= 0) {
player.getInventory().setItem(free, player.getItemInHand());
player.setItemInHand(new ItemStack(config.toolblockID, 1));
player.sendMessage(ChatColor.GREEN + "Here's your tool.");
} else
player.sendMessage(ChatColor.RED + "You have no empty slot in your inventory");
}
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else if (args[0].equalsIgnoreCase("hide")) {
if (checkPermission(player, "logblock.hide")) {
if (consumer.hide(player))
player.sendMessage(ChatColor.GREEN + "You are now hided and won't appear in any log. Type '/lb hide' again to unhide");
else
player.sendMessage(ChatColor.GREEN + "You aren't hided anylonger.");
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else if (args[0].equalsIgnoreCase("savequeue")) {
if (checkPermission(player, "logblock.rollback")) {
player.sendMessage(ChatColor.DARK_AQUA + "Current queue size: " + consumer.getQueueSize());
final Thread thread = new Thread(consumer);
while (consumer.getQueueSize() > 0) {
thread.run();
}
player.sendMessage(ChatColor.GREEN + "Queue saved successfully");
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this.");
} else if (args[0].equalsIgnoreCase("area")) {
if (checkPermission(player,"logblock.area")) {
int radius = config.defaultDist;
if (args.length == 2 && isInt(args[1]))
radius = Integer.parseInt(args[1]);
new Thread(new AreaStats(this, player, radius)).start();
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("world")) {
if (checkPermission(player,"logblock.area"))
new Thread(new AreaStats(this, player, Short.MAX_VALUE)).start();
else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("player")) {
if (checkPermission(player,"logblock.area")) {
if (args.length == 2 || args.length == 3) {
int radius = config.defaultDist;
if (args.length == 3 && isInt(args[2]))
radius = Integer.parseInt(args[2]);
new Thread(new PlayerAreaStats(this, player, args[1], radius)).start();
} else
player.sendMessage(ChatColor.RED + "Usage: /lb player [name] <radius>");
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("block")) {
if (checkPermission(player,"logblock.area")) {
if (args.length == 2 || args.length == 3) {
final Material mat = Material.matchMaterial(args[1]);
int radius = config.defaultDist;
if (args.length == 3 && isInt(args[2]))
radius = Integer.parseInt(args[2]);
if (mat != null)
new Thread(new AreaBlockSearch(this, player, mat.getId(), radius)).start();
else
player.sendMessage(ChatColor.RED + "Can't find any item like '" + args[1] + "'");
} else
player.sendMessage(ChatColor.RED + "Usage: /lb block [type] <radius>");
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("rollback") || args[0].equalsIgnoreCase("undo")) {
if (checkPermission(player,"logblock.rollback")) {
if (args.length >= 2) {
int minutes = config.defaultTime;
if (args[1].equalsIgnoreCase("player")) {
if (args.length == 3 || args.length == 5) {
if (args.length == 5)
minutes = parseTimeSpec(args[3], args[4]);
player.sendMessage(ChatColor.GREEN + "Rolling back " + args[2] + " by " + minutes + " minutes.");
getServer().getScheduler().scheduleAsyncDelayedTask(this, new Rollback(this, player, args[2], -1, null, minutes, false));
} else
player.sendMessage(ChatColor.RED + "Usage: /lb rollback player [name] <time> <minutes|hours|days>");
} else if (args[1].equalsIgnoreCase("area")) {
if (args.length == 3 || args.length == 5) {
if (args.length == 5)
minutes = parseTimeSpec(args[3], args[4]);
if (isInt(args[2])) {
player.sendMessage(ChatColor.GREEN + "Rolling back area within " + args[2] + " blocks of you by " + minutes + " minutes.");
getServer().getScheduler().scheduleAsyncDelayedTask(this, new Rollback(this, player, null, Integer.parseInt(args[2]), null, minutes, false));
} else
player.sendMessage(ChatColor.RED + "Can't parse to an int: " + args[2]);
} else
player.sendMessage(ChatColor.RED + "Usage /lb rollback area [radius] <time> <minutes|hours|days>");
} else if (args[1].equalsIgnoreCase("playerarea")) {
if (args.length == 4 || args.length == 6) {
if (args.length == 6)
minutes = parseTimeSpec(args[4], args[5]);
if (isInt(args[3])) {
player.sendMessage(ChatColor.GREEN + "Rolling back " + args[2] + " within " + args[3] + " blocks by " + minutes + " minutes.");
getServer().getScheduler().scheduleAsyncDelayedTask(this, new Rollback(this, player, args[2], Integer.parseInt(args[3]), null, minutes, false));
} else
player.sendMessage(ChatColor.RED + "Can't parse to an int: " + args[3]);
} else
player.sendMessage(ChatColor.RED + "Usage: /lb rollback playerarea [player] [radius] <time> <minutes|hours|days>");
} else if (args[1].equalsIgnoreCase("selection")) {
if (args.length == 2 || args.length == 4) {
if (args.length == 4)
minutes = parseTimeSpec(args[2], args[3]);
final Plugin we = getServer().getPluginManager().getPlugin("WorldEdit");
if (we != null) {
final Selection sel = ((WorldEditPlugin)we).getSelection(player);
if (sel != null) {
if (sel instanceof CuboidSelection) {
player.sendMessage(ChatColor.GREEN + "Rolling back selection by " + minutes + " minutes.");
getServer().getScheduler().scheduleAsyncDelayedTask(this, new Rollback(this, player, null, -1, sel, minutes, false));
} else
player.sendMessage(ChatColor.RED + "You have to define a cuboid selection");
} else
player.sendMessage(ChatColor.RED + "No selection defined");
} else
player.sendMessage(ChatColor.RED + "WorldEdit plugin not found");
} else
player.sendMessage(ChatColor.RED + "Usage: /lb rollback selection <time> <minutes|hours|days>");
} else
player.sendMessage(ChatColor.RED + "Wrong rollback mode");
} else {
player.sendMessage(ChatColor.RED + "Usage: ");
player.sendMessage(ChatColor.RED + "/lb rollback player [name] <time> <minutes|hours|days>");
player.sendMessage(ChatColor.RED + "/lb rollback area [radius] <time> <minutes|hours|days>");
player.sendMessage(ChatColor.RED + "/lb rollback playerarea [name] [radius] <time> <minutes|hours|days>");
player.sendMessage(ChatColor.RED + "/lb rollback selection <time> <minutes|hours|days>");
}
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("redo")) {
if (checkPermission(player,"logblock.rollback")) {
if (args.length >= 2) {
int minutes = config.defaultTime;
if (args[1].equalsIgnoreCase("player")) {
if (args.length == 3 || args.length == 5) {
if (args.length == 5)
minutes = parseTimeSpec(args[3], args[4]);
player.sendMessage(ChatColor.GREEN + "Redoing " + args[2] + " for " + minutes + " minutes.");
getServer().getScheduler().scheduleAsyncDelayedTask(this, new Rollback(this, player, args[2], -1, null, minutes, true));
} else
player.sendMessage(ChatColor.RED + "Usage: /lb redo player [name] <time> <minutes|hours|days>");
} else if (args[1].equalsIgnoreCase("area")) {
if (args.length == 3 || args.length == 5) {
if (args.length == 5)
minutes = parseTimeSpec(args[3], args[4]);
if (isInt(args[2])) {
player.sendMessage(ChatColor.GREEN + "Redoing area within " + args[2] + " blocks of you for " + minutes + " minutes.");
getServer().getScheduler().scheduleAsyncDelayedTask(this, new Rollback(this, player, null, Integer.parseInt(args[2]), null, minutes, true));
} else
player.sendMessage(ChatColor.RED + "Can't parse to an int: " + args[2]);
} else
player.sendMessage(ChatColor.RED + "Usage /lb redo area [radius] <time> <minutes|hours|days>");
} else if (args[1].equalsIgnoreCase("playerarea")) {
if (args.length == 4 || args.length == 6) {
if (args.length == 6)
minutes = parseTimeSpec(args[4], args[5]);
if (isInt(args[3])) {
player.sendMessage(ChatColor.GREEN + "Redoing " + args[2] + " within " + args[3] + " blocks for " + minutes + " minutes.");
getServer().getScheduler().scheduleAsyncDelayedTask(this, new Rollback(this, player, args[2], Integer.parseInt(args[3]), null, minutes, true));
} else
player.sendMessage(ChatColor.RED + "Can't parse to an int: " + args[3]);
} else
player.sendMessage(ChatColor.RED + "Usage: /lb redo playerarea [player] [radius] <time> <minutes|hours|days>");
} else if (args[1].equalsIgnoreCase("selection")) {
if (args.length == 2 || args.length == 4) {
if (args.length == 4)
minutes = parseTimeSpec(args[2], args[3]);
final Plugin we = getServer().getPluginManager().getPlugin("WorldEdit");
if (we != null) {
final Selection sel = ((WorldEditPlugin)we).getSelection(player);
if (sel != null) {
if (sel instanceof CuboidSelection) {
player.sendMessage(ChatColor.GREEN + "Redoing selection for " + minutes + " minutes.");
getServer().getScheduler().scheduleAsyncDelayedTask(this, new Rollback(this, player, null, -1, sel, minutes, true));
} else
player.sendMessage(ChatColor.RED + "You have to define a cuboid selection");
} else
player.sendMessage(ChatColor.RED + "No selection defined");
} else
player.sendMessage(ChatColor.RED + "WorldEdit plugin not found");
} else
player.sendMessage(ChatColor.RED + "Usage: /lb redo selection <time> <minutes|hours|days>");
} else
player.sendMessage(ChatColor.RED + "Wrong redo mode");
} else {
player.sendMessage(ChatColor.RED + "Usage:");
player.sendMessage(ChatColor.RED + "/lb redo player [name] <time> <minutes|hours|days>");
player.sendMessage(ChatColor.RED + "/lb redo area [radius] <time> <minutes|hours|days>");
player.sendMessage(ChatColor.RED + "/lb redo playerarea [name] [radius] <time> <minutes|hours|days>");
player.sendMessage(ChatColor.RED + "/lb redo selection <time> <minutes|hours|days>");
}
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("writelogfile")) {
if (checkPermission(player,"logblock.rollback")) {
if (args.length == 2)
new Thread(new WriteLogFile(this, player, args[1])).start();
else
player.sendMessage(ChatColor.RED + "Usage: /lb writelogfile [name]");
} else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("me")) {
if (checkPermission(player,"logblock.me"))
new Thread(new PlayerAreaStats(this, player, player.getName(), Short.MAX_VALUE)).start();
else
player.sendMessage(ChatColor.RED + "You aren't allowed to do this");
} else if (args[0].equalsIgnoreCase("help")) {
player.sendMessage(ChatColor.LIGHT_PURPLE + "LogBlock Commands:");
if (checkPermission(player, "logblock.me"))
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb me");
if (checkPermission(player, "logblock.area")) {
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb area <radius>");
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb world");
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb player [name] <radius>");
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb block [type] <radius>");
}
if (checkPermission(player, "logblock.rollback")) {
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb rollback [rollback mode]");
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb redo [redo mode]");
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb writelogfile [player]");
}
if (checkPermission(player, "logblock.hide"))
player.sendMessage(ChatColor.LIGHT_PURPLE + "/lb hide");
} else
player.sendMessage(ChatColor.RED + "Wrong argument. Type /lb help for help");
return true;
}
private boolean checkTables() {
final Connection conn = getConnection();
Statement state = null;
@@ -522,15 +253,6 @@ public class LogBlock extends JavaPlugin
return min;
}
private boolean isInt(String str) {
try {
Integer.parseInt(str);
return true;
} catch (final NumberFormatException ex) {
return false;
}
}
public Connection getConnection() {
try {
return pool.getConnection();

View File

@@ -0,0 +1,392 @@
package de.diddiz.LogBlock;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
import com.sk89q.worldedit.bukkit.selections.Selection;
public class QueryParams
{
private final LogBlock logblock;
private final List<String> players = new ArrayList<String>();
private final List<Integer> types = new ArrayList<Integer>();
private Location loc = null;
private int radius = -1;
private Selection sel = null;
private int minutes = -1;
private SummarizationMode sum = SummarizationMode.NONE;;
private BlockChangeType bct = BlockChangeType.BOTH;
private int limit = 15;
private World world = null;
private Order order = Order.DESC;
public QueryParams(LogBlock logblock) {
this.logblock = logblock;
}
public void merge (QueryParams params) {
loc = params.getLoc();
radius = params.getRadius();
sel = params.getSel();
minutes = params.getMinutes();
sum = params.getSummarizationMode();
bct = params.getBlockChangeType();
limit = params.limit;
world = params.getWorld();
order = params.getOrder();
}
public void parseArgs(CommandSender sender, List<String> args) throws Exception {
Player player = null;
if (sender instanceof Player)
player = (Player)sender;
String name = "Console";
if (player != null)
name = player.getName();
final Session session = logblock.getSession(name);
if (!args.isEmpty() && args.get(0).equalsIgnoreCase("last") && session.getLastQuery() != null)
merge(session.getLastQuery());
if (player != null && world == null)
world = player.getWorld();
for (int i = 0; i < args.size(); i++) {
final String param = args.get(i).toLowerCase();
final String[] values = getValues(args, i +1);
if (values != null)
i += values.length;
if (param.equals("player")) {
if (values == null || values.length < 1)
throw new Exception("No or wrong count of arguments for '" + param + "'");
for (final String playerName : values) {
if (playerName.length() > 0)
players.add(playerName);
}
} else if (param.equals("block")) {
if (values == null || values.length < 1)
throw new Exception("No or wrong count of arguments for '" + param + "'");
for (final String blockName : values) {
final Material mat = Material.matchMaterial(blockName);
if (mat == null)
throw new Exception("No material matching: '" + blockName + "'");
types.add(mat.getId());
}
} else if (param.equals("area")) {
if (player == null)
throw new Exception("You have to ba a player to use area");
if (values == null) {
radius = logblock.getConfig().defaultDist;
loc = player.getLocation();
} else {
if (!isInt(values[0]))
throw new Exception("Not a number: '" + values[0] + "'");
radius = Integer.parseInt(values[0]);
loc = player.getLocation();
}
} else if (param.equals("selection")) {
if (player == null)
throw new Exception("You have to ba a player to use selection");
final Plugin we = player.getServer().getPluginManager().getPlugin("WorldEdit");
if (we == null)
throw new Exception("WorldEdit plugin not found");
final Selection sel = ((WorldEditPlugin)we).getSelection(player);
if (sel == null)
throw new Exception("No selection defined");
if (!(sel instanceof CuboidSelection))
throw new Exception("You have to define a cuboid selection");
this.sel = sel;
} else if (param.equals("time")) {
if (values == null)
minutes = logblock.getConfig().defaultTime;
else {
if (values.length != 2)
throw new Exception("Wrong count of arguments for '" + param + "'");
if (!isInt(values[0]))
throw new Exception("Not a number: '" + values[0] + "'");
minutes = Integer.parseInt(values[0]);
if (values[1].startsWith("h"))
minutes *= 60;
else if (values[1].startsWith("d"))
minutes *= 60*24;
}
} else if (param.equals("since")) {
throw new Exception("Since parameter not implemented yet");
} else if (param.equals("sum")) {
if (values == null || values.length != 1)
throw new Exception("No or wrong count of arguments for '" + param + "'");
if (values[0].startsWith("p"))
sum = SummarizationMode.PLAYERS;
else if (values[0].startsWith("b"))
sum = SummarizationMode.TYPES;
else if (values[0].startsWith("n"))
sum = SummarizationMode.NONE;
else
throw new Exception("Wrong summarization mode");
} else if (param.equals("created")) {
bct = BlockChangeType.CREATED;
} else if (param.equals("destroyed")) {
bct = BlockChangeType.DESTROYED;
} else if (param.equals("chestaccess")) {
bct = BlockChangeType.CHESTACCESS;
} else if (param.equals("limit")) {
if (values.length != 1)
throw new Exception("Wrong count of arguments for '" + param + "'");
if (!isInt(values[0]))
throw new Exception("Not a number: '" + values[0] + "'");
limit = Integer.parseInt(values[0]);
} else if (param.equals("world")) {
if (values.length != 1)
throw new Exception("Wrong count of arguments for '" + param + "'");
if (sender.getServer().getWorld(values[0]) == null)
throw new Exception("There is no world called '" + values[0] + "'");
world = sender.getServer().getWorld(values[0]);
} else if (param.equals("ASC")) {
order = Order.ASC;
} else if (param.equals("DESC")) {
order = Order.DESC;
} else
throw new Exception("Not a valid argument: '" + param + "'");
}
if (world == null)
throw new Exception("No world specified");
if (!logblock.getConfig().tables.containsKey(world.getName().hashCode()))
throw new Exception("This world ('" + world.getName() + "') isn't logged");
session.setLast(this);
}
public void setPlayer(String playerName) {
players.clear();
players.add(playerName);
}
public List<String> getPlayers() {
return players;
}
public List<Integer> getTypes() {
return types;
}
public Location getLoc() {
return loc;
}
public int getRadius() {
return radius;
}
public Selection getSel() {
return sel;
}
public int getMinutes() {
return minutes;
}
public int getLimit() {
return limit;
}
public Order getOrder() {
return order;
}
public void setLimit(int limit) {
this.limit = limit;
}
public void setOrder(Order order) {
this.order = order;
}
public SummarizationMode getSummarizationMode() {
return sum;
}
public void setSummarizationMode(SummarizationMode sum) {
this.sum = sum;
}
public void setBlockChangeType(BlockChangeType bct) {
this.bct = bct;
}
public BlockChangeType getBlockChangeType() {
return bct;
}
public World getWorld() {
return world;
}
public String getTable() {
return logblock.getConfig().tables.get(world.getName().hashCode());
}
public String getTitle() {
final StringBuffer buffer = new StringBuffer();
if (!types.isEmpty()) {
for (int i = 0; i < types.size(); i++) {
buffer.append(getMaterialName(types.get(i)) + ", ");
}
buffer.deleteCharAt(buffer.length() - 2);
} else
buffer.append("Block ");
if (bct == BlockChangeType.CREATED)
buffer.append("creations ");
else if (bct == BlockChangeType.DESTROYED)
buffer.append("destructions ");
else
buffer.append("changes ");
if (!players.isEmpty()) {
buffer.append("from player ");
for (int i = 0; i < players.size(); i++) {
buffer.append(players.get(i) + ", ");
}
buffer.deleteCharAt(buffer.length() - 2);
}
if (loc != null && radius >= 0)
buffer.append("within " + radius + " blocks of you:");
else if (sel != null)
buffer.append("in selection:");
else
buffer.append("in entire world:");
buffer.setCharAt(0,String.valueOf(buffer.charAt(0)).toUpperCase().toCharArray()[0]);
return buffer.toString();
}
public String getQuery() {
final StringBuffer where = new StringBuffer();
switch (bct) {
case ALL:
if (!types.isEmpty()) {
where.append('(');
for (final int type: types) {
where.append("type = " + type + " OR replaced = " + type + " OR ");
}
where.delete(where.length() - 5, where.length() - 1);
where.append(") AND ");
}
break;
case BOTH:
where.append("type <> replaced AND ");
if (!types.isEmpty()) {
where.append('(');
for (final int type: types) {
where.append("type = " + type + " OR replaced = " + type + " OR ");
}
where.delete(where.length() - 5, where.length() - 1);
where.append(") AND ");
}
break;
case CREATED:
where.append("type <> replaced AND ");
if (!types.isEmpty()) {
where.append('(');
for (final int type: types) {
where.append("type = " + type + " OR ");
}
where.delete(where.length() - 5, where.length() - 1);
where.append(") AND ");
} else
where.append("type > 0 AND ");
break;
case DESTROYED:
where.append("type <> replaced AND ");
if (!types.isEmpty()) {
where.append('(');
for (final int type: types) {
where.append("replaced = " + type + " OR ");
}
where.delete(where.length() - 5, where.length() - 1);
where.append(") AND ");
} else
where.append("replaced > 0 AND ");
break;
case CHESTACCESS:
where.append("type = replaced AND (type = 23 OR type = 54 OR type = 61) ");
break;
}
if (!players.isEmpty() && sum != SummarizationMode.PLAYERS) {
for (final String playerName: players) {
where.append("playername = '" + playerName + "' AND ");
}
}
if (loc != null && radius >= 0)
where.append("x > '" + (loc.getBlockX() - radius) + "' AND x < '" + (loc.getBlockX() + radius) + "' AND z > '" + (loc.getBlockZ() - radius) + "' AND z < '" + (loc.getBlockZ() + radius) + "' AND ");
else if (sel != null)
where.append("x >= '"+ sel.getMinimumPoint().getBlockX() + "' AND x <= '" + sel.getMaximumPoint().getBlockX() + "' AND y >= '" + sel.getMinimumPoint().getBlockY() + "' AND y <= '" + sel.getMaximumPoint().getBlockY() + "' AND z >= '" + sel.getMinimumPoint().getBlockZ() + "' AND z <= '" + sel.getMaximumPoint().getBlockZ() + "' AND ");
if (minutes >= 0)
where.append("date > date_sub(now(), INTERVAL " + minutes + " MINUTE) AND ");
where.delete(where.length() - 5, where.length() - 1);
if (sum == SummarizationMode.NONE) {
final StringBuffer sql = new StringBuffer("SELECT date, replaced, type, playername FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) ");
if (bct == BlockChangeType.ALL)
sql.append("LEFT JOIN `" + getTable() + "-sign` USING (id) ");
if (bct == BlockChangeType.ALL || bct == BlockChangeType.CHESTACCESS)
sql.append("LEFT JOIN `" + getTable() + "-chest` USING (id) ");
sql.append("WHERE " + where + "ORDER BY date " + order + ", id " + order + " ");
if (limit > 0)
sql.append("LIMIT " + limit);
return sql.toString();
} else if (sum == SummarizationMode.TYPES)
return "SELECT type, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT type, count(type) AS created, 0 AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) WHERE " + where + "GROUP BY type) UNION (SELECT replaced AS type, 0 AS created, count(replaced) AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) WHERE " + where + "GROUP BY replaced)) AS t GROUP BY type ORDER BY SUM(created) + SUM(destroyed) DESC LIMIT 15";
else {
return "SELECT playername, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT playerid, count(type) AS created, 0 AS destroyed FROM `" + getTable() + "` WHERE " + where + "GROUP BY playerid) UNION (SELECT playerid, 0 AS created, count(replaced) AS destroyed FROM `" + getTable() + "` WHERE " + where + "GROUP BY playerid)) AS t INNER JOIN `lb-players` USING (playerid) GROUP BY playerid ORDER BY SUM(created) + SUM(destroyed) DESC LIMIT 15";
}
}
private String getMaterialName(int type) {
return Material.getMaterial(type).toString().toLowerCase().replace('_', ' ');
}
private String[] getValues(List<String> args, int offset) {
int i;
for (i = offset; i < args.size(); i++) {
if (isKeyWord(args.get(i)))
break;
}
if (i == offset)
return null;
else {
final String[] values = new String[i - offset];
System.arraycopy(args.toArray(), offset, values, 0, i - offset);
return values;
}
}
private boolean isInt(String str) {
try {
Integer.parseInt(str);
return true;
} catch (final Exception ex) {
return false;
}
}
public static boolean isKeyWord(String param) {
final String key = new String(param).toLowerCase();
if (key.equals("player") || key.equals("area") || key.equals("selection") || key.equals("block") || key.equals("sum") || key.equals("destroyed") || key.equals("created") || key.equals("time") || key.equals("since") || key.equals("limit") || key.equals("world") || key.equals("asc") || key.equals("desc"))
return true;
return false;
}
public static enum SummarizationMode {
NONE, TYPES, PLAYERS
}
public static enum BlockChangeType {
BOTH, CREATED, DESTROYED, CHESTACCESS, ALL
}
public static enum Order {
ASC, DESC
}
}

View File

@@ -0,0 +1,13 @@
package de.diddiz.LogBlock;
public class Session {
private QueryParams last = null;
public QueryParams getLastQuery() {
return last;
}
public void setLast(QueryParams params) {
last = params;
}
}

View File

@@ -0,0 +1,139 @@
package de.diddiz.LogBlock;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Logger;
import org.bukkit.World;
import org.bukkit.block.Block;
public class WorldEditor implements Runnable
{
private final Logger log;
private final LogBlock logblock;
private final Config config;
private final Object caller;
private final LinkedBlockingQueue<Edit> edits = new LinkedBlockingQueue<Edit>();
private final World world;
private int taskID;
private int successes = 0;
private int errors = 0;
private int blacklistCollisions = 0;
WorldEditor(LogBlock logblock, Object caller, World world) {
log = logblock.getServer().getLogger();
this.logblock = logblock;
config = logblock.getConfig();
this.caller = caller;
this.world = world;
}
public int getSize() {
return edits.size();
}
public int getSuccesses() {
return successes;
}
public int getErrors() {
return errors;
}
public int getBlacklistCollisions() {
return blacklistCollisions;
}
public void queueBlockChange(int type, int replaced, byte data, int x, int y, int z) {
edits.add(new Edit(type, replaced, data, x, y, z));
}
public boolean start() {
taskID = logblock.getServer().getScheduler().scheduleSyncRepeatingTask(logblock, this, 0, 1);
if (taskID == -1)
return false;
return true;
}
@Override
public void run() {
int counter = 0;
while (!edits.isEmpty() && counter < 1000) {
switch (edits.poll().perform()) {
case SUCCESS:
successes++;
break;
case ERROR:
errors++;
break;
case BLACKLISTED:
blacklistCollisions++;
break;
}
counter++;
}
if (edits.isEmpty()) {
logblock.getServer().getScheduler().cancelTask(taskID);
synchronized (caller) {
caller.notify();
}
}
}
private boolean equalsType(int type1, int type2) {
if (type1 == type2)
return true;
if ((type1 == 2 || type1 == 3) && (type2 == 2 || type2 == 3))
return true;
if ((type1 == 8 || type1 == 9) && (type2 == 8 || type2 == 9))
return true;
if ((type1 == 10 || type1 == 11) && (type2 == 10 || type2 == 11))
return true;
if ((type1 == 73 || type1 == 74) && (type2 == 73 || type2 == 74))
return true;
if ((type1 == 75 || type1 == 76) && (type2 == 75 || type2 == 76))
return true;
if ((type1 == 93 || type1 == 94) && (type2 == 93 || type2 == 94))
return true;
return false;
}
private enum PerformResult {
ERROR, SUCCESS, BLACKLISTED, NO_ACTION
}
private class Edit
{
final int type, replaced;
final int x, y, z;
final byte data;
Edit(int type, int replaced, byte data, int x, int y, int z) {
this.type = type;
this.replaced = replaced;
this.data = data;
this.x = x;
this.y = y;
this.z = z;
}
private PerformResult perform() {
if (config.dontRollback.contains(replaced))
return PerformResult.BLACKLISTED;
try {
final Block block = world.getBlockAt(x, y, z);
if (!world.isChunkLoaded(block.getChunk()))
world.loadChunk(block.getChunk());
if (equalsType(block.getTypeId(), type) || config.replaceAnyway.contains(block.getTypeId()) || type == 0 && replaced == 0) {
if (block.setTypeIdAndData(replaced, data, false))
return PerformResult.SUCCESS;
else
return PerformResult.ERROR;
} else
return PerformResult.NO_ACTION;
} catch (final Exception ex) {
log.severe("[LogBlock Rollback] " + ex.toString());
return PerformResult.ERROR;
}
}
}
}