SteamWar/BauSystem2.0
Archiviert
12
0

Added savind and loading for traces
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
D4rkr34lm 2024-04-16 22:35:07 +02:00
Ursprung 39d2205b85
Commit d13c415565
9 geänderte Dateien mit 503 neuen und 236 gelöschten Zeilen

8
.gitignore vendored
Datei anzeigen

@ -1,5 +1,7 @@
# Package Files # Build files
*.jar *.jar
**/bin
**/build
# Gradle # Gradle
.gradle .gradle
@ -10,6 +12,10 @@ steamwar.properties
# IntelliJ IDEA # IntelliJ IDEA
.idea .idea
*.iml *.iml
plugin.yml
# Other # Other
lib lib
#linkage
LinkageUtils.java

Datei anzeigen

@ -24,7 +24,7 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox; import de.steamwar.bausystem.features.slaves.laufbau.BlockBoundingBox;
import de.steamwar.bausystem.features.slaves.laufbau.Cuboid; import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.bausystem.features.tracer.TNTPoint; import de.steamwar.bausystem.features.tracer.TNTPoint;
import de.steamwar.bausystem.features.tracer.TraceRecorder; import de.steamwar.bausystem.features.tracer.TraceManager;
import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.utils.FlatteningWrapper; import de.steamwar.bausystem.utils.FlatteningWrapper;
import org.bukkit.Location; import org.bukkit.Location;
@ -59,7 +59,7 @@ public class ProcessingTracesState implements LaufbauState {
this.factor = factor; this.factor = factor;
// TODO: Optimize only retrieving traces inside of the affected regions! // TODO: Optimize only retrieving traces inside of the affected regions!
TNTPoints = TraceRecorder.instance.manager.getAll() TNTPoints = TraceManager.instance.getAll()
.stream() .stream()
.flatMap(trace -> trace.getHistories().stream()) .flatMap(trace -> trace.getHistories().stream())
.flatMap(Collection::stream) .flatMap(Collection::stream)

Datei anzeigen

@ -23,73 +23,81 @@ 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.Getter; import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.TNTPrimed;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@Getter @Getter
public class TNTPoint { public class TNTPoint implements Externalizable {
/** /**
* Unique number to identify records being of the same tnt * Unique number to identify records being of the same tnt
*/ */
private final int tntId; private int tntId;
/** /**
* Whether this is a record of a tnt explosion or an entity * Whether this is a record of a tnt explosion or an entity
*/ */
private final boolean explosion; private boolean explosion;
/** /**
* Whether this is a record of a tnt that was in water * Whether this is a record of a tnt that was in water
*/ */
private final boolean inWater; private boolean inWater;
/** /**
* Whether this record was taken after the first tnt exploded * Whether this record was taken after the first tnt exploded
*/ */
private final boolean afterFirstExplosion; private boolean afterFirstExplosion;
/** /**
* Whether this record has destroyed blocks in build area * Whether this record has destroyed blocks in build area
*/ */
private final boolean destroyedBuildArea; private boolean destroyedBuildArea;
/** /**
* Whether this record has destroyed blocks in testblock area * Whether this record has destroyed blocks in testblock area
*/ */
private final boolean destroyedTestBlock; private boolean destroyedTestBlock;
/** /**
* Tick offset, from this record being taken to the start of the trace * Tick offset, from this record being taken to the start of the trace
*/ */
private final long ticksSinceStart; private long ticksSinceStart;
/** /**
* Fuse ticks of the recorded tnt (0 if this is an explosion) * Fuse ticks of the recorded tnt (0 if this is an explosion)
*/ */
private final int fuse; private int fuse;
/** /**
* Location of the recorded tnt * Location of the recorded tnt
*/ */
private final Location location; private Location location;
/** /**
* Velocity of the recorded tnt * Velocity of the recorded tnt
*/ */
private final Vector velocity; private Vector velocity;
/** /**
* List of all tnt records, that are represent the same tnt * List of all tnt records, that are represent the same tnt
*/ */
private final List<TNTPoint> history; private List<TNTPoint> history;
public TNTPoint(int tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart, List<TNTPoint> history, List<Block> destroyedBlocks) { public TNTPoint() {
}
public TNTPoint(int tntId, TNTPrimed tnt, boolean explosion, boolean afterFirstExplosion, long ticksSinceStart,
List<TNTPoint> history, List<Block> destroyedBlocks) {
this.tntId = tntId; this.tntId = tntId;
this.explosion = explosion; this.explosion = explosion;
this.inWater = tnt.isInWater(); this.inWater = tnt.isInWater();
@ -103,10 +111,12 @@ public class TNTPoint {
boolean buildDestroy = false; boolean buildDestroy = false;
boolean testblockDestroy = false; boolean testblockDestroy = false;
for (Block destroyedBlock : destroyedBlocks) { for (Block destroyedBlock : destroyedBlocks) {
if (Region.getRegion(destroyedBlock.getLocation()).inRegion(destroyedBlock.getLocation(), RegionType.BUILD, RegionExtensionType.EXTENSION)) { if (Region.getRegion(destroyedBlock.getLocation()).inRegion(destroyedBlock.getLocation(), RegionType.BUILD,
RegionExtensionType.EXTENSION)) {
buildDestroy = true; buildDestroy = true;
} }
if (Region.getRegion(destroyedBlock.getLocation()).inRegion(destroyedBlock.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) { if (Region.getRegion(destroyedBlock.getLocation()).inRegion(destroyedBlock.getLocation(),
RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) {
testblockDestroy = true; testblockDestroy = true;
} }
} }
@ -125,6 +135,50 @@ public class TNTPoint {
return index == 0 ? Optional.empty() : Optional.of(history.get(index - 1)); return index == 0 ? Optional.empty() : Optional.of(history.get(index - 1));
} }
void setHistory(List<TNTPoint> 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.writeUTF(location.getWorld().getName());
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, ClassNotFoundException {
tntId = objectInput.readInt();
explosion = objectInput.readBoolean();
inWater = objectInput.readBoolean();
afterFirstExplosion = objectInput.readBoolean();
destroyedBuildArea = objectInput.readBoolean();
destroyedTestBlock = objectInput.readBoolean();
ticksSinceStart = objectInput.readLong();
fuse = objectInput.readInt();
String worldName = objectInput.readUTF();
double locX = objectInput.readDouble();
double locY = objectInput.readDouble();
double locZ = objectInput.readDouble();
location = new Location(Bukkit.getWorld(worldName), 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 "TNTRecord{" + return "TNTRecord{" +
@ -138,11 +192,15 @@ public class TNTPoint {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (!(obj instanceof TNTPoint)) return false; if (!(obj instanceof TNTPoint))
return false;
TNTPoint record = (TNTPoint) obj; TNTPoint record = (TNTPoint) obj;
if (record.isExplosion() != explosion) return false; if (record.isExplosion() != explosion)
if (!record.getLocation().equals(location)) return false; return false;
if (!record.getVelocity().equals(velocity)) return false; if (!record.getLocation().equals(location))
return false;
if (!record.getVelocity().equals(velocity))
return false;
return true; return true;
} }
} }

Datei anzeigen

@ -19,102 +19,104 @@
package de.steamwar.bausystem.features.tracer; package de.steamwar.bausystem.features.tracer;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; import de.steamwar.bausystem.features.tracer.rendering.BundleFilter;
import de.steamwar.bausystem.features.tracer.rendering.PlayerTraceShowData;
import de.steamwar.bausystem.features.tracer.rendering.TraceEntity; import de.steamwar.bausystem.features.tracer.rendering.TraceEntity;
import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; 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 org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.io.*;
import java.lang.ref.SoftReference;
import java.util.*; import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class Trace { // TODO: Add UUID for file saving and so on! public class Trace {
/**
* UUID of the trace used for
*/
@Getter
private final UUID uuid;
/** /**
* Region this trace has been recorded in * File the records are saved in
*/
@Getter
private final File recordsSaveFile;
/**
* File the metadata are saved in
*/
@Getter
private final File metadataSaveFile;
/**
* Region the trace was recorded in
*/ */
@Getter @Getter
private final Region region; private final Region region;
/** /**
* Tick the recording started at * Date the trace was recorded at
*/ */
@Getter @Getter
private final long startTime = TPSUtils.currentTick.get(); private final Date date;
/**
*
*/
@Getter
private final Date date = new Date();
/** /**
* Records of TNTs, making up the trace * Records of TNTs, making up the trace
*/ */
@Getter private SoftReference<List<TNTPoint>> records;
private List<TNTPoint> records = new ArrayList<>();
/**
* ID that should be assigned to the next record of a unique tnt
*/
@Getter
private int nextOpenRecordId = -1;
private final Map<Player, REntityServer> entityServerMap = new HashMap<>(); private final Map<Player, REntityServer> entityServerMap = new HashMap<>();
/** public Trace(Region region, List<TNTPoint> recordList) {
* List of all used ids this.uuid = UUID.randomUUID();
*/ recordsSaveFile = new File(TraceManager.tracesFolder, uuid + ".records");
public List<String> getUsedIds() {
return getRecords()
.stream()
.map(TNTPoint::getTntId)
.map(i -> i + "")
.collect(Collectors.toList());
}
public Trace(Region region) {
this.region = region; this.region = region;
} this.date = new Date();
records = new SoftReference<>(recordList);
metadataSaveFile = new File(TraceManager.tracesFolder, uuid + ".meta");
/** try {
* Gets and increments the next open record id @Cleanup
* ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(metadataSaveFile));
* @return next open record id outputStream.writeUTF(uuid.toString());
*/ outputStream.writeUTF(region.getName());
protected int getAndIncrementNextOpenRecordId() { outputStream.writeObject(date);
return ++nextOpenRecordId; } catch (IOException | ClassCastException e) {
} e.printStackTrace();
/**
* Adds the given records and updates potential trace renderings
*/
protected void addAll(List<TNTPoint> records, Function<Player, PlayerTraceShowData> getter) {
this.getRecords().addAll(records);
Iterator<Player> keySetIterator = entityServerMap.keySet().iterator();
while (keySetIterator.hasNext()) {
Player player = keySetIterator.next();
PlayerTraceShowData playerTraceShowData = getter.apply(player);
if (playerTraceShowData == null) {
keySetIterator.remove();
continue;
}
render(records, entityServerMap.get(player), playerTraceShowData);
} }
} }
/** public Trace(File metadataSaveFile) {
* Internal methode to make records immutable after recording is finished String uuid = null;
* Region region = null;
* @param records immutable records list Date date = null;
*/
protected void setRecords(List<TNTPoint> records) { this.metadataSaveFile = metadataSaveFile;
this.records = records;
try {
@Cleanup
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(metadataSaveFile));
uuid = inputStream.readUTF();
region = Region.getREGION_MAP().get(inputStream.readUTF());
date = (Date) inputStream.readObject();
inputStream.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
this.uuid = UUID.fromString(uuid);
this.region = region;
this.date = date;
recordsSaveFile = new File(TraceManager.tracesFolder, uuid + ".records");
this.records = new SoftReference<>(null);
}
System.out.println(this);
} }
/** /**
@ -132,6 +134,17 @@ public class Trace { // TODO: Add UUID for file saving and so on!
return histories; return histories;
} }
/**
* List of all used ids
*/
public List<String> getUsedIds() {
return getRecords()
.stream()
.map(TNTPoint::getTntId)
.map(i -> i + "")
.collect(Collectors.toList());
}
/** /**
* Renders this traces * Renders this traces
* *
@ -150,34 +163,41 @@ public class Trace { // TODO: Add UUID for file saving and so on!
render(getRecords(), entityServer, playerTraceShowData); render(getRecords(), entityServer, playerTraceShowData);
} }
protected void render(List<TNTPoint> records, Player player, PlayerTraceShowData playerTraceShowData) {
render(records, entityServerMap.get(player), playerTraceShowData);
}
/** /**
* Internal methode to render records to a REntityServer * Internal methode to render records to a REntityServer
* *
* @param records Records to render * @param records Records to render
* @param entityServer The show server the trace will be renderd to
* @param playerTraceShowData The showData for modifying the rendering * @param playerTraceShowData The showData for modifying the rendering
*/ */
private void render(List<TNTPoint> records, REntityServer entityServer, PlayerTraceShowData playerTraceShowData) { private void render(List<TNTPoint> records, REntityServer entityServer, PlayerTraceShowData playerTraceShowData) {
if (records.isEmpty()) return; if (records.isEmpty())
return;
List<TNTPoint> workingRecords = new ArrayList<>(records); List<TNTPoint> workingRecords = new ArrayList<>(records);
Set<ViewFlag> flagList = playerTraceShowData.getEffectiveViewFlags(); Set<ViewFlag> flagList = playerTraceShowData.getEffectiveViewFlags();
//Apply filters // Apply filters
for (ViewFlag flag : flagList) { for (ViewFlag flag : flagList) {
workingRecords = flag.filter(workingRecords); workingRecords = flag.filter(workingRecords);
} }
//Bundle records at unique positions // Bundle records at unique positions
List<List<TNTPoint>> bundles = bundleRecords(workingRecords, playerTraceShowData.getBundleFilter()); List<List<TNTPoint>> bundles = bundleRecords(workingRecords, playerTraceShowData.getBundleFilter());
//Render bundled records // Render bundled records
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)); entities.add(
new TraceEntity(entityServer, bundle.get(0).getLocation(), bundle.get(0).isExplosion(), bundle));
} }
//Apply modifiers // Apply modifiers
for (ViewFlag flag : flagList) { for (ViewFlag flag : flagList) {
flag.modify(entityServer, entities); flag.modify(entityServer, entities);
} }
@ -195,13 +215,13 @@ public class Trace { // TODO: Add UUID for file saving and so on!
* Bundles the passed TNTRecords based on whether they are at the same location * Bundles the passed TNTRecords based on whether they are at the same location
* *
* @param records The TNTRecords that are supposed to be bundled * @param records The TNTRecords that are supposed to be bundled
* @param filter A filter specefieng whether records can be bundled
* @return A list of bundles * @return A list of bundles
*/ */
private List<List<TNTPoint>> bundleRecords(List<TNTPoint> records, BundleFilter filter) { private List<List<TNTPoint>> bundleRecords(List<TNTPoint> records, BundleFilter filter) {
List<List<TNTPoint>> bundles = new ArrayList<>(); List<List<TNTPoint>> bundles = new ArrayList<>();
recordsLoop: recordsLoop: for (TNTPoint record : records) {
for (TNTPoint record : records) {
if (bundles.isEmpty()) { if (bundles.isEmpty()) {
List<TNTPoint> firstBundle = new ArrayList<>(); List<TNTPoint> firstBundle = new ArrayList<>();
firstBundle.add(record); firstBundle.add(record);
@ -226,6 +246,26 @@ public class Trace { // TODO: Add UUID for file saving and so on!
return bundles; return bundles;
} }
/**
* Makes the first passed player follow the trace render of the second passed
* player
*
* @param player
* @param toFollow
*/
public void follow(Player player, Player toFollow) {
throw new UnsupportedOperationException();
}
/**
* Makes the passed player stop following any other players trace render
*
* @param player
*/
public void unfollow(Player player) {
throw new UnsupportedOperationException();
}
/** /**
* Hides this trail for the given player * Hides this trail for the given player
* *
@ -233,7 +273,10 @@ public class Trace { // TODO: Add UUID for file saving and so on!
*/ */
public void hide(Player player) { public void hide(Player player) {
REntityServer entityServer = entityServerMap.remove(player); REntityServer entityServer = entityServerMap.remove(player);
if (entityServer == null) return; if (entityServer == null)
return;
entityServer.removePlayer(player);
if (entityServer.getPlayers().isEmpty())
entityServer.close(); entityServer.close();
} }
@ -244,12 +287,47 @@ public class Trace { // TODO: Add UUID for file saving and so on!
entityServerMap.clear(); entityServerMap.clear();
} }
private void loadRecords() {
try {
List<TNTPoint> records = new ArrayList<>();
@Cleanup
FileInputStream fileInputStream = new FileInputStream(recordsSaveFile);
@Cleanup
ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
while (fileInputStream.getChannel().position() < recordsSaveFile.length()) {
records.add((TNTPoint) inputStream.readObject());
}
System.out.println("Loaded... " + records);
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);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public List<TNTPoint> getRecords() {
if (records.get() == null)
loadRecords();
return records.get();
}
@Override @Override
public String toString() { public String toString() {
return "Trace{" + return "Trace{" +
"region=" + region + "uuid=" + uuid +
", startTime=" + startTime + ", region=" + region +
", records=" + records + ", creationTime=" + date +
", recordsSaveFile=" + recordsSaveFile.getName() +
", records=" + getRecords() +
'}'; '}';
} }
} }

Datei anzeigen

@ -21,6 +21,7 @@ package de.steamwar.bausystem.features.tracer;
import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; import de.steamwar.bausystem.features.tracer.rendering.BundleFilter;
import de.steamwar.bausystem.features.tracer.rendering.PlayerTraceShowData;
import de.steamwar.bausystem.features.tracer.rendering.ViewFlag; import de.steamwar.bausystem.features.tracer.rendering.ViewFlag;
import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag; import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag;
import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.Region;
@ -28,7 +29,6 @@ import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper; import de.steamwar.command.TypeMapper;
import de.steamwar.linkage.Linked; import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -41,12 +41,6 @@ import java.util.stream.Stream;
@Linked @Linked
public class TraceCommand extends SWCommand { public class TraceCommand extends SWCommand {
@LinkedInstance
public TraceRecorder traceRecorder;
@LinkedInstance
public TraceManager manager;
public TraceCommand() { public TraceCommand() {
super("trace", "trail"); super("trace", "trail");
} }
@ -54,21 +48,21 @@ public class TraceCommand extends SWCommand {
@Register(value = "start", description = "TRACE_COMMAND_HELP_START") @Register(value = "start", description = "TRACE_COMMAND_HELP_START")
public void start(@Validator Player player) { public void start(@Validator Player player) {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
traceRecorder.startRecording(region); TraceRecorder.instance.startRecording(region);
BauSystem.MESSAGE.send("TRACE_MESSAGE_START", player); BauSystem.MESSAGE.send("TRACE_MESSAGE_START", player);
} }
@Register(value = "stop", description = "TRACE_COMMAND_HELP_STOP") @Register(value = "stop", description = "TRACE_COMMAND_HELP_STOP")
public void stop(@Validator Player player) { public void stop(@Validator Player player) {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
traceRecorder.stopRecording(region); TraceRecorder.instance.stopRecording(region);
BauSystem.MESSAGE.send("TRACE_MESSAGE_STOP", player); BauSystem.MESSAGE.send("TRACE_MESSAGE_STOP", player);
} }
@Register(value = "auto", description = "TRACE_COMMAND_HELP_AUTO") @Register(value = "auto", description = "TRACE_COMMAND_HELP_AUTO")
public void auto(@Validator Player player) { public void auto(@Validator Player player) {
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
traceRecorder.toggleAutoTrace(region); TraceRecorder.instance.toggleAutoTrace(region);
// TODO: Add Auto toggle Message! // TODO: Add Auto toggle Message!
} }
@ -78,20 +72,24 @@ public class TraceCommand extends SWCommand {
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW", player); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW", player);
} }
@Register(value = {"show", "at"}, description = "TRACE_COMMAND_HELP_SHOW_AT_WITH") @Register(value = { "show", "at" }, description = "TRACE_COMMAND_HELP_SHOW_AT_WITH")
public void showAt(@Validator Player player, @Min(intValue = 0) int time, @StaticValue("with") String with, @OptionalValue("STRICT") BundleFilter bundleFilter, @ArrayLength(min = 1) ViewFlag... flags) { public void showAt(@Validator Player player, @Min(intValue = 0) int time, @StaticValue("with") String with,
@OptionalValue("STRICT") BundleFilter bundleFilter, @ArrayLength(min = 1) ViewFlag... flags) {
showInternal(player, time, time, bundleFilter, flags); showInternal(player, time, time, bundleFilter, flags);
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_AT", player, time); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_AT", player, time);
} }
@Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_WITH") @Register(value = { "show", "from" }, description = "TRACE_COMMAND_HELP_SHOW_FROM_WITH")
public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("with") String with, @OptionalValue("STRICT") BundleFilter bundleFilter, @ArrayLength(min = 1) ViewFlag... flags) { public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("with") String with,
@OptionalValue("STRICT") BundleFilter bundleFilter, @ArrayLength(min = 1) ViewFlag... flags) {
showInternal(player, from, Integer.MAX_VALUE, bundleFilter, flags); showInternal(player, from, Integer.MAX_VALUE, bundleFilter, flags);
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM", player, from); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM", player, from);
} }
@Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO_WITH") @Register(value = { "show", "from" }, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO_WITH")
public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString, int to, @StaticValue("with") String with, @OptionalValue("STRICT") BundleFilter bundleFilter, @ArrayLength(min = 1) ViewFlag... flags) { public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString,
int to, @StaticValue("with") String with, @OptionalValue("STRICT") BundleFilter bundleFilter,
@ArrayLength(min = 1) ViewFlag... flags) {
if (to < from) { if (to < from) {
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_TO_SMALLER", player); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_TO_SMALLER", player);
return; return;
@ -103,71 +101,73 @@ public class TraceCommand extends SWCommand {
private void showInternal(Player player, int from, int to, BundleFilter bundleFilter, ViewFlag... flags) { private void showInternal(Player player, int from, int to, BundleFilter bundleFilter, ViewFlag... flags) {
PlayerTraceShowData playerTraceShowData = new PlayerTraceShowData(bundleFilter, flags); PlayerTraceShowData playerTraceShowData = new PlayerTraceShowData(bundleFilter, flags);
playerTraceShowData.addViewFlag(new AtFlag(from, to)); playerTraceShowData.addViewFlag(new AtFlag(from, to));
manager.show(player, playerTraceShowData); TraceManager.instance.show(player, playerTraceShowData);
} }
@Register(value = {"show", "at"}, description = "TRACE_COMMAND_HELP_SHOW_AT") @Register(value = { "show", "at" }, description = "TRACE_COMMAND_HELP_SHOW_AT")
public void showAt(@Validator Player player, @Min(intValue = 0) int time) { public void showAt(@Validator Player player, @Min(intValue = 0) int time) {
manager.renderAt(player, time, time); TraceManager.instance.renderAt(player, time, time);
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_AT", player, time); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_AT", player, time);
} }
@Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM") @Register(value = { "show", "from" }, description = "TRACE_COMMAND_HELP_SHOW_FROM")
public void showFrom(@Validator Player player, @Min(intValue = 0) int from) { public void showFrom(@Validator Player player, @Min(intValue = 0) int from) {
manager.renderAt(player, from, Integer.MAX_VALUE); TraceManager.instance.renderAt(player, from, Integer.MAX_VALUE);
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM", player, from); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM", player, from);
} }
@Register(value = {"show", "from"}, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO") @Register(value = { "show", "from" }, description = "TRACE_COMMAND_HELP_SHOW_FROM_TO")
public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString, int to) { public void showFromTo(@Validator Player player, @Min(intValue = 0) int from, @StaticValue("to") String toString,
manager.renderAt(player, from, to); int to) {
TraceManager.instance.renderAt(player, from, to);
BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM_TO", player, from, to); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_FROM_TO", player, from, to);
} }
@Register(value = "hide", description = "TRACE_COMMAND_HELP_HIDE") @Register(value = "hide", description = "TRACE_COMMAND_HELP_HIDE")
public void hide(@Validator Player player) { public void hide(@Validator Player player) {
manager.hide(player); TraceManager.instance.hide(player);
BauSystem.MESSAGE.send("TRACE_MESSAGE_HIDE", player); BauSystem.MESSAGE.send("TRACE_MESSAGE_HIDE", player);
} }
@Register(value = "delete", description = "TRACE_COMMAND_HELP_DELETE") @Register(value = "delete", description = "TRACE_COMMAND_HELP_DELETE")
@Register(value = "clear") @Register(value = "clear")
public void delete(@Validator Player player) { public void delete(@Validator Player player) {
manager.clear(); TraceManager.instance.clear();
BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE", player); BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE", player);
} }
@Register(value = "delete") @Register(value = "delete")
public void delete(@Validator Player player, Trace trace) { public void delete(@Validator Player player, Trace trace) {
manager.remove(trace); TraceManager.instance.remove(trace);
BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE_SPECIFIC", player); BauSystem.MESSAGE.send("TRACE_MESSAGE_DELETE_SPECIFIC", player);
} }
@Register(value = "isolate", description = "TRACE_COMMAND_HELP_ISOLATE") @Register(value = "isolate", description = "TRACE_COMMAND_HELP_ISOLATE")
public void isolate(@Validator Player player, Trace trace, @ErrorMessage("TRACE_RECORD_ID_INVALID") TNTPoint... records) { public void isolate(@Validator Player player, Trace trace,
manager.isolate(player, records); @ErrorMessage("TRACE_RECORD_ID_INVALID") TNTPoint... records) {
TraceManager.instance.isolate(player, records);
// TODO: Add Message! // TODO: Add Message!
} }
@Register(value = "share", description = "TRACE_COMMAND_HELP_SHOW") @Register(value = "share", description = "TRACE_COMMAND_HELP_SHOW")
public void share(@Validator Player player) { public void share(@Validator Player player) {
//TODO Rücksprache // TODO Rücksprache
} }
@Register(value = "follow", description = "TRACE_COMMAND_HELP_SHOW") @Register(value = "follow", description = "TRACE_COMMAND_HELP_SHOW")
public void follow(@Validator Player player, Player toFollow) { public void follow(@Validator Player player, Player toFollow) {
if (player == toFollow) { // TODO: Implement
// TODO: Implement message for (Trace trace : TraceManager.instance.getAll()) {
return; trace.follow(player, toFollow);
} }
manager.follow(player, toFollow);
// TODO: Implement message
} }
@Register(value = "unfollow", description = "TRACE_COMMAND_HELP_SHOW") @Register(value = "unfollow", description = "TRACE_COMMAND_HELP_SHOW")
public void unfollow(@Validator Player player) { public void unfollow(@Validator Player player) {
manager.unfollow(player); // TODO: Implement
// TODO: Implement message for (Trace trace : TraceManager.instance.getAll()) {
trace.unfollow(player);
}
} }
@ClassMapper(value = Trace.class, local = true) @ClassMapper(value = Trace.class, local = true)
@ -175,12 +175,13 @@ public class TraceCommand extends SWCommand {
return new TypeMapper<>() { return new TypeMapper<>() {
@Override @Override
public Trace map(CommandSender commandSender, String[] previousArguments, String s) { public Trace map(CommandSender commandSender, String[] previousArguments, String s) {
return manager.get(Integer.parseInt(s)).orElse(null); return TraceManager.instance.get(Integer.parseInt(s)).orElse(null);
} }
@Override @Override
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments,
return manager.getAllIds().stream() String s) {
return TraceManager.instance.getAllIds().stream()
.map(Object::toString) .map(Object::toString)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -193,7 +194,8 @@ public class TraceCommand extends SWCommand {
@Override @Override
public TNTPoint map(CommandSender commandSender, PreviousArguments previousArguments, String s) { public TNTPoint map(CommandSender commandSender, PreviousArguments previousArguments, String s) {
Trace trace = previousArguments.getFirst(Trace.class).orElse(null); Trace trace = previousArguments.getFirst(Trace.class).orElse(null);
if (trace == null) return null; if (trace == null)
return null;
int id = Integer.parseInt(s); int id = Integer.parseInt(s);
return trace.getRecords().stream() return trace.getRecords().stream()
@ -202,11 +204,13 @@ public class TraceCommand extends SWCommand {
.orElse(null); .orElse(null);
} }
//TODO change when new command framework update // TODO change when new command framework update
@Override @Override
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments,
String s) {
Trace trace = previousArguments.getFirst(Trace.class).orElse(null); Trace trace = previousArguments.getFirst(Trace.class).orElse(null);
if (trace == null) return null; if (trace == null)
return null;
return trace.getUsedIds(); return trace.getUsedIds();
} }
}; };
@ -226,7 +230,8 @@ public class TraceCommand extends SWCommand {
} }
@Override @Override
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments,
String s) {
if (s.length() == 0) { if (s.length() == 0) {
return new ArrayList<>(); return new ArrayList<>();
} }
@ -258,7 +263,8 @@ public class TraceCommand extends SWCommand {
} }
@Override @Override
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) { public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments,
String s) {
return ViewFlag.flags.stream() return ViewFlag.flags.stream()
.flatMap(viewFlag -> Stream.concat(Stream.of("--" + viewFlag.name), .flatMap(viewFlag -> Stream.concat(Stream.of("--" + viewFlag.name),
Arrays.stream(viewFlag.aliases).map(name -> "-" + name))) Arrays.stream(viewFlag.aliases).map(name -> "-" + name)))

Datei anzeigen

@ -20,19 +20,47 @@
package de.steamwar.bausystem.features.tracer; package de.steamwar.bausystem.features.tracer;
import de.steamwar.bausystem.features.tracer.rendering.BundleFilter; import de.steamwar.bausystem.features.tracer.rendering.BundleFilter;
import de.steamwar.bausystem.features.tracer.rendering.PlayerTraceShowData;
import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag; import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.AtFlag;
import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.IsolateFlag; import de.steamwar.bausystem.features.tracer.rendering.dynamicflags.IsolateFlag;
import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.Region;
import de.steamwar.linkage.Linked; import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; 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 java.io.File;
import java.util.*; import java.util.*;
@Linked @Linked
public class TraceManager implements Listener { public class TraceManager implements Listener {
public static TraceManager instance;
{
instance = this;
}
public static File tracesFolder = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "traces");
public TraceManager() {
if (!tracesFolder.exists())
tracesFolder.mkdir();
File[] traceFiles = tracesFolder.listFiles();
if (traceFiles == null)
return;
for (File traceFile : traceFiles) {
if (traceFile.getName().contains(".records"))
continue;
add(new Trace(traceFile));
}
}
/** /**
* List of all current traces * List of all current traces
*/ */
@ -56,31 +84,15 @@ public class TraceManager implements Listener {
* @return id of the created trace * @return id of the created trace
*/ */
protected int add(Trace trace) { protected int add(Trace trace) {
showDataPerRegionPerPlayer.getOrDefault(trace.getRegion(), Collections.emptyMap()).forEach((player, playerTraceShowData) -> { showDataPerRegionPerPlayer.getOrDefault(trace.getRegion(), Collections.emptyMap()).forEach(trace::render);
trace.render(player, playerTraceShowData);
followerMap.getOrDefault(player, Collections.emptySet()).forEach(follower -> {
trace.render(follower, playerTraceShowData);
});
});
traces.put(nextOpenId, trace); traces.put(nextOpenId, trace);
tracesByRegion.computeIfAbsent(trace.getRegion(), region -> new HashMap<>()).put(nextOpenId, trace); tracesByRegion.computeIfAbsent(trace.getRegion(), region -> new HashMap<>()).put(nextOpenId, trace);
nextOpenId++; nextOpenId++;
return nextOpenId; return nextOpenId;
} }
protected void addAll(Trace trace, List<TNTPoint> TNTPoints) { protected Map<Player, PlayerTraceShowData> getTraceShowDataPlayerMapping(Region region) {
trace.addAll(TNTPoints, player -> { return showDataPerRegionPerPlayer.getOrDefault(region, new HashMap<>());
Map.Entry<Player, Set<Player>> entry = followerMap.entrySet()
.stream()
.filter(playerSetEntry -> playerSetEntry.getValue().contains(player))
.findFirst()
.orElse(null);
if (entry == null) {
return showDataPerRegionPerPlayer.getOrDefault(trace.getRegion(), Collections.emptyMap()).get(player);
} else {
return showDataPerRegionPerPlayer.getOrDefault(trace.getRegion(), Collections.emptyMap()).get(entry.getKey());
}
});
} }
/** /**
@ -94,7 +106,8 @@ public class TraceManager implements Listener {
.map(Map.Entry::getKey) .map(Map.Entry::getKey)
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if (traceId == null) return false; if (traceId == null)
return false;
traces.remove(traceId); traces.remove(traceId);
tracesByRegion.getOrDefault(trace.getRegion(), Collections.emptyMap()).remove(traceId); tracesByRegion.getOrDefault(trace.getRegion(), Collections.emptyMap()).remove(traceId);
trace.hide(); trace.hide();
@ -116,6 +129,10 @@ public class TraceManager implements Listener {
players.forEach(trace::hide); players.forEach(trace::hide);
}); });
}); });
traces.forEach((i, trace) -> {
trace.getMetadataSaveFile().delete();
trace.getRecordsSaveFile().delete();
});
traces.clear(); traces.clear();
tracesByRegion.clear(); tracesByRegion.clear();
nextOpenId = 0; nextOpenId = 0;
@ -135,7 +152,7 @@ public class TraceManager implements Listener {
* Methode to get the trace with specific id * Methode to get the trace with specific id
* *
* @param index index of the trace * @param index index of the trace
* @return the trace with given id or null if no trace with id is found * @return the trace with given id
*/ */
public Optional<Trace> get(int index) { public Optional<Trace> get(int index) {
return Optional.ofNullable(traces.get(index)); return Optional.ofNullable(traces.get(index));
@ -185,16 +202,19 @@ public class TraceManager implements Listener {
unfollow(player); unfollow(player);
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
PlayerTraceShowData previous = showDataPerRegionPerPlayer.getOrDefault(region, Collections.emptyMap()).remove(player); PlayerTraceShowData previous = showDataPerRegionPerPlayer.getOrDefault(region, Collections.emptyMap())
if (previous == null) return; .remove(player);
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { if (previous == null)
return;
tracesByRegion.getOrDefault(player, Collections.emptyMap()).forEach((integer, trace) -> {
trace.hide(player); trace.hide(player);
followerMap.getOrDefault(player, Collections.emptySet()).forEach(trace::hide); followerMap.getOrDefault(player, Collections.emptySet()).forEach(trace::hide);
}); });
} }
public boolean follow(Player follower, Player following) { public boolean follow(Player follower, Player following) {
if (followerMap.containsKey(follower)) return false; if (followerMap.containsKey(follower))
return false;
if (followerMap.entrySet().stream().anyMatch(playerSetEntry -> playerSetEntry.getValue().contains(follower))) { if (followerMap.entrySet().stream().anyMatch(playerSetEntry -> playerSetEntry.getValue().contains(follower))) {
unfollow(follower); unfollow(follower);
} }
@ -209,7 +229,8 @@ public class TraceManager implements Listener {
} }
PlayerTraceShowData playerTraceShowData = playerPlayerTraceShowDataMap.get(following); PlayerTraceShowData playerTraceShowData = playerPlayerTraceShowDataMap.get(following);
if (playerTraceShowData == null) return; if (playerTraceShowData == null)
return;
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> {
trace.render(follower, playerTraceShowData); trace.render(follower, playerTraceShowData);
}); });
@ -218,25 +239,30 @@ public class TraceManager implements Listener {
} }
public void unfollow(Player follower) { public void unfollow(Player follower) {
if (followerMap.containsKey(follower)) return; if (followerMap.containsKey(follower))
return;
List<Player> toRemove = new ArrayList<>(); List<Player> toRemove = new ArrayList<>();
Set<Player> toHide = new HashSet<>(); Set<Player> toHide = new HashSet<>();
followerMap.forEach((player, players) -> { followerMap.forEach((player, players) -> {
if (players.remove(follower)) toHide.add(follower); if (players.remove(follower))
if (players.isEmpty()) toRemove.add(player); toHide.add(follower);
if (players.isEmpty())
toRemove.add(player);
}); });
toRemove.forEach(followerMap::remove); toRemove.forEach(followerMap::remove);
showDataPerRegionPerPlayer.forEach((region, playerPlayerTraceShowDataMap) -> { showDataPerRegionPerPlayer.forEach((region, playerPlayerTraceShowDataMap) -> {
toHide.forEach(player -> { toHide.forEach(player -> {
if (!playerPlayerTraceShowDataMap.containsKey(player)) return; if (!playerPlayerTraceShowDataMap.containsKey(player))
return;
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> {
trace.hide(follower); trace.hide(follower);
}); });
}); });
PlayerTraceShowData playerTraceShowData = playerPlayerTraceShowDataMap.get(follower); PlayerTraceShowData playerTraceShowData = playerPlayerTraceShowDataMap.get(follower);
if (playerTraceShowData == null) return; if (playerTraceShowData == null)
return;
tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> { tracesByRegion.getOrDefault(region, Collections.emptyMap()).forEach((integer, trace) -> {
trace.render(follower, playerTraceShowData); trace.render(follower, playerTraceShowData);
}); });
@ -244,7 +270,8 @@ public class TraceManager implements Listener {
} }
/** /**
* Modifies the render for the given player, to only show tnts at the given time interval * Modifies the render for the given player, to only show tnts at the given time
* interval
* *
* @param player * @param player
* @param from start of time interval * @param from start of time interval
@ -254,7 +281,9 @@ public class TraceManager implements Listener {
unfollow(player); unfollow(player);
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
PlayerTraceShowData playerTraceShowData = showDataPerRegionPerPlayer.computeIfAbsent(region, ignored -> new HashMap<>()).computeIfAbsent(player, ignored -> new PlayerTraceShowData(BundleFilter.STRICT)); PlayerTraceShowData playerTraceShowData = showDataPerRegionPerPlayer
.computeIfAbsent(region, ignored -> new HashMap<>())
.computeIfAbsent(player, ignored -> new PlayerTraceShowData(BundleFilter.STRICT));
AtFlag atFlag = playerTraceShowData.getViewFlag(AtFlag.class); AtFlag atFlag = playerTraceShowData.getViewFlag(AtFlag.class);
if (atFlag == null) { if (atFlag == null) {
@ -282,7 +311,9 @@ public class TraceManager implements Listener {
unfollow(player); unfollow(player);
Region region = Region.getRegion(player.getLocation()); Region region = Region.getRegion(player.getLocation());
PlayerTraceShowData playerTraceShowData = showDataPerRegionPerPlayer.computeIfAbsent(region, ignored -> new HashMap<>()).computeIfAbsent(player, ignored -> new PlayerTraceShowData(BundleFilter.STRICT)); PlayerTraceShowData playerTraceShowData = showDataPerRegionPerPlayer
.computeIfAbsent(region, ignored -> new HashMap<>())
.computeIfAbsent(player, ignored -> new PlayerTraceShowData(BundleFilter.STRICT));
IsolateFlag isolateFlag; IsolateFlag isolateFlag;
if (playerTraceShowData.hasViewFlagOnly(IsolateFlag.class)) { if (playerTraceShowData.hasViewFlagOnly(IsolateFlag.class)) {

Datei anzeigen

@ -23,7 +23,6 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tpslimit.TPSUtils; import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.region.Region; import de.steamwar.bausystem.region.Region;
import de.steamwar.linkage.Linked; import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -43,16 +42,10 @@ public class TraceRecorder implements Listener {
instance = this; instance = this;
} }
/**
* Linked instance of TraceManager
*/
@LinkedInstance
public TraceManager manager;
/** /**
* Map for all traces being actively recorded * Map for all traces being actively recorded
*/ */
private final Map<Region, Trace> activeTraces = new HashMap<>(); private final Map<Region, TraceRecordingWrapper> activeTraces = new HashMap<>();
/** /**
* Map for all TNTs being traced, by region * Map for all TNTs being traced, by region
@ -64,16 +57,6 @@ public class TraceRecorder implements Listener {
*/ */
private final Map<TNTPrimed, Region> tntSpawnRegion = new HashMap<>(); private final Map<TNTPrimed, Region> tntSpawnRegion = new HashMap<>();
/**
* Set of all active traces that no explosion has been recorded on
*/
private final Set<Trace> noExplosionRecorded = new HashSet<>();
/**
* A map for records that have been taken in the same tick and now have to be added to the traces
*/
private final Map<Trace, List<TNTPoint>> recordsToAddMap = new HashMap<>();
/** /**
* Maps a tracked tnt entity to its entire recording history * Maps a tracked tnt entity to its entire recording history
*/ */
@ -109,7 +92,8 @@ public class TraceRecorder implements Listener {
*/ */
public void checkForAutoTraceFinish() { public void checkForAutoTraceFinish() {
for (Region region : autoTraceRegions) { for (Region region : autoTraceRegions) {
if (autoTraceRegions.contains(region) && trackedTNT.getOrDefault(region, Collections.emptyList()).size() == 0) { if (autoTraceRegions.contains(region)
&& trackedTNT.getOrDefault(region, Collections.emptyList()).size() == 0) {
stopRecording(region); stopRecording(region);
} }
} }
@ -121,12 +105,12 @@ public class TraceRecorder implements Listener {
* @param region region to be recorded * @param region region to be recorded
*/ */
public int startRecording(Region region) { public int startRecording(Region region) {
if (activeTraces.containsKey(region)) return -1; if (activeTraces.containsKey(region))
Trace trace = new Trace(region); return -1;
noExplosionRecorded.add(trace);
activeTraces.put(region, trace); TraceRecordingWrapper wrappedTrace = new TraceRecordingWrapper(region);
recordsToAddMap.put(trace, new ArrayList<>()); activeTraces.put(region, wrappedTrace);
return manager.add(trace); return TraceManager.instance.add(wrappedTrace.getTrace());
} }
/** /**
@ -135,17 +119,14 @@ public class TraceRecorder implements Listener {
* @param region region to stop recording * @param region region to stop recording
*/ */
public void stopRecording(Region region) { public void stopRecording(Region region) {
Trace trace = activeTraces.getOrDefault(region, null); TraceRecordingWrapper wrappedTrace = activeTraces.getOrDefault(region, null);
if (trace == null) return; if (wrappedTrace == null)
trace.setRecords(Collections.unmodifiableList(trace.getRecords())); return;
noExplosionRecorded.remove(trace);
activeTraces.remove(region); activeTraces.remove(region);
for (TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) { for (TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) {
historyMap.remove(tnt); historyMap.remove(tnt);
} }
recordsToAddMap.remove(trace);
trackedTNT.put(region, new ArrayList<>()); trackedTNT.put(region, new ArrayList<>());
} }
@ -154,15 +135,12 @@ public class TraceRecorder implements Listener {
*/ */
private void record() { private void record() {
for (Region region : activeTraces.keySet()) { for (Region region : activeTraces.keySet()) {
Trace trace = activeTraces.get(region); TraceRecordingWrapper wrappedTrace = activeTraces.get(region);
for (TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) { for (TNTPrimed tnt : trackedTNT.getOrDefault(region, Collections.emptyList())) {
record(tnt, trace, Collections.emptyList()); TNTPoint record = record(tnt, wrappedTrace, Collections.emptyList());
wrappedTrace.addRecord(record);
} }
wrappedTrace.commitRecorded();
List<TNTPoint> TNTPoints = recordsToAddMap.get(trace);
manager.addAll(trace, TNTPoints);
TNTPoints.clear();
} }
} }
@ -170,29 +148,32 @@ public class TraceRecorder implements Listener {
* Internal methode to record exploded tnt * Internal methode to record exploded tnt
* *
* @param tntPrimed tnt exploding * @param tntPrimed tnt exploding
* @param trace trace to record the tnt for * @param wrappedTrace the trace to record the tnt for wrapped with metadata
* @param destroyedBlocks the blocks destoryed by the passed tnt
* @return the record creaded of the passed tnt
*/ */
private void record(TNTPrimed tntPrimed, Trace trace, List<Block> destroyedBlocks) { private TNTPoint record(TNTPrimed tntPrimed, TraceRecordingWrapper wrappedTrace, List<Block> destroyedBlocks) {
List<TNTPoint> history = historyMap.getOrDefault(tntPrimed, new ArrayList<>()); List<TNTPoint> history = historyMap.getOrDefault(tntPrimed, new ArrayList<>());
int tntID; int tntID;
if (history.size() == 0) { if (history.size() == 0) {
historyMap.put(tntPrimed, history); historyMap.put(tntPrimed, history);
tntID = trace.getAndIncrementNextOpenRecordId(); tntID = wrappedTrace.getNextOpenRecordIdAndIncrement();
} else { } else {
tntID = history.get(0).getTntId(); tntID = history.get(0).getTntId();
} }
boolean isExplosion = tntPrimed.getFuseTicks() == 0; boolean isExplosion = tntPrimed.getFuseTicks() == 0;
if (isExplosion) { if (isExplosion) {
noExplosionRecorded.remove(trace); wrappedTrace.activateExplosionRecorded();
} }
boolean afterFirstExplosion = noExplosionRecorded.contains(trace); boolean afterFirstExplosion = wrappedTrace.isExplosionRecorded();
TNTPoint record = new TNTPoint(tntID, tntPrimed, isExplosion, afterFirstExplosion, TPSUtils.currentTick.get() - trace.getStartTime(), history, destroyedBlocks); TNTPoint record = new TNTPoint(tntID, tntPrimed, isExplosion, afterFirstExplosion,
TPSUtils.currentTick.get() - wrappedTrace.getStartTick(), history, destroyedBlocks);
history.add(record); history.add(record);
recordsToAddMap.get(trace).add(record); return record;
} }
/** /**
@ -203,7 +184,8 @@ public class TraceRecorder implements Listener {
*/ */
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onTNTSpawn(EntitySpawnEvent event) { public void onTNTSpawn(EntitySpawnEvent event) {
if (!(event.getEntity() instanceof TNTPrimed)) return; if (!(event.getEntity() instanceof TNTPrimed))
return;
Region region = Region.getRegion(event.getLocation()); Region region = Region.getRegion(event.getLocation());
@ -219,7 +201,8 @@ public class TraceRecorder implements Listener {
trackedTNT.get(region).add((TNTPrimed) event.getEntity()); trackedTNT.get(region).add((TNTPrimed) event.getEntity());
tntSpawnRegion.put((TNTPrimed) event.getEntity(), region); tntSpawnRegion.put((TNTPrimed) event.getEntity(), region);
record((TNTPrimed) event.getEntity(), activeTraces.get(region), Collections.emptyList()); activeTraces.get(region).addRecord(
record((TNTPrimed) event.getEntity(), activeTraces.get(region), Collections.emptyList()));
} }
} }
@ -231,13 +214,16 @@ public class TraceRecorder implements Listener {
*/ */
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onTNTExplode(EntityExplodeEvent event) { public void onTNTExplode(EntityExplodeEvent event) {
if (!(event.getEntity() instanceof TNTPrimed)) return; if (!(event.getEntity() instanceof TNTPrimed))
return;
Region region = tntSpawnRegion.getOrDefault((TNTPrimed) event.getEntity(), null); Region region = tntSpawnRegion.getOrDefault((TNTPrimed) event.getEntity(), null);
if (region == null) return; if (region == null)
return;
trackedTNT.get(region).remove((TNTPrimed) event.getEntity()); trackedTNT.get(region).remove((TNTPrimed) event.getEntity());
tntSpawnRegion.remove((TNTPrimed) event.getEntity()); tntSpawnRegion.remove((TNTPrimed) event.getEntity());
record((TNTPrimed) event.getEntity(), activeTraces.get(region), event.blockList()); activeTraces.get(region)
.addRecord(record((TNTPrimed) event.getEntity(), activeTraces.get(region), event.blockList()));
} }
} }

Datei anzeigen

@ -0,0 +1,102 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.features.tracer;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.region.Region;
import lombok.Getter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
//TODO Rename ?
public class TraceRecordingWrapper {
private final Region region;
@Getter
private final long startTick;
private final List<TNTPoint> recordsToAdd;
private final List<TNTPoint> recordList;
private ObjectOutputStream recordsOutputStream;
private int nextOpenRecordId = 0;
@Getter
private boolean explosionRecorded = false;
@Getter
private final Trace trace;
public TraceRecordingWrapper(Region region) {
this.region = region;
startTick = TPSUtils.currentTick.get();
recordsToAdd = new ArrayList<>();
recordList = new ArrayList<>();
trace = new Trace(region, recordList);
TraceManager.instance.add(trace);
File recordsSaveFile = new File(TraceManager.tracesFolder, trace.getUuid() + ".records");
try {
recordsOutputStream = new ObjectOutputStream(new FileOutputStream(recordsSaveFile));
} catch (IOException e) {
e.printStackTrace();
}
}
public int getNextOpenRecordIdAndIncrement() {
return nextOpenRecordId++;
}
public void activateExplosionRecorded() {
explosionRecorded = true;
}
public void addRecord(TNTPoint record) {
recordsToAdd.add(record);
}
public void commitRecorded() {
TraceManager.instance.getTraceShowDataPlayerMapping(region).forEach((key, value) -> trace.render(recordsToAdd, key, value));
recordsToAdd.forEach(record -> {
try {
recordsOutputStream.writeObject(record);
} catch (IOException e) {
e.printStackTrace();
}
});
recordList.addAll(recordsToAdd);
recordsToAdd.clear();
System.out.println(recordList);
}
protected void finalizeRecording() {
try {
recordsOutputStream.flush();
recordsOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Datei anzeigen

@ -17,10 +17,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.steamwar.bausystem.features.tracer; package de.steamwar.bausystem.features.tracer.rendering;
import de.steamwar.bausystem.features.tracer.rendering.BundleFilter;
import de.steamwar.bausystem.features.tracer.rendering.ViewFlag;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -42,7 +40,7 @@ public class PlayerTraceShowData {
} }
public Set<ViewFlag> getEffectiveViewFlags() { public Set<ViewFlag> getEffectiveViewFlags() {
//Manage flags and required flags // Manage flags and required flags
Set<ViewFlag> flagList = new HashSet<>(); Set<ViewFlag> flagList = new HashSet<>();
for (ViewFlag flag : viewFlags.values()) { for (ViewFlag flag : viewFlags.values()) {
flagList.add(flag); flagList.add(flag);
@ -51,7 +49,7 @@ public class PlayerTraceShowData {
} }
} }
//Manage inverse flags // Manage inverse flags
ViewFlag.inverseFlags.forEach(viewFlag -> { ViewFlag.inverseFlags.forEach(viewFlag -> {
if (!flagList.remove(viewFlag)) { if (!flagList.remove(viewFlag)) {
flagList.add(viewFlag); flagList.add(viewFlag);
@ -73,6 +71,8 @@ public class PlayerTraceShowData {
return viewFlags.containsKey(clazz) && viewFlags.size() == 1; return viewFlags.containsKey(clazz) && viewFlags.size() == 1;
} }
// TODO ?
@SuppressWarnings("unchecked")
public <T extends ViewFlag> T getViewFlag(Class<T> clazz) { public <T extends ViewFlag> T getViewFlag(Class<T> clazz) {
return (T) viewFlags.get(clazz); return (T) viewFlags.get(clazz);
} }