From dc12f26f05bf8d4a46323e770a866c3a95ad2963 Mon Sep 17 00:00:00 2001 From: KennyTV <28825609+KennyTV@users.noreply.github.com> Date: Sun, 9 Jun 2019 11:11:33 +0200 Subject: [PATCH] Let there be light --- .../Protocol1_13_2To1_14.java | 62 ++++++++++++-- .../packets/BlockItemPackets1_14.java | 63 ++++++++++----- .../storage/ChunkLightStorage.java | 80 +++++++++++++++++++ 3 files changed, 179 insertions(+), 26 deletions(-) create mode 100644 core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/storage/ChunkLightStorage.java diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/Protocol1_13_2To1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/Protocol1_13_2To1_14.java index 853205b8..5a7bca83 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/Protocol1_13_2To1_14.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/Protocol1_13_2To1_14.java @@ -10,13 +10,13 @@ import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets.BlockItemPack import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets.EntityPackets1_14; import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets.PlayerPackets1_14; import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets.SoundPackets1_14; +import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.storage.ChunkLightStorage; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; -import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; @Getter @@ -49,7 +49,6 @@ public class Protocol1_13_2To1_14 extends BackwardsProtocol { registerOutgoing(State.PLAY, 0x1B, 0x1C); registerOutgoing(State.PLAY, 0x54, 0x1D); registerOutgoing(State.PLAY, 0x1C, 0x1E); - registerOutgoing(State.PLAY, 0x1D, 0x1F); registerOutgoing(State.PLAY, 0x1E, 0x20); registerOutgoing(State.PLAY, 0x20, 0x21); @@ -212,15 +211,65 @@ public class Protocol1_13_2To1_14 extends BackwardsProtocol { public void registerMap() { handler(new PacketHandler() { @Override - public void handle(PacketWrapper packetWrapper) throws Exception { - packetWrapper.cancel(); // todo + public void handle(PacketWrapper wrapper) throws Exception { + int x = wrapper.read(Type.VAR_INT); + int z = wrapper.read(Type.VAR_INT); + int skyLightMask = wrapper.read(Type.VAR_INT); + int blockLightMask = wrapper.read(Type.VAR_INT); + int emptySkyLightMask = wrapper.read(Type.VAR_INT); + int emptyBlockLightMask = wrapper.read(Type.VAR_INT); + + byte[][] skyLight = new byte[16][]; + // we don't need void and +256 light + if (isSet(skyLightMask, 0)) { + wrapper.read(Type.BYTE_ARRAY); + } + for (int i = 0; i < 16; i++) { + if (isSet(skyLightMask, i + 1)) { + Byte[] array = wrapper.read(Type.BYTE_ARRAY); + skyLight[i] = new byte[array.length]; + for (int j = 0; j < array.length; j++) { + skyLight[i][j] = array[j]; + } + } else if (isSet(emptySkyLightMask, i + 1)) { + skyLight[i] = ChunkLightStorage.EMPTY_LIGHT; + } + } + if (isSet(skyLightMask, 17)) { + wrapper.read(Type.BYTE_ARRAY); + } + + byte[][] blockLight = new byte[18][]; + if (isSet(blockLightMask, 0)) { + wrapper.read(Type.BYTE_ARRAY); + } + for (int i = 0; i < 16; i++) { + if (isSet(blockLightMask, i + 1)) { + Byte[] array = wrapper.read(Type.BYTE_ARRAY); + blockLight[i] = new byte[array.length]; + for (int j = 0; j < array.length; j++) { + blockLight[i][j] = array[j]; + } + } else if (isSet(emptyBlockLightMask, i + 1)) { + blockLight[i] = ChunkLightStorage.EMPTY_LIGHT; + } + } + if (isSet(skyLightMask, 17)) { + wrapper.read(Type.BYTE_ARRAY); + } + + wrapper.user().get(ChunkLightStorage.class).setStoredLight(skyLight, blockLight, x, z); + wrapper.cancel(); + } + + private boolean isSet(int mask, int i) { + return (mask & (1 << i)) != 0; } }); } }); - //Incomming //Unknown packet added in 19w11a - 0x02 @@ -298,5 +347,8 @@ public class Protocol1_13_2To1_14 extends BackwardsProtocol { // Init protocol in EntityTracker user.get(EntityTracker.class).initProtocol(this); + + if (!user.has(ChunkLightStorage.class)) + user.put(new ChunkLightStorage(user)); } } diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/BlockItemPackets1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/BlockItemPackets1_14.java index a11b1fbd..6cfca5c5 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/BlockItemPackets1_14.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/BlockItemPackets1_14.java @@ -7,6 +7,7 @@ import nl.matsv.viabackwards.api.entities.types.AbstractEntityType; import nl.matsv.viabackwards.api.entities.types.EntityType1_14; import nl.matsv.viabackwards.api.rewriters.BlockItemRewriter; import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14; +import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.storage.ChunkLightStorage; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.minecraft.BlockChangeRecord; import us.myles.ViaVersion.api.minecraft.Environment; @@ -18,7 +19,6 @@ import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13_2; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.type.Type; -import us.myles.ViaVersion.api.type.types.StringType; import us.myles.ViaVersion.api.type.types.version.Types1_13; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter; @@ -34,19 +34,12 @@ import us.myles.viaversion.libs.opennbt.tag.builtin.StringTag; import us.myles.viaversion.libs.opennbt.tag.builtin.Tag; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Set; public class BlockItemPackets1_14 extends BlockItemRewriter { private static String NBT_TAG_NAME = "ViaBackwards|" + Protocol1_13_2To1_14.class.getSimpleName(); - private static byte[] fullLight = new byte[2048]; - - static { - Arrays.fill(fullLight, (byte) 0xFF); - } - @Override protected void registerPackets(Protocol1_13_2To1_14 protocol) { // Open window @@ -63,7 +56,7 @@ public class BlockItemPackets1_14 extends BlockItemRewriter fastUtilLongObjectHashMap; + + private final Map storedLight = createLongObjectMap(); + + static { + Arrays.fill(FULL_LIGHT, (byte) 0xFF); + Arrays.fill(EMPTY_LIGHT, (byte) 0x0); + try { + fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap").getConstructor(); + } catch (ClassNotFoundException | NoSuchMethodException ignored) { + } + } + + public ChunkLightStorage(UserConnection user) { + super(user); + } + + public void setStoredLight(byte[][] skyLight, byte[][] blockLight, int x, int z) { + storedLight.put(getChunkSectionIndex(x, z), new ChunkLight(skyLight, blockLight)); + } + + public ChunkLight getStoredLight(int x, int z) { + return storedLight.get(getChunkSectionIndex(x, z)); + } + + public void clear() { + storedLight.clear(); + } + + public void unloadChunk(int x, int z) { + storedLight.remove(getChunkSectionIndex(x, z)); + } + + private long getChunkSectionIndex(int x, int z) { + return ((x & 0x3FFFFFFL) << 38) | (z & 0x3FFFFFFL); + } + + private Map createLongObjectMap() { + if (fastUtilLongObjectHashMap != null) { + try { + return (Map) fastUtilLongObjectHashMap.newInstance(); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { + e.printStackTrace(); + } + } + return new HashMap<>(); + } + + public static class ChunkLight { + private final byte[][] skyLight; + private final byte[][] blockLight; + + public ChunkLight(byte[][] skyLight, byte[][] blockLight) { + this.skyLight = skyLight; + this.blockLight = blockLight; + } + + public byte[][] getSkyLight() { + return skyLight; + } + + public byte[][] getBlockLight() { + return blockLight; + } + } +}