Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-03 14:50:30 +01:00
Use old ids and byte[] + NibbleArray for block connections
Dieser Commit ist enthalten in:
Ursprung
f45a727396
Commit
f6d7976eff
@ -67,11 +67,12 @@ public class NibbleArray {
|
|||||||
* @param value The desired value
|
* @param value The desired value
|
||||||
*/
|
*/
|
||||||
public void set(int index, int value) {
|
public void set(int index, int value) {
|
||||||
index /= 2;
|
|
||||||
if (index % 2 == 0) {
|
if (index % 2 == 0) {
|
||||||
handle[index] = (byte) (handle[index] & 0xF0 | value & 0xF);
|
index /= 2;
|
||||||
|
handle[index] = (byte) ((handle[index] & 0xF0) | (value & 0xF));
|
||||||
} else {
|
} else {
|
||||||
handle[index] = (byte) (handle[index] & 0xF | (value & 0xF) << 4);
|
index /= 2;
|
||||||
|
handle[index] = (byte) ((handle[index] & 0xF) | ((value & 0xF) << 4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,12 +175,13 @@ public class WorldPackets {
|
|||||||
|
|
||||||
if (Via.getConfig().isServersideBlockConnections()) {
|
if (Via.getConfig().isServersideBlockConnections()) {
|
||||||
UserConnection userConnection = wrapper.user();
|
UserConnection userConnection = wrapper.user();
|
||||||
|
|
||||||
|
ConnectionData.updateBlockStorage(userConnection, position, newId);
|
||||||
|
|
||||||
if (ConnectionData.connects(newId)) {
|
if (ConnectionData.connects(newId)) {
|
||||||
newId = ConnectionData.connect(userConnection, position, newId);
|
newId = ConnectionData.connect(userConnection, position, newId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionData.updateBlockStorage(userConnection, position, newId);
|
|
||||||
|
|
||||||
ConnectionData.update(userConnection, position);
|
ConnectionData.update(userConnection, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage;
|
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.Via;
|
||||||
import us.myles.ViaVersion.api.data.StoredObject;
|
import us.myles.ViaVersion.api.data.StoredObject;
|
||||||
import us.myles.ViaVersion.api.data.UserConnection;
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
import us.myles.ViaVersion.api.minecraft.Position;
|
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.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@ -11,9 +15,10 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class BlockConnectionStorage extends StoredObject {
|
public class BlockConnectionStorage extends StoredObject {
|
||||||
private Map<Long, short[]> blockStorage = createLongObjectMap();
|
private Map<Long, Pair<byte[], NibbleArray>> blockStorage = createLongObjectMap();
|
||||||
|
|
||||||
private static Constructor<?> fastUtilLongObjectHashMap;
|
private static Constructor<?> fastUtilLongObjectHashMap;
|
||||||
|
private static HashMap<Short, Short> reverseBlockMappings;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
@ -21,6 +26,11 @@ public class BlockConnectionStorage extends StoredObject {
|
|||||||
Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections");
|
Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections");
|
||||||
} catch (ClassNotFoundException | NoSuchMethodException ignored) {
|
} 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) {
|
public BlockConnectionStorage(UserConnection user) {
|
||||||
@ -28,25 +38,48 @@ public class BlockConnectionStorage extends StoredObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void store(Position position, int blockState) {
|
public void store(Position position, int blockState) {
|
||||||
|
Short mapping = reverseBlockMappings.get((short) blockState);
|
||||||
|
if (mapping == null) return;
|
||||||
|
blockState = mapping;
|
||||||
long pair = getChunkSectionIndex(position);
|
long pair = getChunkSectionIndex(position);
|
||||||
short[] map = getChunkSection(pair);
|
Pair<byte[], NibbleArray> map = getChunkSection(pair, (blockState & 0xF) != 0);
|
||||||
map[encodeBlockPos(position)] = (short) blockState;
|
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) {
|
public int get(Position position) {
|
||||||
long pair = getChunkSectionIndex(position);
|
long pair = getChunkSectionIndex(position);
|
||||||
short[] map = blockStorage.get(pair);
|
Pair<byte[], NibbleArray> map = blockStorage.get(pair);
|
||||||
if (map == null) return 0;
|
if (map == null) return 0;
|
||||||
short blockPosition = encodeBlockPos(position);
|
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) {
|
public void remove(Position position) {
|
||||||
long pair = getChunkSectionIndex(position);
|
long pair = getChunkSectionIndex(position);
|
||||||
short[] map = blockStorage.get(pair);
|
Pair<byte[], NibbleArray> map = blockStorage.get(pair);
|
||||||
if (map == null) return;
|
if (map == null) return;
|
||||||
map[encodeBlockPos(position)] = 0;
|
int blockIndex = encodeBlockPos(position);
|
||||||
for (short entry : map) {
|
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;
|
if (entry != 0) return;
|
||||||
}
|
}
|
||||||
blockStorage.remove(pair);
|
blockStorage.remove(pair);
|
||||||
@ -62,12 +95,15 @@ public class BlockConnectionStorage extends StoredObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private short[] getChunkSection(long index) {
|
private Pair<byte[], NibbleArray> getChunkSection(long index, boolean requireNibbleArray) {
|
||||||
short[] map = blockStorage.get(index);
|
Pair<byte[], NibbleArray> map = blockStorage.get(index);
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
map = new short[4096];
|
map = new Pair<>(new byte[4096], null);
|
||||||
blockStorage.put(index, map);
|
blockStorage.put(index, map);
|
||||||
}
|
}
|
||||||
|
if (map.getValue() == null && requireNibbleArray) {
|
||||||
|
map.setValue(new NibbleArray(4096));
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren