Merge branch 'main' into Backend/init

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