Rollback of killed entities works!

This commit is contained in:
Brokkonaut
2018-11-08 19:13:13 +01:00
parent 868c56ef6a
commit 3a2c1d8d6f
4 changed files with 101 additions and 19 deletions

View File

@ -690,14 +690,9 @@ public class CommandsHandler implements CommandExecutor {
}
rs = executeQuery(state, params.getQuery());
final WorldEditor editor = new WorldEditor(logblock, params.world, params.forceReplace);
WorldEditorEditFactory editFactory = new WorldEditorEditFactory(editor, params, true);
while (rs.next()) {
ChestAccess chestaccess = null;
ItemStack stack = Utils.loadItemStack(rs.getBytes("item"));
if (stack != null) {
chestaccess = new ChestAccess(stack, rs.getBoolean("itemremove"), rs.getInt("itemtype"));
}
editor.queueBlockEdit(rs.getInt("x"), rs.getInt("y"), rs.getInt("z"), rs.getInt("replaced"), rs.getInt("replacedData"), rs.getBytes("replacedState"), rs.getInt("type"), rs.getInt("typeData"), rs.getBytes("typeState"), chestaccess);
editFactory.processRow(rs);
}
final int changes = editor.getSize();
if (changes > 10000) {
@ -781,13 +776,9 @@ public class CommandsHandler implements CommandExecutor {
sender.sendMessage(ChatColor.DARK_AQUA + "Searching " + params.getTitle() + ":");
}
final WorldEditor editor = new WorldEditor(logblock, params.world, params.forceReplace);
WorldEditorEditFactory editFactory = new WorldEditorEditFactory(editor, params, false);
while (rs.next()) {
ChestAccess chestaccess = null;
ItemStack stack = Utils.loadItemStack(rs.getBytes("item"));
if (stack != null) {
chestaccess = new ChestAccess(stack, !rs.getBoolean("itemremove"), rs.getInt("itemtype"));
}
editor.queueBlockEdit(rs.getInt("x"), rs.getInt("y"), rs.getInt("z"), rs.getInt("type"), rs.getInt("typeData"), rs.getBytes("typeState"), rs.getInt("replaced"), rs.getInt("replacedData"), rs.getBytes("replacedState"), chestaccess);
editFactory.processRow(rs);
}
final int changes = editor.getSize();
if (!params.silent) {

View File

@ -18,14 +18,19 @@ import org.bukkit.block.data.type.Piston;
import org.bukkit.block.data.type.PistonHead;
import org.bukkit.block.data.type.TechnicalPiston.Type;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import de.diddiz.LogBlock.blockstate.BlockStateCodecs;
import de.diddiz.util.BukkitUtils;
import de.diddiz.util.Utils;
import de.diddiz.worldedit.WorldEditHelper;
import java.io.File;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
@ -87,6 +92,10 @@ public class WorldEditor implements Runnable {
edits.add(new BlockEdit(0, new Location(world, x, y, z), null, replaced, replaceData, replacedState, type, typeData, typeState, item));
}
public void queueEntityEdit(ResultSet rs, QueryParams p, boolean rollback) throws SQLException {
edits.add(new EntityEdit(rs, p, rollback));
}
public long getElapsedTime() {
return elapsedTime;
}
@ -155,15 +164,46 @@ public class WorldEditor implements Runnable {
}
}
private static enum PerformResult {
public static enum PerformResult {
SUCCESS, BLACKLISTED, NO_ACTION
}
private interface Edit {
public interface Edit {
PerformResult perform() throws WorldEditorException;
}
private class BlockEdit extends BlockChange implements Edit {
public class EntityEdit extends EntityChange implements Edit {
private boolean rollback;
public EntityEdit(ResultSet rs, QueryParams p, boolean rollback) throws SQLException {
super(rs, p);
this.rollback = rollback;
}
@Override
public PerformResult perform() throws WorldEditorException {
if (changeType == EntityChangeType.KILL && rollback) {
YamlConfiguration deserialized = Utils.deserializeYamlConfiguration(data);
double x = deserialized.getDouble("x");
double y = deserialized.getDouble("y");
double z = deserialized.getDouble("z");
float yaw = (float) deserialized.getDouble("yaw");
float pitch = (float) deserialized.getDouble("pitch");
Location location = new Location(world, x, y, z, yaw, pitch);
byte[] serializedWorldEditEntity = (byte[]) deserialized.get("worldedit");
if (serializedWorldEditEntity != null) {
Entity result = WorldEditHelper.restoreEntity(location, type, serializedWorldEditEntity);
if (result == null) {
throw new WorldEditorException("Could not restore " + type, location);
}
return PerformResult.SUCCESS;
}
}
return PerformResult.NO_ACTION;
}
}
public class BlockEdit extends BlockChange implements Edit {
public BlockEdit(long time, Location loc, Actor actor, int replaced, int replaceData, byte[] replacedState, int type, int typeData, byte[] typeState, ChestAccess ca) {
super(time, loc, actor, replaced, replaceData,replacedState , type, typeData, typeState, ca);
}

View File

@ -38,8 +38,8 @@ public class AdvancedKillLogging extends LoggingListener {
Location location = entity.getLocation();
YamlConfiguration data = new YamlConfiguration();
data.set("x", location.getX());
data.set("y", location.getX());
data.set("z", location.getX());
data.set("y", location.getY());
data.set("z", location.getZ());
data.set("yaw", location.getYaw());
data.set("pitch", location.getPitch());

View File

@ -1,13 +1,27 @@
package de.diddiz.worldedit;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.plugin.Plugin;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.NBTOutputStream;
import com.sk89q.jnbt.NamedTag;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
@ -32,6 +46,10 @@ public class WorldEditHelper {
return Internal.serializeEntity(entity);
}
public static Entity restoreEntity(Location location, EntityType type, byte[] serialized) {
return Internal.restoreEntity(location, type, serialized);
}
private static class Internal {
// private static WorldEditPlugin worldEdit;
@ -39,6 +57,33 @@ public class WorldEditHelper {
// Internal.worldEdit = (WorldEditPlugin) worldEdit;
}
public static Entity restoreEntity(Location location, EntityType type, byte[] serialized) {
com.sk89q.worldedit.world.entity.EntityType weType = BukkitAdapter.adapt(type);
com.sk89q.worldedit.util.Location weLocation = BukkitAdapter.adapt(location);
try {
NBTInputStream nbtis = new NBTInputStream(new ByteArrayInputStream(serialized));
NamedTag namedTag = nbtis.readNamedTag();
nbtis.close();
UUID newUUID = null;
if (namedTag.getName().equals("entity") && namedTag.getTag() instanceof CompoundTag) {
CompoundTag serializedState = (CompoundTag) namedTag.getTag();
BaseEntity state = new BaseEntity(weType, serializedState);
CompoundTag oldNbt = state.getNbtData();
UUID oldUUID = new UUID(oldNbt.getLong("UUIDMost"), oldNbt.getLong("UUIDLeast"));
com.sk89q.worldedit.entity.Entity weEntity = weLocation.getExtent().createEntity(weLocation, state);
if (weEntity != null) {
CompoundTag newNbt = weEntity.getState().getNbtData();
newUUID = new UUID(newNbt.getLong("UUIDMost"), newNbt.getLong("UUIDLeast"));
System.out.println("Old UUID: " + oldUUID);
System.out.println("New UUID: " + newUUID);
}
}
return newUUID == null ? null : Bukkit.getEntity(newUUID);
} catch (IOException e) {
throw new RuntimeException("This IOException should be impossible", e);
}
}
public static byte[] serializeEntity(Entity entity) {
com.sk89q.worldedit.entity.Entity weEntity = BukkitAdapter.adapt(entity);
BaseEntity state = weEntity.getState();
@ -46,7 +91,13 @@ public class WorldEditHelper {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
NBTOutputStream nbtos = new NBTOutputStream(baos);
nbtos.writeNamedTag("entity", state.getNbtData());
CompoundTag nbt = state.getNbtData();
LinkedHashMap<String, Tag> value = new LinkedHashMap<>(nbt.getValue());
value.put("Health", new FloatTag(20.0f));
value.put("Motion", new ListTag(DoubleTag.class, Arrays.asList(new DoubleTag[] {new DoubleTag(0),new DoubleTag(0),new DoubleTag(0)})));
value.put("Fire", new ShortTag((short) -20));
value.put("HurtTime", new ShortTag((short) 0));
nbtos.writeNamedTag("entity", new CompoundTag(value));
nbtos.close();
return baos.toByteArray();
} catch (IOException e) {