Merge pull request #2 from GeyserMC/crash-fix

Crash fix
This commit is contained in:
Redned 2019-07-20 17:49:32 -05:00 committed by GitHub
commit 2b72082a6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 13746 additions and 9622 deletions

View file

@ -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() {
} }

View file

@ -29,8 +29,10 @@ import com.nukkitx.protocol.bedrock.BedrockPong;
import com.nukkitx.protocol.bedrock.BedrockServerEventHandler; import com.nukkitx.protocol.bedrock.BedrockServerEventHandler;
import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.BedrockServerSession;
import com.nukkitx.protocol.bedrock.v361.Bedrock_v361; import com.nukkitx.protocol.bedrock.v361.Bedrock_v361;
import org.geysermc.api.Geyser;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.console.GeyserLogger;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -45,13 +47,13 @@ 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;
} }
@Override @Override
public BedrockPong onQuery(InetSocketAddress inetSocketAddress) { public BedrockPong onQuery(InetSocketAddress inetSocketAddress) {
System.out.println(inetSocketAddress + " has pinged you!"); GeyserLogger.DEFAULT.info(inetSocketAddress + " has pinged you!");
GeyserConfiguration config = connector.getConfig(); GeyserConfiguration config = connector.getConfig();
BedrockPong pong = new BedrockPong(); BedrockPong pong = new BedrockPong();
pong.setEdition("MCPE"); pong.setEdition("MCPE");
@ -63,6 +65,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
pong.setNintendoLimited(false); pong.setNintendoLimited(false);
pong.setProtocolVersion(GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()); pong.setProtocolVersion(GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion());
pong.setVersion("1.12.0"); pong.setVersion("1.12.0");
pong.setIpv4Port(19132);
return pong; return pong;
} }
@ -71,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) -> System.out.println("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);
} }

View file

@ -27,6 +27,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;
@ -47,7 +48,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());
} }
} }
} }

View file

@ -26,56 +26,82 @@
package org.geysermc.connector.network.translators; package org.geysermc.connector.network.translators;
import com.flowpowered.math.vector.Vector2f; import com.flowpowered.math.vector.Vector2f;
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.CompoundTagBuilder;
import com.nukkitx.nbt.NbtUtils;
import com.nukkitx.nbt.stream.NBTOutputStream;
import com.nukkitx.nbt.tag.CompoundTag;
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 io.netty.buffer.ByteBuf;
import com.nukkitx.protocol.bedrock.v340.serializer.ResourcePackChunkDataSerializer_v340; import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled;
import org.geysermc.connector.utils.GeyserUtils;
import org.geysermc.connector.utils.Toolbox; import org.geysermc.connector.utils.Toolbox;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
public class TranslatorsInit { public class TranslatorsInit {
private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag();
private static final byte[] EMPTY_LEVEL_CHUNK_DATA;
static {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
outputStream.write(new byte[258]); // Biomes + Border Size + Extra Data Size
try (NBTOutputStream stream = NbtUtils.createNetworkWriter(outputStream)) {
stream.write(EMPTY_TAG);
}
EMPTY_LEVEL_CHUNK_DATA = outputStream.toByteArray();
}catch (IOException e) {
throw new AssertionError("Unable to generate empty level chunk data");
}
}
public static void start() { public static void start() {
addLoginPackets(); addLoginPackets();
} }
private static void addLoginPackets() { private static void addLoginPackets() {
Registry.add(ServerJoinGamePacket.class, (x, y) -> { Registry.add(ServerJoinGamePacket.class, (packet, session) -> {
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket(); AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
bedrockPacket.setUniqueEntityId(x.getEntityId()); bedrockPacket.setUniqueEntityId(packet.getEntityId());
y.getUpstream().sendPacketImmediately(bedrockPacket); session.getUpstream().sendPacketImmediately(bedrockPacket);
System.out.println(y.getUpstream().isClosed());
StartGamePacket startGamePacket = new StartGamePacket(); StartGamePacket startGamePacket = new StartGamePacket();
startGamePacket.setUniqueEntityId(x.getEntityId()); startGamePacket.setUniqueEntityId(packet.getEntityId());
startGamePacket.setRuntimeEntityId(x.getEntityId()); startGamePacket.setRuntimeEntityId(packet.getEntityId());
startGamePacket.setPlayerGamemode(x.getGameMode().ordinal()); startGamePacket.setPlayerGamemode(packet.getGameMode().ordinal());
startGamePacket.setPlayerPosition(new Vector3f(0, 0, 0)); startGamePacket.setPlayerPosition(new Vector3f(0, 0, 0));
startGamePacket.setRotation(new Vector2f(1, 1)); startGamePacket.setRotation(new Vector2f(1, 1));
startGamePacket.setSeed(1111); startGamePacket.setSeed(1111);
startGamePacket.setDimensionId(0); startGamePacket.setDimensionId(0);
startGamePacket.setGeneratorId(0); startGamePacket.setGeneratorId(0);
startGamePacket.setLevelGamemode(x.getGameMode().ordinal()); startGamePacket.setLevelGamemode(packet.getGameMode().ordinal());
startGamePacket.setDifficulty(1); startGamePacket.setDifficulty(1);
startGamePacket.setDefaultSpawn(new Vector3i(0, 0, 0)); startGamePacket.setDefaultSpawn(new Vector3i(0, 0, 0));
startGamePacket.setAcheivementsDisabled(true); startGamePacket.setAcheivementsDisabled(true);
startGamePacket.setTime(1300); startGamePacket.setTime(0);
startGamePacket.setEduLevel(false); startGamePacket.setEduLevel(false);
startGamePacket.setEduFeaturesEnabled(false); startGamePacket.setEduFeaturesEnabled(false);
startGamePacket.setRainLevel(0); startGamePacket.setRainLevel(0);
startGamePacket.setLightningLevel(0); startGamePacket.setLightningLevel(0);
startGamePacket.setMultiplayerGame(false); startGamePacket.setMultiplayerGame(true);
startGamePacket.setBroadcastingToLan(true); startGamePacket.setBroadcastingToLan(true);
startGamePacket.getGamerules().add((new GameRule("showcoordinates", true))); startGamePacket.getGamerules().add(new GameRule<>("showcoordinates", true));
startGamePacket.setPlatformBroadcastMode(GamePublishSetting.FRIENDS_OF_FRIENDS); startGamePacket.setPlatformBroadcastMode(GamePublishSetting.PUBLIC);
startGamePacket.setXblBroadcastMode(GamePublishSetting.FRIENDS_OF_FRIENDS); startGamePacket.setXblBroadcastMode(GamePublishSetting.PUBLIC);
startGamePacket.setCommandsEnabled(true); startGamePacket.setCommandsEnabled(true);
startGamePacket.setTexturePacksRequired(false); startGamePacket.setTexturePacksRequired(false);
startGamePacket.setBonusChestEnabled(false); startGamePacket.setBonusChestEnabled(false);
@ -93,48 +119,61 @@ public class TranslatorsInit {
startGamePacket.setLevelId("oerjhii"); startGamePacket.setLevelId("oerjhii");
startGamePacket.setWorldName("world"); startGamePacket.setWorldName("world");
startGamePacket.setPremiumWorldTemplateId("00000000-0000-0000-0000-000000000000"); startGamePacket.setPremiumWorldTemplateId("00000000-0000-0000-0000-000000000000");
startGamePacket.setCurrentTick(1); startGamePacket.setCurrentTick(0);
startGamePacket.setEnchantmentSeed(1); startGamePacket.setEnchantmentSeed(0);
startGamePacket.setMultiplayerCorrelationId(""); startGamePacket.setMultiplayerCorrelationId("");
startGamePacket.setCachedPalette(Toolbox.CACHED_PALLETE); startGamePacket.setCachedPalette(Toolbox.CACHED_PALLETE);
startGamePacket.setItemEntries(Toolbox.ITEMS);
y.getUpstream().sendPacketImmediately(startGamePacket); session.getUpstream().sendPacket(startGamePacket);
System.out.println(y.getUpstream().isClosed());
Vector3f pos = new Vector3f(0, 0, 0); Vector3f pos = new Vector3f(0, 0, 0);
int chunkX = pos.getFloorX() >> 4; int chunkX = pos.getFloorX() >> 4;
int chunkZ = pos.getFloorX() >> 4; int chunkZ = pos.getFloorZ() >> 4;
for (int x1 = -3; x1 < 3; x1++) { for (int x = -3; x < 3; x++) {
for (int z = -3; z < 3; z++) { for (int z = -3; z < 3; z++) {
LevelChunkPacket data = new LevelChunkPacket(); LevelChunkPacket data = new LevelChunkPacket();
data.setChunkX(chunkX + x);
data.setChunkX(chunkX + x1);
data.setChunkZ(chunkZ + z); data.setChunkZ(chunkZ + z);
data.setSubChunksLength(0);
data.setData(new byte[0]); data.setData(EMPTY_LEVEL_CHUNK_DATA);
y.getUpstream().sendPacketImmediately(data); session.getUpstream().sendPacketImmediately(data);
System.out.println(y.getUpstream().isClosed());
} }
} }
PlayStatusPacket packet = new PlayStatusPacket(); PlayStatusPacket packet1 = new PlayStatusPacket();
packet.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN); packet1.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
y.getUpstream().sendPacket(packet); session.getUpstream().sendPacket(packet1);
System.out.println(y.getUpstream().isClosed());
}); });
} }
private static byte[] empty(byte[] b, Vector2i pos) {
ByteBuf by = Unpooled.buffer();
GeyserUtils.writePEChunkCoord(by, pos);
return by.array();
}
private static class CanWriteToBB extends ByteArrayOutputStream {
CanWriteToBB() {
super(8192);
}
void writeTo(ByteBuf buf) {
buf.writeBytes(super.buf, 0, super.count);
}
}
} }

View file

@ -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;
}
}

View file

@ -1,48 +1,23 @@
/*
* Copyright (c) 2019 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.connector.utils; package org.geysermc.connector.utils;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.nukkitx.network.VarInts; import com.nukkitx.network.VarInts;
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.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class Toolbox { public class Toolbox {
static { static {
InputStream stream = Toolbox.class.getClassLoader().getResourceAsStream("cached_pallete.json"); InputStream stream = Toolbox.class.getClassLoader().getResourceAsStream("cached_pallete.json");
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
List<LinkedHashMap<String, Object>> entries = new ArrayList<>();
ArrayList<LinkedHashMap<String, Object>> entries = new ArrayList<>();
try { try {
entries = mapper.readValue(stream, ArrayList.class); entries = mapper.readValue(stream, ArrayList.class);
@ -51,15 +26,61 @@ public class Toolbox {
} }
ByteBuf b = Unpooled.buffer(); ByteBuf b = Unpooled.buffer();
VarInts.writeInt(b, entries.size());
VarInts.writeUnsignedInt(b, entries.size());
for (Map<String, Object> e : entries) { for (Map<String, Object> e : entries) {
BedrockUtils.writeString(b, (String) e.get("name")); BedrockUtils.writeString(b, (String) e.get("name"));
b.writeShortLE((Integer) e.get("data")); b.writeShortLE((int) e.get("data"));
b.writeShortLE((int) e.get("id"));
} }
CACHED_PALLETE = b; CACHED_PALLETE = b;
InputStream stream2 = Toolbox.class.getClassLoader().getResourceAsStream("items.json");
if (stream2 == null) {
throw new AssertionError("Items Table not found");
}
ObjectMapper mapper2 = new ObjectMapper();
ArrayList<HashMap> s = new ArrayList<>();
try {
s = mapper2.readValue(stream2, ArrayList.class);
} catch (Exception e) {
e.printStackTrace();
}
ArrayList<StartGamePacket.ItemEntry> l = new ArrayList<>();
for(HashMap e : s) {
l.add(new StartGamePacket.ItemEntry((String) e.get("name"), (short) ((int) e.get("id"))));
}
ITEMS = l;
/*ByteBuf serializer;
serializer = Unpooled.buffer();
serializer.writeShortLE(1);
GeyserUtils.writeVarIntByteArray(serializer, (chunkdata) -> {
GeyserUtils.writeEmptySubChunk(chunkdata);
chunkdata.writeZero(512);
chunkdata.writeZero(256);
chunkdata.writeByte(0);
});
EMPTY_CHUNK = GeyserUtils.readAllBytes(serializer);*/
} }
public static final Collection<StartGamePacket.ItemEntry> ITEMS;
public static final ByteBuf CACHED_PALLETE; public static final ByteBuf CACHED_PALLETE;
//public static final byte[] EMPTY_CHUNK;
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff