Improved fire logging and rollback

This commit is contained in:
Brokkonaut
2018-08-21 06:17:24 +02:00
parent 710de5b35a
commit 56404533db
6 changed files with 77 additions and 8 deletions

View File

@@ -12,6 +12,8 @@ import java.util.Collection;
import static de.diddiz.util.BukkitUtils.entityName;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
public class Actor {
@@ -36,23 +38,40 @@ public class Actor {
final String name;
final String UUID;
final Location blockLocation;
public Actor(String name, String UUID) {
this.name = name;
this.UUID = UUID;
this.blockLocation = null;
}
public Actor(String name, String UUID, Block block) {
this.name = name;
this.UUID = UUID;
this.blockLocation = block == null ? null : block.getLocation();
}
public Actor(String name, java.util.UUID UUID) {
this.name = name;
this.UUID = UUID.toString();
this.blockLocation = null;
}
public Actor(String name, java.util.UUID UUID, Block block) {
this.name = name;
this.UUID = UUID.toString();
this.blockLocation = block == null ? null : block.getLocation();
}
public Actor(String name) {
this(name, generateUUID(name));
}
public Actor(String name, Block block) {
this(name, generateUUID(name), block);
}
public Actor(ResultSet rs) throws SQLException {
this(rs.getString("playername"), rs.getString("UUID"));
}
@@ -65,6 +84,10 @@ public class Actor {
return UUID;
}
public Location getBlockLocation() {
return blockLocation;
}
public static Actor actorFromEntity(Entity entity) {
if (entity instanceof Player) {
return new Actor(entityName(entity), entity.getUniqueId());

View File

@@ -705,12 +705,14 @@ public class Consumer extends Thread {
private class BlockRow extends BlockChange implements Row {
final String statementString;
final String selectActorIdStatementString;
public BlockRow(Location loc, Actor actor, int replaced, int replacedData, byte[] replacedState, int type, int typeData, byte[] typeState, ChestAccess ca) {
super(System.currentTimeMillis() / 1000, loc, actor, replaced, replacedData, replacedState, type, typeData, typeState, ca);
final String table = getWorldConfig(loc.getWorld()).table;
statementString = "INSERT INTO `" + table + "-blocks` (date, playerid, replaced, replaceddata, type, typedata, x, y, z) VALUES (FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?, ?)";
selectActorIdStatementString = "SELECT playerid FROM `" + table + "-blocks` WHERE x = ? AND y = ? AND z = ? ORDER BY date DESC LIMIT 1";
}
@Override
@@ -735,9 +737,27 @@ public class Consumer extends Thread {
@Override
public void process(Connection conn, BatchHelper batchHelper) throws SQLException {
int sourceActor = playerIDAsIntIncludeUncommited(actor);
Location actorBlockLocation = actor.getBlockLocation();
if(actorBlockLocation != null) {
Integer tempSourceActor = batchHelper.getUncommitedBlockActor(actorBlockLocation);
if(tempSourceActor != null) {
sourceActor = tempSourceActor;
} else {
PreparedStatement smt = batchHelper.getOrPrepareStatement(conn, selectActorIdStatementString, Statement.NO_GENERATED_KEYS);
smt.setInt(1, actorBlockLocation.getBlockX());
smt.setInt(2, safeY(actorBlockLocation));
smt.setInt(3, actorBlockLocation.getBlockZ());
ResultSet rs = smt.executeQuery();
if (rs.next()) {
sourceActor = rs.getInt(1);
}
rs.close();
}
}
PreparedStatement smt = batchHelper.getOrPrepareStatement(conn, statementString, Statement.RETURN_GENERATED_KEYS);
smt.setLong(1, date);
smt.setInt(2, playerIDAsIntIncludeUncommited(actor));
smt.setInt(2, sourceActor);
smt.setInt(3, replacedMaterial);
smt.setInt(4, replacedData);
smt.setInt(5, typeMaterial);
@@ -745,6 +765,7 @@ public class Consumer extends Thread {
smt.setInt(7, loc.getBlockX());
smt.setInt(8, safeY(loc));
smt.setInt(9, loc.getBlockZ());
batchHelper.addUncommitedBlockActorId(loc, sourceActor);
batchHelper.addBatch(smt, new IntCallback() {
@Override
public void call(int id) throws SQLException {
@@ -936,11 +957,21 @@ public class Consumer extends Thread {
private HashMap<String, PreparedStatement> preparedStatements = new HashMap<>();
private HashSet<PreparedStatement> preparedStatementsWithGeneratedKeys = new HashSet<>();
private LinkedHashMap<PreparedStatement, ArrayList<IntCallback>> generatedKeyHandler = new LinkedHashMap<>();
private HashMap<Location, Integer> uncommitedBlockActors = new HashMap<>();
public void reset() {
preparedStatements.clear();
preparedStatementsWithGeneratedKeys.clear();
generatedKeyHandler.clear();
uncommitedBlockActors.clear();
}
public void addUncommitedBlockActorId(Location loc, int actorId) {
uncommitedBlockActors.put(loc, actorId);
}
public Integer getUncommitedBlockActor(Location loc) {
return uncommitedBlockActors.get(loc);
}
public void processStatements(Connection conn) throws SQLException {
@@ -966,6 +997,7 @@ public class Consumer extends Thread {
}
}
}
uncommitedBlockActors.clear();
}
public PreparedStatement getOrPrepareStatement(Connection conn, String sql, int autoGeneratedKeys) throws SQLException {

View File

@@ -194,7 +194,7 @@ public class WorldEditor implements Runnable {
return PerformResult.NO_ACTION;
}
}
if (block.getType() != setBlock.getMaterial() && !replaceAnyway.contains(block.getType())) {
if (block.getType() != setBlock.getMaterial() && !block.isEmpty() && !replaceAnyway.contains(block.getType())) {
return PerformResult.NO_ACTION;
}
if (state instanceof InventoryHolder && replacedBlock.getMaterial() != block.getType()) {

View File

@@ -34,6 +34,7 @@ public class Config {
public static boolean dumpDeletedLog;
public static boolean logBedExplosionsAsPlayerWhoTriggeredThese;
public static boolean logCreeperExplosionsAsPlayerWhoTriggeredThese, logPlayerInfo;
public static boolean logFireSpreadAsPlayerWhoCreatedIt;
public static LogKillsLevel logKillsLevel;
public static Set<Material> dontRollback, replaceAnyway;
public static int rollbackMaxTime, rollbackMaxArea;
@@ -93,6 +94,7 @@ public class Config {
def.put("clearlog.autoClearLogDelay", "6h");
def.put("logging.logBedExplosionsAsPlayerWhoTriggeredThese", true);
def.put("logging.logCreeperExplosionsAsPlayerWhoTriggeredThese", false);
def.put("logging.logFireSpreadAsPlayerWhoCreatedIt", true);
def.put("logging.logKillsLevel", "PLAYERS");
def.put("logging.logEnvironmentalKills", false);
def.put("logging.logPlayerInfo", false);
@@ -100,7 +102,7 @@ public class Config {
def.put("logging.hiddenBlocks", Arrays.asList(Material.AIR.name(), Material.CAVE_AIR.name(), Material.VOID_AIR.name()));
def.put("logging.ignoredChat", Arrays.asList("/register", "/login"));
def.put("rollback.dontRollback", Arrays.asList(Material.LAVA.name(), Material.TNT.name(), Material.FIRE.name()));
def.put("rollback.replaceAnyway", Arrays.asList(Material.LAVA.name(), Material.WATER.name(), Material.FIRE.name()));
def.put("rollback.replaceAnyway", Arrays.asList(Material.LAVA.name(), Material.WATER.name(), Material.FIRE.name(), Material.GRASS_BLOCK.name()));
def.put("rollback.maxTime", "2 days");
def.put("rollback.maxArea", 50);
def.put("lookup.defaultDist", 20);
@@ -169,6 +171,7 @@ public class Config {
autoClearLogDelay = parseTimeSpec(config.getString("clearlog.autoClearLogDelay").split(" "));
logBedExplosionsAsPlayerWhoTriggeredThese = config.getBoolean("logging.logBedExplosionsAsPlayerWhoTriggeredThese", true);
logCreeperExplosionsAsPlayerWhoTriggeredThese = config.getBoolean("logging.logCreeperExplosionsAsPlayerWhoTriggeredThese", false);
logFireSpreadAsPlayerWhoCreatedIt = config.getBoolean("logging.logFireSpreadAsPlayerWhoCreatedIt", true);
logPlayerInfo = config.getBoolean("logging.logPlayerInfo", true);
try {
logKillsLevel = LogKillsLevel.valueOf(config.getString("logging.logKillsLevel").toUpperCase());

View File

@@ -3,6 +3,8 @@ package de.diddiz.LogBlock.listeners;
import de.diddiz.LogBlock.Actor;
import de.diddiz.LogBlock.LogBlock;
import de.diddiz.LogBlock.Logging;
import de.diddiz.LogBlock.config.Config;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
@@ -16,6 +18,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
import static de.diddiz.LogBlock.config.Config.isLogging;
import static de.diddiz.util.LoggingUtil.smartLogBlockBreak;
import static de.diddiz.util.LoggingUtil.smartLogBlockReplace;
import static de.diddiz.util.LoggingUtil.smartLogFallables;
public class BlockBurnLogging extends LoggingListener {
@@ -26,16 +29,16 @@ public class BlockBurnLogging extends LoggingListener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockBurn(BlockBurnEvent event) {
if (isLogging(event.getBlock().getWorld(), Logging.FIRE)) {
smartLogBlockBreak(consumer, new Actor("Fire"), event.getBlock());
smartLogFallables(consumer, new Actor("Fire"), event.getBlock());
smartLogBlockReplace(consumer, new Actor("Fire", Config.logFireSpreadAsPlayerWhoCreatedIt ? event.getIgnitingBlock() : null), event.getBlock(), Material.FIRE.createBlockData());
smartLogFallables(consumer, new Actor("Fire", Config.logFireSpreadAsPlayerWhoCreatedIt ? event.getIgnitingBlock() : null), event.getBlock());
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockIgnite(BlockIgniteEvent event) {
Actor actor = new Actor("Fire");
Actor actor = new Actor("Fire", Config.logFireSpreadAsPlayerWhoCreatedIt ? event.getIgnitingBlock() : null);
if (event.getCause() == IgniteCause.FLINT_AND_STEEL) {
if(event.getIgnitingEntity() != null) {
if (event.getIgnitingEntity() != null) {
return; // handled in block place
} else {
actor = new Actor("Dispenser");

View File

@@ -101,6 +101,10 @@ public class LoggingUtil {
}
public static void smartLogBlockBreak(Consumer consumer, Actor actor, Block origin) {
smartLogBlockReplace(consumer, actor, origin, null);
}
public static void smartLogBlockReplace(Consumer consumer, Actor actor, Block origin, BlockData replacedWith) {
WorldConfig wcfg = getWorldConfig(origin.getWorld());
if (wcfg == null) {
@@ -187,7 +191,11 @@ public class LoggingUtil {
}
// Do this down here so that the block is added after blocks sitting on it
consumer.queueBlockBreak(actor, origin.getState());
if (replacedWith == null) {
consumer.queueBlockBreak(actor, origin.getState());
} else {
consumer.queueBlockReplace(actor, origin.getState(), replacedWith);
}
}
public static String checkText(String text) {