diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeDecodeHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeDecodeHandler.java index 898df7d11..20d862992 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeDecodeHandler.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeDecodeHandler.java @@ -56,7 +56,7 @@ public class BungeeDecodeHandler extends MessageToMessageDecoder { bytebuf.clear(); bytebuf = newPacket; - } catch (Exception e) { + } catch (Throwable e) { // Clear Buffer bytebuf.clear(); // Release Packet, be free! diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeEncodeHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeEncodeHandler.java index fc39eebdd..34ffb2667 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeEncodeHandler.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeEncodeHandler.java @@ -60,7 +60,7 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder { ProtocolInfo protInfo = info.get(ProtocolInfo.class); protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper); wrapper.writeToBuffer(bytebuf); - } catch (Exception e) { + } catch (Throwable e) { bytebuf.clear(); throw e; } finally { diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockFace.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockFace.java index b63ea78b8..a17129550 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockFace.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/BlockFace.java @@ -9,7 +9,12 @@ import java.util.Map; @Getter @AllArgsConstructor public enum BlockFace { - NORTH(0, 0, -1, EnumAxis.Z), SOUTH(0, 0, 1, EnumAxis.Z), EAST(1, 0, 0, EnumAxis.X), WEST(-1, 0, 0, EnumAxis.X), TOP(0, 1, 0, EnumAxis.Y), BOTTOM(0, -1, 0, EnumAxis.Y); + NORTH(0, 0, -1, EnumAxis.Z), + SOUTH(0, 0, 1, EnumAxis.Z), + EAST(1, 0, 0, EnumAxis.X), + WEST(-1, 0, 0, EnumAxis.X), + TOP(0, 1, 0, EnumAxis.Y), + BOTTOM(0, -1, 0, EnumAxis.Y); private static Map opposites = new HashMap<>(); diff --git a/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java index 3ca1d4745..f66c43693 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java +++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java @@ -4,6 +4,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Pair; +import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.platform.providers.ViaProviders; import us.myles.ViaVersion.api.remapper.PacketRemapper; @@ -14,6 +15,7 @@ import us.myles.ViaVersion.packets.State; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Level; public abstract class Protocol { private final Map, ProtocolPacket> incoming = new HashMap<>(); @@ -104,7 +106,10 @@ public abstract class Protocol { public void registerIncoming(State state, int oldPacketID, int newPacketID, PacketRemapper packetRemapper, boolean override) { ProtocolPacket protocolPacket = new ProtocolPacket(state, oldPacketID, newPacketID, packetRemapper); Pair pair = new Pair<>(state, newPacketID); - if (!override && incoming.containsKey(pair)) throw new IllegalArgumentException(pair + " already registered"); + if (!override && incoming.containsKey(pair)) { + Via.getPlatform().getLogger().log(Level.WARNING, pair + " already registered!" + + " If this override is intentional, set override to true. Stacktrace: ", new Exception()); + } incoming.put(pair, protocolPacket); } @@ -134,7 +139,10 @@ public abstract class Protocol { public void registerOutgoing(State state, int oldPacketID, int newPacketID, PacketRemapper packetRemapper, boolean override) { ProtocolPacket protocolPacket = new ProtocolPacket(state, oldPacketID, newPacketID, packetRemapper); Pair pair = new Pair<>(state, oldPacketID); - if (!override && outgoing.containsKey(pair)) throw new IllegalArgumentException(pair + " already registered"); + if (!override && outgoing.containsKey(pair)) { + Via.getPlatform().getLogger().log(Level.WARNING, pair + " already registered!" + + " If override is intentional, set override to true. Stacktrace: ", new Exception()); + } outgoing.put(pair, protocolPacket); } diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java index 2cc3f478b..7a496f670 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_8.java @@ -4,9 +4,7 @@ import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; -import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.nio.ShortBuffer; public class ChunkSectionType1_8 extends Type { @@ -19,12 +17,10 @@ public class ChunkSectionType1_8 extends Type { ChunkSection chunkSection = new ChunkSection(); chunkSection.clearPalette(); - byte[] blockData = new byte[ChunkSection.SIZE * 2]; - buffer.readBytes(blockData); - ShortBuffer blockBuf = ByteBuffer.wrap(blockData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); + ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN); for (int i = 0; i < ChunkSection.SIZE; i++) { - int mask = blockBuf.get(); + int mask = littleEndianView.readShort(); int type = mask >> 4; int data = mask & 0xF; chunkSection.setBlock(i, type, data); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java index 1e40bfdbc..96ba56e37 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java @@ -135,9 +135,9 @@ public class Protocol1_12To1_11_1 extends Protocol { if (section == null) continue; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { int block = section.getBlockId(x, y, z); // Is this a bed? if (block == 26) { diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java index aa2e7cc1b..62da996c7 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java @@ -6,6 +6,7 @@ import com.google.gson.JsonObject; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; import us.myles.ViaVersion.api.minecraft.BlockFace; import us.myles.ViaVersion.api.minecraft.Position; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; @@ -27,29 +28,111 @@ public class ConnectionData { static Set occludingStates = new HashSet<>(); public static void update(UserConnection user, Position position) { - for (int x = -1; x <= 1; x++) { - for (int z = -1; z <= 1; z++) { - for (int y = -1; y <= 1; y++) { - if (Math.abs(x) + Math.abs(y) + Math.abs(z) != 1) continue; - Position pos = new Position(position.getX() + x, position.getY() + y, position.getZ() + z); - int blockState = Via.getManager().getProviders().get(BlockConnectionProvider.class).getBlockdata(user, pos); - if (!connects(blockState)) continue; - int newBlockState = connect(user, pos, blockState); - if (newBlockState == blockState) continue; + for (BlockFace face : BlockFace.values()) { + Position pos = new Position( + position.getX() + face.getModX(), + position.getY() + face.getModY(), + position.getZ() + face.getModZ() + ); + int blockState = Via.getManager().getProviders().get(BlockConnectionProvider.class).getBlockdata(user, pos); + if (!connects(blockState)) continue; + int newBlockState = connect(user, pos, blockState); - PacketWrapper blockUpdatePacket = new PacketWrapper(0x0B, null, user); - blockUpdatePacket.write(Type.POSITION, pos); - blockUpdatePacket.write(Type.VAR_INT, newBlockState); + PacketWrapper blockUpdatePacket = new PacketWrapper(0x0B, null, user); + blockUpdatePacket.write(Type.POSITION, pos); + blockUpdatePacket.write(Type.VAR_INT, newBlockState); + try { + blockUpdatePacket.send(Protocol1_13To1_12_2.class, true, false); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + public static void updateChunkSectionNeighbours(UserConnection user, int chunkX, int chunkZ, int chunkSectionY) { + for (int chunkDeltaX = -1; chunkDeltaX <= 1; chunkDeltaX++) { + for (int chunkDeltaZ = -1; chunkDeltaZ <= 1; chunkDeltaZ++) { + if (Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ) == 0) continue; + + ArrayList updates = new ArrayList<>(); + + if (Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ) == 2) { // Corner + for (int blockY = chunkSectionY * 16; blockY < chunkSectionY * 16 + 16; blockY++) { + int blockPosX = chunkDeltaX == 1 ? 0 : 15; + int blockPosZ = chunkDeltaZ == 1 ? 0 : 15; + updateBlock(user, + new Position( + (long) ((chunkX + chunkDeltaX) << 4) + blockPosX, + (long) blockY, + (long) ((chunkZ + chunkDeltaZ) << 4) + blockPosZ + ), + updates + ); + } + } else { + for (int blockY = chunkSectionY * 16; blockY < chunkSectionY * 16 + 16; blockY++) { + int xStart; + int xEnd; + int zStart; + int zEnd; + if (chunkDeltaX == 1) { + xStart = 0; + xEnd = 2; + zStart = 0; + zEnd = 16; + } else if (chunkDeltaX == -1) { + xStart = 14; + xEnd = 16; + zStart = 0; + zEnd = 16; + } else if (chunkDeltaZ == 1) { + xStart = 0; + xEnd = 16; + zStart = 0; + zEnd = 2; + } else { + xStart = 0; + xEnd = 16; + zStart = 14; + zEnd = 16; + } + for (int blockX = xStart; blockX < xEnd; blockX++) { + for (int blockZ = zStart; blockZ < zEnd; blockZ++) { + updateBlock(user, + new Position( + (long) ((chunkX + chunkDeltaX) << 4) + blockX, + (long) blockY, + (long) ((chunkZ + chunkDeltaZ) << 4) + blockZ), + updates + ); + } + } + } + } + + if (!updates.isEmpty()) { + PacketWrapper wrapper = new PacketWrapper(0x0F, null, user); + wrapper.write(Type.INT, chunkX + chunkDeltaX); + wrapper.write(Type.INT, chunkZ + chunkDeltaZ); + wrapper.write(Type.BLOCK_CHANGE_RECORD_ARRAY, updates.toArray(new BlockChangeRecord[0])); try { - blockUpdatePacket.send(Protocol1_13To1_12_2.class, true, false); - } catch (Exception ex) { - ex.printStackTrace(); + wrapper.send(Protocol1_13To1_12_2.class); + } catch (Exception e) { + e.printStackTrace(); } } } } } + public static void updateBlock(UserConnection user, Position pos, List records) { + int blockState = Via.getManager().getProviders().get(BlockConnectionProvider.class).getBlockdata(user, pos); + if (!connects(blockState)) return; + int newBlockState = connect(user, pos, blockState); + + records.add(new BlockChangeRecord((short) (((pos.getX() & 0xF) << 4) | (pos.getZ() & 0xF)), pos.getY().shortValue(), newBlockState)); + } + public static BlockConnectionProvider getProvider() { return Via.getManager().getProviders().get(BlockConnectionProvider.class); } @@ -93,29 +176,19 @@ public class ConnectionData { long yOff = i << 4; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { int block = section.getFlatBlock(x, y, z); if (ConnectionData.connects(block)) { block = ConnectionData.connect(user, new Position(xOff + x, yOff + y, zOff + z), block); section.setFlatBlock(x, y, z, block); } - - if (x == 0) { - update(user, new Position(xOff - 1, yOff + y, zOff + z)); - } else if (x == 15) { - update(user, new Position(xOff + 16, yOff + y, zOff + z)); - } - if (z == 0) { - update(user, new Position(xOff + x, yOff + y, zOff - 1)); - } else if (z == 15) { - update(user, new Position(xOff + x, yOff + y, zOff + 16)); - } } } } + updateChunkSectionNeighbours(user, chunk.getX(), chunk.getZ(), i); } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index 5593028f0..63bbe1613 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java @@ -292,21 +292,36 @@ public class WorldPackets { if (section == null) continue; - boolean willStoreAnyBlock = false; - for (int p = 0; p < section.getPaletteSize(); p++) { int old = section.getPaletteEntry(p); int newId = toNewId(old); - if (storage.isWelcome(newId) || (Via.getConfig().isServersideBlockConnections() && ConnectionData.needStoreBlocks() && ConnectionData.isWelcome(newId))) { - willStoreAnyBlock = true; - } section.setPaletteEntry(p, newId); } - if (willStoreAnyBlock) { - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { + boolean willSaveToStorage = false; + for (int p = 0; p < section.getPaletteSize(); p++) { + int newId = section.getPaletteEntry(p); + if (storage.isWelcome(newId)) { + willSaveToStorage = true; + break; + } + } + + boolean willSaveConnection = false; + if (ConnectionData.needStoreBlocks() && Via.getConfig().isServersideBlockConnections()) { + for (int p = 0; p < section.getPaletteSize(); p++) { + int newId = section.getPaletteEntry(p); + if (ConnectionData.isWelcome(newId)) { + willSaveConnection = true; + break; + } + } + } + + if (willSaveToStorage) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { int block = section.getFlatBlock(x, y, z); if (storage.isWelcome(block)) { storage.store(new Position( @@ -315,7 +330,17 @@ public class WorldPackets { (long) (z + (chunk.getZ() << 4)) ), block); } - if (Via.getConfig().isServersideBlockConnections() && ConnectionData.isWelcome(block)) { + } + } + } + } + + if (willSaveConnection) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + int block = section.getFlatBlock(x, y, z); + if (ConnectionData.isWelcome(block)) { ConnectionData.getProvider().storeBlock(wrapper.user(), (long) (x + (chunk.getX() << 4)), (long) (y + (i << 4)), (long) (z + (chunk.getZ() << 4)), diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BannerHandler.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BannerHandler.java index c321f409f..7e071d31a 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BannerHandler.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BannerHandler.java @@ -29,7 +29,11 @@ public class BannerHandler implements BlockEntityProvider.BlockEntityHandler { int blockId = storage.get(position).getOriginal(); - int color = (int) tag.get("Base").getValue(); + Tag base = tag.get("Base"); + int color = 0; + if (base != null) { + color = ((Number) tag.get("Base").getValue()).intValue(); + } // Standing banner if (blockId >= BANNER_START && blockId <= BANNER_STOP) { blockId += ((15 - color) * 16); @@ -43,8 +47,10 @@ public class BannerHandler implements BlockEntityProvider.BlockEntityHandler { if (tag.get("Patterns") instanceof ListTag) { for (Tag pattern : (ListTag) tag.get("Patterns")) { if (pattern instanceof CompoundTag) { - IntTag c = ((CompoundTag) pattern).get("Color"); - c.setValue(15 - c.getValue()); // Invert color id + Tag c = ((CompoundTag) pattern).get("Color"); + if (c instanceof IntTag) { + ((IntTag)c).setValue(15 - (int) c.getValue()); // Invert color id + } } } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BedHandler.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BedHandler.java index f676a4c9a..3558a9fed 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BedHandler.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/BedHandler.java @@ -23,8 +23,10 @@ public class BedHandler implements BlockEntityProvider.BlockEntityHandler { // RED_BED + FIRST_BED int blockId = storage.get(position).getOriginal() - 972 + 748; - int color = (int) tag.get("color").getValue(); - blockId += (color * 16); + Tag color = tag.get("color"); + if (color != null) { + blockId += (((Number) color.getValue()).intValue() * 16); + } return blockId; } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/SkullHandler.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/SkullHandler.java index 90b0b745b..5198ba9cf 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/SkullHandler.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/providers/blockentities/SkullHandler.java @@ -25,9 +25,12 @@ public class SkullHandler implements BlockEntityProvider.BlockEntityHandler { int id = storage.get(position).getOriginal(); if (id >= SKULL_WALL_START && id <= SKULL_END) { - id += (byte) tag.get("SkullType").getValue() * 20; + Tag skullType = tag.get("SkullType"); + if (skullType != null) { + id += ((Number) tag.get("SkullType").getValue()).intValue() * 20; + } if (tag.contains("Rot")) { - id += (byte) tag.get("Rot").getValue(); + id += ((Number) tag.get("Rot").getValue()).intValue(); } } else { Via.getPlatform().getLogger().warning("Why does this block have the skull block entity? " + tag); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index 1694e2af9..176e66563 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -91,7 +91,7 @@ public class BlockConnectionStorage extends StoredObject { public void unloadChunk(int x, int z) { for (int y = 0; y < 256; y += 16) { - blockStorage.remove(getChunkSectionIndex(x, y, z)); + blockStorage.remove(getChunkSectionIndex(x << 4, y, z << 4)); } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3TO1_9_1_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3TO1_9_1_2.java index 2069f1fb1..62bcf0306 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3TO1_9_1_2.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3TO1_9_1_2.java @@ -85,9 +85,9 @@ public class Protocol1_9_3TO1_9_1_2 extends Protocol { if (section == null) continue; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { int block = section.getBlockId(x, y, z); if (FakeTileEntity.hasBlock(block)) { tags.add(FakeTileEntity.getFromBlock(x + (chunk.getX() << 4), y + (i << 4), z + (chunk.getZ() << 4), block)); diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeDecodeHandler.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeDecodeHandler.java index 8ee2180db..cd7f10370 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeDecodeHandler.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeDecodeHandler.java @@ -57,7 +57,7 @@ public class SpongeDecodeHandler extends ByteToMessageDecoder { bytebuf.clear(); bytebuf = newPacket; - } catch (Exception e) { + } catch (Throwable e) { // Clear Buffer bytebuf.clear(); // Release Packet, be free! diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeEncodeHandler.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeEncodeHandler.java index 8f12b42a4..5db88d64a 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeEncodeHandler.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/handlers/SpongeEncodeHandler.java @@ -53,7 +53,7 @@ public class SpongeEncodeHandler extends MessageToByteEncoder { ProtocolInfo protInfo = info.get(ProtocolInfo.class); protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper); wrapper.writeToBuffer(bytebuf); - } catch (Exception e) { + } catch (Throwable e) { bytebuf.clear(); throw e; } finally { diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java index 23dbd77fd..1b4baa8d4 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java @@ -53,7 +53,7 @@ public class VelocityDecodeHandler extends MessageToMessageDecoder { bytebuf.clear(); bytebuf = newPacket; - } catch (Exception e) { + } catch (Throwable e) { // Clear Buffer bytebuf.clear(); // Release Packet, be free! diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java index 1a929c2e8..b671159c5 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java @@ -65,7 +65,7 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder { bytebuf.clear(); bytebuf.release(); bytebuf = newPacket; - } catch (Exception e) { + } catch (Throwable e) { bytebuf.clear(); bytebuf.release(); newPacket.release(); diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java index daa63940d..64c7c4f6e 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java @@ -4,11 +4,25 @@ import io.netty.channel.ChannelInitializer; import us.myles.ViaVersion.VelocityPlugin; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.platform.ViaInjector; +import us.myles.ViaVersion.api.protocol.ProtocolVersion; import us.myles.ViaVersion.util.ReflectionUtil; import us.myles.ViaVersion.velocity.handlers.VelocityChannelInitializer; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + public class VelocityViaInjector implements ViaInjector { + public static Method getPlayerInfoForwardingMode; + + static { + try { + getPlayerInfoForwardingMode = Class.forName("com.velocitypowered.proxy.config.VelocityConfiguration").getMethod("getPlayerInfoForwardingMode"); + } catch (NoSuchMethodException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + @Override public void inject() throws Exception { Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class); @@ -30,6 +44,12 @@ public class VelocityViaInjector implements ViaInjector { } public static int getLowestSupportedProtocolVersion() { + try { + if (getPlayerInfoForwardingMode != null + && ((Enum) getPlayerInfoForwardingMode.invoke(VelocityPlugin.PROXY.getConfiguration())) + .name().equals("MODERN")) return ProtocolVersion.v1_13.getId(); + } catch (IllegalAccessException | InvocationTargetException ignored) { + } return com.velocitypowered.api.network.ProtocolVersion.MINIMUM_VERSION.getProtocol(); } diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java index 04939df8b..7f7f786c9 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java @@ -1,6 +1,6 @@ package us.myles.ViaVersion.velocity.providers; -import com.google.common.collect.Lists; +import us.myles.ViaVersion.VelocityPlugin; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.protocol.ProtocolVersion; @@ -8,32 +8,41 @@ import us.myles.ViaVersion.protocols.base.ProtocolInfo; import us.myles.ViaVersion.protocols.base.VersionProvider; import us.myles.ViaVersion.velocity.platform.VelocityViaInjector; -import java.util.*; -import java.util.stream.Collectors; +import java.util.Arrays; +import java.util.stream.IntStream; public class VelocityVersionProvider extends VersionProvider { - private static final List VELOCITY_PROTOCOLS = com.velocitypowered.api.network.ProtocolVersion.SUPPORTED_VERSIONS.stream() - .map(com.velocitypowered.api.network.ProtocolVersion::getProtocol) - .collect(Collectors.toList()); @Override public int getServerProtocol(UserConnection user) throws Exception { int playerVersion = user.get(ProtocolInfo.class).getProtocolVersion(); + IntStream versions = com.velocitypowered.api.network.ProtocolVersion.SUPPORTED_VERSIONS.stream() + .mapToInt(com.velocitypowered.api.network.ProtocolVersion::getProtocol); + + // Modern forwarding mode needs 1.13 Login plugin message + if (VelocityViaInjector.getPlayerInfoForwardingMode != null + && ((Enum) VelocityViaInjector.getPlayerInfoForwardingMode.invoke(VelocityPlugin.PROXY.getConfiguration())) + .name().equals("MODERN")) { + versions = versions.filter(ver -> ver >= ProtocolVersion.v1_13.getId()); + } + int[] compatibleProtocols = versions.toArray(); + // Bungee supports it - if (Collections.binarySearch(VELOCITY_PROTOCOLS, playerVersion) >= 0) + if (Arrays.binarySearch(compatibleProtocols, playerVersion) >= 0) return playerVersion; // Older than bungee supports, get the lowest version - if (playerVersion < VELOCITY_PROTOCOLS.get(0)) { - return VelocityViaInjector.getLowestSupportedProtocolVersion(); + if (playerVersion < compatibleProtocols[0]) { + return compatibleProtocols[0]; } // Loop through all protocols to get the closest protocol id that bungee supports (and that viaversion does too) // TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work. // This is more of a workaround for snapshot support by bungee. - for (Integer protocol : Lists.reverse(VELOCITY_PROTOCOLS)) { + for (int i = compatibleProtocols.length - 1; i >= 0; i--) { + int protocol = compatibleProtocols[i]; if (playerVersion > protocol && ProtocolVersion.isRegistered(protocol)) return protocol; }