diff --git a/mod/common/src/main/java/gjum/minecraft/mapsync/common/Cartography.java b/mod/common/src/main/java/gjum/minecraft/mapsync/common/Cartography.java index 9f7457fb..7a25604f 100644 --- a/mod/common/src/main/java/gjum/minecraft/mapsync/common/Cartography.java +++ b/mod/common/src/main/java/gjum/minecraft/mapsync/common/Cartography.java @@ -1,11 +1,12 @@ package gjum.minecraft.mapsync.common; import gjum.minecraft.mapsync.common.data.*; -import gjum.minecraft.mapsync.common.utils.Hasher; +import gjum.minecraft.mapsync.common.utils.Shortcuts; +import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import java.security.MessageDigest; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; -import net.minecraft.tags.BlockTags; import net.minecraft.world.level.Level; import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.chunk.LevelChunk; @@ -31,11 +32,13 @@ public static ChunkTile chunkTileFromLevel(Level level, int cx, int cz) { int dataVersion = 1; // TODO speedup: don't serialize twice (once here, once later when writing to network) - var columnsBuf = Unpooled.buffer(); - ChunkTile.writeColumns(columns, columnsBuf); - final byte[] dataHash = Hasher.sha1() - .update(columnsBuf) - .generateHash(); + final byte[] dataHash; { + final ByteBuf columnsBuf = Unpooled.buffer(); + ChunkTile.writeColumns(columns, columnsBuf); + final MessageDigest md = Shortcuts.shaHash(); + md.update(columnsBuf.nioBuffer()); + dataHash = md.digest(); + } return new ChunkTile(dimension, cx, cz, timestamp, dataVersion, dataHash, columns); } diff --git a/mod/common/src/main/java/gjum/minecraft/mapsync/common/net/SyncClient.java b/mod/common/src/main/java/gjum/minecraft/mapsync/common/net/SyncClient.java index 37995a8d..7585433d 100644 --- a/mod/common/src/main/java/gjum/minecraft/mapsync/common/net/SyncClient.java +++ b/mod/common/src/main/java/gjum/minecraft/mapsync/common/net/SyncClient.java @@ -6,7 +6,7 @@ import gjum.minecraft.mapsync.common.net.encryption.EncryptionDecoder; import gjum.minecraft.mapsync.common.net.encryption.EncryptionEncoder; import gjum.minecraft.mapsync.common.net.packet.*; -import gjum.minecraft.mapsync.common.utils.Hasher; +import gjum.minecraft.mapsync.common.utils.Shortcuts; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; @@ -247,11 +247,12 @@ void setUpEncryption(ChannelHandlerContext ctx, ClientboundEncryptionRequestPack if (!MapSyncMod.getMod().isDevMode()) { // note that this is different from minecraft (we get no negative hashes) - final String shaHex = HexFormat.of().formatHex(Hasher.sha1() - .update(sharedSecret) - .update(packet.publicKey.getEncoded()) - .generateHash() - ); + final String shaHex; { + final MessageDigest md = Shortcuts.shaHash(); + md.update(sharedSecret); + md.update(packet.publicKey.getEncoded()); + shaHex = HexFormat.of().formatHex(md.digest()); + } final User session = Minecraft.getInstance().getUser(); try { diff --git a/mod/common/src/main/java/gjum/minecraft/mapsync/common/utils/Hasher.java b/mod/common/src/main/java/gjum/minecraft/mapsync/common/utils/Hasher.java deleted file mode 100644 index dc8468a3..00000000 --- a/mod/common/src/main/java/gjum/minecraft/mapsync/common/utils/Hasher.java +++ /dev/null @@ -1,116 +0,0 @@ -package gjum.minecraft.mapsync.common.utils; - -import io.netty.buffer.ByteBuf; -import java.nio.ByteBuffer; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Objects; -import org.jetbrains.annotations.NotNull; - -public final class Hasher { - private final MessageDigest messageDigest; - - private Hasher( - final @NotNull MessageDigest messageDigest - ) { - this.messageDigest = Objects.requireNonNull(messageDigest); - } - - /** - * Updates the digest with a single byte. - */ - public @NotNull Hasher update( - final byte input - ) { - this.messageDigest.update((byte) input); - return this; - } - - /** - * Updates the digest with an entire byte array. - */ - public @NotNull Hasher update( - final byte @NotNull [] input - ) { - this.messageDigest.update((byte[]) input); - return this; - } - - /** - * Updates the digest with a byte-array slice, defined by the given offset and length. - */ - public @NotNull Hasher update( - final byte @NotNull [] input, - final int offset, - final int length - ) { - this.messageDigest.update((byte[]) input, offset, length); - return this; - } - - /** - * Updates the digest with a ByteBuffer slice, using {@link ByteBuffer#position()} as the offset and - * {@link ByteBuffer#remaining()} as the length. If you have been writing to this ByteBuffer, you may wish to - * {@link ByteBuffer#flip()} it first before passing it into this method. - */ - public @NotNull Hasher update( - final @NotNull ByteBuffer input - ) { - this.messageDigest.update((ByteBuffer) input); - return this; - } - - /** - * Updates the digest with a ByteBuffer slice, defined by the given offset and length. - */ - public @NotNull Hasher update( - final @NotNull ByteBuffer input, - final int offset, - final int length - ) { - return update((ByteBuffer) input.slice(offset, length)); - } - - /** - * Updates the digest with a ByteBuf slice, using {@link ByteBuf#readerIndex()} as the offset and - * {@link ByteBuf#readableBytes()} as the length. - */ - public @NotNull Hasher update( - final @NotNull ByteBuf input - ) { - update((ByteBuffer) input.nioBuffer()); - return this; - } - - /** - * Updates the digest with a ByteBuf slice, defined by the given offset and length. - */ - public @NotNull Hasher update( - final @NotNull ByteBuf input, - final int offset, - final int length - ) { - update((ByteBuffer) input.nioBuffer(offset, length)); - return this; - } - - public byte @NotNull [] generateHash() { - return this.messageDigest.digest(); - } - - /** - * Since every implementation of Java is required to support SHA-1 - * (source) - * it's a safe bet that the algorithm exists. - */ - public static @NotNull Hasher sha1() { - final MessageDigest messageDigest; - try { - messageDigest = MessageDigest.getInstance("SHA-1"); - } - catch (final NoSuchAlgorithmException thrown) { - throw new IllegalStateException("This should never happen!", thrown); - } - return new Hasher(messageDigest); - } -} diff --git a/mod/common/src/main/java/gjum/minecraft/mapsync/common/utils/Shortcuts.java b/mod/common/src/main/java/gjum/minecraft/mapsync/common/utils/Shortcuts.java new file mode 100644 index 00000000..7eeb74a3 --- /dev/null +++ b/mod/common/src/main/java/gjum/minecraft/mapsync/common/utils/Shortcuts.java @@ -0,0 +1,16 @@ +package gjum.minecraft.mapsync.common.utils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import org.jetbrains.annotations.NotNull; + +public final class Shortcuts { + public static @NotNull MessageDigest shaHash() { + try { + return MessageDigest.getInstance("SHA-1"); + } + catch (final NoSuchAlgorithmException e) { + throw new IllegalStateException("unreachable", e); + } + } +}