Merge branch 'killlogging' into HEAD

This commit is contained in:
Robin Kupper
2011-04-14 22:27:39 +02:00
3 changed files with 132 additions and 5 deletions

View File

@@ -24,6 +24,7 @@ public class Config {
final boolean logFire;
final boolean logLeavesDecay;
final boolean logChestAccess;
final boolean logKills;
final List<Integer> dontRollback;
final List<Integer> replaceAnyway;
final int defaultDist;
@@ -86,6 +87,8 @@ public class Config {
config.setProperty("logging.logChestAccess", false);
if (!subkeys.contains("logLeavesDecay"))
config.setProperty("logging.logLeavesDecay", false);
if (!subkeys.contains("logKills"))
config.setProperty("logging.logKills", false);
subkeys = config.getKeys("rollback");
if (subkeys == null)
subkeys = new ArrayList<String>();
@@ -120,6 +123,7 @@ public class Config {
logFire = config.getBoolean("logging.logFire", false);
logChestAccess = config.getBoolean("logging.logChestAccess", false);
logLeavesDecay = config.getBoolean("logging.logLeavesDecay", false);
logKills = config.getBoolean("logging.logKills", false);
dontRollback = config.getIntList("rollback.dontRollback", null);
replaceAnyway = config.getIntList("rollback.replaceAnyway", null);
defaultDist = config.getInt("lookup.defaultDist", 20);

View File

@@ -4,19 +4,33 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.HashSet;
import java.util.TimerTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import org.bukkit.block.Block;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Giant;
import org.bukkit.entity.PigZombie;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Spider;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Zombie;
public class Consumer extends TimerTask implements Runnable
{
private LinkedBlockingQueue<BlockRow> bqueue = new LinkedBlockingQueue<BlockRow>();
private LinkedBlockingQueue<KillRow> kqueue = new LinkedBlockingQueue<KillRow>();
private HashSet<Integer> hiddenplayers = new HashSet<Integer>();
private LogBlock logblock;
private HashMap<Integer, Integer> lastAttackedEntity = new HashMap<Integer, Integer>();
private HashMap<Integer, Long> lastAttackTime = new HashMap<Integer, Long>();
private LogBlock logblock;
Consumer (LogBlock logblock) {
this.logblock = logblock;
@@ -53,8 +67,26 @@ public class Consumer extends TimerTask implements Runnable
LogBlock.log.info("[LogBlock] Failed to queue block for " + playerName);
}
public void queueKill(Entity attacker, Entity defender) {
if (lastAttackedEntity.containsKey(attacker.getEntityId()) && lastAttackedEntity.get(attacker.getEntityId()) == defender.getEntityId() && System.currentTimeMillis() - lastAttackTime.get(attacker.getEntityId()) < 3000)
return;
String table = LogBlock.config.tables.get(defender.getWorld().getName().hashCode());
if (table == null)
return;
int weapon = 0;
if (attacker instanceof Player && ((Player)attacker).getItemInHand() != null)
weapon = ((Player)attacker).getItemInHand().getTypeId();
String attackerName = getEntityName(attacker);
String defenderName = getEntityName(defender);
if (attackerName == null || defenderName == null)
return;
lastAttackedEntity.put(attacker.getEntityId(), defender.getEntityId());
lastAttackTime.put(attacker.getEntityId(), System.currentTimeMillis());
kqueue.add(new KillRow(table, getEntityName(attacker), getEntityName(defender), weapon));
}
public int getQueueSize() {
return bqueue.size();
return bqueue.size() + kqueue.size();
}
public boolean hide(Player player) {
@@ -67,13 +99,13 @@ public class Consumer extends TimerTask implements Runnable
return true;
}
}
public synchronized void run() {
Connection conn = logblock.pool.getConnection();
if (conn == null)
return;
Statement state = null;
BlockRow b;
BlockRow b; KillRow k;
int count = 0;
if (bqueue.size() > 100)
LogBlock.log.info("[LogBlock Consumer] Queue overloaded. Size: " + bqueue.size());
@@ -102,6 +134,13 @@ public class Consumer extends TimerTask implements Runnable
count++;
}
conn.commit();
while (!kqueue.isEmpty() && count < 1000 && (System.currentTimeMillis() - start < 100 || count < 100)) {
k = kqueue.poll();
if (k == null)
continue;
state.execute("INSERT INTO `" + k.table + "-kills` (date, killer, victim, weapon) SELECT now(), playerid, (SELECT playerid FROM `lb-players` WHERE playername = '" + k.victim + "'), " + k.weapon + " FROM `lb-players` WHERE playername = '" + k.killer + "'");
}
conn.commit();
} catch (SQLException ex) {
LogBlock.log.log(Level.SEVERE, "[LogBlock Consumer] SQL exception", ex);
} finally {
@@ -116,6 +155,30 @@ public class Consumer extends TimerTask implements Runnable
}
}
private String getEntityName(Entity entity) {
if (entity instanceof Player)
return ((Player)entity).getName();
if (entity instanceof Creeper)
return "Creeper";
if (entity instanceof Ghast)
return "Ghast";
if (entity instanceof Giant)
return "Giant";
if (entity instanceof PigZombie)
return "PigZombie";
if (entity instanceof Skeleton)
return "Skeleton";
if (entity instanceof Slime)
return "Slime";
if (entity instanceof Spider)
return "Spider";
if (entity instanceof Wolf)
return "Wolf";
if (entity instanceof Zombie)
return "Zombie";
return null;
}
private class ChestAccess
{
public short inType, outType;
@@ -152,4 +215,38 @@ public class Consumer extends TimerTask implements Runnable
this.ca = null;
}
}
private class KillRow
{
public String table;
public String killer;
public String victim;
public int weapon;
KillRow(String table, String attacker, String defender, int weapon) {
this.table = table;
this.killer = attacker;
this.victim = defender;
this.weapon = weapon;
}
@Override
public int hashCode() {
return killer.hashCode() * 31 + victim.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
KillRow k = (KillRow)obj;
if (!killer.equals(k.killer))
return false;
if (!victim.equals(k.victim))
return false;
return true;
}
}
}

View File

@@ -17,7 +17,9 @@ import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.Event;
@@ -29,6 +31,8 @@ import org.bukkit.event.block.BlockListener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityListener;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
@@ -105,6 +109,7 @@ public class LogBlock extends JavaPlugin
new Thread(new ClearLog(this)).start();
LBBlockListener lbBlockListener = new LBBlockListener();
LBPlayerListener lbPlayerListener = new LBPlayerListener();
LBEntityListener lbEntityListener = new LBEntityListener();
PluginManager pm = getServer().getPluginManager();
pm.registerEvent(Type.PLAYER_INTERACT, new LBToolPlayerListener(), Event.Priority.Normal, this);
pm.registerEvent(Type.PLAYER_JOIN, lbPlayerListener, Event.Priority.Normal, this);
@@ -121,11 +126,13 @@ public class LogBlock extends JavaPlugin
if (config.logFire)
pm.registerEvent(Type.BLOCK_BURN, lbBlockListener, Event.Priority.Monitor, this);
if (config.logExplosions)
pm.registerEvent(Type.ENTITY_EXPLODE, new LBEntityListener(), Event.Priority.Monitor, this);
pm.registerEvent(Type.ENTITY_EXPLODE, lbEntityListener, Event.Priority.Monitor, this);
if (config.logLeavesDecay)
pm.registerEvent(Type.LEAVES_DECAY, lbBlockListener, Event.Priority.Monitor, this);
if (config.logChestAccess)
pm.registerEvent(Type.PLAYER_INTERACT, lbPlayerListener, Event.Priority.Monitor, this);
if (config.logKills)
pm.registerEvent(Type.ENTITY_DAMAGE, lbEntityListener, Event.Priority.Monitor, this);
consumer = new Consumer(this);
if (config.useBukkitScheduler) {
if (getServer().getScheduler().scheduleAsyncRepeatingTask(this, consumer, config.delay * 20, config.delay * 20) > 0)
@@ -552,6 +559,25 @@ public class LogBlock extends JavaPlugin
consumer.queueBlock(name, block, block.getTypeId(), 0, block.getData());
}
}
@Override
public void onEntityDamage(EntityDamageEvent event) {
if (event.isCancelled())
return;
if (!(event instanceof EntityDamageByEntityEvent))
return;
if (!(event.getEntity() instanceof LivingEntity))
return;
LivingEntity victim = (LivingEntity)event.getEntity();
Entity killer = ((EntityDamageByEntityEvent)event).getDamager();
if (!(victim instanceof Player) && !(killer instanceof Player))
return;
if (victim.getHealth() - event.getDamage() > 0)
return;
if (victim.getHealth() <= 0 )
return;
consumer.queueKill(killer, victim);
}
}
public class LBPlayerListener extends PlayerListener