Skip to content

Commit

Permalink
Convert Packet into an interface
Browse files Browse the repository at this point in the history
And moves / adds typical serialisation static functions to the Packet interface.
  • Loading branch information
Protonull authored and Huskydog9988 committed Sep 27, 2023
1 parent 13afe57 commit b460252
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 93 deletions.
21 changes: 0 additions & 21 deletions mod/common/src/main/java/gjum/minecraft/mapsync/common/Utils.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package gjum.minecraft.mapsync.common;

import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.core.Registry;
import net.minecraft.world.level.biome.Biome;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Utils {
public static final Minecraft mc = Minecraft.getInstance();

Expand All @@ -31,21 +27,4 @@ public static void printErrorRateLimited(@NotNull Throwable e) {
e2.printStackTrace();
}
}

public static void writeStringToBuf(@NotNull ByteBuf buf, @Nullable String string) {
if (string == null || string.isEmpty()) {
buf.writeInt(0);
return;
}
final byte[] bytes = string.getBytes(UTF_8);
buf.writeInt(bytes.length);
buf.writeBytes(bytes);
}

public static @NotNull String readStringFromBuf(@NotNull ByteBuf buf) {
int length = buf.readInt();
final byte[] bytes = new byte[length];
buf.readBytes(bytes);
return new String(bytes, UTF_8);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package gjum.minecraft.mapsync.common.data;

import gjum.minecraft.mapsync.common.net.Packet;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import static gjum.minecraft.mapsync.common.Utils.readStringFromBuf;
import static gjum.minecraft.mapsync.common.Utils.writeStringToBuf;

public record ChunkTile(
ResourceKey<Level> dimension,
int x, int z,
Expand All @@ -34,7 +31,7 @@ public void write(ByteBuf buf) {
* without columns
*/
public void writeMetadata(ByteBuf buf) {
writeStringToBuf(buf, dimension.location().toString());
Packet.writeResourceKey(buf, dimension);
buf.writeInt(x);
buf.writeInt(z);
buf.writeLong(timestamp);
Expand All @@ -51,8 +48,7 @@ public static void writeColumns(BlockColumn[] columns, ByteBuf buf) {
}

public static ChunkTile fromBuf(ByteBuf buf) {
String dimensionStr = readStringFromBuf(buf);
var dimension = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(dimensionStr));
var dimension = Packet.readResourceKey(buf, Registry.DIMENSION_REGISTRY);
int x = buf.readInt();
int z = buf.readInt();
long timestamp = buf.readLong();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,77 @@
package gjum.minecraft.mapsync.common.net;

import io.netty.buffer.ByteBuf;
import java.nio.charset.StandardCharsets;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import org.apache.commons.lang3.NotImplementedException;
import org.jetbrains.annotations.NotNull;

public abstract class Packet {
public abstract void write(ByteBuf buf);
public interface Packet {
default void write(@NotNull ByteBuf out) {
throw new NotImplementedException();
}

protected static byte[] readByteArray(ByteBuf in) {
int length = in.readInt();
byte[] array = new byte[length];
in.readBytes(array);
static byte @NotNull [] readIntLengthByteArray(
final @NotNull ByteBuf in
) {
final var array = new byte[in.readInt()];
if (array.length > 0) {
in.readBytes(array);
}
return array;
}

protected static void writeByteArray(ByteBuf out, byte[] array) {
out.writeInt(array.length);
out.writeBytes(array);
static void writeIntLengthByteArray(
final @NotNull ByteBuf out,
final byte @NotNull [] array
) {
if (array.length > 0) {
out.writeInt(array.length);
out.writeBytes(array);
}
else {
out.writeInt(0);
}
}

static @NotNull String readUtf8String(
final @NotNull ByteBuf in
) {
return new String(
readIntLengthByteArray(in),
StandardCharsets.UTF_8
);
}

static void writeUtf8String(
final @NotNull ByteBuf out,
final @NotNull String string
) {
writeIntLengthByteArray(
out,
string.getBytes(StandardCharsets.UTF_8)
);
}

static <T, R extends ResourceKey<Registry<T>>> @NotNull ResourceKey<T> readResourceKey(
final @NotNull ByteBuf in,
final @NotNull R registry
) {
return ResourceKey.create(
registry,
new ResourceLocation(readUtf8String(in))
);
}

static void writeResourceKey(
final @NotNull ByteBuf out,
final @NotNull ResourceKey<?> resourceKey
) {
writeUtf8String(
out,
resourceKey.location().toString()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import gjum.minecraft.mapsync.common.data.ChunkTile;
import gjum.minecraft.mapsync.common.net.Packet;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nonnull;

Expand All @@ -13,7 +14,7 @@
*
* 2. You have requested synchronisation via {@link ServerboundCatchupRequestPacket}.
*/
public class ChunkTilePacket extends Packet {
public class ChunkTilePacket implements Packet {
public static final int PACKET_ID = 4;

public final ChunkTile chunkTile;
Expand All @@ -28,7 +29,7 @@ public static Packet read(ByteBuf buf) {
}

@Override
public void write(ByteBuf buf) {
public void write(@NotNull ByteBuf buf) {
chunkTile.write(buf);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@
import gjum.minecraft.mapsync.common.net.Packet;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;

import static gjum.minecraft.mapsync.common.Utils.readStringFromBuf;

/**
* You'll receive this in response to a sent {@link ServerboundChunkTimestampsRequestPacket},
* containing an elaboration of chunk timestamps of all the regions you listed.
* You should respond with a {@link ServerboundCatchupRequestPacket}.
*/
public class ClientboundChunkTimestampsResponsePacket extends Packet {
public class ClientboundChunkTimestampsResponsePacket implements Packet {
public static final int PACKET_ID = 5;

/**
Expand All @@ -31,8 +27,7 @@ public ClientboundChunkTimestampsResponsePacket(@Nonnull List<CatchupChunk> chun
}

public static Packet read(ByteBuf buf) {
String dimensionStr = readStringFromBuf(buf);
var dimension = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(dimensionStr));
var dimension = Packet.readResourceKey(buf, Registry.DIMENSION_REGISTRY);

int length = buf.readInt();
List<CatchupChunk> chunks = new ArrayList<>(length);
Expand All @@ -46,9 +41,4 @@ public static Packet read(ByteBuf buf) {
}
return new ClientboundChunkTimestampsResponsePacket(chunks);
}

@Override
public void write(ByteBuf buf) {
throw new Error("Can't be sent from client");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* You will receive this in response to {@link ServerboundHandshakePacket}, and
* will expect a {@link ServerboundEncryptionResponsePacket} in response.
*/
public class ClientboundEncryptionRequestPacket extends Packet {
public class ClientboundEncryptionRequestPacket implements Packet {
public static final int PACKET_ID = 2;

@Nonnull
Expand All @@ -28,18 +28,12 @@ public ClientboundEncryptionRequestPacket(@Nonnull PublicKey publicKey, @Nonnull
public static Packet read(ByteBuf buf) {
return new ClientboundEncryptionRequestPacket(
readKey(buf),
readByteArray(buf));
}

@Override
public void write(ByteBuf buf) {
writeByteArray(buf, publicKey.getEncoded());
writeByteArray(buf, verifyToken);
Packet.readIntLengthByteArray(buf));
}

protected static PublicKey readKey(ByteBuf in) {
try {
byte[] encodedKey = readByteArray(in);
byte[] encodedKey = Packet.readIntLengthByteArray(in);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package gjum.minecraft.mapsync.common.net.packet;

import gjum.minecraft.mapsync.common.Utils;
import gjum.minecraft.mapsync.common.data.RegionTimestamp;
import gjum.minecraft.mapsync.common.net.Packet;
import io.netty.buffer.ByteBuf;
Expand All @@ -10,7 +9,7 @@
* sent immediately after you've been authenticated. You should respond with a
* {@link ServerboundChunkTimestampsRequestPacket}.
*/
public class ClientboundRegionTimestampsPacket extends Packet {
public class ClientboundRegionTimestampsPacket implements Packet {
public static final int PACKET_ID = 7;

private final String dimension;
Expand All @@ -31,7 +30,7 @@ public RegionTimestamp[] getTimestamps() {
}

public static Packet read(ByteBuf buf) {
String dimension = Utils.readStringFromBuf(buf);
String dimension = Packet.readUtf8String(buf);

short totalRegions = buf.readShort();
RegionTimestamp[] timestamps = new RegionTimestamp[totalRegions];
Expand All @@ -46,9 +45,4 @@ public static Packet read(ByteBuf buf) {

return new ClientboundRegionTimestampsPacket(dimension, timestamps);
}

@Override
public void write(ByteBuf buf) {
throw new IllegalStateException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@
import io.netty.buffer.ByteBuf;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nonnull;
import java.util.List;

import static gjum.minecraft.mapsync.common.Utils.writeStringToBuf;

/**
* This is the final stage in the synchronisation process, sent in response to
* a received {@link ClientboundChunkTimestampsResponsePacket}. Here you list
* what chunks you'd like to receive from the server, who'll then respond with
* a bunch of {@link ChunkTilePacket}.
*/
public class ServerboundCatchupRequestPacket extends Packet {
public class ServerboundCatchupRequestPacket implements Packet {
public static final int PACKET_ID = 6;

/**
Expand All @@ -41,8 +40,8 @@ else if (!dim.equals(chunk.dimension())) {
}

@Override
public void write(ByteBuf buf) {
writeStringToBuf(buf, chunks.get(0).dimension().location().toString());
public void write(@NotNull ByteBuf buf) {
Packet.writeResourceKey(buf, chunks.get(0).dimension());
buf.writeInt(chunks.size());
for (CatchupChunk chunk : chunks) {
buf.writeInt(chunk.chunk_x());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package gjum.minecraft.mapsync.common.net.packet;

import gjum.minecraft.mapsync.common.Utils;
import gjum.minecraft.mapsync.common.data.RegionPos;
import gjum.minecraft.mapsync.common.net.Packet;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;

import java.util.List;

Expand All @@ -12,7 +12,7 @@
* listing all the regions you'd like the server to elaborate on. You should
* expect a {@link ClientboundChunkTimestampsResponsePacket}.
*/
public class ServerboundChunkTimestampsRequestPacket extends Packet {
public class ServerboundChunkTimestampsRequestPacket implements Packet {
public static final int PACKET_ID = 8;

private final String dimension;
Expand All @@ -24,8 +24,8 @@ public ServerboundChunkTimestampsRequestPacket(String dimension, List<RegionPos>
}

@Override
public void write(ByteBuf buf) {
Utils.writeStringToBuf(buf, dimension);
public void write(@NotNull ByteBuf buf) {
Packet.writeUtf8String(buf, dimension);
buf.writeShort(regions.size());
for (var region : regions) {
buf.writeShort(region.x());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import gjum.minecraft.mapsync.common.net.Packet;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;

/**
* This is sent to the server in response to a {@link ClientboundEncryptionRequestPacket},
* after which, if the connection persists, you are considered authenticated
* with the server. You should then receive a {@link ClientboundRegionTimestampsPacket}.
*/
public class ServerboundEncryptionResponsePacket extends Packet {
public class ServerboundEncryptionResponsePacket implements Packet {
public static final int PACKET_ID = 3;

/**
Expand All @@ -25,13 +26,9 @@ public ServerboundEncryptionResponsePacket(byte[] sharedSecret, byte[] verifyTok
this.verifyToken = verifyToken;
}

public static Packet read(ByteBuf buf) {
return new ServerboundEncryptionResponsePacket(readByteArray(buf), readByteArray(buf));
}

@Override
public void write(ByteBuf out) {
writeByteArray(out, sharedSecret);
writeByteArray(out, verifyToken);
public void write(@NotNull ByteBuf out) {
Packet.writeIntLengthByteArray(out, sharedSecret);
Packet.writeIntLengthByteArray(out, verifyToken);
}
}
Loading

0 comments on commit b460252

Please sign in to comment.