forked from GeyserMC/Geyser
attempt crash fix/fix typo/others
This commit is contained in:
parent
3d7ee87a58
commit
9ba14d9dc9
12 changed files with 833 additions and 779 deletions
|
@ -92,29 +92,38 @@ public class GeyserLogger implements org.geysermc.api.logger.Logger {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void severe(String message) {
|
public void severe(String message) {
|
||||||
|
waitFor();
|
||||||
System.out.println(printConsole(ChatColor.DARK_RED + message, colored));
|
System.out.println(printConsole(ChatColor.DARK_RED + message, colored));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(String message) {
|
public void error(String message) {
|
||||||
|
waitFor();
|
||||||
System.out.println(printConsole(ChatColor.RED + message, colored));
|
System.out.println(printConsole(ChatColor.RED + message, colored));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void warning(String message) {
|
public void warning(String message) {
|
||||||
|
waitFor();
|
||||||
System.out.println(printConsole(ChatColor.YELLOW + message, colored));
|
System.out.println(printConsole(ChatColor.YELLOW + message, colored));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void info(String message) {
|
public void info(String message) {
|
||||||
|
waitFor();
|
||||||
System.out.println(printConsole(ChatColor.WHITE + message, colored));
|
System.out.println(printConsole(ChatColor.WHITE + message, colored));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void debug(String message) {
|
public void debug(String message) {
|
||||||
|
waitFor();
|
||||||
System.out.println(printConsole(ChatColor.GRAY + message, colored));
|
System.out.println(printConsole(ChatColor.GRAY + message, colored));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void waitFor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) {
|
public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) {
|
||||||
System.out.println(inetSocketAddress + " tried to connect!");
|
GeyserLogger.DEFAULT.info(inetSocketAddress + " tried to connect!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
|
||||||
public void onSessionCreation(BedrockServerSession bedrockServerSession) {
|
public void onSessionCreation(BedrockServerSession bedrockServerSession) {
|
||||||
bedrockServerSession.setLogging(true);
|
bedrockServerSession.setLogging(true);
|
||||||
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession)));
|
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);
|
bedrockServerSession.setPacketCodec(Bedrock_v361.V361_CODEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.geysermc.connector.network.translators;
|
||||||
|
|
||||||
import com.github.steveice10.packetlib.packet.Packet;
|
import com.github.steveice10.packetlib.packet.Packet;
|
||||||
import org.geysermc.api.Geyser;
|
import org.geysermc.api.Geyser;
|
||||||
|
import org.geysermc.connector.console.GeyserLogger;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -22,7 +23,7 @@ public class Registry<T> {
|
||||||
try {
|
try {
|
||||||
((BiConsumer<P, GeyserSession>) JAVA.MAP.get(clazz)).accept(p, s);
|
((BiConsumer<P, GeyserSession>) JAVA.MAP.get(clazz)).accept(p, s);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
System.err.println("could not translate packet" + p.getClass().getSimpleName());
|
GeyserLogger.DEFAULT.warning("could not translate packet " + p.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import com.flowpowered.math.vector.Vector2i;
|
||||||
import com.flowpowered.math.vector.Vector3f;
|
import com.flowpowered.math.vector.Vector3f;
|
||||||
import com.flowpowered.math.vector.Vector3i;
|
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.ServerJoinGamePacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerAbilitiesPacket;
|
|
||||||
import com.nukkitx.nbt.NbtUtils;
|
import com.nukkitx.nbt.NbtUtils;
|
||||||
import com.nukkitx.nbt.stream.NBTOutputStream;
|
import com.nukkitx.nbt.stream.NBTOutputStream;
|
||||||
import com.nukkitx.nbt.tag.CompoundTag;
|
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.GamePublishSetting;
|
||||||
import com.nukkitx.protocol.bedrock.data.GameRule;
|
import com.nukkitx.protocol.bedrock.data.GameRule;
|
||||||
import com.nukkitx.protocol.bedrock.packet.*;
|
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.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import org.geysermc.connector.console.GeyserLogger;
|
import org.geysermc.connector.utils.GeyserUtils;
|
||||||
import org.geysermc.connector.utils.PositionSerializer;
|
|
||||||
import org.geysermc.connector.utils.Toolbox;
|
import org.geysermc.connector.utils.Toolbox;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
@ -32,9 +27,6 @@ public class TranslatorsInit {
|
||||||
|
|
||||||
private static void addLoginPackets() {
|
private static void addLoginPackets() {
|
||||||
Registry.add(ServerJoinGamePacket.class, (packet, session) -> {
|
Registry.add(ServerJoinGamePacket.class, (packet, session) -> {
|
||||||
for(byte b : Toolbox.EMPTY_CHUNK) {
|
|
||||||
GeyserLogger.DEFAULT.warning("" + b);
|
|
||||||
}
|
|
||||||
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
|
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
|
||||||
|
|
||||||
bedrockPacket.setUniqueEntityId(packet.getEntityId());
|
bedrockPacket.setUniqueEntityId(packet.getEntityId());
|
||||||
|
@ -104,7 +96,37 @@ public class TranslatorsInit {
|
||||||
data.setChunkX(chunkX + x);
|
data.setChunkX(chunkX + x);
|
||||||
data.setChunkZ(chunkZ + z);
|
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);
|
session.getUpstream().sendPacketImmediately(data);
|
||||||
|
|
||||||
|
@ -123,7 +145,7 @@ public class TranslatorsInit {
|
||||||
private static byte[] empty(byte[] b, Vector2i pos) {
|
private static byte[] empty(byte[] b, Vector2i pos) {
|
||||||
ByteBuf by = Unpooled.buffer();
|
ByteBuf by = Unpooled.buffer();
|
||||||
|
|
||||||
PositionSerializer.writePEChunkCoord(by, pos);
|
GeyserUtils.writePEChunkCoord(by, pos);
|
||||||
|
|
||||||
return by.array();
|
return by.array();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> T[] readShortTArray(ByteBuf from, Class<T> tclass, Function<ByteBuf, T> 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> T[] readVarIntTArray(ByteBuf from, Class<T> tclass, Function<ByteBuf, T> 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<ByteBuf> dataWriter) {
|
|
||||||
|
|
||||||
MiscSerializer.writeLengthPrefixedBytes(to, (lTo, length) -> lTo.writeShort(length), dataWriter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static <T> void writeShortTArray(ByteBuf to, T[] array, BiConsumer<ByteBuf, T> 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<ByteBuf> dataWriter) {
|
|
||||||
|
|
||||||
MiscSerializer.writeLengthPrefixedBytes(to, VarNumberSerializer::writeFixedSizeVarInt, dataWriter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void writeVarIntTArray(ByteBuf to, ToIntFunction<ByteBuf> arrayWriter) {
|
|
||||||
|
|
||||||
MiscSerializer.writeSizePrefixedData(to, VarNumberSerializer::writeFixedSizeVarInt, arrayWriter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static <T> void writeVarIntTArray(ByteBuf to, T[] array, BiConsumer<ByteBuf, T> elementWriter) {
|
|
||||||
|
|
||||||
VarNumberSerializer.writeVarInt(to, array.length);
|
|
||||||
|
|
||||||
for (T element : array) {
|
|
||||||
|
|
||||||
elementWriter.accept(to, element);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static <T> void writeVarIntTArray(ByteBuf to, List<T> array, BiConsumer<ByteBuf, T> 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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -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> T[] readShortTArray(ByteBuf from, Class<T> tclass, Function<ByteBuf, T> 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> T[] readVarIntTArray(ByteBuf from, Class<T> tclass, Function<ByteBuf, T> 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<ByteBuf> dataWriter) {
|
||||||
|
|
||||||
|
writeLengthPrefixedBytes(to, (lTo, length) -> lTo.writeShort(length), dataWriter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> void writeShortTArray(ByteBuf to, T[] array, BiConsumer<ByteBuf, T> 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<ByteBuf> dataWriter) {
|
||||||
|
|
||||||
|
writeLengthPrefixedBytes(to, GeyserUtils::writeFixedSizeVarInt, dataWriter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void writeVarIntTArray(ByteBuf to, ToIntFunction<ByteBuf> arrayWriter) {
|
||||||
|
|
||||||
|
writeSizePrefixedData(to, GeyserUtils::writeFixedSizeVarInt, arrayWriter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> void writeVarIntTArray(ByteBuf to, T[] array, BiConsumer<ByteBuf, T> elementWriter) {
|
||||||
|
|
||||||
|
writeVarInt(to, array.length);
|
||||||
|
|
||||||
|
for (T element : array) {
|
||||||
|
|
||||||
|
elementWriter.accept(to, element);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static <T> void writeVarIntTArray(ByteBuf to, List<T> array, BiConsumer<ByteBuf, T> 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<ByteBuf> lengthWriter, Consumer<ByteBuf> 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<ByteBuf> sizeWriter, ToIntFunction<ByteBuf> 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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<ByteBuf> lengthWriter, Consumer<ByteBuf> 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<ByteBuf> sizeWriter, ToIntFunction<ByteBuf> 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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -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());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +1,12 @@
|
||||||
package org.geysermc.connector.utils;
|
package org.geysermc.connector.utils;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
|
||||||
import com.nukkitx.network.VarInts;
|
import com.nukkitx.network.VarInts;
|
||||||
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
||||||
import com.nukkitx.protocol.bedrock.v361.BedrockUtils;
|
import com.nukkitx.protocol.bedrock.v361.BedrockUtils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -64,18 +61,18 @@ public class Toolbox {
|
||||||
|
|
||||||
ITEMS = l;
|
ITEMS = l;
|
||||||
|
|
||||||
ByteBuf serializer;
|
/*ByteBuf serializer;
|
||||||
|
|
||||||
serializer = Unpooled.buffer();
|
serializer = Unpooled.buffer();
|
||||||
serializer.writeShortLE(1);
|
serializer.writeShortLE(1);
|
||||||
ArraySerializer.writeVarIntByteArray(serializer, (chunkdata) -> {
|
GeyserUtils.writeVarIntByteArray(serializer, (chunkdata) -> {
|
||||||
PSPEStuff.writeEmptySubChunk(chunkdata);
|
GeyserUtils.writeEmptySubChunk(chunkdata);
|
||||||
chunkdata.writeZero(512);
|
chunkdata.writeZero(512);
|
||||||
chunkdata.writeZero(256);
|
chunkdata.writeZero(256);
|
||||||
chunkdata.writeByte(0);
|
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 ByteBuf CACHED_PALLETE;
|
||||||
|
|
||||||
public static final byte[] EMPTY_CHUNK;
|
//public static final byte[] EMPTY_CHUNK;
|
||||||
|
|
||||||
}
|
}
|
|
@ -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));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue