Skip to content

Commit

Permalink
Stop length-prefixing hashes
Browse files Browse the repository at this point in the history
This can be applied to other things too, of course, but didn't want to de-length-prefix everything at once.
  • Loading branch information
Protonull authored and Gjum committed Oct 5, 2023
1 parent f834e89 commit febfff0
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package gjum.minecraft.mapsync.common.data;

import gjum.minecraft.mapsync.common.net.Packet;
import gjum.minecraft.mapsync.common.utils.Arguments;
import gjum.minecraft.mapsync.common.utils.MagicValues;
import io.netty.buffer.ByteBuf;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
Expand All @@ -18,6 +20,11 @@ public record ChunkTile(
byte[] dataHash,
BlockColumn[] columns
) {
public ChunkTile {
Arguments.checkNotNull("dataHash", dataHash);
Arguments.checkLength("dataHash", dataHash.length, MagicValues.SHA1_HASH_LENGTH);
}

public ChunkPos chunkPos() {
return new ChunkPos(x, z);
}
Expand All @@ -36,7 +43,6 @@ public void writeMetadata(ByteBuf buf) {
buf.writeInt(z);
buf.writeLong(timestamp);
buf.writeShort(dataVersion);
buf.writeInt(dataHash.length); // TODO could be Short as hash length is known to be small
buf.writeBytes(dataHash);
}

Expand All @@ -53,8 +59,7 @@ public static ChunkTile fromBuf(ByteBuf buf) {
int z = buf.readInt();
long timestamp = buf.readLong();
int dataVersion = buf.readUnsignedShort();
byte[] hash = new byte[buf.readInt()];
buf.readBytes(hash);
byte[] hash = Packet.readByteArrayOfSize(buf, MagicValues.SHA1_HASH_LENGTH);
var columns = new BlockColumn[256];
for (int i = 0; i < 256; i++) {
columns[i] = BlockColumn.fromBuf(buf);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,21 @@ default void write(@NotNull ByteBuf out) {
throw new NotImplementedException();
}

static byte @NotNull [] readByteArrayOfSize(
final @NotNull ByteBuf in,
final int size
) {
final var bytes = new byte[size];
if (size > 0) {
in.readBytes(bytes);
}
return bytes;
}

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

static void writeIntLengthByteArray(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package gjum.minecraft.mapsync.common.utils;

import org.jetbrains.annotations.NotNull;

public final class Arguments {
public static void checkNotNull(
final @NotNull String name,
final Object value
) {
if (value == null) {
throw new IllegalArgumentException("'" + name + "' is null!");
}
}

public static void checkLength(
final @NotNull String name,
final int currentLength,
final int requiredLength
) {
if (currentLength != requiredLength) {
throw new IllegalArgumentException("'" + name + "' has length " + currentLength + " when it must be " + requiredLength);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package gjum.minecraft.mapsync.common.utils;

public final class MagicValues {
// SHA1 produces 160-bit (20-byte) hashes
// https://en.wikipedia.org/wiki/SHA-1
public static final int SHA1_HASH_LENGTH = 20;
}
4 changes: 4 additions & 0 deletions server/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ export const SUPPORTED_VERSIONS = new Set([
'2.0.1-1.18.2+fabric',
'2.0.1-1.18.2+forge',
])

// SHA1 produces 160-bit (20-byte) hashes
// https://en.wikipedia.org/wiki/SHA-1
export const SHA1_HASH_LENGTH = 20
5 changes: 3 additions & 2 deletions server/src/protocol/ChunkTilePacket.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BufReader } from './BufReader'
import { BufWriter } from './BufWriter'
import { SHA1_HASH_LENGTH } from '../constants'

export interface ChunkTilePacket {
type: 'ChunkTile'
Expand All @@ -20,7 +21,7 @@ export namespace ChunkTilePacket {
ts: reader.readUInt64(),
data: {
version: reader.readUInt16(),
hash: reader.readBufWithLen(),
hash: reader.readBufLen(SHA1_HASH_LENGTH),
data: reader.readRemainder(),
},
}
Expand All @@ -32,7 +33,7 @@ export namespace ChunkTilePacket {
writer.writeInt32(pkt.chunk_z)
writer.writeUInt64(pkt.ts)
writer.writeUInt16(pkt.data.version)
writer.writeBufWithLen(pkt.data.hash)
writer.writeBufRaw(pkt.data.hash)
writer.writeBufRaw(pkt.data.data) // XXX do we need to prefix with length?
}
}

0 comments on commit febfff0

Please sign in to comment.