Files
LogBlock/src/de/diddiz/LogBlock/LogBlock.java
T

287 lines
11 KiB
Java

package de.diddiz.LogBlock;
import static de.diddiz.util.Utils.download;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import com.nijiko.permissions.PermissionHandler;
import com.nijikokun.bukkit.Permissions.Permissions;
import de.diddiz.LogBlock.QueryParams.BlockChangeType;
import de.diddiz.util.MySQLConnectionPool;
public class LogBlock extends JavaPlugin
{
private Logger log;
private Config config;
private MySQLConnectionPool pool;
private Consumer consumer = null;
private CommandsHandler commandsHandler;
private Updater updater = null;
private Timer timer = null;
private PermissionHandler permissions = null;
private boolean errorAtLoading = false;
private final Map<Integer, Session> sessions = new HashMap<Integer, Session>();
public Config getConfig() {
return config;
}
public Consumer getConsumer() {
return consumer;
}
public CommandsHandler getCommandsHandler() {
return commandsHandler;
}
Updater getUpdater() {
return updater;
}
@Override
public void onLoad() {
log = getServer().getLogger();
try {
updater = new Updater(this);
log.info("[LogBlock] Version check: " + updater.checkVersion());
config = new Config(this);
File file = new File("lib/mysql-connector-java-bin.jar");
if (!file.exists() || file.length() == 0)
download(log, new URL("http://diddiz.insane-architects.net/download/mysql-connector-java-bin.jar"), file);
if (!file.exists() || file.length() == 0)
throw new FileNotFoundException(file.getAbsolutePath() + file.getName());
log.info("[LogBlock] Connecting to " + config.user + "@" + config.url + "...");
pool = new MySQLConnectionPool(config.url, config.user, config.password);
getConnection().close();
if (updater.update())
config = new Config(this);
updater.checkTables();
file = new File("plugins/LogBlock/consumer/queue.sql");
if (file.exists()) {
log.info("[LogBlock] Found stored queue. Try to import now.");
Connection conn = null;
try {
conn = getConnection();
conn.setAutoCommit(false);
final Statement state = conn.createStatement();
final BufferedReader reader = new BufferedReader(new FileReader(file));
String insert = null;
while ((insert = reader.readLine()) != null)
state.execute(insert);
conn.commit();
reader.close();
file.delete();
log.info("[LogBlock] Successfully imported stored queue.");
} catch (final Exception ex) {
log.log(Level.WARNING, "[LogBlock] Failed to import stored queue: ", ex);
} finally {
if (conn != null)
conn.close();
}
}
} catch (final Exception ex) {
log.log(Level.SEVERE, "[LogBlock] Error while loading: ", ex);
errorAtLoading = true;
return;
}
consumer = new Consumer(this);
}
@Override
public void onEnable() {
final PluginManager pm = getServer().getPluginManager();
if (errorAtLoading) {
pm.disablePlugin(this);
return;
}
if (pm.getPlugin("WorldEdit") == null && !new File("lib/WorldEdit.jar").exists() && !new File("WorldEdit.jar").exists())
try {
download(log, new URL("http://diddiz.insane-architects.net/download/WorldEdit.jar"), new File("lib/WorldEdit.jar"));
log.info("[LogBlock] You've to restart/reload your server now.");
pm.disablePlugin(this);
return;
} catch (final Exception ex) {
log.warning("[LogBlock] Failed to download WorldEdit. You may have to download it manually. You don't have to install it, just place the jar in the lib folder.");
}
if (config.logChestAccess && pm.getPlugin("Spout") == null)
try {
download(log, new URL("http://ci.getspout.org/job/Spout/Recommended/artifact/target/spout-dev-SNAPSHOT.jar"), new File("plugins/Spout.jar"));
pm.loadPlugin(new File("plugins/Spout.jar"));
pm.enablePlugin(pm.getPlugin("Spout"));
} catch (final Exception ex) {
log.warning("[LogBlock] Failed to install Spout, you may have to restart your server or install it manually.");
}
commandsHandler = new CommandsHandler(this);
getCommand("lb").setExecutor(commandsHandler);
if (pm.getPlugin("Permissions") != null) {
permissions = ((Permissions)pm.getPlugin("Permissions")).getHandler();
log.info("[LogBlock] Permissions plugin found.");
} else
log.info("[LogBlock] Permissions plugin not found. Using Bukkit Permissions.");
if (config.keepLogDays >= 0) {
final QueryParams params = new QueryParams(this);
params.minutes = config.keepLogDays * -1440;
params.bct = BlockChangeType.ALL;
for (final World world : getServer().getWorlds())
if (config.worlds.containsKey(world.getName().hashCode())) {
params.world = world;
try {
commandsHandler.new CommandClearLog(new ConsoleCommandSender(getServer()), params.clone(), true);
} catch (final Exception ex) {
log.severe("Failed to schedule ClearLog: " + ex.getMessage());
}
}
}
final LBBlockListener lbBlockListener = new LBBlockListener(this);
final LBPlayerListener lbPlayerListener = new LBPlayerListener(this);
final LBEntityListener lbEntityListener = new LBEntityListener(this);
pm.registerEvent(Type.PLAYER_INTERACT, new LBToolListener(this), Priority.Normal, this);
if (config.logBlockPlacings) {
pm.registerEvent(Type.BLOCK_PLACE, lbBlockListener, Priority.Monitor, this);
pm.registerEvent(Type.PLAYER_BUCKET_EMPTY, lbPlayerListener, Priority.Monitor, this);
}
if (config.logBlockBreaks) {
pm.registerEvent(Type.BLOCK_BREAK, lbBlockListener, Priority.Monitor, this);
pm.registerEvent(Type.PLAYER_BUCKET_FILL, lbPlayerListener, Priority.Monitor, this);
pm.registerEvent(Type.BLOCK_FROMTO, lbBlockListener, Priority.Monitor, this);
}
if (config.logSignTexts)
pm.registerEvent(Type.SIGN_CHANGE, lbBlockListener, Priority.Monitor, this);
if (config.logFire)
pm.registerEvent(Type.BLOCK_BURN, lbBlockListener, Priority.Monitor, this);
if (config.logExplosions)
pm.registerEvent(Type.ENTITY_EXPLODE, lbEntityListener, Priority.Monitor, this);
if (config.logLeavesDecay)
pm.registerEvent(Type.LEAVES_DECAY, lbBlockListener, Priority.Monitor, this);
if (config.logChestAccess)
if (pm.getPlugin("Spout") != null)
pm.registerEvent(Type.CUSTOM_EVENT, new LBChestAccessListener(this), Priority.Monitor, this);
else
log.warning("[LogBlock] BukkitContrib not found. Can't log chest accesses.");
if (config.logButtonsAndLevers)
pm.registerEvent(Type.PLAYER_INTERACT, lbPlayerListener, Priority.Monitor, this);
if (config.logKills)
pm.registerEvent(Type.ENTITY_DAMAGE, lbEntityListener, Priority.Monitor, this);
if (config.logChat) {
pm.registerEvent(Type.PLAYER_CHAT, lbPlayerListener, Priority.Monitor, this);
pm.registerEvent(Type.PLAYER_COMMAND_PREPROCESS, lbPlayerListener, Priority.Monitor, this);
}
if (config.useBukkitScheduler) {
if (getServer().getScheduler().scheduleAsyncRepeatingTask(this, consumer, config.delayBetweenRuns * 20, config.delayBetweenRuns * 20) > 0)
log.info("[LogBlock] Scheduled consumer with bukkit scheduler.");
else {
log.warning("[LogBlock] Failed to schedule consumer with bukkit scheduler. Now trying schedule with timer.");
timer = new Timer();
timer.scheduleAtFixedRate(consumer, config.delayBetweenRuns * 1000, config.delayBetweenRuns * 1000);
}
} else {
timer = new Timer();
timer.scheduleAtFixedRate(consumer, config.delayBetweenRuns * 1000, config.delayBetweenRuns * 1000);
log.info("[LogBlock] Scheduled consumer with timer.");
}
log.info("LogBlock v" + getDescription().getVersion() + " by DiddiZ enabled.");
}
@Override
public void onDisable() {
if (timer != null)
timer.cancel();
getServer().getScheduler().cancelTasks(this);
if (consumer != null && consumer.getQueueSize() > 0) {
log.info("[LogBlock] Waiting for consumer ...");
int lastSize = -1, fails = 0;
while (consumer.getQueueSize() > 0) {
log.info("[LogBlock] Remaining queue size: " + consumer.getQueueSize());
if (lastSize == consumer.getQueueSize()) {
fails++;
log.info("[LogBlock] Remaining tries: " + (10 - fails));
} else
fails = 0;
if (fails == 10) {
log.info("Unable to save queue to database. Trying to write to a local file.");
try {
consumer.writeToFile();
} catch (final FileNotFoundException ex) {
log.info("Failed to write. Given up.");
break;
}
}
lastSize = consumer.getQueueSize();
consumer.run();
}
}
if (pool != null)
pool.close();
log.info("LogBlock disabled.");
}
boolean hasPermission(CommandSender sender, String permission) {
if (permissions != null && sender instanceof Player)
return permissions.has((Player)sender, permission);
return sender.hasPermission(permission);
}
public Connection getConnection() {
try {
return pool.getConnection();
} catch (final Exception ex) {
log.log(Level.SEVERE, "[LogBlock] Error while fetching connection", ex);
return null;
}
}
public Session getSession(String playerName) {
Session session = sessions.get(playerName.hashCode());
if (session == null) {
session = new Session(this);
sessions.put(playerName.hashCode(), session);
}
return session;
}
/**
* @param params
* QueryParams that contains the needed columns (all other will be filled with default values) and the params. World is required.
*/
public List<BlockChange> getBlockChanges(QueryParams params) throws SQLException {
final Connection conn = getConnection();
Statement state = null;
ResultSet rs = null;
if (conn == null)
throw new SQLException("No connection");
try {
state = conn.createStatement();
rs = state.executeQuery(params.getQuery());
final List<BlockChange> blockchanges = new ArrayList<BlockChange>();
while (rs.next())
blockchanges.add(new BlockChange(rs, params));
return blockchanges;
} finally {
if (state != null)
state.close();
conn.close();
}
}
}