forked from SteamWar/SteamWar
Merge branch 'main' into Backend/init
This commit is contained in:
@@ -11,5 +11,9 @@ steamwar.properties
|
|||||||
.idea
|
.idea
|
||||||
*.iml
|
*.iml
|
||||||
|
|
||||||
|
# VSCode
|
||||||
|
bin/
|
||||||
|
.vscode
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
lib
|
lib
|
||||||
@@ -28,6 +28,8 @@ import de.steamwar.bausystem.features.script.lua.libs.LuaLib;
|
|||||||
import de.steamwar.bausystem.features.slaves.panzern.Panzern;
|
import de.steamwar.bausystem.features.slaves.panzern.Panzern;
|
||||||
import de.steamwar.bausystem.features.slaves.panzern.PanzernAlgorithm;
|
import de.steamwar.bausystem.features.slaves.panzern.PanzernAlgorithm;
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils;
|
import de.steamwar.bausystem.features.tpslimit.TPSFreezeUtils;
|
||||||
|
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||||
|
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||||
import de.steamwar.bausystem.features.world.BauScoreboard;
|
import de.steamwar.bausystem.features.world.BauScoreboard;
|
||||||
import de.steamwar.bausystem.linkage.specific.BauGuiItem;
|
import de.steamwar.bausystem.linkage.specific.BauGuiItem;
|
||||||
import de.steamwar.bausystem.region.loader.PrototypeLoader;
|
import de.steamwar.bausystem.region.loader.PrototypeLoader;
|
||||||
@@ -197,6 +199,9 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
});
|
});
|
||||||
|
|
||||||
TickListener.impl.init();
|
TickListener.impl.init();
|
||||||
|
|
||||||
|
TraceManager.instance.init();
|
||||||
|
TraceRecorder.instance.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ package de.steamwar.bausystem.features.tracer;
|
|||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||||
import de.steamwar.bausystem.region.utils.RegionType;
|
import de.steamwar.bausystem.region.utils.RegionType;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -39,8 +41,9 @@ import java.util.Optional;
|
|||||||
/**
|
/**
|
||||||
* Recording of a tnt at a specific tick
|
* Recording of a tnt at a specific tick
|
||||||
*/
|
*/
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
@Getter
|
@Getter
|
||||||
public class TNTPoint implements Externalizable {
|
public class TNTPoint{
|
||||||
/**
|
/**
|
||||||
* Unique number to identify records being of the same tnt
|
* Unique number to identify records being of the same tnt
|
||||||
*/
|
*/
|
||||||
@@ -97,12 +100,9 @@ public class TNTPoint implements Externalizable {
|
|||||||
private List<TNTPoint> history;
|
private List<TNTPoint> history;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for deserialization only !! Do not Call !!
|
* Constructor for object creation in trace recording
|
||||||
*/
|
*/
|
||||||
public TNTPoint() {
|
protected TNTPoint(int tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart,
|
||||||
}
|
|
||||||
|
|
||||||
public TNTPoint(int tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart,
|
|
||||||
List<TNTPoint> history, List<Block> destroyedBlocks) {
|
List<TNTPoint> history, List<Block> destroyedBlocks) {
|
||||||
this.tntId = tntId;
|
this.tntId = tntId;
|
||||||
this.explosion = explosion;
|
this.explosion = explosion;
|
||||||
@@ -161,44 +161,6 @@ public class TNTPoint implements Externalizable {
|
|||||||
this.history = history;
|
this.history = history;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeExternal(ObjectOutput objectOutput) throws IOException {
|
|
||||||
objectOutput.writeInt(tntId);
|
|
||||||
objectOutput.writeBoolean(explosion);
|
|
||||||
objectOutput.writeBoolean(inWater);
|
|
||||||
objectOutput.writeBoolean(afterFirstExplosion);
|
|
||||||
objectOutput.writeBoolean(destroyedBuildArea);
|
|
||||||
objectOutput.writeBoolean(destroyedTestBlock);
|
|
||||||
objectOutput.writeLong(ticksSinceStart);
|
|
||||||
objectOutput.writeInt(fuse);
|
|
||||||
objectOutput.writeDouble(location.getX());
|
|
||||||
objectOutput.writeDouble(location.getY());
|
|
||||||
objectOutput.writeDouble(location.getZ());
|
|
||||||
objectOutput.writeDouble(velocity.getX());
|
|
||||||
objectOutput.writeDouble(velocity.getY());
|
|
||||||
objectOutput.writeDouble(velocity.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readExternal(ObjectInput objectInput) throws IOException {
|
|
||||||
tntId = objectInput.readInt();
|
|
||||||
explosion = objectInput.readBoolean();
|
|
||||||
inWater = objectInput.readBoolean();
|
|
||||||
afterFirstExplosion = objectInput.readBoolean();
|
|
||||||
destroyedBuildArea = objectInput.readBoolean();
|
|
||||||
destroyedTestBlock = objectInput.readBoolean();
|
|
||||||
ticksSinceStart = objectInput.readLong();
|
|
||||||
fuse = objectInput.readInt();
|
|
||||||
double locX = objectInput.readDouble();
|
|
||||||
double locY = objectInput.readDouble();
|
|
||||||
double locZ = objectInput.readDouble();
|
|
||||||
location = new Location(Bukkit.getWorlds().get(0), locX, locY, locZ);
|
|
||||||
double velX = objectInput.readDouble();
|
|
||||||
double velY = objectInput.readDouble();
|
|
||||||
double velZ = objectInput.readDouble();
|
|
||||||
velocity = new Vector(velX, velY, velZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TNTPoint{" +
|
return "TNTPoint{" +
|
||||||
|
|||||||
@@ -26,20 +26,16 @@ import de.steamwar.bausystem.features.tracer.rendering.ViewFlag;
|
|||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
import de.steamwar.entity.REntityServer;
|
import de.steamwar.entity.REntityServer;
|
||||||
import lombok.Cleanup;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.lang.ref.SoftReference;
|
import java.lang.ref.SoftReference;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
public class Trace {
|
public class Trace {
|
||||||
/**
|
/**
|
||||||
@@ -77,6 +73,10 @@ public class Trace {
|
|||||||
*/
|
*/
|
||||||
private SoftReference<List<TNTPoint>> records;
|
private SoftReference<List<TNTPoint>> records;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
private int recordsCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of all REntityServers rendering this trace
|
* A map of all REntityServers rendering this trace
|
||||||
*/
|
*/
|
||||||
@@ -91,46 +91,25 @@ public class Trace {
|
|||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public Trace(Region region, List<TNTPoint> recordList) {
|
public Trace(Region region, List<TNTPoint> recordList) {
|
||||||
this.uuid = UUID.randomUUID();
|
this.uuid = UUID.randomUUID();
|
||||||
recordsSaveFile = new File(TraceManager.tracesFolder, uuid + ".records");
|
|
||||||
this.region = region;
|
this.region = region;
|
||||||
this.date = new Date();
|
this.date = new Date();
|
||||||
records = new SoftReference<>(recordList);
|
records = new SoftReference<>(recordList);
|
||||||
metadataSaveFile = new File(TraceManager.tracesFolder, uuid + ".meta");
|
recordsSaveFile = new File(TraceRepository.tracesFolder, uuid + ".records");
|
||||||
|
metadataSaveFile = new File(TraceRepository.tracesFolder, uuid + ".meta");
|
||||||
@Cleanup
|
|
||||||
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(metadataSaveFile));
|
|
||||||
outputStream.writeUTF(uuid.toString());
|
|
||||||
outputStream.writeUTF(region.getName());
|
|
||||||
outputStream.writeObject(date);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for serialising a trace from the file system
|
* Constructor for deserialising a trace from the file system
|
||||||
*
|
|
||||||
* @param metadataSaveFile the file for this traces metadata
|
|
||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public Trace(File metadataSaveFile) {
|
protected Trace(UUID uuid, Region region, Date date, File metadataFile, File recordsFile, int recordsCount) {
|
||||||
String uuid = null;
|
this.metadataSaveFile = metadataFile;
|
||||||
Region region = null;
|
recordsSaveFile = recordsFile;
|
||||||
Date date = null;
|
this.uuid = uuid;
|
||||||
|
this.region = region;
|
||||||
this.metadataSaveFile = metadataSaveFile;
|
this.date = date;
|
||||||
|
this.records = new SoftReference<>(null);
|
||||||
try {
|
this.recordsCount = recordsCount;
|
||||||
@Cleanup
|
|
||||||
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(metadataSaveFile));
|
|
||||||
uuid = inputStream.readUTF();
|
|
||||||
region = Region.getREGION_MAP().get(inputStream.readUTF());
|
|
||||||
date = (Date) inputStream.readObject();
|
|
||||||
inputStream.close();
|
|
||||||
} finally {
|
|
||||||
this.uuid = UUID.fromString(uuid);
|
|
||||||
this.region = region;
|
|
||||||
this.date = date;
|
|
||||||
recordsSaveFile = new File(TraceManager.tracesFolder, uuid + ".records");
|
|
||||||
this.records = new SoftReference<>(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,7 +152,8 @@ public class Trace {
|
|||||||
entityServer = new REntityServer();
|
entityServer = new REntityServer();
|
||||||
entityServer.addPlayer(player);
|
entityServer.addPlayer(player);
|
||||||
entityServer.setCallback((p, rEntity, entityAction) -> {
|
entityServer.setCallback((p, rEntity, entityAction) -> {
|
||||||
if (entityAction != REntityServer.EntityAction.INTERACT) return;
|
if (entityAction != REntityServer.EntityAction.INTERACT)
|
||||||
|
return;
|
||||||
if (rEntity instanceof TraceEntity) {
|
if (rEntity instanceof TraceEntity) {
|
||||||
((TraceEntity) rEntity).printIntoChat(p);
|
((TraceEntity) rEntity).printIntoChat(p);
|
||||||
}
|
}
|
||||||
@@ -195,7 +175,8 @@ public class Trace {
|
|||||||
REntityServer newEntityServer = new REntityServer();
|
REntityServer newEntityServer = new REntityServer();
|
||||||
newEntityServer.addPlayer(k);
|
newEntityServer.addPlayer(k);
|
||||||
newEntityServer.setCallback((p, rEntity, entityAction) -> {
|
newEntityServer.setCallback((p, rEntity, entityAction) -> {
|
||||||
if (entityAction != REntityServer.EntityAction.INTERACT) return;
|
if (entityAction != REntityServer.EntityAction.INTERACT)
|
||||||
|
return;
|
||||||
if (rEntity instanceof TraceEntity) {
|
if (rEntity instanceof TraceEntity) {
|
||||||
((TraceEntity) rEntity).printIntoChat(p);
|
((TraceEntity) rEntity).printIntoChat(p);
|
||||||
}
|
}
|
||||||
@@ -234,7 +215,8 @@ public class Trace {
|
|||||||
List<TraceEntity> entities = new LinkedList<>();
|
List<TraceEntity> entities = new LinkedList<>();
|
||||||
|
|
||||||
for (List<TNTPoint> bundle : bundles) {
|
for (List<TNTPoint> bundle : bundles) {
|
||||||
entities.add(new TraceEntity(entityServer, bundle.get(0).getLocation(), bundle.get(0).isExplosion(), bundle, this));
|
entities.add(new TraceEntity(entityServer, bundle.get(0).getLocation(), bundle.get(0).isExplosion(), bundle,
|
||||||
|
this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply modifiers
|
// Apply modifiers
|
||||||
@@ -312,38 +294,7 @@ public class Trace {
|
|||||||
* Loads the records of this trace from storage to memory
|
* Loads the records of this trace from storage to memory
|
||||||
*/
|
*/
|
||||||
private void loadRecords() {
|
private void loadRecords() {
|
||||||
List<TNTPoint> records = new ArrayList<>();
|
records = new SoftReference<>(TraceRepository.readTraceRecords(this));
|
||||||
long readBytes = 0;
|
|
||||||
try {
|
|
||||||
FileInputStream fileInputStream = new FileInputStream(recordsSaveFile);
|
|
||||||
|
|
||||||
@Cleanup
|
|
||||||
ObjectInputStream inputStream = new ObjectInputStream(new GZIPInputStream(fileInputStream));
|
|
||||||
long fileLenght = recordsSaveFile.length();
|
|
||||||
while (fileInputStream.getChannel().position() < fileLenght) {
|
|
||||||
records.add((TNTPoint) inputStream.readObject());
|
|
||||||
readBytes = fileInputStream.getChannel().position();
|
|
||||||
}
|
|
||||||
} catch (EOFException e) {
|
|
||||||
Logger logger = Bukkit.getLogger();
|
|
||||||
logger.log(Level.WARNING, "EOF in trace read detected in " + uuid);
|
|
||||||
logger.log(Level.WARNING, "Read " + readBytes + "/" + recordsSaveFile.length() + " Bytes");
|
|
||||||
logger.log(Level.WARNING, "Read so far: " + records);
|
|
||||||
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException | ClassNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<Integer, List<TNTPoint>> histories = new HashMap<>();
|
|
||||||
for (TNTPoint record : records) {
|
|
||||||
int tntId = record.getTntId();
|
|
||||||
List<TNTPoint> history = histories.computeIfAbsent(tntId, id -> new ArrayList<>());
|
|
||||||
history.add(record);
|
|
||||||
record.setHistory(history);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.records = new SoftReference<>(records);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized List<TNTPoint> getRecords() {
|
public synchronized List<TNTPoint> getRecords() {
|
||||||
@@ -360,6 +311,7 @@ public class Trace {
|
|||||||
", region=" + region +
|
", region=" + region +
|
||||||
", creationTime=" + date +
|
", creationTime=" + date +
|
||||||
", recordsSaveFile=" + recordsSaveFile.getName() +
|
", recordsSaveFile=" + recordsSaveFile.getName() +
|
||||||
|
", recordCount=" + recordsCount +
|
||||||
", records=" + getRecords() +
|
", records=" + getRecords() +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-5
@@ -30,11 +30,14 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
import org.bukkit.event.server.PluginEnableEvent;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static de.steamwar.bausystem.features.tracer.TraceRepository.tracesFolder;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class TraceManager implements Listener {
|
public class TraceManager implements Listener {
|
||||||
|
|
||||||
@@ -44,9 +47,9 @@ public class TraceManager implements Listener {
|
|||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File tracesFolder = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "traces");
|
|
||||||
|
|
||||||
public TraceManager() {
|
|
||||||
|
public void init() {
|
||||||
if (!tracesFolder.exists())
|
if (!tracesFolder.exists())
|
||||||
tracesFolder.mkdir();
|
tracesFolder.mkdir();
|
||||||
|
|
||||||
@@ -58,7 +61,15 @@ public class TraceManager implements Listener {
|
|||||||
if (traceFile.getName().contains(".records"))
|
if (traceFile.getName().contains(".records"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
add(new Trace(traceFile));
|
if (TraceRepository.getVersion(traceFile) == TraceRepository.SERIALISATION_VERSION) {
|
||||||
|
add(TraceRepository.readTrace(traceFile));
|
||||||
|
} else {
|
||||||
|
String uuid = traceFile.getName().replace(".meta", "");
|
||||||
|
|
||||||
|
new File(tracesFolder, uuid + ".records").deleteOnExit();
|
||||||
|
new File(tracesFolder, uuid + ".meta").deleteOnExit();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,8 +171,8 @@ public class TraceManager implements Listener {
|
|||||||
tracesByRegion.getOrDefault(region, new HashMap<>())
|
tracesByRegion.getOrDefault(region, new HashMap<>())
|
||||||
.forEach((i, trace) -> {
|
.forEach((i, trace) -> {
|
||||||
if (trace.getRegion() != region) return;
|
if (trace.getRegion() != region) return;
|
||||||
trace.getMetadataSaveFile().delete();
|
trace.getMetadataSaveFile().deleteOnExit();
|
||||||
trace.getRecordsSaveFile().delete();
|
trace.getRecordsSaveFile().deleteOnExit();
|
||||||
});
|
});
|
||||||
tracesByRegion.getOrDefault(region, new HashMap<>()).clear();
|
tracesByRegion.getOrDefault(region, new HashMap<>()).clear();
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -31,6 +31,7 @@ import org.bukkit.event.EventPriority;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||||
|
import org.bukkit.event.server.PluginEnableEvent;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -70,7 +71,7 @@ public class TraceRecorder implements Listener {
|
|||||||
*/
|
*/
|
||||||
private final Set<Region> autoTraceRegions = new HashSet<>();
|
private final Set<Region> autoTraceRegions = new HashSet<>();
|
||||||
|
|
||||||
public TraceRecorder() {
|
public void init() {
|
||||||
BauSystem.runTaskTimer(BauSystem.getInstance(), () -> {
|
BauSystem.runTaskTimer(BauSystem.getInstance(), () -> {
|
||||||
record();
|
record();
|
||||||
checkForAutoTraceFinish();
|
checkForAutoTraceFinish();
|
||||||
@@ -170,14 +171,13 @@ public class TraceRecorder implements Listener {
|
|||||||
if (history.size() == 0) {
|
if (history.size() == 0) {
|
||||||
try {
|
try {
|
||||||
historyMap.put(tntPrimed, history);
|
historyMap.put(tntPrimed, history);
|
||||||
}
|
} catch (NullPointerException e) {
|
||||||
catch (NullPointerException e) {
|
|
||||||
Logger logger = Bukkit.getLogger();
|
Logger logger = Bukkit.getLogger();
|
||||||
//TODO remove when no longer neccecary
|
//TODO remove when no longer neccecary
|
||||||
logger.log(Level.WARNING, "Nullpointer thrown by historyMap");
|
logger.log(Level.WARNING, "Nullpointer thrown by historyMap");
|
||||||
logger.log(Level.WARNING, "TNT History: " + history);
|
logger.log(Level.WARNING, "TNT History: " + history);
|
||||||
logger.log(Level.WARNING, "History Map: " + historyMap);
|
logger.log(Level.WARNING, "History Map: " + historyMap);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
tntID = wrappedTrace.getNextOpenRecordIdAndIncrement();
|
tntID = wrappedTrace.getNextOpenRecordIdAndIncrement();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+5
-22
@@ -24,28 +24,22 @@ import de.steamwar.bausystem.region.Region;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.GZIPOutputStream;
|
|
||||||
|
|
||||||
public class TraceRecordingWrapper {
|
public class TraceRecordingWrapper {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Trace trace;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final long startTick;
|
private final long startTick;
|
||||||
private final List<TNTPoint> recordsToAdd;
|
private final List<TNTPoint> recordsToAdd;
|
||||||
private final List<TNTPoint> recordList;
|
private final List<TNTPoint> recordList;
|
||||||
private final ObjectOutputStream recordsOutputStream;
|
|
||||||
private int nextOpenRecordId = 0;
|
private int nextOpenRecordId = 0;
|
||||||
@Getter
|
@Getter
|
||||||
private boolean explosionRecorded = false;
|
private boolean explosionRecorded = false;
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final Trace trace;
|
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public TraceRecordingWrapper(Region region) {
|
public TraceRecordingWrapper(Region region) {
|
||||||
startTick = TPSUtils.currentRealTick.get();
|
startTick = TPSUtils.currentRealTick.get();
|
||||||
@@ -53,8 +47,6 @@ public class TraceRecordingWrapper {
|
|||||||
recordList = new ArrayList<>();
|
recordList = new ArrayList<>();
|
||||||
|
|
||||||
trace = new Trace(region, recordList);
|
trace = new Trace(region, recordList);
|
||||||
File recordsSaveFile = new File(TraceManager.tracesFolder, trace.getUuid() + ".records");
|
|
||||||
recordsOutputStream = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(recordsSaveFile)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNextOpenRecordIdAndIncrement() {
|
public int getNextOpenRecordIdAndIncrement() {
|
||||||
@@ -72,23 +64,14 @@ public class TraceRecordingWrapper {
|
|||||||
public void commitRecorded() {
|
public void commitRecorded() {
|
||||||
TraceManager.instance.showPartial(trace, recordsToAdd);
|
TraceManager.instance.showPartial(trace, recordsToAdd);
|
||||||
|
|
||||||
recordsToAdd.forEach(record -> {
|
|
||||||
try {
|
|
||||||
recordsOutputStream.writeObject(record);
|
|
||||||
recordsOutputStream.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
recordList.addAll(recordsToAdd);
|
recordList.addAll(recordsToAdd);
|
||||||
|
trace.setRecordsCount(recordList.size());
|
||||||
recordsToAdd.clear();
|
recordsToAdd.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
protected void finalizeRecording() {
|
protected void finalizeRecording() {
|
||||||
recordsOutputStream.flush();
|
TraceRepository.writeTrace(trace, recordList);
|
||||||
recordsOutputStream.close();
|
|
||||||
TraceManager.instance.add(trace);
|
TraceManager.instance.add(trace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+136
@@ -0,0 +1,136 @@
|
|||||||
|
package de.steamwar.bausystem.features.tracer;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.region.Region;
|
||||||
|
import lombok.Cleanup;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class TraceRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment this when changing serialisation format
|
||||||
|
*/
|
||||||
|
public static final int SERIALISATION_VERSION = 1;
|
||||||
|
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 metadataFile) {
|
||||||
|
@Cleanup
|
||||||
|
ObjectInputStream reader = new ObjectInputStream(new FileInputStream(metadataFile));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
protected static void writeTrace(Trace trace, List<TNTPoint> records) {
|
||||||
|
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(trace.getMetadataSaveFile()));
|
||||||
|
outputStream.writeUTF(trace.getUuid().toString());
|
||||||
|
outputStream.writeUTF(trace.getRegion().getName());
|
||||||
|
outputStream.writeObject(trace.getDate());
|
||||||
|
outputStream.writeInt(SERIALISATION_VERSION);
|
||||||
|
outputStream.writeInt(records.size());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
|
||||||
|
|
||||||
|
writeTraceRecords(trace.getRecordsSaveFile(), records);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
protected static void writeTraceRecords(File recordsFile, List<TNTPoint> 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());
|
||||||
|
}
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
protected static TNTPoint readTraceRecord(DataInputStream 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();
|
||||||
|
|
||||||
|
double locX = objectInput.readDouble();
|
||||||
|
double locY = objectInput.readDouble();
|
||||||
|
double locZ = objectInput.readDouble();
|
||||||
|
Location location = new Location(Bukkit.getWorlds().get(0), locX, locY, locZ);
|
||||||
|
|
||||||
|
double velX = objectInput.readDouble();
|
||||||
|
double velY = objectInput.readDouble();
|
||||||
|
double velZ = objectInput.readDouble();
|
||||||
|
Vector velocity = new Vector(velX, velY, velZ);
|
||||||
|
|
||||||
|
return new TNTPoint(tntId, explosion, inWater, afterFirstExplosion, destroyedBuildArea, destroyedTestBlock, ticksSinceStart, fuse, location, velocity, Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
protected static List<TNTPoint> readTraceRecords(Trace trace) {
|
||||||
|
File recordsFile = trace.getRecordsSaveFile();
|
||||||
|
@Cleanup
|
||||||
|
DataInputStream inputStream = new DataInputStream(new FileInputStream(recordsFile));
|
||||||
|
|
||||||
|
List<TNTPoint> records = new ArrayList<>();
|
||||||
|
for (int i = 0; i < trace.getRecordsCount(); i++) {
|
||||||
|
records.add(readTraceRecord(inputStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<Integer, List<TNTPoint>> histories = new HashMap<>();
|
||||||
|
for (TNTPoint record : records) {
|
||||||
|
int tntId = record.getTntId();
|
||||||
|
List<TNTPoint> history = histories.computeIfAbsent(tntId, id -> new ArrayList<>());
|
||||||
|
history.add(record);
|
||||||
|
record.setHistory(history);
|
||||||
|
}
|
||||||
|
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
@ChannelHandler.Sharable
|
@ChannelHandler.Sharable
|
||||||
@@ -63,7 +64,6 @@ public class Tablist extends ChannelInboundHandlerAdapter {
|
|||||||
this.player = player;
|
this.player = player;
|
||||||
this.viewer = Chatter.of(player);
|
this.viewer = Chatter.of(player);
|
||||||
this.directTabItems = Storage.directTabItems.computeIfAbsent(player, p -> new HashMap<>());
|
this.directTabItems = Storage.directTabItems.computeIfAbsent(player, p -> new HashMap<>());
|
||||||
injection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(TablistPart global, int seconds) {
|
public void update(TablistPart global, int seconds) {
|
||||||
@@ -139,7 +139,9 @@ public class Tablist extends ChannelInboundHandlerAdapter {
|
|||||||
synchronized (directTabItems) {
|
synchronized (directTabItems) {
|
||||||
directTabItems.clear();
|
directTabItems.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onServerPostSwitch() {
|
||||||
if(player.getProtocolVersion().greaterThan(ProtocolVersion.MINECRAFT_1_20)) {
|
if(player.getProtocolVersion().greaterThan(ProtocolVersion.MINECRAFT_1_20)) {
|
||||||
current.clear();
|
current.clear();
|
||||||
sendPacket(player, createTeamPacket);
|
sendPacket(player, createTeamPacket);
|
||||||
@@ -148,8 +150,14 @@ public class Tablist extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
private void injection() {
|
private void injection() {
|
||||||
connection = (VelocityServerConnection) player.getCurrentServer().orElse(null);
|
connection = (VelocityServerConnection) player.getCurrentServer().orElse(null);
|
||||||
if(connection == null)
|
if(connection == null) {
|
||||||
return;
|
connection = ((ConnectedPlayer) player).getConnectionInFlight();
|
||||||
|
|
||||||
|
if(connection == null) {
|
||||||
|
VelocityCore.getLogger().log(Level.WARNING, "Could not inject Tablist: %s".formatted(player));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ChannelPipeline pipeline = connection.getConnection().getChannel().pipeline();
|
ChannelPipeline pipeline = connection.getConnection().getChannel().pipeline();
|
||||||
if(pipeline.get("steamwar-tablist") != null) //Catch unclean exit
|
if(pipeline.get("steamwar-tablist") != null) //Catch unclean exit
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ package de.steamwar.velocitycore.tablist;
|
|||||||
|
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
||||||
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
||||||
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
import de.steamwar.network.packets.common.FightInfoPacket;
|
import de.steamwar.network.packets.common.FightInfoPacket;
|
||||||
@@ -59,17 +60,19 @@ public class TablistManager extends BasicListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onJoin(PostLoginEvent event) {
|
public void onServerConnection(ServerConnectedEvent event) {
|
||||||
synchronized (tablists) {
|
synchronized (tablists) {
|
||||||
tablists.put(event.getPlayer(), new Tablist(event.getPlayer()));
|
tablists.computeIfAbsent(event.getPlayer(), Tablist::new).onServerSwitch();
|
||||||
}
|
}
|
||||||
Tablist.sendPacket(event.getPlayer(), Tablist.createTeamPacket);
|
|
||||||
|
if(event.getPlayer().getProtocolVersion().noGreaterThan(ProtocolVersion.MINECRAFT_1_20))
|
||||||
|
Tablist.sendPacket(event.getPlayer(), Tablist.createTeamPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onServerConnection(ServerPostConnectEvent event) {
|
public void onServerPostConnection(ServerPostConnectEvent event) {
|
||||||
synchronized (tablists) {
|
synchronized (tablists) {
|
||||||
tablists.get(event.getPlayer()).onServerSwitch();
|
tablists.get(event.getPlayer()).onServerPostSwitch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,14 +93,14 @@ public class TablistManager extends BasicListener {
|
|||||||
|
|
||||||
private void updateTablist() {
|
private void updateTablist() {
|
||||||
List<TablistPart> subservers = new ArrayList<>();
|
List<TablistPart> subservers = new ArrayList<>();
|
||||||
for (RegisteredServer server : new ArrayList<>(VelocityCore.getProxy().getAllServers())){
|
for (RegisteredServer server : new ArrayList<>(VelocityCore.getProxy().getAllServers())) {
|
||||||
if(server.getPlayersConnected().isEmpty())
|
if (server.getPlayersConnected().isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Subserver subserver = Subserver.getSubserver(server.getServerInfo());
|
Subserver subserver = Subserver.getSubserver(server.getServerInfo());
|
||||||
if(fightInfos.containsKey(server))
|
if (fightInfos.containsKey(server))
|
||||||
subservers.add(new TablistServer(server, fightInfos.get(server)));
|
subservers.add(new TablistServer(server, fightInfos.get(server)));
|
||||||
else if(subserver == null || subserver.getType() != Servertype.BAUSERVER)
|
else if (subserver == null || subserver.getType() != Servertype.BAUSERVER)
|
||||||
subservers.add(new TablistServer(server));
|
subservers.add(new TablistServer(server));
|
||||||
}
|
}
|
||||||
subservers.add(new TablistBuild());
|
subservers.add(new TablistBuild());
|
||||||
|
|||||||
Reference in New Issue
Block a user