2011-05-06 15:46:49 +02:00
package de.diddiz.LogBlock ;
2011-06-01 14:13:08 +02:00
import static de.diddiz.util.BukkitUtils.giveTool ;
2011-06-20 13:28:54 +02:00
import static de.diddiz.util.BukkitUtils.saveSpawnHeight ;
2011-07-03 20:28:19 +02:00
import static de.diddiz.util.BukkitUtils.senderName ;
import static de.diddiz.util.Utils.isInt ;
2011-05-22 04:01:43 +02:00
import java.io.Closeable ;
2011-05-06 15:46:49 +02:00
import java.io.File ;
import java.io.FileWriter ;
import java.sql.Connection ;
import java.sql.ResultSet ;
import java.sql.SQLException ;
import java.sql.Statement ;
import java.text.SimpleDateFormat ;
2011-05-22 04:01:43 +02:00
import java.util.ArrayList ;
2011-05-06 15:46:49 +02:00
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.command.Command ;
import org.bukkit.command.CommandExecutor ;
import org.bukkit.command.CommandSender ;
import org.bukkit.entity.Player ;
2011-05-22 04:01:43 +02:00
import org.bukkit.scheduler.BukkitScheduler ;
2011-05-06 15:46:49 +02:00
import de.diddiz.LogBlock.QueryParams.BlockChangeType ;
2011-05-22 04:01:43 +02:00
import de.diddiz.LogBlock.QueryParams.Order ;
2011-05-06 15:46:49 +02:00
import de.diddiz.LogBlock.QueryParams.SummarizationMode ;
2011-05-22 04:01:43 +02:00
import de.diddiz.LogBlockQuestioner.LogBlockQuestioner ;
2011-05-06 15:46:49 +02:00
public class CommandsHandler implements CommandExecutor
{
private final Logger log ;
private final LogBlock logblock ;
private final Config config ;
2011-05-22 04:01:43 +02:00
private final BukkitScheduler scheduler ;
private final LogBlockQuestioner questioner ;
2011-05-06 15:46:49 +02:00
2011-05-22 04:01:43 +02:00
CommandsHandler ( LogBlock logblock ) {
2011-05-06 15:46:49 +02:00
this . logblock = logblock ;
log = logblock . getServer (). getLogger ();
config = logblock . getConfig ();
2011-05-22 04:01:43 +02:00
scheduler = logblock . getServer (). getScheduler ();
questioner = ( LogBlockQuestioner ) logblock . getServer (). getPluginManager (). getPlugin ( "LogBlockQuestioner" );
2011-05-06 15:46:49 +02:00
}
@Override
2011-05-22 04:01:43 +02:00
public boolean onCommand ( CommandSender sender , Command cmd , String commandLabel , String [] args ) {
2011-05-06 15:46:49 +02:00
if ( ! cmd . getName (). equalsIgnoreCase ( "lb" ))
return false ;
if ( args . length == 0 ) {
sender . sendMessage ( ChatColor . LIGHT_PURPLE + "LogBlock v" + logblock . getDescription (). getVersion () + " by DiddiZ" );
2011-06-11 16:14:13 +02:00
sender . sendMessage ( ChatColor . LIGHT_PURPLE + logblock . getUpdater (). checkVersion ());
2011-05-06 15:46:49 +02:00
sender . sendMessage ( ChatColor . LIGHT_PURPLE + "Type /lb help for help" );
2011-05-22 04:01:43 +02:00
} else {
final String command = args [ 0 ] . toLowerCase ();
if ( command . equals ( "help" )) {
sender . sendMessage ( ChatColor . DARK_AQUA + "LogBlock Help:" );
sender . sendMessage ( ChatColor . GOLD + "For the commands list type '/lb commands'" );
sender . sendMessage ( ChatColor . GOLD + "For the parameters list type '/lb params'" );
sender . sendMessage ( ChatColor . GOLD + "For the list of permissions you got type '/lb permissions'" );
} else if ( command . equals ( "commands" )) {
sender . sendMessage ( ChatColor . DARK_AQUA + "LogBlock Commands:" );
sender . sendMessage ( ChatColor . GOLD + "/lb tool -- Gives you the lb tool" );
sender . sendMessage ( ChatColor . GOLD + "/lb tool [on|off] -- Enables/Disables tool" );
sender . sendMessage ( ChatColor . GOLD + "/lb tool [params] -- Sets the tool lookup query" );
2011-07-06 21:24:33 +02:00
sender . sendMessage ( ChatColor . GOLD + "/lb tool default -- Sets the tool lookup query to default" );
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . GOLD + "/lb toolblock -- Analog to tool" );
sender . sendMessage ( ChatColor . GOLD + "/lb hide -- Hides you from log" );
sender . sendMessage ( ChatColor . GOLD + "/lb rollback [params] -- Rollback" );
sender . sendMessage ( ChatColor . GOLD + "/lb redo [params] -- Redo" );
sender . sendMessage ( ChatColor . GOLD + "/lb tp [params] -- Teleports you to the location of griefing" );
sender . sendMessage ( ChatColor . GOLD + "/lb writelogfile [params] -- Writes a log file" );
sender . sendMessage ( ChatColor . GOLD + "/lb lookup [params] -- Lookup" );
2011-07-08 02:19:24 +02:00
sender . sendMessage ( ChatColor . GOLD + "/lb prev|next -- Browse lookup result pages" );
sender . sendMessage ( ChatColor . GOLD + "/lb page -- Shows a specific lookup result page" );
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . GOLD + "/lb me -- Displays your stats" );
2011-07-06 21:24:33 +02:00
sender . sendMessage ( ChatColor . GOLD + "Look at github.com/DiddiZ/LogBlock/wiki/Commands for the full commands reference" );
2011-05-22 04:01:43 +02:00
} else if ( command . equals ( "params" )) {
sender . sendMessage ( ChatColor . DARK_AQUA + "LogBlock Query Parameters:" );
sender . sendMessage ( ChatColor . GOLD + "Use doublequotes to escape a keyword: world \"world\"" );
sender . sendMessage ( ChatColor . GOLD + "player [name1] <name2> <name3> -- List of players" );
sender . sendMessage ( ChatColor . GOLD + "block [type1] <type2> <type3> -- List of block types" );
sender . sendMessage ( ChatColor . GOLD + "created, destroyed -- Show only created/destroyed blocks" );
sender . sendMessage ( ChatColor . GOLD + "chestaccess -- Show only chest accesses" );
sender . sendMessage ( ChatColor . GOLD + "area <radius> -- Area around you" );
sender . sendMessage ( ChatColor . GOLD + "selection, sel -- Inside current WorldEdit selection" );
sender . sendMessage ( ChatColor . GOLD + "world [worldname] -- Changes the world" );
sender . sendMessage ( ChatColor . GOLD + "time [number] [minutes|hours|days] -- Limits time" );
sender . sendMessage ( ChatColor . GOLD + "since <dd.MM.yyyy> <HH:mm:ss> -- Limits time to a fixed point" );
2011-06-28 23:17:11 +02:00
sender . sendMessage ( ChatColor . GOLD + "before <dd.MM.yyyy> <HH:mm:ss> -- Affects only blocks before a fixed time" );
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . GOLD + "limit <row count> -- Limits the result to count of rows" );
sender . sendMessage ( ChatColor . GOLD + "sum [none|blocks|players] -- Sums the result" );
sender . sendMessage ( ChatColor . GOLD + "asc, desc -- Changes the order of the displayed log" );
2011-06-28 23:17:11 +02:00
sender . sendMessage ( ChatColor . GOLD + "coords -- Shows coordinates for each block" );
2011-07-07 16:35:01 +02:00
sender . sendMessage ( ChatColor . GOLD + "silent -- Displays lesser messages" );
2011-05-22 04:01:43 +02:00
} else if ( command . equals ( "permissions" )) {
2011-07-06 21:24:33 +02:00
final String [] permissions = { "tool" , "toolblock" , "me" , "lookup" , "tp" , "rollback" , "clearlog" , "hide" , "ignoreRestrictions" };
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . DARK_AQUA + "You've got the following permissions:" );
2011-07-06 21:24:33 +02:00
for ( final String permission : permissions )
if ( logblock . hasPermission ( sender , "logblock." + permission ))
sender . sendMessage ( ChatColor . GOLD + "logblock." + permission );
2011-05-22 04:01:43 +02:00
} else if ( command . equals ( "tool" )) {
if ( sender instanceof Player ) {
final Player player = ( Player ) sender ;
if ( args . length == 1 ) {
if ( logblock . hasPermission ( player , "logblock.tool" ))
2011-06-01 14:13:08 +02:00
giveTool ( player , config . toolID );
2011-05-22 04:01:43 +02:00
else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
} else if ( args [ 1 ] . equalsIgnoreCase ( "enable" ) || args [ 1 ] . equalsIgnoreCase ( "on" )) {
logblock . getSession ( player . getName ()). toolEnabled = true ;
player . sendMessage ( ChatColor . GREEN + "Tool enabled." );
} else if ( args [ 1 ] . equalsIgnoreCase ( "disable" ) || args [ 1 ] . equalsIgnoreCase ( "off" )) {
logblock . getSession ( player . getName ()). toolEnabled = false ;
player . sendMessage ( ChatColor . GREEN + "Tool disabled." );
2011-06-09 22:47:20 +02:00
} else if ( args [ 1 ] . equalsIgnoreCase ( "mode" )) {
final Session session = logblock . getSession ( player . getName ());
if ( args . length == 3 ) {
final ToolMode mode ;
try {
mode = ToolMode . valueOf ( args [ 2 ] . toUpperCase ());
} catch ( final IllegalArgumentException ex ) {
sender . sendMessage ( ChatColor . RED + "Can't find mode " + args [ 2 ] );
return true ;
}
if ( logblock . hasPermission ( player , mode . getPermission ())) {
session . toolMode = mode ;
sender . sendMessage ( ChatColor . GREEN + "Tool mode set to " + args [ 2 ] );
} else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to use mode " + args [ 2 ] );
} else
player . sendMessage ( ChatColor . RED + "No mode specified" );
2011-07-05 13:51:53 +02:00
} else if ( args [ 1 ] . equalsIgnoreCase ( "default" )) {
2011-07-09 18:19:42 +02:00
final Session session = logblock . getSession ( player . getName ());
session . toolQuery = config . toolQuery . clone ();
session . toolMode = ToolMode . LOOKUP ;
sender . sendMessage ( ChatColor . GREEN + "Tool set to default." );
2011-05-22 04:01:43 +02:00
} else if ( logblock . hasPermission ( player , "logblock.lookup" ))
try {
2011-07-07 16:35:01 +02:00
final QueryParams params = config . toolQuery . clone ();
2011-07-05 13:51:53 +02:00
params . parseArgs ( sender , argsToList ( args , 1 ));
2011-05-22 04:01:43 +02:00
logblock . getSession ( player . getName ()). toolQuery = params ;
sender . sendMessage ( ChatColor . GREEN + "Set tool query to: " + params . getTitle ());
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
}
2011-05-06 15:46:49 +02:00
else
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
2011-05-06 15:46:49 +02:00
} else
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . RED + "You have to be a player." );
} else if ( command . equals ( "toolblock" )) {
if ( sender instanceof Player ) {
final Player player = ( Player ) sender ;
if ( args . length == 1 ) {
if ( logblock . hasPermission ( player , "logblock.toolblock" ))
2011-06-01 14:13:08 +02:00
giveTool ( player , config . toolblockID );
2011-05-22 04:01:43 +02:00
else
player . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
} else if ( args [ 1 ] . equalsIgnoreCase ( "enable" ) || args [ 1 ] . equalsIgnoreCase ( "on" )) {
logblock . getSession ( player . getName ()). toolBlockEnabled = true ;
player . sendMessage ( ChatColor . GREEN + "Tool block enabled." );
} else if ( args [ 1 ] . equalsIgnoreCase ( "disable" ) || args [ 1 ] . equalsIgnoreCase ( "off" )) {
logblock . getSession ( player . getName ()). toolBlockEnabled = false ;
player . sendMessage ( ChatColor . GREEN + "Tool block disabled." );
2011-06-09 22:47:20 +02:00
} else if ( args [ 1 ] . equalsIgnoreCase ( "mode" )) {
final Session session = logblock . getSession ( player . getName ());
if ( args . length == 3 ) {
final ToolMode mode ;
try {
mode = ToolMode . valueOf ( args [ 2 ] . toUpperCase ());
} catch ( final IllegalArgumentException ex ) {
sender . sendMessage ( ChatColor . RED + "Can't find mode " + args [ 2 ] );
return true ;
}
if ( logblock . hasPermission ( player , mode . getPermission ())) {
session . toolBlockMode = mode ;
sender . sendMessage ( ChatColor . GREEN + "Toolblock mode set to " + args [ 2 ] );
} else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to use mode " + args [ 2 ] );
} else
player . sendMessage ( ChatColor . RED + "No mode specified" );
2011-07-05 13:51:53 +02:00
} else if ( args [ 1 ] . equalsIgnoreCase ( "default" )) {
2011-07-09 18:19:42 +02:00
final Session session = logblock . getSession ( player . getName ());
session . toolBlockQuery = config . toolBlockQuery . clone ();
session . toolBlockMode = ToolMode . LOOKUP ;
sender . sendMessage ( ChatColor . GREEN + "Toolblock set to default." );
2011-05-22 04:01:43 +02:00
} else if ( logblock . hasPermission ( player , "logblock.lookup" ))
try {
2011-07-07 16:35:01 +02:00
final QueryParams params = config . toolBlockQuery . clone ();
2011-07-05 13:51:53 +02:00
params . parseArgs ( sender , argsToList ( args , 1 ));
2011-05-22 04:01:43 +02:00
logblock . getSession ( player . getName ()). toolBlockQuery = params ;
sender . sendMessage ( ChatColor . GREEN + "Set tool block query to: " + params . getTitle ());
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
}
else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
2011-05-06 15:46:49 +02:00
} else
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . RED + "You have to be a player." );
} else if ( command . equals ( "hide" )) {
if ( sender instanceof Player ) {
if ( logblock . hasPermission ( sender , "logblock.hide" )) {
if ( logblock . getConsumer (). hide (( Player ) sender ))
2011-07-07 16:35:01 +02:00
sender . sendMessage ( ChatColor . GREEN + "You are now hidden and aren't logged. Type '/lb hide' again to unhide" );
2011-05-22 04:01:43 +02:00
else
2011-06-09 22:47:20 +02:00
sender . sendMessage ( ChatColor . GREEN + "You aren't hidden anylonger." );
2011-05-22 04:01:43 +02:00
} else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
} else
sender . sendMessage ( ChatColor . RED + "You have to be a player." );
2011-07-03 20:28:19 +02:00
} else if ( command . equals ( "page" )) {
if ( args . length == 2 && isInt ( args [ 1 ] ))
showPage ( sender , Integer . valueOf ( args [ 1 ] ));
else
sender . sendMessage ( ChatColor . RED + "You have to specify a page" );
} else if ( command . equals ( "next" ))
showPage ( sender , logblock . getSession ( senderName ( sender )). page + 1 );
else if ( command . equals ( "prev" ))
showPage ( sender , logblock . getSession ( senderName ( sender )). page - 1 );
else if ( args [ 0 ] . equalsIgnoreCase ( "savequeue" )) {
2011-05-22 04:01:43 +02:00
if ( logblock . hasPermission ( sender , "logblock.rollback" ))
2011-05-06 15:46:49 +02:00
try {
2011-06-16 22:31:13 +02:00
new CommandSaveQueue ( sender , null , true );
2011-05-06 15:46:49 +02:00
} catch ( final Exception ex ) {
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
2011-05-06 15:46:49 +02:00
}
2011-05-22 04:01:43 +02:00
else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
} else if ( command . equals ( "rollback" ) || command . equals ( "undo" ) || command . equals ( "rb" )) {
if ( logblock . hasPermission ( sender , "logblock.rollback" ))
try {
final QueryParams params = new QueryParams ( logblock );
params . minutes = logblock . getConfig (). defaultTime ;
2011-07-05 13:51:53 +02:00
params . parseArgs ( sender , argsToList ( args , 1 ));
2011-05-22 04:01:43 +02:00
params . limit = - 1 ;
params . order = Order . DESC ;
params . sum = SummarizationMode . NONE ;
params . bct = BlockChangeType . ALL ;
2011-06-16 22:31:13 +02:00
new CommandRollback ( sender , params , true );
2011-05-22 04:01:43 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
}
else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
} else if ( command . equals ( "redo" )) {
if ( logblock . hasPermission ( sender , "logblock.rollback" ))
try {
final QueryParams params = new QueryParams ( logblock );
params . minutes = logblock . getConfig (). defaultTime ;
2011-07-05 13:51:53 +02:00
params . parseArgs ( sender , argsToList ( args , 1 ));
2011-05-22 04:01:43 +02:00
params . limit = - 1 ;
params . order = Order . ASC ;
params . sum = SummarizationMode . NONE ;
params . bct = BlockChangeType . ALL ;
2011-06-16 22:31:13 +02:00
new CommandRedo ( sender , params , true );
2011-05-22 04:01:43 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
}
else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
} else if ( command . equals ( "me" )) {
if ( sender instanceof Player ) {
if ( logblock . hasPermission ( sender , "logblock.me" ))
try {
final Player player = ( Player ) sender ;
final QueryParams params = new QueryParams ( logblock );
params . setPlayer ( player . getName ());
params . sum = SummarizationMode . TYPES ;
params . world = player . getWorld ();
2011-06-16 22:31:13 +02:00
new CommandLookup ( sender , params , true );
2011-05-22 04:01:43 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
}
else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this." );
2011-05-06 15:46:49 +02:00
} else
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . RED + "You have to be a player." );
} else if ( command . equals ( "writelogfile" )) {
if ( logblock . hasPermission ( sender , "logblock.rollback" ))
try {
2011-07-05 13:51:53 +02:00
final QueryParams params = new QueryParams ( logblock , sender , argsToList ( args , 1 ));
2011-05-22 04:01:43 +02:00
params . limit = - 1 ;
params . bct = BlockChangeType . ALL ;
params . sum = SummarizationMode . NONE ;
2011-06-16 22:31:13 +02:00
new CommandWriteLogFile ( sender , params , true );
2011-05-22 04:01:43 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
}
else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this" );
} else if ( command . equals ( "clearlog" )) {
if ( logblock . hasPermission ( sender , "logblock.clearlog" ))
try {
2011-07-05 13:51:53 +02:00
final QueryParams params = new QueryParams ( logblock , sender , argsToList ( args , 1 ));
2011-05-22 04:01:43 +02:00
params . bct = BlockChangeType . ALL ;
params . limit = - 1 ;
2011-06-16 22:31:13 +02:00
new CommandClearLog ( sender , params , true );
2011-05-22 04:01:43 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
}
else
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this" );
} else if ( command . equals ( "tp" )) {
if ( sender instanceof Player ) {
if ( logblock . hasPermission ( sender , "logblock.tp" ))
try {
2011-07-05 13:51:53 +02:00
new CommandTeleport ( sender , new QueryParams ( logblock , sender , argsToList ( args , 1 )), true );
2011-05-22 04:01:43 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + 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 ( command . equals ( "lookup" ) || QueryParams . isKeyWord ( args [ 0 ] )) {
if ( logblock . hasPermission ( sender , "logblock.lookup" ))
try {
final List < String > argsList = new ArrayList < String > ( Arrays . asList ( args ));
if ( command . equals ( "lookup" ))
argsList . remove ( 0 );
2011-06-16 22:31:13 +02:00
new CommandLookup ( sender , new QueryParams ( logblock , sender , argsList ), true );
2011-05-22 04:01:43 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + ex . getMessage ());
}
else
2011-05-06 15:46:49 +02:00
sender . sendMessage ( ChatColor . RED + "You aren't allowed to do this" );
} else
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . RED + "Unknown command '" + args [ 0 ] + "'" );
2011-05-06 15:46:49 +02:00
}
return true ;
}
2011-07-03 20:28:19 +02:00
private void showPage ( CommandSender sender , int page ) {
final Session session = logblock . getSession ( senderName ( sender ));
if ( session . lookupCache != null && session . lookupCache . length > 0 ) {
final int startpos = ( page - 1 ) * config . linesPerPage ;
2011-07-04 00:13:46 +02:00
if ( page > 0 && startpos <= session . lookupCache . length - 1 ) {
final int stoppos = startpos + config . linesPerPage > session . lookupCache . length ? session . lookupCache . length - 1 : startpos + config . linesPerPage - 1 ;
final int numberOfPages = ( int ) Math . ceil ( session . lookupCache . length / ( double ) config . linesPerPage );
if ( numberOfPages != 1 )
sender . sendMessage ( ChatColor . DARK_AQUA + "Page " + page + "/" + numberOfPages );
2011-07-03 20:28:19 +02:00
for ( int i = startpos ; i <= stoppos ; i ++ )
sender . sendMessage ( ChatColor . GOLD + session . lookupCache [ i ] . toString ());
session . page = page ;
} else
sender . sendMessage ( ChatColor . RED + "There isn't a page '" + page + "'" );
} else
sender . sendMessage ( ChatColor . RED + "No blocks in lookup cache" );
}
2011-07-06 21:24:33 +02:00
private boolean checkRestrictions ( CommandSender sender , QueryParams params ) {
if ( logblock . hasPermission ( sender , "logblock.ignoreRestrictions" ))
return true ;
if ( params . minutes <= 0 || params . minutes > config . rollbackMaxTime ) {
sender . sendMessage ( ChatColor . RED + "You are not allowed to rollback more than " + config . rollbackMaxTime + " minutes" );
return false ;
}
if ( params . sel == null && params . loc == null || params . radius > config . rollbackMaxArea || params . sel != null && ( params . sel . getLength () > config . rollbackMaxArea || params . sel . getWidth () > config . rollbackMaxArea )) {
sender . sendMessage ( ChatColor . RED + "You are not allowed to rollback an area larger than " + config . rollbackMaxArea + " blocks" );
return false ;
}
return true ;
}
2011-07-08 13:22:54 +02:00
public abstract class AbstractCommand implements Runnable , Closeable
2011-05-06 15:46:49 +02:00
{
2011-07-08 13:22:54 +02:00
protected CommandSender sender ;
protected QueryParams params ;
2011-05-06 15:46:49 +02:00
protected Connection conn = null ;
protected Statement state = null ;
protected ResultSet rs = null ;
2011-07-08 13:22:54 +02:00
protected AbstractCommand ( CommandSender sender , QueryParams params , boolean async ) throws Exception {
2011-05-06 15:46:49 +02:00
this . sender = sender ;
this . params = params ;
2011-06-16 22:31:13 +02:00
if ( async ) {
if ( scheduler . scheduleAsyncDelayedTask ( logblock , this ) == - 1 )
throw new Exception ( "Failed to schedule the command" );
} else
run ();
2011-05-06 15:46:49 +02:00
}
2011-05-22 04:01:43 +02:00
@Override
public final void close () {
2011-05-06 15:46:49 +02:00
try {
if ( conn != null )
conn . close ();
if ( state != null )
state . close ();
if ( rs != null )
rs . close ();
} catch ( final SQLException ex ) {
2011-06-12 22:24:52 +02:00
log . log ( Level . SEVERE , "[LogBlock CommandsHandler] SQL exception on close" , ex );
2011-05-06 15:46:49 +02:00
}
}
}
2011-07-08 13:22:54 +02:00
public class CommandLookup extends AbstractCommand
2011-05-06 15:46:49 +02:00
{
2011-06-16 22:31:13 +02:00
public CommandLookup ( CommandSender sender , QueryParams params , boolean async ) throws Exception {
super ( sender , params , async );
2011-05-06 15:46:49 +02:00
}
@Override
public void run () {
try {
2011-07-08 13:22:54 +02:00
conn = logblock . getConnection ();
state = conn . createStatement ();
2011-07-08 02:19:24 +02:00
if ( params . limit == 15 && params . sum == SummarizationMode . NONE )
2011-07-03 20:28:19 +02:00
params . limit = config . linesLimit ;
2011-06-10 02:19:31 +02:00
rs = state . executeQuery ( params . getLookupQuery ());
2011-07-07 16:35:01 +02:00
sender . sendMessage ( ChatColor . DARK_AQUA + params . getTitle () + ":" );
2011-07-03 20:28:19 +02:00
final List < BlockChange > blockchanges = new ArrayList < BlockChange > ();
2011-05-06 15:46:49 +02:00
if ( rs . next ()) {
rs . beforeFirst ();
2011-07-08 02:19:24 +02:00
if ( params . sum == SummarizationMode . NONE ) {
while ( rs . next ())
blockchanges . add ( new BlockChange ( rs , params . coords ));
logblock . getSession ( senderName ( sender )). lookupCache = blockchanges . toArray ( new BlockChange [ blockchanges . size () ] );
if ( blockchanges . size () > config . linesPerPage )
sender . sendMessage ( ChatColor . DARK_AQUA . toString () + blockchanges . size () + " changes found." + ( blockchanges . size () == config . linesLimit ? " Use 'limit -1' to see all changes." : "" ));
showPage ( sender , 1 );
} else {
final HistoryFormatter histformatter = new HistoryFormatter ( params . sum , params . coords , ( sender instanceof Player ? 2 / 3f : 1 ));
sender . sendMessage ( ChatColor . GOLD + "Created - Destroyed - " + ( params . sum == SummarizationMode . TYPES ? "Block" : "Player" ));
while ( rs . next ())
sender . sendMessage ( ChatColor . GOLD + histformatter . format ( rs ));
}
2011-07-03 20:28:19 +02:00
} else {
2011-05-06 15:46:49 +02:00
sender . sendMessage ( ChatColor . DARK_AQUA + "No results found." );
2011-07-03 20:28:19 +02:00
logblock . getSession ( senderName ( sender )). lookupCache = null ;
}
2011-06-12 22:24:52 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + "Exception, check error log" );
log . log ( Level . SEVERE , "[LogBlock Lookup] Exception: " , ex );
2011-05-06 15:46:49 +02:00
} finally {
close ();
}
}
}
2011-07-08 13:22:54 +02:00
public class CommandWriteLogFile extends AbstractCommand
2011-05-06 15:46:49 +02:00
{
2011-06-16 22:31:13 +02:00
CommandWriteLogFile ( CommandSender sender , QueryParams params , boolean async ) throws Exception {
super ( sender , params , async );
2011-05-06 15:46:49 +02:00
}
@Override
public void run () {
2011-06-06 11:19:25 +02:00
File file = null ;
2011-05-06 15:46:49 +02:00
try {
2011-07-08 13:22:54 +02:00
conn = logblock . getConnection ();
state = conn . createStatement ();
2011-06-13 13:01:07 +02:00
file = new File ( "plugins/LogBlock/log/" + params . getTitle (). replace ( ":" , "." ) + ".log" );
sender . sendMessage ( ChatColor . GREEN + "Creating " + file . getName ());
2011-06-10 02:19:31 +02:00
rs = state . executeQuery ( params . getLookupQuery ());
2011-06-13 13:01:07 +02:00
file . getParentFile (). mkdirs ();
2011-05-22 04:01:43 +02:00
file . createNewFile ();
2011-05-06 15:46:49 +02:00
final FileWriter writer = new FileWriter ( file );
final String newline = System . getProperty ( "line.separator" );
2011-06-22 20:54:52 +02:00
final HistoryFormatter histformatter = new HistoryFormatter ( params . sum , params . coords , 1 );
2011-05-06 15:46:49 +02:00
file . getParentFile (). mkdirs ();
2011-06-13 13:01:07 +02:00
int counter = 0 ;
while ( rs . next ()) {
2011-06-22 20:54:52 +02:00
writer . write ( histformatter . format ( rs ) + newline );
2011-06-13 13:01:07 +02:00
counter ++ ;
}
2011-05-06 15:46:49 +02:00
writer . close ();
2011-06-13 13:01:07 +02:00
sender . sendMessage ( ChatColor . GREEN + "Wrote " + counter + " lines." );
2011-06-12 22:24:52 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + "Exception, check error log" );
log . log ( Level . SEVERE , "[LogBlock WriteLogFile] Exception (file was " + file . getAbsolutePath () + "): " , ex );
2011-05-06 15:46:49 +02:00
} finally {
close ();
}
}
}
2011-07-08 13:22:54 +02:00
public class CommandSaveQueue extends AbstractCommand
2011-05-06 15:46:49 +02:00
{
2011-06-16 22:31:13 +02:00
public CommandSaveQueue ( CommandSender sender , QueryParams params , boolean async ) throws Exception {
super ( sender , params , async );
2011-05-06 15:46:49 +02:00
}
@Override
public void run () {
final Consumer consumer = logblock . getConsumer ();
2011-06-30 03:11:39 +02:00
if ( consumer . getQueueSize () > 0 ) {
sender . sendMessage ( ChatColor . DARK_AQUA + "Current queue size: " + consumer . getQueueSize ());
while ( consumer . getQueueSize () > 0 )
consumer . run ();
sender . sendMessage ( ChatColor . GREEN + "Queue saved successfully" );
}
2011-05-06 15:46:49 +02:00
}
}
2011-07-08 13:22:54 +02:00
public class CommandTeleport extends AbstractCommand
2011-05-06 15:46:49 +02:00
{
2011-06-16 22:31:13 +02:00
public CommandTeleport ( CommandSender sender , QueryParams params , boolean async ) throws Exception {
super ( sender , params , async );
2011-05-06 15:46:49 +02:00
}
@Override
public void run () {
try {
2011-07-08 13:22:54 +02:00
conn = logblock . getConnection ();
state = conn . createStatement ();
2011-06-20 13:28:54 +02:00
rs = state . executeQuery ( "SELECT x, y, z FROM `" + params . getTable () + "` INNER JOIN `lb-players` USING (playerid) " + params . getWhere () + params . getOrderBy () + " LIMIT 1" );
2011-05-06 15:46:49 +02:00
if ( rs . next ()) {
final Player player = ( Player ) sender ;
2011-06-20 13:28:54 +02:00
final int y = rs . getInt ( 2 );
final Location loc = new Location ( params . world , rs . getInt ( 1 ) + 0 . 5 , y , rs . getInt ( 3 ) + 0 . 5 , player . getLocation (). getYaw (), 90 );
final int y2 = saveSpawnHeight ( loc );
loc . setY ( y2 );
player . teleport ( loc );
sender . sendMessage ( ChatColor . GREEN + "You were teleported " + Math . abs ( y2 - y ) + " blocks " + ( y2 - y > 0 ? "above" : "below" ));
2011-05-06 15:46:49 +02:00
} else
2011-07-08 13:22:54 +02:00
sender . sendMessage ( ChatColor . RED + "No block change found to teleport to" );
2011-06-12 22:24:52 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + "Exception, check error log" );
log . log ( Level . SEVERE , "[LogBlock Teleport] Exception: " , ex );
2011-05-06 15:46:49 +02:00
} finally {
close ();
}
}
}
2011-07-08 13:22:54 +02:00
public class CommandRollback extends AbstractCommand
2011-05-06 15:46:49 +02:00
{
2011-06-16 22:31:13 +02:00
public CommandRollback ( CommandSender sender , QueryParams params , boolean async ) throws Exception {
super ( sender , params , async );
2011-05-06 15:46:49 +02:00
}
@Override
public void run () {
try {
2011-07-08 13:22:54 +02:00
conn = logblock . getConnection ();
state = conn . createStatement ();
2011-07-06 21:24:33 +02:00
if ( ! checkRestrictions ( sender , params ))
return ;
2011-07-10 19:06:54 +02:00
if ( logblock . getConsumer (). getQueueSize () > 0 )
new CommandSaveQueue ( sender , null , false );
2011-06-12 23:50:52 +02:00
if ( ! params . silent )
sender . sendMessage ( ChatColor . DARK_AQUA + "Searching " + params . getTitle () + ":" );
2011-06-10 01:54:18 +02:00
rs = state . executeQuery ( params . getRollbackQuery ());
2011-05-22 04:01:43 +02:00
final WorldEditor editor = new WorldEditor ( logblock , params . world );
while ( rs . next ())
2011-06-29 21:43:07 +02:00
editor . queueEdit ( rs . getInt ( "x" ), rs . getInt ( "y" ), rs . getInt ( "z" ), rs . getInt ( "replaced" ), rs . getInt ( "type" ), rs . getByte ( "data" ), rs . getString ( "signtext" ), rs . getShort ( "itemtype" ), rs . getShort ( "itemamount" ), rs . getByte ( "itemdata" ));
2011-05-06 15:46:49 +02:00
final int changes = editor . getSize ();
2011-06-12 23:50:52 +02:00
if ( ! params . silent )
sender . sendMessage ( ChatColor . GREEN . toString () + changes + " blocks found." );
2011-06-01 14:13:08 +02:00
if ( changes == 0 ) {
2011-06-12 23:50:52 +02:00
if ( ! params . silent )
sender . sendMessage ( ChatColor . RED + "Rollback aborted" );
2011-06-01 14:13:08 +02:00
return ;
}
2011-06-12 23:50:52 +02:00
if ( ! params . silent && config . askRollbacks && questioner != null && sender instanceof Player && ! questioner . ask (( Player ) sender , "Are you sure you want to continue?" , "yes" , "no" ). equals ( "yes" )) {
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . RED + "Rollback aborted" );
2011-05-06 15:46:49 +02:00
return ;
}
2011-05-22 04:01:43 +02:00
editor . start ();
2011-06-13 18:49:42 +02:00
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" : "" ) + ")" );
2011-07-10 19:06:54 +02:00
if ( ! params . silent && logblock . hasPermission ( sender , "logblock.clearlog" ) && questioner != null && sender instanceof Player && questioner . ask (( Player ) sender , "Do you want to delete the rollbacked log?" , "yes" , "no" ). equals ( "yes" )) {
params . silent = true ;
new CommandClearLog ( sender , params , false );
}
2011-06-12 22:24:52 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + "Exception, check error log" );
log . log ( Level . SEVERE , "[LogBlock Rollback] Exception: " , ex );
2011-05-06 15:46:49 +02:00
} finally {
close ();
}
}
}
2011-07-08 13:22:54 +02:00
public class CommandRedo extends AbstractCommand
2011-05-06 15:46:49 +02:00
{
2011-06-16 22:31:13 +02:00
public CommandRedo ( CommandSender sender , QueryParams params , boolean async ) throws Exception {
super ( sender , params , async );
2011-05-06 15:46:49 +02:00
}
@Override
public void run () {
try {
2011-07-08 13:22:54 +02:00
conn = logblock . getConnection ();
state = conn . createStatement ();
2011-07-06 21:24:33 +02:00
if ( ! checkRestrictions ( sender , params ))
return ;
2011-06-10 01:54:18 +02:00
rs = state . executeQuery ( params . getRollbackQuery ());
2011-06-12 23:50:52 +02:00
if ( ! params . silent )
sender . sendMessage ( ChatColor . DARK_AQUA + "Searching " + params . getTitle () + ":" );
2011-05-22 04:01:43 +02:00
final WorldEditor editor = new WorldEditor ( logblock , params . world );
2011-06-29 21:43:07 +02:00
2011-05-22 04:01:43 +02:00
while ( rs . next ())
2011-06-29 21:43:07 +02:00
editor . queueEdit ( rs . getInt ( "x" ), rs . getInt ( "y" ), rs . getInt ( "z" ), rs . getInt ( "type" ), rs . getInt ( "replaced" ), rs . getByte ( "data" ), rs . getString ( "signtext" ), rs . getShort ( "itemtype" ), ( short )( rs . getShort ( "itemamount" ) * - 1 ), rs . getByte ( "itemdata" ));
2011-05-06 15:46:49 +02:00
final int changes = editor . getSize ();
2011-06-12 23:50:52 +02:00
if ( ! params . silent )
sender . sendMessage ( ChatColor . GREEN . toString () + changes + " blocks found." );
2011-06-01 14:13:08 +02:00
if ( changes == 0 ) {
2011-06-12 23:50:52 +02:00
if ( ! params . silent )
sender . sendMessage ( ChatColor . RED + "Redo aborted" );
2011-06-01 14:13:08 +02:00
return ;
}
2011-06-12 23:50:52 +02:00
if ( ! params . silent && config . askRedos && questioner != null && sender instanceof Player && ! questioner . ask (( Player ) sender , "Are you sure you want to continue?" , "yes" , "no" ). equals ( "yes" )) {
2011-05-22 04:01:43 +02:00
sender . sendMessage ( ChatColor . RED + "Redo aborted" );
2011-05-06 15:46:49 +02:00
return ;
}
2011-05-22 04:01:43 +02:00
editor . start ();
2011-06-13 18:49:42 +02:00
sender . sendMessage ( ChatColor . GREEN + "Redo 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" : "" ) + ")" );
2011-06-12 22:24:52 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + "Exception, check error log" );
log . log ( Level . SEVERE , "[LogBlock Redo] Exception: " , ex );
2011-05-06 15:46:49 +02:00
} finally {
close ();
}
}
}
2011-07-08 13:22:54 +02:00
public class CommandClearLog extends AbstractCommand
2011-05-22 04:01:43 +02:00
{
2011-06-16 22:31:13 +02:00
public CommandClearLog ( CommandSender sender , QueryParams params , boolean async ) throws Exception {
super ( sender , params , async );
2011-05-22 04:01:43 +02:00
}
@Override
public void run () {
try {
2011-07-08 13:22:54 +02:00
conn = logblock . getConnection ();
state = conn . createStatement ();
2011-07-06 21:24:33 +02:00
if ( ! checkRestrictions ( sender , params ))
return ;
2011-05-22 04:01:43 +02:00
final File dumpFolder = new File ( logblock . getDataFolder (), "dumb" );
2011-05-26 16:58:07 +02:00
final SimpleDateFormat formatter = new SimpleDateFormat ( "yyMMddHHmmss" );
2011-05-22 04:01:43 +02:00
int deleted ;
2011-05-26 16:58:07 +02:00
final String table = params . getTable ();
2011-06-01 14:13:08 +02:00
final String join ;
if ( params . players . size () > 0 )
join = "INNER JOIN `lb-players` USING (playerid) " ;
else
join = "" ;
rs = state . executeQuery ( "SELECT count(*) FROM `" + table + "` " + join + params . getWhere ());
2011-05-26 16:58:07 +02:00
rs . next ();
if (( deleted = rs . getInt ( 1 )) > 0 ) {
2011-06-12 23:50:52 +02:00
if ( ! params . silent && config . askClearLogs && sender instanceof Player && questioner != null ) {
2011-05-26 16:58:07 +02:00
sender . sendMessage ( ChatColor . DARK_AQUA + "Searching " + params . getTitle () + ":" );
sender . sendMessage ( ChatColor . GREEN . toString () + deleted + " blocks found." );
2011-06-11 01:53:24 +02:00
if ( ! questioner . ask (( Player ) sender , "Are you sure you want to continue?" , "yes" , "no" ). equals ( "yes" )) {
2011-05-26 16:58:07 +02:00
sender . sendMessage ( ChatColor . RED + "ClearLog aborted" );
return ;
2011-05-22 04:01:43 +02:00
}
}
2011-05-26 16:58:07 +02:00
if ( config . dumpDeletedLog )
try {
2011-06-09 22:47:20 +02:00
state . execute ( "SELECT * FROM `" + table + "` " + join + params . getWhere () + "INTO OUTFILE '" + new File ( dumpFolder , formatter . format ( System . currentTimeMillis ()) + " " + table + " " + params . getTitle (). replace ( ":" , "." ) + ".csv" ). getAbsolutePath (). replace ( "\\" , "\\\\" ) + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'" );
2011-05-26 16:58:07 +02:00
} catch ( final SQLException ex ) {
sender . sendMessage ( ChatColor . RED + "Error while dumping log. Make sure your MySQL user has access to the LogBlock folder, or disable clearlog.dumpDeletedLog" );
log . log ( Level . SEVERE , "[LogBlock ClearLog] Exception while dumping" , ex );
return ;
}
2011-06-01 14:13:08 +02:00
state . execute ( "DELETE `" + table + "` FROM `" + table + "` " + join + params . getWhere ());
2011-05-26 16:58:07 +02:00
sender . sendMessage ( ChatColor . GREEN + "Cleared out table " + table + ". Deleted " + deleted + " entries." );
}
rs = state . executeQuery ( "SELECT COUNT(*) FROM `" + table + "-sign` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL" );
rs . next ();
if (( deleted = rs . getInt ( 1 )) > 0 ) {
if ( config . dumpDeletedLog )
state . execute ( "SELECT id, signtext FROM `" + table + "-sign` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL INTO OUTFILE '" + new File ( dumpFolder , formatter . format ( System . currentTimeMillis ()) + " " + table + "-sign " + params . getTitle () + ".csv" ). getAbsolutePath (). replace ( "\\" , "\\\\" ) + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'" );
state . execute ( "DELETE `" + table + "-sign` FROM `" + table + "-sign` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL;" );
sender . sendMessage ( ChatColor . GREEN + "Cleared out table " + table + "-sign. Deleted " + deleted + " entries." );
}
rs = state . executeQuery ( "SELECT COUNT(*) FROM `" + table + "-chest` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL" );
rs . next ();
if (( deleted = rs . getInt ( 1 )) > 0 ) {
if ( config . dumpDeletedLog )
state . execute ( "SELECT id, itemtype, itemamount, itemdata FROM `" + table + "-chest` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL INTO OUTFILE '" + new File ( dumpFolder , formatter . format ( System . currentTimeMillis ()) + " " + table + "-chest " + params . getTitle () + ".csv" ). getAbsolutePath (). replace ( "\\" , "\\\\" ) + "' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n'" );
state . execute ( "DELETE `" + table + "-chest` FROM `" + table + "-chest` LEFT JOIN `" + table + "` USING (id) WHERE `" + table + "`.id IS NULL;" );
sender . sendMessage ( ChatColor . GREEN + "Cleared out table " + table + "-chest. Deleted " + deleted + " entries." );
2011-05-22 04:01:43 +02:00
}
2011-06-12 22:24:52 +02:00
} catch ( final Exception ex ) {
sender . sendMessage ( ChatColor . RED + "Exception, check error log" );
log . log ( Level . SEVERE , "[LogBlock ClearLog] Exception: " , ex );
2011-05-22 04:01:43 +02:00
} finally {
close ();
}
}
}
2011-07-05 13:51:53 +02:00
private static List < String > argsToList ( String [] arr , int offset ) {
2011-05-22 04:01:43 +02:00
final List < String > list = new ArrayList < String > ( Arrays . asList ( arr ));
for ( int i = 0 ; i < offset ; i ++ )
list . remove ( 0 );
return list ;
2011-05-06 15:46:49 +02:00
}
}