Trace Refactor #233
8
.gitignore
vendored
8
.gitignore
vendored
@ -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
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)))
|
||||||
|
@ -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)) {
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
}
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren