From f6d7976eff7f95ce7c98e56b3fa681f5e3edbfc9 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Thu, 17 Jan 2019 14:49:08 -0200 Subject: [PATCH] Use old ids and byte[] + NibbleArray for block connections --- .../api/minecraft/chunks/NibbleArray.java | 7 ++- .../packets/WorldPackets.java | 5 +- .../storage/BlockConnectionStorage.java | 58 +++++++++++++++---- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java index 8245d2a8c..4cfeddccc 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java @@ -67,11 +67,12 @@ public class NibbleArray { * @param value The desired value */ public void set(int index, int value) { - index /= 2; if (index % 2 == 0) { - handle[index] = (byte) (handle[index] & 0xF0 | value & 0xF); + index /= 2; + handle[index] = (byte) ((handle[index] & 0xF0) | (value & 0xF)); } else { - handle[index] = (byte) (handle[index] & 0xF | (value & 0xF) << 4); + index /= 2; + handle[index] = (byte) ((handle[index] & 0xF) | ((value & 0xF) << 4)); } } 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 0c932eaf6..18aea5bab 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 @@ -175,12 +175,13 @@ public class WorldPackets { if (Via.getConfig().isServersideBlockConnections()) { UserConnection userConnection = wrapper.user(); + + ConnectionData.updateBlockStorage(userConnection, position, newId); + if (ConnectionData.connects(newId)) { newId = ConnectionData.connect(userConnection, position, newId); } - ConnectionData.updateBlockStorage(userConnection, position, newId); - ConnectionData.update(userConnection, position); } 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 b7e5c5da6..1694e2af9 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 @@ -1,9 +1,13 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage; +import us.myles.ViaVersion.api.Pair; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.StoredObject; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.minecraft.Position; +import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -11,9 +15,10 @@ import java.util.HashMap; import java.util.Map; public class BlockConnectionStorage extends StoredObject { - private Map blockStorage = createLongObjectMap(); + private Map> blockStorage = createLongObjectMap(); private static Constructor fastUtilLongObjectHashMap; + private static HashMap reverseBlockMappings; static { try { @@ -21,6 +26,11 @@ public class BlockConnectionStorage extends StoredObject { Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections"); } catch (ClassNotFoundException | NoSuchMethodException ignored) { } + reverseBlockMappings = new HashMap<>(); + for (int i = 0; i < 4096; i++) { + int newBlock = MappingData.blockMappings.getNewBlock(i); + if (newBlock != -1) reverseBlockMappings.put((short) newBlock, (short) i); + } } public BlockConnectionStorage(UserConnection user) { @@ -28,25 +38,48 @@ public class BlockConnectionStorage extends StoredObject { } public void store(Position position, int blockState) { + Short mapping = reverseBlockMappings.get((short) blockState); + if (mapping == null) return; + blockState = mapping; long pair = getChunkSectionIndex(position); - short[] map = getChunkSection(pair); - map[encodeBlockPos(position)] = (short) blockState; + Pair map = getChunkSection(pair, (blockState & 0xF) != 0); + int blockIndex = encodeBlockPos(position); + map.getKey()[blockIndex] = (byte) (blockState >> 4); + NibbleArray nibbleArray = map.getValue(); + if (nibbleArray != null) nibbleArray.set(blockIndex, blockState); } public int get(Position position) { long pair = getChunkSectionIndex(position); - short[] map = blockStorage.get(pair); + Pair map = blockStorage.get(pair); if (map == null) return 0; short blockPosition = encodeBlockPos(position); - return map[blockPosition]; + NibbleArray nibbleArray = map.getValue(); + return WorldPackets.toNewId( + ((map.getKey()[blockPosition] & 0xFF) << 4) + | (nibbleArray == null ? 0 : nibbleArray.get(blockPosition)) + ); } public void remove(Position position) { long pair = getChunkSectionIndex(position); - short[] map = blockStorage.get(pair); + Pair map = blockStorage.get(pair); if (map == null) return; - map[encodeBlockPos(position)] = 0; - for (short entry : map) { + int blockIndex = encodeBlockPos(position); + NibbleArray nibbleArray = map.getValue(); + if (nibbleArray != null) { + nibbleArray.set(blockIndex, 0); + boolean allZero = true; + for (int i = 0; i < 4096; i++) { + if (nibbleArray.get(i) != 0) { + allZero = false; + break; + } + } + if (allZero) map.setValue(null); + } + map.getKey()[blockIndex] = 0; + for (short entry : map.getKey()) { if (entry != 0) return; } blockStorage.remove(pair); @@ -62,12 +95,15 @@ public class BlockConnectionStorage extends StoredObject { } } - private short[] getChunkSection(long index) { - short[] map = blockStorage.get(index); + private Pair getChunkSection(long index, boolean requireNibbleArray) { + Pair map = blockStorage.get(index); if (map == null) { - map = new short[4096]; + map = new Pair<>(new byte[4096], null); blockStorage.put(index, map); } + if (map.getValue() == null && requireNibbleArray) { + map.setValue(new NibbleArray(4096)); + } return map; }