Skip to content

Commit

Permalink
Optimise packet
Browse files Browse the repository at this point in the history
  • Loading branch information
senseiwells committed Jan 18, 2022
1 parent d9c839d commit 3c0278a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 61 deletions.
39 changes: 28 additions & 11 deletions src/main/java/chunkdebug/feature/ChunkServerNetworkHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
import chunkdebug.ChunkDebugServer;
import chunkdebug.mixins.ThreadedAnvilChunkStorageAccessor;
import chunkdebug.utils.ChunkData;
import chunkdebug.utils.ChunkMapSerializer;
import chunkdebug.utils.IChunkTicketManager;
import com.google.common.collect.Iterables;
import io.netty.buffer.Unpooled;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ChunkHolder;
import net.minecraft.server.world.ChunkTicketType;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.server.world.ThreadedAnvilChunkStorage;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
Expand All @@ -26,15 +25,21 @@ public class ChunkServerNetworkHandler {
public static final int
HELLO = 0,
RELOAD = 15,
DATA = 16;
DATA = 16,
VERSION = 1_0_1;

private final Map<ServerPlayerEntity, ServerWorld> validPlayersEnabled = new HashMap<>();
private final Map<ServerWorld, Set<ChunkData>> serverWorldChunks = new HashMap<>();
private final Map<ServerWorld, Set<ChunkData>> updatesInLastTick = new HashMap<>();

public void onHello(ServerPlayerEntity player) {
public void onHello(ServerPlayerEntity player, PacketByteBuf packetByteBuf) {
String essentialVersion = packetByteBuf.readString(32767);
if (packetByteBuf.readableBytes() == 0 || packetByteBuf.readVarInt() < VERSION) {
player.sendMessage(new LiteralText("You cannot use ChunkDebug, client out of date"), false);
return;
}
this.validPlayersEnabled.put(player, null);
ChunkDebugServer.LOGGER.info("%s has logged in with ChunkDebug".formatted(player.getEntityName()));
ChunkDebugServer.LOGGER.info("%s has logged in with ChunkDebug. EssentialClient %s".formatted(player.getEntityName(), essentialVersion));
}

public void removePlayer(ServerPlayerEntity player) {
Expand All @@ -44,7 +49,7 @@ public void removePlayer(ServerPlayerEntity player) {
public void handlePacket(PacketByteBuf packetByteBuf, ServerPlayerEntity player) {
if (packetByteBuf != null) {
switch (packetByteBuf.readVarInt()) {
case HELLO -> this.onHello(player);
case HELLO -> this.onHello(player, packetByteBuf);
case DATA -> this.processPacket(packetByteBuf, player);
case RELOAD -> this.forceReloadChunks();
}
Expand All @@ -69,7 +74,7 @@ public synchronized void updateChunkMap(ServerWorld world, ChunkData chunkData)
Set<ChunkData> tickChunkDataSet = this.updatesInLastTick.get(world);
chunkDataSet.remove(chunkData);
tickChunkDataSet.remove(chunkData);
if (chunkData.levelType != ChunkHolder.LevelType.INACCESSIBLE) {
if (!chunkData.isLevelType(ChunkHolder.LevelType.INACCESSIBLE)) {
chunkDataSet.add(chunkData);
}
tickChunkDataSet.add(chunkData);
Expand Down Expand Up @@ -98,8 +103,8 @@ private synchronized void sendClientUpdate(ServerPlayerEntity player, boolean fo
if (chunkDataSet == null || chunkDataSet.isEmpty()) {
return;
}
if (chunkDataSet.size() > 10000) {
for (List<ChunkData> subChunkDataSet : Iterables.partition(chunkDataSet, 10000)) {
if (chunkDataSet.size() > 100000) {
for (List<ChunkData> subChunkDataSet : Iterables.partition(chunkDataSet, 100000)) {
this.sendClientChunkData(player, world, subChunkDataSet);
}
return;
Expand All @@ -108,10 +113,22 @@ private synchronized void sendClientUpdate(ServerPlayerEntity player, boolean fo
}

private void sendClientChunkData(ServerPlayerEntity player, ServerWorld world, Collection<ChunkData> chunkDataCollection) {
NbtCompound serializedMap = ChunkMapSerializer.serialize(world, chunkDataCollection);
int size = chunkDataCollection.size();
long[] chunkPositions = new long[size];
byte[] levelTypes = new byte[size];
byte[] ticketTypes = new byte[size];
int i = 0;
for (ChunkData chunkData : chunkDataCollection) {
chunkPositions[i] = chunkData.getLongPos();
levelTypes[i] = chunkData.getLevelByte();
ticketTypes[i] = chunkData.getTicketByte();
i++;
}
player.networkHandler.sendPacket(new CustomPayloadS2CPacket(
ESSENTIAL_CHANNEL,
new PacketByteBuf(Unpooled.buffer()).writeVarInt(DATA).writeNbt(serializedMap)
new PacketByteBuf(Unpooled.buffer()).writeVarInt(DATA)
.writeVarInt(size).writeLongArray(chunkPositions).writeByteArray(levelTypes).writeByteArray(ticketTypes)
.writeString(world.getRegistryKey().getValue().getPath())
));
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/chunkdebug/mixins/PlayerManagerMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class PlayerManagerMixin {
private void onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, CallbackInfo ci) {
player.networkHandler.sendPacket(new CustomPayloadS2CPacket(
ChunkServerNetworkHandler.ESSENTIAL_CHANNEL,
new PacketByteBuf(Unpooled.buffer()).writeVarInt(ChunkServerNetworkHandler.HELLO)
new PacketByteBuf(Unpooled.buffer()).writeVarInt(ChunkServerNetworkHandler.HELLO).writeVarInt(ChunkServerNetworkHandler.VERSION)
));
}
}
2 changes: 1 addition & 1 deletion src/main/java/chunkdebug/mixins/ServerWorldMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

@Mixin(ServerWorld.class)
public class ServerWorldMixin {
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerTickScheduler;<init>(Lnet/minecraft/server/world/ServerWorld;Ljava/util/function/Predicate;Ljava/util/function/Function;Ljava/util/function/Consumer;)V"))
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;<init>(Lnet/minecraft/world/MutableWorldProperties;Lnet/minecraft/util/registry/RegistryKey;Lnet/minecraft/world/dimension/DimensionType;Ljava/util/function/Supplier;ZZJ)V", shift = At.Shift.AFTER))
private void onCreateServerWorld(MinecraftServer server, Executor workerExecutor, LevelStorage.Session session, ServerWorldProperties properties, RegistryKey<?> worldKey, DimensionType dimensionType, WorldGenerationProgressListener worldGenerationProgressListener, ChunkGenerator chunkGenerator, boolean debugWorld, long seed, List<?> spawners, boolean shouldTickTime, CallbackInfo ci) {
ChunkDebugServer.chunkNetHandler.addWorld((ServerWorld) (Object) this);
}
Expand Down
42 changes: 38 additions & 4 deletions src/main/java/chunkdebug/utils/ChunkData.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,48 @@
import net.minecraft.util.math.ChunkPos;

public class ChunkData {
public ChunkPos chunkPos;
public ChunkHolder.LevelType levelType;
public int ticketCode;
private final ChunkPos chunkPos;
private final ChunkHolder.LevelType levelType;
private final byte ticketCode;

public ChunkData(ChunkPos chunkPos, ChunkHolder.LevelType levelType, ChunkTicketType<?> ticketType) {
this.chunkPos = chunkPos;
this.levelType = levelType;
this.ticketCode = ChunkMapSerializer.getTicketCode(ticketType);
this.ticketCode = getTicketCode(ticketType);
}

public boolean isLevelType(ChunkHolder.LevelType other) {
return this.levelType == other;
}

public long getLongPos() {
return this.chunkPos.toLong();
}

public byte getLevelByte() {
return (byte) this.levelType.ordinal();
}

public byte getTicketByte() {
return this.ticketCode;
}

private static byte getTicketCode(ChunkTicketType<?> chunkTicketType) {
if (chunkTicketType == null) {
return 0;
}
return (byte) switch (chunkTicketType.toString()) {
default -> 0;
case "start" -> 1;
case "dragon" -> 2;
case "player" -> 3;
case "forced" -> 4;
case "light" -> 5;
case "portal" -> 6;
case "post_teleport" -> 7;
case "chonk" -> 8;
case "unknown" -> 9;
};
}

@Override
Expand Down
44 changes: 0 additions & 44 deletions src/main/java/chunkdebug/utils/ChunkMapSerializer.java

This file was deleted.

0 comments on commit 3c0278a

Please sign in to comment.