From 9ba14d9dc9f3862f3d8e3010b8d5484d521739fe Mon Sep 17 00:00:00 2001 From: EOT3000 <43685885+EOT3000@users.noreply.github.com> Date: Thu, 18 Jul 2019 20:11:58 -0400 Subject: [PATCH] attempt crash fix/fix typo/others --- .../connector/console/GeyserLogger.java | 9 + .../network/ConnectorServerEventHandler.java | 4 +- .../network/translators/Registry.java | 3 +- .../network/translators/TranslatorsInit.java | 44 +- .../connector/utils/ArraySerializer.java | 272 -------- .../geysermc/connector/utils/GeyserUtils.java | 653 ++++++++++++++++++ .../connector/utils/MiscSerializer.java | 159 ----- .../geysermc/connector/utils/NibbleArray.java | 129 ++++ .../geysermc/connector/utils/PSPEStuff.java | 52 -- .../connector/utils/PositionSerializer.java | 97 --- .../org/geysermc/connector/utils/Toolbox.java | 13 +- .../connector/utils/VarNumberSerializer.java | 177 ----- 12 files changed, 833 insertions(+), 779 deletions(-) delete mode 100644 connector/src/main/java/org/geysermc/connector/utils/ArraySerializer.java create mode 100644 connector/src/main/java/org/geysermc/connector/utils/GeyserUtils.java delete mode 100644 connector/src/main/java/org/geysermc/connector/utils/MiscSerializer.java create mode 100644 connector/src/main/java/org/geysermc/connector/utils/NibbleArray.java delete mode 100644 connector/src/main/java/org/geysermc/connector/utils/PSPEStuff.java delete mode 100644 connector/src/main/java/org/geysermc/connector/utils/PositionSerializer.java delete mode 100644 connector/src/main/java/org/geysermc/connector/utils/VarNumberSerializer.java diff --git a/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java b/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java index a57d9553..da76a308 100644 --- a/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java +++ b/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java @@ -92,29 +92,38 @@ public class GeyserLogger implements org.geysermc.api.logger.Logger { @Override public void severe(String message) { + waitFor(); System.out.println(printConsole(ChatColor.DARK_RED + message, colored)); } @Override public void error(String message) { + waitFor(); System.out.println(printConsole(ChatColor.RED + message, colored)); } @Override public void warning(String message) { + waitFor(); System.out.println(printConsole(ChatColor.YELLOW + message, colored)); } @Override public void info(String message) { + waitFor(); System.out.println(printConsole(ChatColor.WHITE + message, colored)); } @Override public void debug(String message) { + waitFor(); System.out.println(printConsole(ChatColor.GRAY + message, colored)); } + private synchronized void waitFor() { + + } + public void stop() { } diff --git a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java index 0732676e..ae1b779b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -47,7 +47,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { @Override public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) { - System.out.println(inetSocketAddress + " tried to connect!"); + GeyserLogger.DEFAULT.info(inetSocketAddress + " tried to connect!"); return true; } @@ -74,7 +74,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { public void onSessionCreation(BedrockServerSession bedrockServerSession) { bedrockServerSession.setLogging(true); bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession))); - bedrockServerSession.addDisconnectHandler((x) -> GeyserLogger.DEFAULT.warning("Bedrock user with ip: " + bedrockServerSession.getAddress().getAddress() + " has disconected for reason " + x)); + bedrockServerSession.addDisconnectHandler((x) -> GeyserLogger.DEFAULT.warning("Bedrock user with ip: " + bedrockServerSession.getAddress().getAddress() + " has disconnected for reason " + x)); bedrockServerSession.setPacketCodec(Bedrock_v361.V361_CODEC); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java b/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java index de10204a..ffb80afa 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java @@ -2,6 +2,7 @@ package org.geysermc.connector.network.translators; import com.github.steveice10.packetlib.packet.Packet; import org.geysermc.api.Geyser; +import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.network.session.GeyserSession; import java.util.HashMap; @@ -22,7 +23,7 @@ public class Registry { try { ((BiConsumer) JAVA.MAP.get(clazz)).accept(p, s); } catch (NullPointerException e) { - System.err.println("could not translate packet" + p.getClass().getSimpleName()); + GeyserLogger.DEFAULT.warning("could not translate packet " + p.getClass().getSimpleName()); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 623c56bf..6ab1224e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -5,7 +5,6 @@ import com.flowpowered.math.vector.Vector2i; import com.flowpowered.math.vector.Vector3f; import com.flowpowered.math.vector.Vector3i; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerAbilitiesPacket; import com.nukkitx.nbt.NbtUtils; import com.nukkitx.nbt.stream.NBTOutputStream; import com.nukkitx.nbt.tag.CompoundTag; @@ -13,13 +12,9 @@ import com.nukkitx.network.VarInts; import com.nukkitx.protocol.bedrock.data.GamePublishSetting; import com.nukkitx.protocol.bedrock.data.GameRule; import com.nukkitx.protocol.bedrock.packet.*; -import com.nukkitx.protocol.bedrock.v340.serializer.FullChunkDataSerializer_v340; -import com.nukkitx.protocol.bedrock.v340.serializer.ResourcePackChunkDataSerializer_v340; -import com.nukkitx.protocol.bedrock.v340.serializer.SetSpawnPositionSerializer_v340; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import org.geysermc.connector.console.GeyserLogger; -import org.geysermc.connector.utils.PositionSerializer; +import org.geysermc.connector.utils.GeyserUtils; import org.geysermc.connector.utils.Toolbox; import java.io.ByteArrayOutputStream; @@ -32,9 +27,6 @@ public class TranslatorsInit { private static void addLoginPackets() { Registry.add(ServerJoinGamePacket.class, (packet, session) -> { - for(byte b : Toolbox.EMPTY_CHUNK) { - GeyserLogger.DEFAULT.warning("" + b); - } AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket(); bedrockPacket.setUniqueEntityId(packet.getEntityId()); @@ -104,7 +96,37 @@ public class TranslatorsInit { data.setChunkX(chunkX + x); data.setChunkZ(chunkZ + z); - data.setData(Toolbox.EMPTY_CHUNK); + ByteBuf buf = Unpooled.buffer(); + + data.setSubChunksLength(1); + + for(int i = 0; i < 1; i++) { + GeyserUtils.writeEmptySubChunk(buf); + } + + for(int i = 0; i < 256; i++) { + buf.writeByte(0); + } + + buf.writeZero(1); + + VarInts.writeInt(buf, 0); + + ByteArrayOutputStream s = new ByteArrayOutputStream(); + + NBTOutputStream stream = NbtUtils.createNetworkWriter(s); + + try { + stream.write(new CompoundTag("", new HashMap<>())); + s.close(); + stream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + buf.writeBytes(s.toByteArray()); + + data.setData(new byte[0]); session.getUpstream().sendPacketImmediately(data); @@ -123,7 +145,7 @@ public class TranslatorsInit { private static byte[] empty(byte[] b, Vector2i pos) { ByteBuf by = Unpooled.buffer(); - PositionSerializer.writePEChunkCoord(by, pos); + GeyserUtils.writePEChunkCoord(by, pos); return by.array(); } diff --git a/connector/src/main/java/org/geysermc/connector/utils/ArraySerializer.java b/connector/src/main/java/org/geysermc/connector/utils/ArraySerializer.java deleted file mode 100644 index c8b0ceab..00000000 --- a/connector/src/main/java/org/geysermc/connector/utils/ArraySerializer.java +++ /dev/null @@ -1,272 +0,0 @@ -package org.geysermc.connector.utils; - -import java.lang.reflect.Array; - -import java.util.List; - -import java.util.function.BiConsumer; - -import java.util.function.Consumer; - -import java.util.function.Function; - -import java.util.function.ToIntFunction; - - - -import io.netty.buffer.ByteBuf; - - - -public class ArraySerializer { - - - - public static ByteBuf readShortByteArraySlice(ByteBuf from, int limit) { - - int length = from.readShort(); - - MiscSerializer.checkLimit(length, limit); - - return from.readSlice(length); - - } - - - - @SuppressWarnings("unchecked") - - public static T[] readShortTArray(ByteBuf from, Class tclass, Function elementReader) { - - T[] array = (T[]) Array.newInstance(tclass, from.readShort()); - - for (int i = 0; i < array.length; i++) { - - array[i] = elementReader.apply(from); - - } - - return array; - - } - - - - - - public static byte[] readVarIntByteArray(ByteBuf from) { - - return MiscSerializer.readBytes(from, VarNumberSerializer.readVarInt(from)); - - } - - - - public static ByteBuf readVarIntByteArraySlice(ByteBuf from, int limit) { - - int length = VarNumberSerializer.readVarInt(from); - - MiscSerializer.checkLimit(length, limit); - - return from.readSlice(length); - - } - - - - public static ByteBuf readVarIntByteArraySlice(ByteBuf from) { - - return from.readSlice(VarNumberSerializer.readVarInt(from)); - - } - - - - @SuppressWarnings("unchecked") - - public static T[] readVarIntTArray(ByteBuf from, Class tclass, Function elementReader) { - - T[] array = (T[]) Array.newInstance(tclass, VarNumberSerializer.readVarInt(from)); - - for (int i = 0; i < array.length; i++) { - - array[i] = elementReader.apply(from); - - } - - return array; - - } - - - - public static int[] readVarIntVarIntArray(ByteBuf from) { - - int[] array = new int[VarNumberSerializer.readVarInt(from)]; - - for (int i = 0; i < array.length; i++) { - - array[i] = VarNumberSerializer.readVarInt(from); - - } - - return array; - - } - - - - - - public static void writeShortByteArray(ByteBuf to, ByteBuf data) { - - to.writeShort(data.readableBytes()); - - to.writeBytes(data); - - } - - - - public static void writeShortByteArray(ByteBuf to, byte[] data) { - - to.writeShort(data.length); - - to.writeBytes(data); - - } - - - - public static void writeShortByteArray(ByteBuf to, Consumer dataWriter) { - - MiscSerializer.writeLengthPrefixedBytes(to, (lTo, length) -> lTo.writeShort(length), dataWriter); - - } - - - - public static void writeShortTArray(ByteBuf to, T[] array, BiConsumer elementWriter) { - - to.writeShort(array.length); - - for (T element : array) { - - elementWriter.accept(to, element); - - } - - } - - - - - - public static void writeVarIntByteArray(ByteBuf to, ByteBuf data) { - - VarNumberSerializer.writeVarInt(to, data.readableBytes()); - - to.writeBytes(data); - - } - - - - public static void writeVarIntByteArray(ByteBuf to, byte[] data) { - - VarNumberSerializer.writeVarInt(to, data.length); - - to.writeBytes(data); - - } - - - - public static void writeVarIntByteArray(ByteBuf to, Consumer dataWriter) { - - MiscSerializer.writeLengthPrefixedBytes(to, VarNumberSerializer::writeFixedSizeVarInt, dataWriter); - - } - - - - public static void writeVarIntTArray(ByteBuf to, ToIntFunction arrayWriter) { - - MiscSerializer.writeSizePrefixedData(to, VarNumberSerializer::writeFixedSizeVarInt, arrayWriter); - - } - - - - public static void writeVarIntTArray(ByteBuf to, T[] array, BiConsumer elementWriter) { - - VarNumberSerializer.writeVarInt(to, array.length); - - for (T element : array) { - - elementWriter.accept(to, element); - - } - - } - - - - public static void writeVarIntTArray(ByteBuf to, List array, BiConsumer elementWriter) { - - VarNumberSerializer.writeVarInt(to, array.size()); - - for (T element : array) { - - elementWriter.accept(to, element); - - } - - } - - - - - public static void writeVarIntVarIntArray(ByteBuf to, int[] array) { - - VarNumberSerializer.writeVarInt(to, array.length); - - for (int element : array) { - - VarNumberSerializer.writeVarInt(to, element); - - } - - } - - - - public static void writeSVarIntSVarIntArray(ByteBuf to, int[] array) { - - VarNumberSerializer.writeSVarInt(to, array.length); - - for (int element : array) { - - VarNumberSerializer.writeSVarInt(to, element); - - } - - } - - - - public static void writeVarIntLongArray(ByteBuf to, long[] array) { - - VarNumberSerializer.writeVarInt(to, array.length); - - for (long element : array) { - - to.writeLong(element); - - } - - } - - - -} diff --git a/connector/src/main/java/org/geysermc/connector/utils/GeyserUtils.java b/connector/src/main/java/org/geysermc/connector/utils/GeyserUtils.java new file mode 100644 index 00000000..1e95a3e3 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/GeyserUtils.java @@ -0,0 +1,653 @@ +package org.geysermc.connector.utils; + +import com.flowpowered.math.vector.Vector2i; +import com.flowpowered.math.vector.Vector3d; +import com.flowpowered.math.vector.Vector3i; +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.DecoderException; + +import java.lang.reflect.Array; +import java.text.MessageFormat; +import java.util.List; +import java.util.UUID; +import java.util.function.*; + +public class GeyserUtils { + + public static final int FLAG_RUNTIME = 1; + + public static final int GLOBAL_PALETTE_BITS_PER_BLOCK = 14; + + public static final int SECTION_COUNT_BLOCKS = 16; + + public static final int SECTION_COUNT_LIGHT = 18; + + public static final int BLOCKS_IN_SECTION = 16 * 16 * 16; + + public static final int LIGHT_DATA_LENGTH = BLOCKS_IN_SECTION / 2; + + public static final int EMPTY_SUBCHUNK_BYTES = BLOCKS_IN_SECTION / 8; + + public static final int SUBCHUNK_VERSION = 8; + + public static void writeEmpty(ByteBuf to) { + + to.writeByte(storageHeader(1)); + + to.writeZero(EMPTY_SUBCHUNK_BYTES); + + } + + + + protected static final int storageHeader(int bitsPerBlock) { + + return (bitsPerBlock << 1) | FLAG_RUNTIME; + + } + + public static void writeEmptySubChunk(ByteBuf out) { + + out.writeBytes(new byte[4096 + 4096]); + + } + + public static void skipPosition(ByteBuf from) { + from.skipBytes(Long.BYTES); + } + + public static Vector3d readPosition(ByteBuf from) { + long l = from.readLong(); + return new Vector3d( + (int) (l >> 38), (int) (l & 0xFFF), (int) ((l << 26) >> 38) + ); + } + + public static void readPEPosition(ByteBuf from) { + readSVarInt(from); + readVarInt(from); + readSVarInt(from); + } + + public static Vector3d readLegacyPositionI(ByteBuf from) { + return new Vector3d(from.readInt(), from.readInt(), from.readInt()); + } + + public static void writePosition(ByteBuf to, Vector3i position) { + to.writeLong(((position.getX() & 0x3FFFFFFL) << 38) | ((position.getZ() & 0x3FFFFFFL) << 12) | (position.getY() & 0xFFFL)); + } + + public static void writeLegacyPositionL(ByteBuf to, Vector3d position) { + to.writeLong((((int) position.getX() & 0x3FFFFFFL) << 38) | (((int) position.getY() & 0xFFFL) << 26) | ((int) position.getZ() & 0x3FFFFFFL)); + } + + public static void writePEPosition(ByteBuf to, Vector3d position) { + writeSVarInt(to, (int) position.getX()); + writeVarInt(to, (int) position.getY()); + writeSVarInt(to, (int) position.getZ()); + } + + public static void writeLegacyPositionB(ByteBuf to, Vector3d position) { + to.writeInt((int) position.getX()); + to.writeByte((int) position.getY()); + to.writeInt((int) position.getZ()); + } + + public static void writeLegacyPositionS(ByteBuf to, Vector3d position) { + to.writeInt((int) position.getX()); + to.writeShort((int) position.getY()); + to.writeInt((int) position.getZ()); + } + + public static void writeLegacyPositionI(ByteBuf to, Vector3d position) { + to.writeInt((int) position.getX()); + to.writeInt((int) position.getY()); + to.writeInt((int) position.getZ()); + } + + public static Vector2i readIntChunkCoord(ByteBuf from) { + return new Vector2i(from.readInt(), from.readInt()); + } + + public static Vector2i readVarIntChunkCoord(ByteBuf from) { + return new Vector2i(readVarInt(from), readVarInt(from)); + } + + public static void writeIntChunkCoord(ByteBuf to, Vector2i chunk) { + to.writeInt(chunk.getX()); + to.writeInt(chunk.getY()); + } + + public static Vector2i readPEChunkCoord(ByteBuf from) { + return new Vector2i(readSVarInt(from), readSVarInt(from)); + } + + public static void writePEChunkCoord(ByteBuf to, Vector2i chunk) { + writeSVarInt(to, chunk.getX()); + writeSVarInt(to, chunk.getY()); + } + + public static int readLocalCoord(ByteBuf from) { + return from.readUnsignedShort(); + } + + public static void writeLocalCoord(ByteBuf to, int coord) { + to.writeShort(coord); + } + + public static void writeVarIntChunkCoord(ByteBuf to, Vector2i chunk) { + writeVarInt(to, chunk.getX()); + writeVarInt(to, chunk.getY()); + } + + + + public static final int MAX_LENGTH = 5; + + + + public static void writeFixedSizeVarInt(ByteBuf to, int i) { + + int writerIndex = to.writerIndex(); + + while ((i & 0xFFFFFF80) != 0x0) { + + to.writeByte(i | 0x80); + + i >>>= 7; + + } + + int paddingBytes = MAX_LENGTH - (to.writerIndex() - writerIndex) - 1; + + if (paddingBytes == 0) { + + to.writeByte(i); + + } else { + + to.writeByte(i | 0x80); + + while (--paddingBytes > 0) { + + to.writeByte(0x80); + + } + + to.writeByte(0); + + } + + } + + + + public static int readVarInt(ByteBuf from) { + + int value = 0; + + int length = 0; + + byte part; + + do { + + part = from.readByte(); + + value |= (part & 0x7F) << (length++ * 7); + + if (length > MAX_LENGTH) { + + throw new DecoderException("VarInt too big"); + + } + + } while (part < 0); + + return value; + + } + + + + public static void writeVarInt(ByteBuf to, int i) { + + while ((i & 0xFFFFFF80) != 0x0) { + + to.writeByte(i | 0x80); + + i >>>= 7; + + } + + to.writeByte(i); + + } + + + + public static int readSVarInt(ByteBuf from) { + + int varint = readVarInt(from); + + return (varint >> 1) ^ -(varint & 1); + + } + + + + public static void writeSVarInt(ByteBuf to, int varint) { + + writeVarInt(to, (varint << 1) ^ (varint >> 31)); + + } + + + + public static long readVarLong(ByteBuf from) { + + long varlong = 0L; + + int length = 0; + + byte part; + + do { + + part = from.readByte(); + + varlong |= (part & 0x7F) << (length++ * 7); + + if (length > 10) { + + throw new RuntimeException("VarLong too big"); + + } + + } while ((part & 0x80) == 0x80); + + return varlong; + + } + + + + public static void writeVarLong(ByteBuf to, long varlong) { + + while ((varlong & 0xFFFFFFFFFFFFFF80L) != 0x0L) { + + to.writeByte((int) (varlong & 0x7FL) | 0x80); + + varlong >>>= 7; + + } + + to.writeByte((int) varlong); + + } + + + + public static long readSVarLong(ByteBuf from) { + + long varlong = readVarLong(from); + + return (varlong >> 1) ^ -(varlong & 1); + + } + + + + public static void writeSVarLong(ByteBuf to, long varlong) { + + writeVarLong(to, (varlong << 1) ^ (varlong >> 63)); + + } + + + public static ByteBuf readShortByteArraySlice(ByteBuf from, int limit) { + + int length = from.readShort(); + + checkLimit(length, limit); + + return from.readSlice(length); + + } + + + + @SuppressWarnings("unchecked") + + public static T[] readShortTArray(ByteBuf from, Class tclass, Function elementReader) { + + T[] array = (T[]) Array.newInstance(tclass, from.readShort()); + + for (int i = 0; i < array.length; i++) { + + array[i] = elementReader.apply(from); + + } + + return array; + + } + + + + + + public static byte[] readVarIntByteArray(ByteBuf from) { + + return readBytes(from, readVarInt(from)); + + } + + + + public static ByteBuf readVarIntByteArraySlice(ByteBuf from, int limit) { + + int length = readVarInt(from); + + checkLimit(length, limit); + + return from.readSlice(length); + + } + + + + public static ByteBuf readVarIntByteArraySlice(ByteBuf from) { + + return from.readSlice(readVarInt(from)); + + } + + + + @SuppressWarnings("unchecked") + + public static T[] readVarIntTArray(ByteBuf from, Class tclass, Function elementReader) { + + T[] array = (T[]) Array.newInstance(tclass, readVarInt(from)); + + for (int i = 0; i < array.length; i++) { + + array[i] = elementReader.apply(from); + + } + + return array; + + } + + + + public static int[] readVarIntVarIntArray(ByteBuf from) { + + int[] array = new int[readVarInt(from)]; + + for (int i = 0; i < array.length; i++) { + + array[i] = readVarInt(from); + + } + + return array; + + } + + + + + + public static void writeShortByteArray(ByteBuf to, ByteBuf data) { + + to.writeShort(data.readableBytes()); + + to.writeBytes(data); + + } + + + + public static void writeShortByteArray(ByteBuf to, byte[] data) { + + to.writeShort(data.length); + + to.writeBytes(data); + + } + + + + public static void writeShortByteArray(ByteBuf to, Consumer dataWriter) { + + writeLengthPrefixedBytes(to, (lTo, length) -> lTo.writeShort(length), dataWriter); + + } + + + + public static void writeShortTArray(ByteBuf to, T[] array, BiConsumer elementWriter) { + + to.writeShort(array.length); + + for (T element : array) { + + elementWriter.accept(to, element); + + } + + } + + + + + + public static void writeVarIntByteArray(ByteBuf to, ByteBuf data) { + + writeVarInt(to, data.readableBytes()); + + to.writeBytes(data); + + } + + + + public static void writeVarIntByteArray(ByteBuf to, byte[] data) { + + writeVarInt(to, data.length); + + to.writeBytes(data); + + } + + + + public static void writeVarIntByteArray(ByteBuf to, Consumer dataWriter) { + + writeLengthPrefixedBytes(to, GeyserUtils::writeFixedSizeVarInt, dataWriter); + + } + + + + public static void writeVarIntTArray(ByteBuf to, ToIntFunction arrayWriter) { + + writeSizePrefixedData(to, GeyserUtils::writeFixedSizeVarInt, arrayWriter); + + } + + + + public static void writeVarIntTArray(ByteBuf to, T[] array, BiConsumer elementWriter) { + + writeVarInt(to, array.length); + + for (T element : array) { + + elementWriter.accept(to, element); + + } + + } + + + + public static void writeVarIntTArray(ByteBuf to, List array, BiConsumer elementWriter) { + + writeVarInt(to, array.size()); + + for (T element : array) { + + elementWriter.accept(to, element); + + } + + } + + + public static void writeVarIntEnum(ByteBuf to, Enum e) { + + writeVarInt(to, e.ordinal()); + + } + + + + public static void writeByteEnum(ByteBuf to, Enum e) { + + to.writeByte(e.ordinal()); + + } + + + + public static UUID readUUID(ByteBuf from) { + + return new UUID(from.readLong(), from.readLong()); + + } + + + + public static void writeUUID(ByteBuf to, UUID uuid) { + + to.writeLong(uuid.getMostSignificantBits()); + + to.writeLong(uuid.getLeastSignificantBits()); + + } + + + + public static void writePEUUID(ByteBuf to, UUID uuid) { + + to.writeLongLE(uuid.getMostSignificantBits()); + + to.writeLongLE(uuid.getLeastSignificantBits()); + + } + + + + public static byte[] readAllBytes(ByteBuf buf) { + + return readBytes(buf, buf.readableBytes()); + + } + + + + public static ByteBuf readAllBytesSlice(ByteBuf from) { + + return from.readSlice(from.readableBytes()); + + } + + + + public static ByteBuf readAllBytesSlice(ByteBuf buf, int limit) { + + checkLimit(buf.readableBytes(), limit); + + return readAllBytesSlice(buf); + + } + + + + public static byte[] readBytes(ByteBuf buf, int length) { + + byte[] result = new byte[length]; + + buf.readBytes(result); + + return result; + + } + + + + protected static void checkLimit(int length, int limit) { + + if (length > limit) { + + throw new DecoderException(MessageFormat.format("Size {0} is bigger than allowed {1}", length, limit)); + + } + + } + + + + public static void writeLengthPrefixedBytes(ByteBuf to, ObjIntConsumer lengthWriter, Consumer dataWriter) { + + int lengthWriterIndex = to.writerIndex(); + + lengthWriter.accept(to, 0); + + int writerIndexDataStart = to.writerIndex(); + + dataWriter.accept(to); + + int writerIndexDataEnd = to.writerIndex(); + + to.writerIndex(lengthWriterIndex); + + lengthWriter.accept(to, writerIndexDataEnd - writerIndexDataStart); + + to.writerIndex(writerIndexDataEnd); + + } + + + + public static void writeSizePrefixedData(ByteBuf to, ObjIntConsumer sizeWriter, ToIntFunction dataWriter) { + + int sizeWriterIndex = to.writerIndex(); + + sizeWriter.accept(to, 0); + + int size = dataWriter.applyAsInt(to); + + int writerIndexDataEnd = to.writerIndex(); + + to.writerIndex(sizeWriterIndex); + + sizeWriter.accept(to, size); + + to.writerIndex(writerIndexDataEnd); + + } + + + private static int getAnvilIndex(int x, int y, int z) { + + return (y << 8) + (z << 4) + x; + + } + + +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/MiscSerializer.java b/connector/src/main/java/org/geysermc/connector/utils/MiscSerializer.java deleted file mode 100644 index f928106d..00000000 --- a/connector/src/main/java/org/geysermc/connector/utils/MiscSerializer.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.geysermc.connector.utils; - -import java.text.MessageFormat; - -import java.util.UUID; - -import java.util.function.Consumer; - -import java.util.function.ObjIntConsumer; - -import java.util.function.ToIntFunction; - - - -import io.netty.buffer.ByteBuf; - -import io.netty.handler.codec.DecoderException; - - -public class MiscSerializer { - - - public static void writeVarIntEnum(ByteBuf to, Enum e) { - - VarNumberSerializer.writeVarInt(to, e.ordinal()); - - } - - - - public static void writeByteEnum(ByteBuf to, Enum e) { - - to.writeByte(e.ordinal()); - - } - - - - public static UUID readUUID(ByteBuf from) { - - return new UUID(from.readLong(), from.readLong()); - - } - - - - public static void writeUUID(ByteBuf to, UUID uuid) { - - to.writeLong(uuid.getMostSignificantBits()); - - to.writeLong(uuid.getLeastSignificantBits()); - - } - - - - public static void writePEUUID(ByteBuf to, UUID uuid) { - - to.writeLongLE(uuid.getMostSignificantBits()); - - to.writeLongLE(uuid.getLeastSignificantBits()); - - } - - - - public static byte[] readAllBytes(ByteBuf buf) { - - return MiscSerializer.readBytes(buf, buf.readableBytes()); - - } - - - - public static ByteBuf readAllBytesSlice(ByteBuf from) { - - return from.readSlice(from.readableBytes()); - - } - - - - public static ByteBuf readAllBytesSlice(ByteBuf buf, int limit) { - - checkLimit(buf.readableBytes(), limit); - - return readAllBytesSlice(buf); - - } - - - - public static byte[] readBytes(ByteBuf buf, int length) { - - byte[] result = new byte[length]; - - buf.readBytes(result); - - return result; - - } - - - - protected static void checkLimit(int length, int limit) { - - if (length > limit) { - - throw new DecoderException(MessageFormat.format("Size {0} is bigger than allowed {1}", length, limit)); - - } - - } - - - - public static void writeLengthPrefixedBytes(ByteBuf to, ObjIntConsumer lengthWriter, Consumer dataWriter) { - - int lengthWriterIndex = to.writerIndex(); - - lengthWriter.accept(to, 0); - - int writerIndexDataStart = to.writerIndex(); - - dataWriter.accept(to); - - int writerIndexDataEnd = to.writerIndex(); - - to.writerIndex(lengthWriterIndex); - - lengthWriter.accept(to, writerIndexDataEnd - writerIndexDataStart); - - to.writerIndex(writerIndexDataEnd); - - } - - - - public static void writeSizePrefixedData(ByteBuf to, ObjIntConsumer sizeWriter, ToIntFunction dataWriter) { - - int sizeWriterIndex = to.writerIndex(); - - sizeWriter.accept(to, 0); - - int size = dataWriter.applyAsInt(to); - - int writerIndexDataEnd = to.writerIndex(); - - to.writerIndex(sizeWriterIndex); - - sizeWriter.accept(to, size); - - to.writerIndex(writerIndexDataEnd); - - } - - - -} diff --git a/connector/src/main/java/org/geysermc/connector/utils/NibbleArray.java b/connector/src/main/java/org/geysermc/connector/utils/NibbleArray.java new file mode 100644 index 00000000..85be81f8 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/NibbleArray.java @@ -0,0 +1,129 @@ +package org.geysermc.connector.utils; + +import com.google.common.base.Preconditions; + + + +public class NibbleArray implements Cloneable { + + private final byte[] data; + + + + public NibbleArray(int length) { + + data = new byte[length / 2]; + + } + + + + public NibbleArray(byte[] array) { + + data = array; + + } + + + + public byte get(int index) { + + Preconditions.checkElementIndex(index, data.length * 2); + + byte val = data[index / 2]; + + if ((index & 1) == 0) { + + return (byte) (val & 0x0f); + + } else { + + return (byte) ((val & 0xf0) >>> 4); + + } + + } + + + + public void set(int index, byte value) { + + Preconditions.checkArgument(value >= 0 && value < 16, "Nibbles must have a value between 0 and 15."); + + Preconditions.checkElementIndex(index, data.length * 2); + + value &= 0xf; + + int half = index / 2; + + byte previous = data[half]; + + if ((index & 1) == 0) { + + data[half] = (byte) (previous & 0xf0 | value); + + } else { + + data[half] = (byte) (previous & 0x0f | value << 4); + + } + + } + + + + public void fill(byte value) { + + Preconditions.checkArgument(value >= 0 && value < 16, "Nibbles must have a value between 0 and 15."); + + value &= 0xf; + + for (int i = 0; i < data.length; i++) { + + data[i] = (byte) ((value << 4) | value); + + } + + } + + + + public void copyFrom(byte[] bytes) { + + Preconditions.checkNotNull(bytes, "bytes"); + + Preconditions.checkArgument(bytes.length == data.length, "length of provided byte array is %s but expected %s", bytes.length, + + data.length); + + System.arraycopy(bytes, 0, data, 0, data.length); + + } + + + + public void copyFrom(NibbleArray array) { + + Preconditions.checkNotNull(array, "array"); + + copyFrom(array.data); + + } + + + + public byte[] getData() { + + return data; + + } + + + + public NibbleArray copy() { + + return new NibbleArray(getData().clone()); + + } + +} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/utils/PSPEStuff.java b/connector/src/main/java/org/geysermc/connector/utils/PSPEStuff.java deleted file mode 100644 index c513be3f..00000000 --- a/connector/src/main/java/org/geysermc/connector/utils/PSPEStuff.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.geysermc.connector.utils; - -import io.netty.buffer.ByteBuf; - -public class PSPEStuff { - - public static final int FLAG_RUNTIME = 1; - - public static final int GLOBAL_PALETTE_BITS_PER_BLOCK = 14; - - public static final int SECTION_COUNT_BLOCKS = 16; - - public static final int SECTION_COUNT_LIGHT = 18; - - public static final int BLOCKS_IN_SECTION = 16 * 16 * 16; - - public static final int LIGHT_DATA_LENGTH = BLOCKS_IN_SECTION / 2; - - public static final int EMPTY_SUBCHUNK_BYTES = BLOCKS_IN_SECTION / 8; - - public static final int SUBCHUNK_VERSION = 8; - - public static void writeEmpty(ByteBuf to) { - - to.writeByte(storageHeader(1)); - - to.writeZero(EMPTY_SUBCHUNK_BYTES); - - } - - - - protected static final int storageHeader(int bitsPerBlock) { - - return (bitsPerBlock << 1) | FLAG_RUNTIME; - - } - - public static void writeEmptySubChunk(ByteBuf out) { - - out.writeByte(SUBCHUNK_VERSION); - - out.writeByte(1); //only blockstate storage - - writeEmpty(out); - - VarNumberSerializer.writeSVarInt(out, 1); //Palette size - - VarNumberSerializer.writeSVarInt(out, 0); //Palette: Air - - } -} diff --git a/connector/src/main/java/org/geysermc/connector/utils/PositionSerializer.java b/connector/src/main/java/org/geysermc/connector/utils/PositionSerializer.java deleted file mode 100644 index 2a63fcc8..00000000 --- a/connector/src/main/java/org/geysermc/connector/utils/PositionSerializer.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.geysermc.connector.utils; - -import com.flowpowered.math.vector.Vector2i; -import com.flowpowered.math.vector.Vector3d; -import com.flowpowered.math.vector.Vector3i; -import io.netty.buffer.ByteBuf; - -public class PositionSerializer { - - public static void skipPosition(ByteBuf from) { - from.skipBytes(Long.BYTES); - } - - public static Vector3d readPosition(ByteBuf from) { - long l = from.readLong(); - return new Vector3d( - (int) (l >> 38), (int) (l & 0xFFF), (int) ((l << 26) >> 38) - ); - } - - public static void readPEPosition(ByteBuf from) { - VarNumberSerializer.readSVarInt(from); - VarNumberSerializer.readVarInt(from); - VarNumberSerializer.readSVarInt(from); - } - - public static Vector3d readLegacyPositionI(ByteBuf from) { - return new Vector3d(from.readInt(), from.readInt(), from.readInt()); - } - - public static void writePosition(ByteBuf to, Vector3i position) { - to.writeLong(((position.getX() & 0x3FFFFFFL) << 38) | ((position.getZ() & 0x3FFFFFFL) << 12) | (position.getY() & 0xFFFL)); - } - - public static void writeLegacyPositionL(ByteBuf to, Vector3d position) { - to.writeLong((((int) position.getX() & 0x3FFFFFFL) << 38) | (((int) position.getY() & 0xFFFL) << 26) | ((int) position.getZ() & 0x3FFFFFFL)); - } - - public static void writePEPosition(ByteBuf to, Vector3d position) { - VarNumberSerializer.writeSVarInt(to, (int) position.getX()); - VarNumberSerializer.writeVarInt(to, (int) position.getY()); - VarNumberSerializer.writeSVarInt(to, (int) position.getZ()); - } - - public static void writeLegacyPositionB(ByteBuf to, Vector3d position) { - to.writeInt((int) position.getX()); - to.writeByte((int) position.getY()); - to.writeInt((int) position.getZ()); - } - - public static void writeLegacyPositionS(ByteBuf to, Vector3d position) { - to.writeInt((int) position.getX()); - to.writeShort((int) position.getY()); - to.writeInt((int) position.getZ()); - } - - public static void writeLegacyPositionI(ByteBuf to, Vector3d position) { - to.writeInt((int) position.getX()); - to.writeInt((int) position.getY()); - to.writeInt((int) position.getZ()); - } - - public static Vector2i readIntChunkCoord(ByteBuf from) { - return new Vector2i(from.readInt(), from.readInt()); - } - - public static Vector2i readVarIntChunkCoord(ByteBuf from) { - return new Vector2i(VarNumberSerializer.readVarInt(from), VarNumberSerializer.readVarInt(from)); - } - - public static void writeIntChunkCoord(ByteBuf to, Vector2i chunk) { - to.writeInt(chunk.getX()); - to.writeInt(chunk.getY()); - } - - public static Vector2i readPEChunkCoord(ByteBuf from) { - return new Vector2i(VarNumberSerializer.readSVarInt(from), VarNumberSerializer.readSVarInt(from)); - } - - public static void writePEChunkCoord(ByteBuf to, Vector2i chunk) { - VarNumberSerializer.writeSVarInt(to, chunk.getX()); - VarNumberSerializer.writeSVarInt(to, chunk.getY()); - } - - public static int readLocalCoord(ByteBuf from) { - return from.readUnsignedShort(); - } - - public static void writeLocalCoord(ByteBuf to, int coord) { - to.writeShort(coord); - } - - public static void writeVarIntChunkCoord(ByteBuf to, Vector2i chunk) { - VarNumberSerializer.writeVarInt(to, chunk.getX()); - VarNumberSerializer.writeVarInt(to, chunk.getY()); - } -} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java index 0b6fe955..59ae3992 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java +++ b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java @@ -1,15 +1,12 @@ package org.geysermc.connector.utils; -import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.CollectionType; import com.nukkitx.network.VarInts; import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import com.nukkitx.protocol.bedrock.v361.BedrockUtils; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import java.io.IOException; import java.io.InputStream; import java.util.*; @@ -64,18 +61,18 @@ public class Toolbox { ITEMS = l; - ByteBuf serializer; + /*ByteBuf serializer; serializer = Unpooled.buffer(); serializer.writeShortLE(1); - ArraySerializer.writeVarIntByteArray(serializer, (chunkdata) -> { - PSPEStuff.writeEmptySubChunk(chunkdata); + GeyserUtils.writeVarIntByteArray(serializer, (chunkdata) -> { + GeyserUtils.writeEmptySubChunk(chunkdata); chunkdata.writeZero(512); chunkdata.writeZero(256); chunkdata.writeByte(0); }); - EMPTY_CHUNK = MiscSerializer.readAllBytes(serializer); + EMPTY_CHUNK = GeyserUtils.readAllBytes(serializer);*/ } @@ -83,6 +80,6 @@ public class Toolbox { public static final ByteBuf CACHED_PALLETE; - public static final byte[] EMPTY_CHUNK; + //public static final byte[] EMPTY_CHUNK; } \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/utils/VarNumberSerializer.java b/connector/src/main/java/org/geysermc/connector/utils/VarNumberSerializer.java deleted file mode 100644 index 02d05579..00000000 --- a/connector/src/main/java/org/geysermc/connector/utils/VarNumberSerializer.java +++ /dev/null @@ -1,177 +0,0 @@ -package org.geysermc.connector.utils; - -import io.netty.buffer.ByteBuf; - -import io.netty.handler.codec.DecoderException; - - - -public class VarNumberSerializer { - - - - public static final int MAX_LENGTH = 5; - - - - public static void writeFixedSizeVarInt(ByteBuf to, int i) { - - int writerIndex = to.writerIndex(); - - while ((i & 0xFFFFFF80) != 0x0) { - - to.writeByte(i | 0x80); - - i >>>= 7; - - } - - int paddingBytes = MAX_LENGTH - (to.writerIndex() - writerIndex) - 1; - - if (paddingBytes == 0) { - - to.writeByte(i); - - } else { - - to.writeByte(i | 0x80); - - while (--paddingBytes > 0) { - - to.writeByte(0x80); - - } - - to.writeByte(0); - - } - - } - - - - public static int readVarInt(ByteBuf from) { - - int value = 0; - - int length = 0; - - byte part; - - do { - - part = from.readByte(); - - value |= (part & 0x7F) << (length++ * 7); - - if (length > MAX_LENGTH) { - - throw new DecoderException("VarInt too big"); - - } - - } while (part < 0); - - return value; - - } - - - - public static void writeVarInt(ByteBuf to, int i) { - - while ((i & 0xFFFFFF80) != 0x0) { - - to.writeByte(i | 0x80); - - i >>>= 7; - - } - - to.writeByte(i); - - } - - - - public static int readSVarInt(ByteBuf from) { - - int varint = readVarInt(from); - - return (varint >> 1) ^ -(varint & 1); - - } - - - - public static void writeSVarInt(ByteBuf to, int varint) { - - writeVarInt(to, (varint << 1) ^ (varint >> 31)); - - } - - - - public static long readVarLong(ByteBuf from) { - - long varlong = 0L; - - int length = 0; - - byte part; - - do { - - part = from.readByte(); - - varlong |= (part & 0x7F) << (length++ * 7); - - if (length > 10) { - - throw new RuntimeException("VarLong too big"); - - } - - } while ((part & 0x80) == 0x80); - - return varlong; - - } - - - - public static void writeVarLong(ByteBuf to, long varlong) { - - while ((varlong & 0xFFFFFFFFFFFFFF80L) != 0x0L) { - - to.writeByte((int) (varlong & 0x7FL) | 0x80); - - varlong >>>= 7; - - } - - to.writeByte((int) varlong); - - } - - - - public static long readSVarLong(ByteBuf from) { - - long varlong = readVarLong(from); - - return (varlong >> 1) ^ -(varlong & 1); - - } - - - - public static void writeSVarLong(ByteBuf to, long varlong) { - - writeVarLong(to, (varlong << 1) ^ (varlong >> 63)); - - } - - - -}