From d04939fb2c06b18c19a00c7f67aa47f96340f828 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 12 Mar 2025 08:41:21 +0100 Subject: [PATCH 1/3] Add a simple smaller Trace file, not finished! --- .../features/tracer/TraceManager.java | 4 +- .../features/tracer/TraceRepository.java | 84 ++++++++++++------- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java index 213d5e8e..9e949c9d 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java @@ -58,13 +58,13 @@ public class TraceManager implements Listener { return; for (File traceFile : traceFiles) { - if (traceFile.getName().contains(".records")) + if (traceFile.getName().contains(".meta")) continue; if (TraceRepository.getVersion(traceFile) == TraceRepository.SERIALISATION_VERSION) { add(TraceRepository.readTrace(traceFile)); } else { - String uuid = traceFile.getName().replace(".meta", ""); + String uuid = traceFile.getName().replace(".records", ""); new File(tracesFolder, uuid + ".records").deleteOnExit(); new File(tracesFolder, uuid + ".meta").deleteOnExit(); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java index 39f50fe1..0f8b8816 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java @@ -34,17 +34,16 @@ public class TraceRepository { } @SneakyThrows - public static Trace readTrace(File metadataFile) { + public static Trace readTrace(File recordsFile) { @Cleanup - ObjectInputStream reader = new ObjectInputStream(new FileInputStream(metadataFile)); + ObjectInputStream reader = new ObjectInputStream(new FileInputStream(recordsFile)); UUID uuid = UUID.fromString(reader.readUTF()); Region region = Region.getREGION_MAP().get(reader.readUTF()); Date date = (Date) reader.readObject(); - File recordsFile = new File(tracesFolder,uuid + ".records"); int serialisationVersion = reader.readInt(); int recordsCount = reader.readInt(); - return new Trace(uuid, region, date, metadataFile, recordsFile, recordsCount); + return new Trace(uuid, region, date, recordsFile, recordsFile, recordsCount); } @SneakyThrows @@ -53,38 +52,65 @@ public class TraceRepository { outputStream.writeUTF(trace.getUuid().toString()); outputStream.writeUTF(trace.getRegion().getName()); outputStream.writeObject(trace.getDate()); - outputStream.writeInt(SERIALISATION_VERSION); + outputStream.writeInt(SERIALISATION_VERSION + 1); outputStream.writeInt(records.size()); + + Map> pointsByTNTId = new HashMap<>(); + records.forEach(tntPoint -> { + pointsByTNTId.computeIfAbsent(tntPoint.getTntId(), integer -> new ArrayList<>()).add(tntPoint); + }); + + for (Map.Entry> entry : pointsByTNTId.entrySet()) { + outputStream.writeInt(entry.getKey()); + outputStream.write(entry.getValue().size()); + + for (int i = 0; i < entry.getValue().size(); i++) { + TNTPoint current = entry.getValue().get(i); + if (i == 0) { + writeTNTPoint(outputStream, current, true); + continue; + } + + TNTPoint last = entry.getValue().get(i - 1); + + boolean writeTickData = true; + if (last.getTicksSinceStart() + 1 == current.getTicksSinceStart() && last.getFuse() - 1 == current.getFuse()) { + writeTickData = false; + } + + writeTNTPoint(outputStream, current, writeTickData); + } + } + outputStream.flush(); outputStream.close(); - - - writeTraceRecords(trace.getRecordsSaveFile(), records); } @SneakyThrows - protected static void writeTraceRecords(File recordsFile, List records) { - DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(recordsFile)); - for (TNTPoint record : records) { - outputStream.writeInt(record.getTntId()); - outputStream.writeBoolean(record.isExplosion()); - outputStream.writeBoolean(record.isInWater()); - outputStream.writeBoolean(record.isAfterFirstExplosion()); - outputStream.writeBoolean(record.isDestroyedBuildArea()); - outputStream.writeBoolean(record.isDestroyedTestBlock()); - outputStream.writeLong(record.getTicksSinceStart()); - outputStream.writeInt(record.getFuse()); - Location location = record.getLocation(); - outputStream.writeDouble(location.getX()); - outputStream.writeDouble(location.getY()); - outputStream.writeDouble(location.getZ()); - Vector velocity = record.getVelocity(); - outputStream.writeDouble(velocity.getX()); - outputStream.writeDouble(velocity.getY()); - outputStream.writeDouble(velocity.getZ()); + private static void writeTNTPoint(ObjectOutputStream outputStream, TNTPoint tntPoint, boolean writeTickData) { + byte data = 0; + if (writeTickData) data |= 0x01; + if (tntPoint.isExplosion()) data |= 0x02; + if (tntPoint.isInWater()) data |= 0x04; + if (tntPoint.isAfterFirstExplosion()) data |= 0x08; + if (tntPoint.isDestroyedBuildArea()) data |= 0x10; + if (tntPoint.isDestroyedTestBlock()) data |= 0x20; + outputStream.write(data); + + if (writeTickData) { + outputStream.writeLong(tntPoint.getTicksSinceStart()); + outputStream.writeInt(tntPoint.getFuse()); } - outputStream.flush(); - outputStream.close(); + + Location location = tntPoint.getLocation(); + outputStream.writeDouble(location.getX()); + outputStream.writeDouble(location.getY()); + outputStream.writeDouble(location.getZ()); + + Vector velocity = tntPoint.getVelocity(); + outputStream.writeDouble(velocity.getX()); + outputStream.writeDouble(velocity.getY()); + outputStream.writeDouble(velocity.getZ()); } @SneakyThrows From 95a97aed938e2d354b3a6493e7ae298ac910f411 Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Wed, 2 Jul 2025 09:16:48 +0200 Subject: [PATCH 2/3] Update TraceRepository to save quite a bit smaller traces --- .../bausystem/features/tracer/Trace.java | 16 +-- .../features/tracer/TraceManager.java | 30 +++-- .../tracer/TraceRecordingWrapper.java | 2 +- .../features/tracer/TraceRepository.java | 110 ++++++++++-------- 4 files changed, 84 insertions(+), 74 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java index 9628570a..2c7cf22c 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/Trace.java @@ -50,12 +50,6 @@ public class Trace { @Getter private final File recordsSaveFile; - /** - * File the metadata are saved in - */ - @Getter - private final File metadataSaveFile; - /** * Region the trace was recorded in */ @@ -75,7 +69,7 @@ public class Trace { @Setter @Getter - private int recordsCount; + private int tntIdCount; /** * A map of all REntityServers rendering this trace @@ -95,21 +89,19 @@ public class Trace { this.date = new Date(); records = new SoftReference<>(recordList); recordsSaveFile = new File(TraceRepository.tracesFolder, uuid + ".records"); - metadataSaveFile = new File(TraceRepository.tracesFolder, uuid + ".meta"); } /** * Constructor for deserialising a trace from the file system */ @SneakyThrows - protected Trace(UUID uuid, Region region, Date date, File metadataFile, File recordsFile, int recordsCount) { - this.metadataSaveFile = metadataFile; + protected Trace(UUID uuid, Region region, Date date, File recordsFile, int tntIdCount) { recordsSaveFile = recordsFile; this.uuid = uuid; this.region = region; this.date = date; this.records = new SoftReference<>(null); - this.recordsCount = recordsCount; + this.tntIdCount = tntIdCount; } /** @@ -311,7 +303,7 @@ public class Trace { ", region=" + region + ", creationTime=" + date + ", recordsSaveFile=" + recordsSaveFile.getName() + - ", recordCount=" + recordsCount + + ", tntCount=" + tntIdCount + ", records=" + getRecords() + '}'; } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java index 9e949c9d..4a741e77 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java @@ -57,19 +57,27 @@ public class TraceManager implements Listener { if (traceFiles == null) return; + boolean hasMetaFiles = false; for (File traceFile : traceFiles) { - if (traceFile.getName().contains(".meta")) - continue; - - if (TraceRepository.getVersion(traceFile) == TraceRepository.SERIALISATION_VERSION) { - add(TraceRepository.readTrace(traceFile)); - } else { - String uuid = traceFile.getName().replace(".records", ""); - - new File(tracesFolder, uuid + ".records").deleteOnExit(); - new File(tracesFolder, uuid + ".meta").deleteOnExit(); + if (traceFile.getName().contains(".meta")) { + hasMetaFiles = true; } + } + if (hasMetaFiles) { + for (File traceFile : traceFiles) { + traceFile.delete(); + } + traceFiles = new File[0]; + } + // TODO: Cleanup all traces if a .meta is present! + for (File traceFile : traceFiles) { + Trace trace = TraceRepository.readTrace(traceFile); + if (trace == null) { + traceFile.delete(); + continue; + } + add(trace); } } @@ -152,7 +160,6 @@ public class TraceManager implements Listener { if (traceId == null) throw new RuntimeException("Trace not found while trying to remove see (c978eb98-b0b2-4009-91d8-acfa34e2831a)"); traces.remove(traceId); trace.hide(); - trace.getMetadataSaveFile().delete(); trace.getRecordsSaveFile().delete(); } @@ -172,7 +179,6 @@ public class TraceManager implements Listener { tracesByRegion.getOrDefault(region, new HashMap<>()) .forEach((i, trace) -> { if (trace.getRegion() != region) return; - trace.getMetadataSaveFile().delete(); trace.getRecordsSaveFile().delete(); }); tracesByRegion.getOrDefault(region, new HashMap<>()).clear(); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecordingWrapper.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecordingWrapper.java index 82eb3019..38cde80d 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecordingWrapper.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRecordingWrapper.java @@ -65,7 +65,7 @@ public class TraceRecordingWrapper { TraceManager.instance.showPartial(trace, recordsToAdd); recordList.addAll(recordsToAdd); - trace.setRecordsCount(recordList.size()); + trace.setTntIdCount((int) recordList.stream().map(TNTPoint::getTntId).distinct().count()); recordsToAdd.clear(); } diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java index 0f8b8816..3aee95e6 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java @@ -9,60 +9,56 @@ import org.bukkit.util.Vector; import java.io.*; import java.util.*; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; public class TraceRepository { /** * Increment this when changing serialisation format */ - public static final int SERIALISATION_VERSION = 1; + public static final int SERIALISATION_VERSION = 2; + public static final int WRITE_TICK_DATA = 0x01; + public static final int EXPLOSION = 0x02; + public static final int IN_WATER = 0x04; + public static final int AFTER_FIRST_EXPLOSION = 0x08; + public static final int DESTROYED_BUILD_AREA = 0x10; + public static final int DESTROYED_TEST_BLOCK = 0x20; public static File tracesFolder = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "traces"); - @SneakyThrows - protected static int getVersion(File metadataFile) { - @Cleanup - ObjectInputStream reader = new ObjectInputStream(new FileInputStream(metadataFile)); - reader.readUTF(); - reader.readUTF(); - reader.readObject(); - try { - int version = reader.readInt(); - return version; - } catch (EOFException e) { - return 0; - } - } - @SneakyThrows public static Trace readTrace(File recordsFile) { @Cleanup - ObjectInputStream reader = new ObjectInputStream(new FileInputStream(recordsFile)); + ObjectInputStream reader = new ObjectInputStream(new GZIPInputStream(new FileInputStream(recordsFile))); UUID uuid = UUID.fromString(reader.readUTF()); Region region = Region.getREGION_MAP().get(reader.readUTF()); Date date = (Date) reader.readObject(); int serialisationVersion = reader.readInt(); - int recordsCount = reader.readInt(); + if (serialisationVersion != SERIALISATION_VERSION) { + return null; + } + int tntIdCount = reader.readInt(); - return new Trace(uuid, region, date, recordsFile, recordsFile, recordsCount); + return new Trace(uuid, region, date, recordsFile, tntIdCount); } @SneakyThrows protected static void writeTrace(Trace trace, List records) { - ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(trace.getMetadataSaveFile())); + ObjectOutputStream outputStream = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(trace.getRecordsSaveFile()))); outputStream.writeUTF(trace.getUuid().toString()); outputStream.writeUTF(trace.getRegion().getName()); outputStream.writeObject(trace.getDate()); - outputStream.writeInt(SERIALISATION_VERSION + 1); - outputStream.writeInt(records.size()); + outputStream.writeInt(SERIALISATION_VERSION); Map> pointsByTNTId = new HashMap<>(); records.forEach(tntPoint -> { pointsByTNTId.computeIfAbsent(tntPoint.getTntId(), integer -> new ArrayList<>()).add(tntPoint); }); + outputStream.writeInt(pointsByTNTId.size()); for (Map.Entry> entry : pointsByTNTId.entrySet()) { outputStream.writeInt(entry.getKey()); - outputStream.write(entry.getValue().size()); + outputStream.writeInt(entry.getValue().size()); for (int i = 0; i < entry.getValue().size(); i++) { TNTPoint current = entry.getValue().get(i); @@ -89,12 +85,12 @@ public class TraceRepository { @SneakyThrows private static void writeTNTPoint(ObjectOutputStream outputStream, TNTPoint tntPoint, boolean writeTickData) { byte data = 0; - if (writeTickData) data |= 0x01; - if (tntPoint.isExplosion()) data |= 0x02; - if (tntPoint.isInWater()) data |= 0x04; - if (tntPoint.isAfterFirstExplosion()) data |= 0x08; - if (tntPoint.isDestroyedBuildArea()) data |= 0x10; - if (tntPoint.isDestroyedTestBlock()) data |= 0x20; + if (writeTickData) data |= WRITE_TICK_DATA; + if (tntPoint.isExplosion()) data |= EXPLOSION; + if (tntPoint.isInWater()) data |= IN_WATER; + if (tntPoint.isAfterFirstExplosion()) data |= AFTER_FIRST_EXPLOSION; + if (tntPoint.isDestroyedBuildArea()) data |= DESTROYED_BUILD_AREA; + if (tntPoint.isDestroyedTestBlock()) data |= DESTROYED_TEST_BLOCK; outputStream.write(data); if (writeTickData) { @@ -114,16 +110,24 @@ public class TraceRepository { } @SneakyThrows - protected static TNTPoint readTraceRecord(DataInputStream objectInput) { + protected static TNTPoint readTraceRecord(int tntId, TNTPoint last, ObjectInputStream objectInput) { - int tntId = objectInput.readInt(); - boolean explosion = objectInput.readBoolean(); - boolean inWater = objectInput.readBoolean(); - boolean afterFirstExplosion = objectInput.readBoolean(); - boolean destroyedBuildArea = objectInput.readBoolean(); - boolean destroyedTestBlock = objectInput.readBoolean(); - long ticksSinceStart = objectInput.readLong(); - int fuse = objectInput.readInt(); + int data = objectInput.read(); + boolean explosion = (data & EXPLOSION) > 0; + boolean inWater = (data & IN_WATER) > 0; + boolean afterFirstExplosion = (data & AFTER_FIRST_EXPLOSION) > 0; + boolean destroyedBuildArea = (data & DESTROYED_BUILD_AREA) > 0; + boolean destroyedTestBlock = (data & DESTROYED_TEST_BLOCK) > 0; + + long ticksSinceStart; + int fuse; + if ((data & WRITE_TICK_DATA) > 0) { + ticksSinceStart = objectInput.readLong(); + fuse = objectInput.readInt(); + } else { + ticksSinceStart = last.getTicksSinceStart() + 1; + fuse = last.getFuse() - 1; + } double locX = objectInput.readDouble(); double locY = objectInput.readDouble(); @@ -142,21 +146,29 @@ public class TraceRepository { protected static List readTraceRecords(Trace trace) { File recordsFile = trace.getRecordsSaveFile(); @Cleanup - DataInputStream inputStream = new DataInputStream(new FileInputStream(recordsFile)); + ObjectInputStream inputStream = new ObjectInputStream(new GZIPInputStream(new FileInputStream(recordsFile))); + inputStream.readUTF(); + inputStream.readUTF(); + inputStream.readObject(); + inputStream.readInt(); + inputStream.readInt(); List records = new ArrayList<>(); - for (int i = 0; i < trace.getRecordsCount(); i++) { - records.add(readTraceRecord(inputStream)); - } - Map> histories = new HashMap<>(); - for (TNTPoint record : records) { - int tntId = record.getTntId(); - List history = histories.computeIfAbsent(tntId, id -> new ArrayList<>()); - history.add(record); - record.setHistory(history); - } + for (int i = 0; i < trace.getTntIdCount(); i++) { + int tntId = inputStream.readInt(); + int size = inputStream.readInt(); + List points = histories.computeIfAbsent(tntId, id -> new ArrayList<>()); + TNTPoint last = null; + for (int j = 0; j < size; j++) { + TNTPoint point = readTraceRecord(tntId, last, inputStream); + point.setHistory(points); + points.add(point); + last = point; + records.add(point); + } + } return records; } } From 6f64d03feeba0c44fdbf4364d758827e6c746a7b Mon Sep 17 00:00:00 2001 From: YoyoNow Date: Thu, 3 Jul 2025 11:07:52 +0200 Subject: [PATCH 3/3] Update pr stuff --- .../bausystem/features/tracer/TraceManager.java | 1 - .../bausystem/features/tracer/TraceRepository.java | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java index 4a741e77..060db33b 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceManager.java @@ -70,7 +70,6 @@ public class TraceManager implements Listener { traceFiles = new File[0]; } - // TODO: Cleanup all traces if a .meta is present! for (File traceFile : traceFiles) { Trace trace = TraceRepository.readTrace(traceFile); if (trace == null) { diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java index 3aee95e6..899ea5f1 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceRepository.java @@ -18,12 +18,12 @@ public class TraceRepository { * Increment this when changing serialisation format */ public static final int SERIALISATION_VERSION = 2; - public static final int WRITE_TICK_DATA = 0x01; - public static final int EXPLOSION = 0x02; - public static final int IN_WATER = 0x04; - public static final int AFTER_FIRST_EXPLOSION = 0x08; - public static final int DESTROYED_BUILD_AREA = 0x10; - public static final int DESTROYED_TEST_BLOCK = 0x20; + public static final int WRITE_TICK_DATA = 0b00000001; + public static final int EXPLOSION = 0b00000010; + public static final int IN_WATER = 0b00000100; + public static final int AFTER_FIRST_EXPLOSION = 0b00001000; + public static final int DESTROYED_BUILD_AREA = 0b00010000; + public static final int DESTROYED_TEST_BLOCK = 0b00100000; public static File tracesFolder = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "traces"); @SneakyThrows