forked from LogBlock/LogBlock
Merge branch 'killlogging' into HEAD
This commit is contained in:
@@ -24,6 +24,7 @@ public class Config {
|
|||||||
final boolean logFire;
|
final boolean logFire;
|
||||||
final boolean logLeavesDecay;
|
final boolean logLeavesDecay;
|
||||||
final boolean logChestAccess;
|
final boolean logChestAccess;
|
||||||
|
final boolean logKills;
|
||||||
final List<Integer> dontRollback;
|
final List<Integer> dontRollback;
|
||||||
final List<Integer> replaceAnyway;
|
final List<Integer> replaceAnyway;
|
||||||
final int defaultDist;
|
final int defaultDist;
|
||||||
@@ -86,6 +87,8 @@ public class Config {
|
|||||||
config.setProperty("logging.logChestAccess", false);
|
config.setProperty("logging.logChestAccess", false);
|
||||||
if (!subkeys.contains("logLeavesDecay"))
|
if (!subkeys.contains("logLeavesDecay"))
|
||||||
config.setProperty("logging.logLeavesDecay", false);
|
config.setProperty("logging.logLeavesDecay", false);
|
||||||
|
if (!subkeys.contains("logKills"))
|
||||||
|
config.setProperty("logging.logKills", false);
|
||||||
subkeys = config.getKeys("rollback");
|
subkeys = config.getKeys("rollback");
|
||||||
if (subkeys == null)
|
if (subkeys == null)
|
||||||
subkeys = new ArrayList<String>();
|
subkeys = new ArrayList<String>();
|
||||||
@@ -120,6 +123,7 @@ public class Config {
|
|||||||
logFire = config.getBoolean("logging.logFire", false);
|
logFire = config.getBoolean("logging.logFire", false);
|
||||||
logChestAccess = config.getBoolean("logging.logChestAccess", false);
|
logChestAccess = config.getBoolean("logging.logChestAccess", false);
|
||||||
logLeavesDecay = config.getBoolean("logging.logLeavesDecay", false);
|
logLeavesDecay = config.getBoolean("logging.logLeavesDecay", false);
|
||||||
|
logKills = config.getBoolean("logging.logKills", false);
|
||||||
dontRollback = config.getIntList("rollback.dontRollback", null);
|
dontRollback = config.getIntList("rollback.dontRollback", null);
|
||||||
replaceAnyway = config.getIntList("rollback.replaceAnyway", null);
|
replaceAnyway = config.getIntList("rollback.replaceAnyway", null);
|
||||||
defaultDist = config.getInt("lookup.defaultDist", 20);
|
defaultDist = config.getInt("lookup.defaultDist", 20);
|
||||||
|
@@ -4,19 +4,33 @@ import java.sql.Connection;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.bukkit.block.Block;
|
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.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
|
public class Consumer extends TimerTask implements Runnable
|
||||||
{
|
{
|
||||||
private LinkedBlockingQueue<BlockRow> bqueue = new LinkedBlockingQueue<BlockRow>();
|
private LinkedBlockingQueue<BlockRow> bqueue = new LinkedBlockingQueue<BlockRow>();
|
||||||
|
private LinkedBlockingQueue<KillRow> kqueue = new LinkedBlockingQueue<KillRow>();
|
||||||
private HashSet<Integer> hiddenplayers = new HashSet<Integer>();
|
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) {
|
Consumer (LogBlock logblock) {
|
||||||
this.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);
|
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() {
|
public int getQueueSize() {
|
||||||
return bqueue.size();
|
return bqueue.size() + kqueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hide(Player player) {
|
public boolean hide(Player player) {
|
||||||
@@ -67,13 +99,13 @@ public class Consumer extends TimerTask implements Runnable
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void run() {
|
public synchronized void run() {
|
||||||
Connection conn = logblock.pool.getConnection();
|
Connection conn = logblock.pool.getConnection();
|
||||||
if (conn == null)
|
if (conn == null)
|
||||||
return;
|
return;
|
||||||
Statement state = null;
|
Statement state = null;
|
||||||
BlockRow b;
|
BlockRow b; KillRow k;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
if (bqueue.size() > 100)
|
if (bqueue.size() > 100)
|
||||||
LogBlock.log.info("[LogBlock Consumer] Queue overloaded. Size: " + bqueue.size());
|
LogBlock.log.info("[LogBlock Consumer] Queue overloaded. Size: " + bqueue.size());
|
||||||
@@ -102,6 +134,13 @@ public class Consumer extends TimerTask implements Runnable
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
conn.commit();
|
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) {
|
} catch (SQLException ex) {
|
||||||
LogBlock.log.log(Level.SEVERE, "[LogBlock Consumer] SQL exception", ex);
|
LogBlock.log.log(Level.SEVERE, "[LogBlock Consumer] SQL exception", ex);
|
||||||
} finally {
|
} 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
|
private class ChestAccess
|
||||||
{
|
{
|
||||||
public short inType, outType;
|
public short inType, outType;
|
||||||
@@ -152,4 +215,38 @@ public class Consumer extends TimerTask implements Runnable
|
|||||||
this.ca = null;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,9 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Creeper;
|
import org.bukkit.entity.Creeper;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Fireball;
|
import org.bukkit.entity.Fireball;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.TNTPrimed;
|
import org.bukkit.entity.TNTPrimed;
|
||||||
import org.bukkit.event.Event;
|
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.BlockPlaceEvent;
|
||||||
import org.bukkit.event.block.LeavesDecayEvent;
|
import org.bukkit.event.block.LeavesDecayEvent;
|
||||||
import org.bukkit.event.block.SignChangeEvent;
|
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.EntityExplodeEvent;
|
||||||
import org.bukkit.event.entity.EntityListener;
|
import org.bukkit.event.entity.EntityListener;
|
||||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||||
@@ -105,6 +109,7 @@ public class LogBlock extends JavaPlugin
|
|||||||
new Thread(new ClearLog(this)).start();
|
new Thread(new ClearLog(this)).start();
|
||||||
LBBlockListener lbBlockListener = new LBBlockListener();
|
LBBlockListener lbBlockListener = new LBBlockListener();
|
||||||
LBPlayerListener lbPlayerListener = new LBPlayerListener();
|
LBPlayerListener lbPlayerListener = new LBPlayerListener();
|
||||||
|
LBEntityListener lbEntityListener = new LBEntityListener();
|
||||||
PluginManager pm = getServer().getPluginManager();
|
PluginManager pm = getServer().getPluginManager();
|
||||||
pm.registerEvent(Type.PLAYER_INTERACT, new LBToolPlayerListener(), Event.Priority.Normal, this);
|
pm.registerEvent(Type.PLAYER_INTERACT, new LBToolPlayerListener(), Event.Priority.Normal, this);
|
||||||
pm.registerEvent(Type.PLAYER_JOIN, lbPlayerListener, 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)
|
if (config.logFire)
|
||||||
pm.registerEvent(Type.BLOCK_BURN, lbBlockListener, Event.Priority.Monitor, this);
|
pm.registerEvent(Type.BLOCK_BURN, lbBlockListener, Event.Priority.Monitor, this);
|
||||||
if (config.logExplosions)
|
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)
|
if (config.logLeavesDecay)
|
||||||
pm.registerEvent(Type.LEAVES_DECAY, lbBlockListener, Event.Priority.Monitor, this);
|
pm.registerEvent(Type.LEAVES_DECAY, lbBlockListener, Event.Priority.Monitor, this);
|
||||||
if (config.logChestAccess)
|
if (config.logChestAccess)
|
||||||
pm.registerEvent(Type.PLAYER_INTERACT, lbPlayerListener, Event.Priority.Monitor, this);
|
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);
|
consumer = new Consumer(this);
|
||||||
if (config.useBukkitScheduler) {
|
if (config.useBukkitScheduler) {
|
||||||
if (getServer().getScheduler().scheduleAsyncRepeatingTask(this, consumer, config.delay * 20, config.delay * 20) > 0)
|
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());
|
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
|
public class LBPlayerListener extends PlayerListener
|
||||||
|
Reference in New Issue
Block a user