Merge pull request #1799 from KennyTV/abstraction

Use FastUtil collections for frequently called code
This commit is contained in:
Myles 2020-06-09 15:50:23 +01:00 committed by GitHub
commit 7be8c9d8aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 357 additions and 269 deletions

View File

@ -19,5 +19,13 @@
<version>1.18</version>
<scope>compile</scope> <!-- Velocity doesn't have snakeyaml -->
</dependency>
<!-- FastUtil for performance increases -->
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>8.3.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -91,12 +91,11 @@ public class Entity1_13Types {
// Fish
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE), // agb
COD_MOB(8, ABSTRACT_FISHES), // agf
COD(8, ABSTRACT_FISHES), // agf
PUFFERFISH(52, ABSTRACT_FISHES), // agn
SALMON(57, ABSTRACT_FISHES), // agp
TROPICAL_FISH(72, ABSTRACT_FISHES), // agu
// Monsters
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE), // ajs
BLAZE(4, ABSTRACT_MONSTER), // ajd
@ -248,7 +247,7 @@ public class Entity1_13Types {
ENDER_PEARL(65, EntityType.ENDER_PEARL),
WITHER_SKULL(66, EntityType.WITHER_SKULL),
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
LIAMA_SPIT(68, EntityType.LLAMA_SPIT),
LLAMA_SPIT(68, EntityType.LLAMA_SPIT),
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
ITEM_FRAME(71, EntityType.ITEM_FRAME),
EYE_OF_ENDER(72, EntityType.EYE_OF_ENDER),

View File

@ -2,6 +2,8 @@ package us.myles.ViaVersion.api.protocol;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.Via;
@ -52,7 +54,7 @@ public class ProtocolRegistry {
public static final Protocol BASE_PROTOCOL = new BaseProtocol();
public static int SERVER_PROTOCOL = -1;
// Input Version -> Output Version & Protocol (Allows fast lookup)
private static final Map<Integer, Map<Integer, Protocol>> registryMap = new ConcurrentHashMap<>();
private static final Int2ObjectMap<Int2ObjectMap<Protocol>> registryMap = new Int2ObjectOpenHashMap<>(32);
private static final Map<Class<? extends Protocol>, Protocol> protocols = new HashMap<>();
private static final Map<Pair<Integer, Integer>, List<Pair<Integer, Protocol>>> pathCache = new ConcurrentHashMap<>();
private static final Set<Integer> supportedVersions = new HashSet<>();
@ -126,7 +128,7 @@ public class ProtocolRegistry {
* @param supported Supported client versions.
* @param output The output server version it converts to.
*/
public static void registerProtocol(Protocol protocol, List<Integer> supported, Integer output) {
public static void registerProtocol(Protocol protocol, List<Integer> supported, int output) {
// Clear cache as this may make new routes.
if (!pathCache.isEmpty()) {
pathCache.clear();
@ -135,7 +137,7 @@ public class ProtocolRegistry {
protocols.put(protocol.getClass(), protocol);
for (int version : supported) {
Map<Integer, Protocol> protocolMap = registryMap.computeIfAbsent(version, k -> new HashMap<>());
Int2ObjectMap<Protocol> protocolMap = registryMap.computeIfAbsent(version, s -> new Int2ObjectOpenHashMap<>(2));
protocolMap.put(output, protocol);
}
@ -204,8 +206,8 @@ public class ProtocolRegistry {
* @return True if there is a useful pipe
*/
public static boolean isWorkingPipe() {
for (Map<Integer, Protocol> maps : registryMap.values()) {
if (maps.containsKey(SERVER_PROTOCOL)) return true;
for (Int2ObjectMap<Protocol> map : registryMap.values()) {
if (map.containsKey(SERVER_PROTOCOL)) return true;
}
return false; // No destination for protocol
}
@ -234,36 +236,37 @@ public class ProtocolRegistry {
if (current.size() > 50) return null; // Fail safe, protocol too complicated.
// First check if there is any protocols for this
Map<Integer, Protocol> inputMap = registryMap.get(clientVersion);
Int2ObjectMap<Protocol> inputMap = registryMap.get(clientVersion);
if (inputMap == null) {
return null; // Not supported
}
// Next check there isn't an obvious path
Protocol protocol = inputMap.get(serverVersion);
if (protocol != null) {
current.add(new Pair<>(serverVersion, protocol));
return current; // Easy solution
}
// There might be a more advanced solution... So we'll see if any of the others can get us there
List<Pair<Integer, Protocol>> shortest = null;
for (Map.Entry<Integer, Protocol> entry : inputMap.entrySet()) {
for (Int2ObjectMap.Entry<Protocol> entry : inputMap.int2ObjectEntrySet()) {
// Ensure it wasn't caught by the other loop
if (!entry.getKey().equals(serverVersion)) {
Pair<Integer, Protocol> pair = new Pair<>(entry.getKey(), entry.getValue());
// Ensure no recursion
if (!current.contains(pair)) {
// Create a copy
List<Pair<Integer, Protocol>> newCurrent = new ArrayList<>(current);
newCurrent.add(pair);
// Calculate the rest of the protocol using the current
newCurrent = getProtocolPath(newCurrent, entry.getKey(), serverVersion);
if (newCurrent != null) {
// If it's shorter then choose it
if (shortest == null || shortest.size() > newCurrent.size()) {
shortest = newCurrent;
}
}
if (entry.getIntKey() == (serverVersion)) continue;
Pair<Integer, Protocol> pair = new Pair<>(entry.getIntKey(), entry.getValue());
// Ensure no recursion
if (current.contains(pair)) continue;
// Create a copy
List<Pair<Integer, Protocol>> newCurrent = new ArrayList<>(current);
newCurrent.add(pair);
// Calculate the rest of the protocol using the current
newCurrent = getProtocolPath(newCurrent, entry.getKey(), serverVersion);
if (newCurrent != null) {
// If it's shorter then choose it
if (shortest == null || shortest.size() > newCurrent.size()) {
shortest = newCurrent;
}
}
}

View File

@ -1,5 +1,7 @@
package us.myles.ViaVersion.api.rewriters;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
@ -23,7 +25,7 @@ import java.util.logging.Logger;
public abstract class MetadataRewriter {
private final Class<? extends EntityTracker> entityTrackerClass;
private final Protocol protocol;
private Map<Integer, Integer> typeMapping;
private Int2IntMap typeMapping;
protected MetadataRewriter(Protocol protocol, Class<? extends EntityTracker> entityTrackerClass) {
this.protocol = protocol;
@ -182,7 +184,10 @@ public abstract class MetadataRewriter {
}
public <T extends Enum<T> & EntityType> void mapTypes(EntityType[] oldTypes, Class<T> newTypeClass) {
if (typeMapping == null) typeMapping = new HashMap<>(oldTypes.length);
if (typeMapping == null) {
typeMapping = new Int2IntOpenHashMap(oldTypes.length, 1F);
typeMapping.defaultReturnValue(-1);
}
for (EntityType oldType : oldTypes) {
try {
T newType = Enum.valueOf(newTypeClass, oldType.name());
@ -190,14 +195,17 @@ public abstract class MetadataRewriter {
} catch (IllegalArgumentException notFound) {
if (!typeMapping.containsKey(oldType.getId())) {
Via.getPlatform().getLogger().warning("Could not find new entity type for " + oldType + "! " +
"Old type: " + oldType.getClass().getSimpleName() + " New type: " + newTypeClass.getSimpleName());
"Old type: " + oldType.getClass().getEnclosingClass().getSimpleName() + ", new type: " + newTypeClass.getEnclosingClass().getSimpleName());
}
}
}
}
public void mapType(EntityType oldType, EntityType newType) {
if (typeMapping == null) typeMapping = new HashMap<>();
if (typeMapping == null) {
typeMapping = new Int2IntOpenHashMap();
typeMapping.defaultReturnValue(-1);
}
typeMapping.put(oldType.getId(), newType.getId());
}

View File

@ -346,8 +346,8 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
}
} else {
for (int i = 0; i < 16; i++) {
Integer newItem = MappingData.oldToNewItems.get(item << 4 | i);
if (newItem != null) {
int newItem = MappingData.oldToNewItems.get(item << 4 | i);
if (newItem != -1) {
PacketWrapper packet = wrapper.create(0x18);
packet.write(Type.VAR_INT, newItem);
packet.write(Type.VAR_INT, ticks);

View File

@ -3,6 +3,10 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
@ -17,17 +21,21 @@ import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.providers.PacketBlockConnectionProvider;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
public class ConnectionData {
private static final BlockChangeRecord[] A = new BlockChangeRecord[0];
public static BlockConnectionProvider blockConnectionProvider;
static Map<Integer, String> idToKey = new HashMap<>();
static Map<String, Integer> keyToId = new HashMap<>();
static Map<Integer, ConnectionHandler> connectionHandlerMap = new HashMap<>();
static Map<Integer, BlockData> blockConnectionData = new HashMap<>();
static Set<Integer> occludingStates = new HashSet<>();
static Int2ObjectMap<String> idToKey = new Int2ObjectOpenHashMap<>(8582, 1F);
static Map<String, Integer> keyToId = new HashMap<>(8582, 1F);
static Int2ObjectMap<ConnectionHandler> connectionHandlerMap = new Int2ObjectOpenHashMap<>(1);
static Int2ObjectMap<BlockData> blockConnectionData = new Int2ObjectOpenHashMap<>(1);
static IntSet occludingStates = new IntOpenHashSet(377, 1F);
public static void update(UserConnection user, Position position) {
for (BlockFace face : BlockFace.values()) {
@ -194,17 +202,21 @@ public class ConnectionData {
public static void init() {
if (!Via.getConfig().isServersideBlockConnections()) return;
Via.getPlatform().getLogger().info("Loading block connection mappings ...");
JsonObject mapping1_13 = MappingDataLoader.loadData("mapping-1.13.json", true);
JsonObject blocks1_13 = mapping1_13.getAsJsonObject("blocks");
for (Entry<String, JsonElement> blockState : blocks1_13.entrySet()) {
Integer id = Integer.parseInt(blockState.getKey());
int id = Integer.parseInt(blockState.getKey());
String key = blockState.getValue().getAsString();
idToKey.put(id, key);
keyToId.put(key, id);
}
connectionHandlerMap = new Int2ObjectOpenHashMap<>(3650, 1F);
if (!Via.getConfig().isReduceBlockStorageMemory()) {
blockConnectionData = new Int2ObjectOpenHashMap<>(1146, 1F);
JsonObject mappingBlockConnections = MappingDataLoader.loadData("blockConnections.json");
for (Entry<String, JsonElement> entry : mappingBlockConnections.entrySet()) {
int id = keyToId.get(entry.getKey());
@ -231,7 +243,7 @@ public class ConnectionData {
JsonObject blockData = MappingDataLoader.loadData("blockData.json");
JsonArray occluding = blockData.getAsJsonArray("occluding");
for (JsonElement jsonElement : occluding) {
occludingStates.add(keyToId.get(jsonElement.getAsString()));
occludingStates.add(keyToId.get(jsonElement.getAsString()).intValue());
}
List<ConnectorInitAction> initActions = new ArrayList<>();

View File

@ -1,18 +1,18 @@
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.BlockFace;
import us.myles.ViaVersion.api.minecraft.Position;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class FlowerConnectionHandler extends ConnectionHandler {
private static final Map<Integer, Integer> flowers = new HashMap<>();
private static final Int2IntMap flowers = new Int2IntOpenHashMap();
static ConnectionData.ConnectorInitAction init() {
final Set<String> baseFlower = new HashSet<>();
@ -38,8 +38,8 @@ public class FlowerConnectionHandler extends ConnectionHandler {
@Override
public int connect(UserConnection user, Position position, int blockState) {
int blockBelowId = getBlockData(user, position.getRelative(BlockFace.BOTTOM));
Integer connectBelow = flowers.get(blockBelowId);
if (connectBelow != null) {
int connectBelow = flowers.get(blockBelowId);
if (connectBelow != 0) {
int blockAboveId = getBlockData(user, position.getRelative(BlockFace.TOP));
if (Via.getConfig().isStemWhenBlockAbove()) {
if (blockAboveId == 0) {

View File

@ -1,18 +1,18 @@
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.BlockFace;
import us.myles.ViaVersion.api.minecraft.Position;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class RedstoneConnectionHandler extends ConnectionHandler {
private static final Set<Integer> redstone = new HashSet<>();
private static final Map<Short, Integer> connectedBlockStates = new HashMap<>();
private static final Map<Integer, Integer> powerMappings = new HashMap<>();
private static final Int2IntMap connectedBlockStates = new Int2IntOpenHashMap(1296);
private static final Int2IntMap powerMappings = new Int2IntOpenHashMap(1296);
static ConnectionData.ConnectorInitAction init() {
final RedstoneConnectionHandler connectionHandler = new RedstoneConnectionHandler();
@ -22,7 +22,7 @@ public class RedstoneConnectionHandler extends ConnectionHandler {
redstone.add(blockData.getSavedBlockStateId());
ConnectionData.connectionHandlerMap.put(blockData.getSavedBlockStateId(), connectionHandler);
connectedBlockStates.put(getStates(blockData), blockData.getSavedBlockStateId());
powerMappings.put(blockData.getSavedBlockStateId(), Integer.valueOf(blockData.getValue("power")));
powerMappings.put(blockData.getSavedBlockStateId(), Integer.parseInt(blockData.getValue("power")));
};
}
@ -57,8 +57,7 @@ public class RedstoneConnectionHandler extends ConnectionHandler {
b |= connects(user, position, BlockFace.SOUTH) << 4;
b |= connects(user, position, BlockFace.WEST) << 6;
b |= powerMappings.get(blockState) << 8;
final Integer newBlockState = connectedBlockStates.get(b);
return newBlockState == null ? blockState : newBlockState;
return connectedBlockStates.getOrDefault(b, blockState);
}
private int connects(UserConnection user, Position position, BlockFace side) {

View File

@ -2,6 +2,8 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data;
import com.google.common.collect.ObjectArrays;
import com.google.gson.reflect.TypeToken;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import us.myles.ViaVersion.util.GsonUtil;
import java.io.IOException;
@ -13,18 +15,18 @@ import java.util.Map;
public class BlockIdData {
public static Map<String, String[]> blockIdMapping;
public static Map<String, String[]> fallbackReverseMapping;
public static Map<Integer, String> numberIdToString;
public static Int2ObjectMap<String> numberIdToString;
public static void init() {
InputStream stream = MappingData.class.getClassLoader()
.getResourceAsStream("assets/viaversion/data/blockIds1.12to1.13.json");
InputStreamReader reader = new InputStreamReader(stream);
try {
blockIdMapping = new HashMap<>((Map<String, String[]>) GsonUtil.getGson().fromJson(
blockIdMapping = new HashMap<>(GsonUtil.getGson().fromJson(
reader,
new TypeToken<Map<String, String[]>>() {
}.getType()
));
), 1F);
fallbackReverseMapping = new HashMap<>();
for (Map.Entry<String, String[]> entry : blockIdMapping.entrySet()) {
for (String val : entry.getValue()) {
@ -45,7 +47,7 @@ public class BlockIdData {
.getResourceAsStream("assets/viaversion/data/blockNumberToString1.12.json");
InputStreamReader blockR = new InputStreamReader(blockS);
try {
numberIdToString = new HashMap<>((Map<Integer, String>) GsonUtil.getGson().fromJson(
numberIdToString = new Int2ObjectOpenHashMap<>(GsonUtil.getGson().fromJson(
blockR,
new TypeToken<Map<Integer, String>>() {
}.getType()

View File

@ -1,14 +1,13 @@
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
public class EntityTypeRewriter {
private static final Map<Integer, Integer> entityTypes = new HashMap<>();
private static final Int2IntMap ENTITY_TYPES = new Int2IntOpenHashMap(83, 1F);
static {
ENTITY_TYPES.defaultReturnValue(-1);
registerEntity(1, 32); // item - ajl
registerEntity(2, 22); // xp_orb - abx
registerEntity(3, 0); // area_effect_cloud - abp
@ -92,16 +91,13 @@ public class EntityTypeRewriter {
registerEntity(104, 37); // llama_spit - alr
registerEntity(105, 50); // parrot - agx
registerEntity(120, 79); // villager - ala
// OBJECTS
// Couldn't find any object id change with mapped values
}
private static void registerEntity(int type1_12, int type1_13) {
entityTypes.put(type1_12, type1_13);
ENTITY_TYPES.put(type1_12, type1_13);
}
public static Optional<Integer> getNewId(int type1_12) {
return Optional.ofNullable(entityTypes.get(type1_12));
public static int getNewId(int type1_12) {
return ENTITY_TYPES.getOrDefault(type1_12, type1_12);
}
}

View File

@ -11,6 +11,7 @@ import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.util.GsonUtil;
import us.myles.ViaVersion.util.Int2IntBiMap;
import java.io.IOException;
import java.io.InputStreamReader;
@ -20,7 +21,7 @@ import java.util.HashMap;
import java.util.Map;
public class MappingData {
public static final BiMap<Integer, Integer> oldToNewItems = HashBiMap.create();
public static final Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static final Map<String, Integer[]> blockTags = new HashMap<>();
public static final Map<String, Integer[]> itemTags = new HashMap<>();
public static final Map<String, Integer[]> fluidTags = new HashMap<>();
@ -37,6 +38,7 @@ public class MappingData {
JsonObject mapping1_12 = MappingDataLoader.loadData("mapping-1.12.json", true);
JsonObject mapping1_13 = MappingDataLoader.loadData("mapping-1.13.json", true);
oldToNewItems.defaultReturnValue(-1);
blockMappings = new BlockMappingsShortArray(mapping1_12.getAsJsonObject("blocks"), mapping1_13.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_12.getAsJsonObject("items"), mapping1_13.getAsJsonObject("items"));
loadTags(blockTags, mapping1_13.getAsJsonObject("block_tags"));

View File

@ -102,7 +102,7 @@ public class MetadataRewriter1_13To1_12_2 extends MetadataRewriter {
@Override
public int getNewEntityId(final int oldId) {
return EntityTypeRewriter.getNewId(oldId).orElse(oldId);
return EntityTypeRewriter.getNewId(oldId);
}
@Override

View File

@ -435,7 +435,7 @@ public class InventoryPackets {
}
}
item.setIdentifier(MappingData.oldToNewItems.get(rawId).shortValue());
item.setIdentifier(MappingData.oldToNewItems.get(rawId));
item.setData((short) 0);
}
@ -487,8 +487,8 @@ public class InventoryPackets {
}
if (rawId == null) {
Integer oldId = MappingData.oldToNewItems.inverse().get(item.getIdentifier());
if (oldId != null) {
int oldId = MappingData.oldToNewItems.inverse().get(item.getIdentifier());
if (oldId != -1) {
// Handle spawn eggs
Optional<String> eggEntityId = SpawnEggRewriter.getEntityId(oldId);
if (eggEntityId.isPresent()) {

View File

@ -1,6 +1,8 @@
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
@ -27,31 +29,29 @@ import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public class WorldPackets {
private static final Set<Integer> validBiomes = new HashSet<>();
private static final IntSet VALID_BIOMES = new IntOpenHashSet(70, 1F);
static {
// Client will crash if it receives a invalid biome id
for (int i = 0; i < 50; i++) {
validBiomes.add(i);
VALID_BIOMES.add(i);
}
validBiomes.add(127);
VALID_BIOMES.add(127);
for (int i = 129; i <= 134; i++) {
validBiomes.add(i);
VALID_BIOMES.add(i);
}
validBiomes.add(140);
validBiomes.add(149);
validBiomes.add(151);
VALID_BIOMES.add(140);
VALID_BIOMES.add(149);
VALID_BIOMES.add(151);
for (int i = 155; i <= 158; i++) {
validBiomes.add(i);
VALID_BIOMES.add(i);
}
for (int i = 160; i <= 167; i++) {
validBiomes.add(i);
VALID_BIOMES.add(i);
}
}
@ -407,7 +407,7 @@ public class WorldPackets {
int latestBiomeWarn = Integer.MIN_VALUE;
for (int i = 0; i < 256; i++) {
int biome = chunk.getBiomeData()[i];
if (!validBiomes.contains(biome)) {
if (!VALID_BIOMES.contains(biome)) {
if (biome != 255 // is it generated naturally? *shrug*
&& latestBiomeWarn != biome) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {

View File

@ -11,25 +11,29 @@ import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class BlockConnectionStorage extends StoredObject {
private final Map<Long, Pair<byte[], NibbleArray>> blockStorage = createLongObjectMap();
private static final Map<Short, Short> reverseBlockMappings;
private static final short[] REVERSE_BLOCK_MAPPINGS = new short[8582];
private static Constructor<?> fastUtilLongObjectHashMap;
private final Map<Long, Pair<byte[], NibbleArray>> blockStorage = createLongObjectMap();
static {
try {
fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap").getConstructor();
Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections");
} catch (ClassNotFoundException | NoSuchMethodException ignored) {
}
reverseBlockMappings = new HashMap<>();
Arrays.fill(REVERSE_BLOCK_MAPPINGS, (short) -1);
for (int i = 0; i < 4096; i++) {
int newBlock = MappingData.blockMappings.getNewId(i);
if (newBlock != -1) reverseBlockMappings.put((short) newBlock, (short) i);
if (newBlock != -1) {
REVERSE_BLOCK_MAPPINGS[newBlock] = (short) i;
}
}
}
@ -38,15 +42,18 @@ public class BlockConnectionStorage extends StoredObject {
}
public void store(int x, int y, int z, int blockState) {
Short mapping = reverseBlockMappings.get((short) blockState);
if (mapping == null) return;
short mapping = REVERSE_BLOCK_MAPPINGS[blockState];
if (mapping == -1) return;
blockState = mapping;
long pair = getChunkSectionIndex(x, y, z);
Pair<byte[], NibbleArray> map = getChunkSection(pair, (blockState & 0xF) != 0);
int blockIndex = encodeBlockPos(x, y, z);
map.getKey()[blockIndex] = (byte) (blockState >> 4);
NibbleArray nibbleArray = map.getValue();
if (nibbleArray != null) nibbleArray.set(blockIndex, blockState);
if (nibbleArray != null) {
nibbleArray.set(blockIndex, blockState);
}
}
public int get(int x, int y, int z) {

View File

@ -1,38 +1,41 @@
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.Position;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class BlockStorage extends StoredObject {
private static final Set<Integer> whitelist = new HashSet<>();
private static final IntSet WHITELIST = new IntOpenHashSet(46, 1F);
private final Map<Position, ReplacementData> blocks = new ConcurrentHashMap<>();
static {
// Flower pots
whitelist.add(5266);
WHITELIST.add(5266);
// Add those red beds
for (int i = 0; i < 16; i++)
whitelist.add(972 + i);
for (int i = 0; i < 16; i++) {
WHITELIST.add(972 + i);
}
// Add the white banners
for (int i = 0; i < 20; i++)
whitelist.add(6854 + i);
for (int i = 0; i < 20; i++) {
WHITELIST.add(6854 + i);
}
// Add the white wall banners
for (int i = 0; i < 4; i++) {
whitelist.add(7110 + i);
WHITELIST.add(7110 + i);
}
// Skeleton skulls
for (int i = 0; i < 5; i++)
whitelist.add(5447 + i);
for (int i = 0; i < 5; i++) {
WHITELIST.add(5447 + i);
}
}
public BlockStorage(UserConnection user) {
@ -44,14 +47,14 @@ public class BlockStorage extends StoredObject {
}
public void store(Position position, int block, int replacementId) {
if (!whitelist.contains(block))
if (!WHITELIST.contains(block))
return;
blocks.put(position, new ReplacementData(block, replacementId));
}
public boolean isWelcome(int block) {
return whitelist.contains(block);
return WHITELIST.contains(block);
}
public boolean contains(Position position) {

View File

@ -1,109 +0,0 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class EntityTypeRewriter {
private static final Map<Integer, Integer> entityTypes = new HashMap<>();
static {
regEnt(6, 7); // cave_spider
regEnt(7, 8); // chicken
regEnt(8, 9); // cod
regEnt(9, 10); // cow
regEnt(10, 11); // creeper
regEnt(11, 12); // donkey
regEnt(12, 13); // dolphin
regEnt(13, 14); // dragon_fireball
regEnt(14, 15); // drowned
regEnt(15, 16); // elder_guardian
regEnt(16, 17); // end_crystal
regEnt(17, 18); // ender_dragon
regEnt(18, 19); // enderman
regEnt(19, 20); // endermite
regEnt(20, 21); // evoker_fangs
regEnt(21, 22); // evoker
regEnt(22, 23); // experience_orb
regEnt(23, 24); // eye_of_ender
regEnt(24, 25); // falling_block
regEnt(25, 26); // firework_rocket
regEnt(26, 28); // ghast
regEnt(27, 29); // giant
regEnt(28, 30); // guardian
regEnt(29, 31); // horse
regEnt(30, 32); // husk
regEnt(31, 33); // illusioner
regEnt(32, 34); // item
regEnt(33, 35); // item_frame
regEnt(34, 36); // fireball
regEnt(35, 37); // leash_knot
regEnt(36, 38); // llama
regEnt(37, 39); // llama_spit
regEnt(38, 40); // magma_cube
regEnt(39, 41); // minecart
regEnt(40, 42); // chest_minecart
regEnt(41, 43); // command_block_minecart
regEnt(42, 44); // furnace_minecart
regEnt(43, 45); // hopper_minecart
regEnt(44, 46); // spawner_minecart
regEnt(45, 47); // tnt_minecart
regEnt(46, 48); // mule
regEnt(47, 49); // mooshroom
regEnt(48, 6); // ocelot -> cat TODO Remap untamed ocelot to ocelot?
regEnt(49, 51); // painting
regEnt(50, 53); // parrot
regEnt(51, 54); // pig
regEnt(52, 55); // pufferfish
regEnt(53, 56); // zombie_pigman
regEnt(54, 57); // polar_bear
regEnt(55, 58); // tnt
regEnt(56, 59); // rabbit
regEnt(57, 60); // salmon
regEnt(58, 61); // sheep
regEnt(59, 62); // shulker
regEnt(60, 63); // shulker_bullet
regEnt(61, 64); // silverfish
regEnt(62, 65); // skeleton
regEnt(63, 66); // skeleton_horse
regEnt(64, 67); // slime
regEnt(65, 68); // small_fireball
regEnt(66, 69); // snowgolem
regEnt(67, 70); // snowball
regEnt(68, 71); // spectral_arrow
regEnt(69, 72); // spider
regEnt(70, 73); // squid
regEnt(71, 74); // stray
regEnt(72, 76); // tropical_fish
regEnt(73, 77); // turtle
regEnt(74, 78); // egg
regEnt(75, 79); // ender_pearl
regEnt(76, 80); // experience_bottle
regEnt(77, 81); // potion
regEnt(78, 83); // vex
regEnt(79, 84); // villager
regEnt(80, 85); // iron_golem
regEnt(81, 86); // vindicator
regEnt(82, 89); // witch
regEnt(83, 90); // wither
regEnt(84, 91); // wither_skeleton
regEnt(85, 92); // wither_skull
regEnt(86, 93); // wolf
regEnt(87, 94); // zombie
regEnt(88, 95); // zombie_horse
regEnt(89, 96); // zombie_villager
regEnt(90, 97); // phantom
regEnt(91, 99); // lightning_bolt
regEnt(92, 100); // player
regEnt(93, 101); // fishing_bobber
regEnt(94, 82); // trident
}
private static void regEnt(int type1_13, int type1_14) {
entityTypes.put(type1_13, type1_14);
}
public static Optional<Integer> getNewId(int type1_13) {
return Optional.ofNullable(entityTypes.get(type1_13));
}
}

View File

@ -1,32 +1,32 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.util.Int2IntBiMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class MappingData {
public static final BiMap<Integer, Integer> oldToNewItems = HashBiMap.create();
public static final Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static Mappings blockStateMappings;
public static Mappings blockMappings;
public static Mappings soundMappings;
public static Set<Integer> motionBlocking;
public static Set<Integer> nonFullBlocks;
public static IntSet motionBlocking;
public static IntSet nonFullBlocks;
public static void init() {
Via.getPlatform().getLogger().info("Loading 1.13.2 -> 1.14 mappings...");
JsonObject mapping1_13_2 = MappingDataLoader.loadData("mapping-1.13.2.json", true);
JsonObject mapping1_14 = MappingDataLoader.loadData("mapping-1.14.json", true);
oldToNewItems.defaultReturnValue(-1);
blockStateMappings = new Mappings(mapping1_13_2.getAsJsonObject("blockstates"), mapping1_14.getAsJsonObject("blockstates"));
blockMappings = new Mappings(mapping1_13_2.getAsJsonObject("blocks"), mapping1_14.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_13_2.getAsJsonObject("items"), mapping1_14.getAsJsonObject("items"));
@ -40,19 +40,19 @@ public class MappingData {
JsonObject heightMapData = MappingDataLoader.loadData("heightMapData-1.14.json");
JsonArray motionBlocking = heightMapData.getAsJsonArray("MOTION_BLOCKING");
us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.motionBlocking = new HashSet<>(motionBlocking.size());
MappingData.motionBlocking = new IntOpenHashSet(motionBlocking.size(), 1F);
for (JsonElement blockState : motionBlocking) {
String key = blockState.getAsString();
Integer id = blockStateMap.get(key);
if (id == null) {
Via.getPlatform().getLogger().warning("Unknown blockstate " + key + " :(");
} else {
us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.motionBlocking.add(id);
MappingData.motionBlocking.add(id.intValue());
}
}
if (Via.getConfig().isNonFullBlockLightFix()) {
nonFullBlocks = new HashSet<>();
nonFullBlocks = new IntOpenHashSet(1611, 1F);
for (Map.Entry<String, JsonElement> blockstates : mapping1_13_2.getAsJsonObject("blockstates").entrySet()) {
final String state = blockstates.getValue().getAsString();
if (state.contains("_slab") || state.contains("_stairs") || state.contains("_wall["))

View File

@ -3,6 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.metadata;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.Entity1_13Types;
import us.myles.ViaVersion.api.entities.Entity1_14Types;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.minecraft.VillagerData;
@ -13,7 +14,6 @@ import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.EntityTypeRewriter;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker1_14;
@ -23,6 +23,7 @@ public class MetadataRewriter1_14To1_13_2 extends MetadataRewriter {
public MetadataRewriter1_14To1_13_2(Protocol1_14To1_13_2 protocol) {
super(protocol, EntityTracker1_14.class);
mapTypes(Entity1_13Types.EntityType.values(), Entity1_14Types.EntityType.class);
}
@Override
@ -168,11 +169,6 @@ public class MetadataRewriter1_14To1_13_2 extends MetadataRewriter {
}
}
@Override
public int getNewEntityId(final int oldId) {
return EntityTypeRewriter.getNewId(oldId).orElse(oldId);
}
@Override
protected EntityType getTypeFromId(int type) {
return Entity1_14Types.getTypeFromId(type);

View File

@ -14,7 +14,6 @@ import us.myles.ViaVersion.api.type.types.version.Types1_14;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.EntityTypeRewriter;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.metadata.MetadataRewriter1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker1_14;
@ -50,7 +49,7 @@ public class EntityPackets {
int typeId = wrapper.get(Type.VAR_INT, 1);
Entity1_13Types.EntityType type1_13 = Entity1_13Types.getTypeFromId(typeId, true);
typeId = EntityTypeRewriter.getNewId(type1_13.getId()).orElse(type1_13.getId());
typeId = metadataRewriter.getNewEntityId(type1_13.getId());
Entity1_14Types.EntityType type1_14 = Entity1_14Types.getTypeFromId(typeId);
if (type1_14 != null) {

View File

@ -271,8 +271,8 @@ public class InventoryPackets {
}
public static int getNewItemId(int id) {
Integer newId = MappingData.oldToNewItems.get(id);
if (newId == null) {
int newId = MappingData.oldToNewItems.get(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.14 item for 1.13.2 item " + id);
return 1;
}
@ -313,7 +313,7 @@ public class InventoryPackets {
}
public static int getOldItemId(int id) {
Integer oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != null ? oldId : 1;
int oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != -1 ? oldId : 1;
}
}

View File

@ -1,14 +1,13 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.gson.JsonObject;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.util.Int2IntBiMap;
public class MappingData {
public static BiMap<Integer, Integer> oldToNewItems = HashBiMap.create();
public static Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static Mappings blockMappings;
public static Mappings blockStateMappings;
public static Mappings soundMappings;
@ -19,6 +18,7 @@ public class MappingData {
JsonObject mapping1_14 = MappingDataLoader.loadData("mapping-1.14.json", true);
JsonObject mapping1_15 = MappingDataLoader.loadData("mapping-1.15.json", true);
oldToNewItems.defaultReturnValue(-1);
blockStateMappings = new Mappings(mapping1_14.getAsJsonObject("blockstates"), mapping1_15.getAsJsonObject("blockstates"), diffmapping.getAsJsonObject("blockstates"));
blockMappings = new Mappings(mapping1_14.getAsJsonObject("blocks"), mapping1_15.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_14.getAsJsonObject("items"), mapping1_15.getAsJsonObject("items"));

View File

@ -143,8 +143,8 @@ public class InventoryPackets {
}
public static int getNewItemId(int id) {
Integer newId = MappingData.oldToNewItems.get(id);
if (newId == null) {
int newId = MappingData.oldToNewItems.get(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.15 item for 1.14 item " + id);
return 1;
}
@ -152,7 +152,7 @@ public class InventoryPackets {
}
public static int getOldItemId(int id) {
Integer oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != null ? oldId : 1;
int oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != -1 ? oldId : 1;
}
}

View File

@ -1,17 +1,16 @@
package us.myles.ViaVersion.protocols.protocol1_16to1_15_2.data;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.gson.JsonObject;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.util.Int2IntBiMap;
import java.util.HashMap;
import java.util.Map;
public class MappingData {
public static BiMap<Integer, Integer> oldToNewItems = HashBiMap.create();
public static Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static Map<String, String> attributeMappings = new HashMap<>();
public static Mappings blockMappings;
public static Mappings blockStateMappings;
@ -23,6 +22,7 @@ public class MappingData {
JsonObject mapping1_15 = MappingDataLoader.loadData("mapping-1.15.json", true);
JsonObject mapping1_16 = MappingDataLoader.loadData("mapping-1.16.json", true);
oldToNewItems.defaultReturnValue(-1);
blockStateMappings = new Mappings(mapping1_15.getAsJsonObject("blockstates"), mapping1_16.getAsJsonObject("blockstates"), diffmapping.getAsJsonObject("blockstates"));
blockMappings = new Mappings(mapping1_15.getAsJsonObject("blocks"), mapping1_16.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_15.getAsJsonObject("items"), mapping1_16.getAsJsonObject("items"), diffmapping.getAsJsonObject("items"));

View File

@ -206,8 +206,8 @@ public class InventoryPackets {
}
public static int getNewItemId(int id) {
Integer newId = MappingData.oldToNewItems.get(id);
if (newId == null) {
int newId = MappingData.oldToNewItems.get(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.16 item for 1.15.2 item " + id);
return 1;
}
@ -215,7 +215,7 @@ public class InventoryPackets {
}
public static int getOldItemId(int id) {
Integer oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != null ? oldId : 1;
int oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != -1 ? oldId : 1;
}
}

View File

@ -4,6 +4,8 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import us.myles.ViaVersion.api.minecraft.item.Item;
import java.util.Collections;
@ -17,7 +19,7 @@ public class ItemRewriter {
private static final Map<String, Integer> POTION_NAME_TO_ID = new HashMap<>();
private static final Map<Integer, String> POTION_ID_TO_NAME = new HashMap<>();
private static final Map<Integer, Integer> POTION_INDEX = new HashMap<>();
private static final Int2IntMap POTION_INDEX = new Int2IntOpenHashMap(36, 1F);
static {
/* Entities */
@ -218,7 +220,7 @@ public class ItemRewriter {
return str;
}
// hacky but it works :)
str = "\u00A7r" + str;
str = "§r" + str;
return str;
}
@ -381,21 +383,21 @@ public class ItemRewriter {
oldID -= 8192;
}
Integer index = POTION_INDEX.get(oldID);
if (index != null) {
int index = POTION_INDEX.get(oldID);
if (index != -1) {
return index;
}
oldID = POTION_NAME_TO_ID.get(potionNameFromDamage((short) oldID));
return (index = POTION_INDEX.get(oldID)) != null ? index : 0;
return (index = POTION_INDEX.get(oldID)) != -1 ? index : 0;
}
private static void registerEntity(Integer id, String name) {
private static void registerEntity(int id, String name) {
ENTTIY_ID_TO_NAME.put(id, name);
ENTTIY_NAME_TO_ID.put(name, id);
}
private static void registerPotion(Integer id, String name) {
private static void registerPotion(int id, String name) {
POTION_INDEX.put(id, POTION_ID_TO_NAME.size());
POTION_ID_TO_NAME.put(id, name);
POTION_NAME_TO_ID.put(name, id);

View File

@ -211,4 +211,3 @@ public enum MetaIndex {
}
}

View File

@ -1,14 +1,13 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds;
import java.util.HashMap;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
public class Effect {
private static final Map<Integer, Integer> effects;
private static final Int2IntMap EFFECTS = new Int2IntOpenHashMap(17, 1F);
static {
effects = new HashMap<>();
addRewrite(1005, 1010); //Play music disc
addRewrite(1003, 1005); //Iron door open
addRewrite(1006, 1011); //Iron door close
@ -26,19 +25,17 @@ public class Effect {
addRewrite(1020, 1029); //Anvil break
addRewrite(1021, 1030); //Anvil use
addRewrite(1022, 1031); //Anvil land
}
public static int getNewId(int id) {
Integer newId = effects.get(id);
return newId != null ? newId : id;
return EFFECTS.getOrDefault(id, id);
}
public static boolean contains(int oldId) {
return effects.containsKey(oldId);
return EFFECTS.containsKey(oldId);
}
private static void addRewrite(int oldId, int newId) {
effects.put(oldId, newId);
EFFECTS.put(oldId, newId);
}
}

View File

@ -0,0 +1,128 @@
package us.myles.ViaVersion.util;
import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* Simple wrapper class for two {@link Int2IntMap}s.
*
* @see #inverse() to get the inversed map
*/
public class Int2IntBiMap implements Int2IntMap {
private final Int2IntMap map;
private final Int2IntBiMap inverse;
public Int2IntBiMap() {
this.map = new Int2IntOpenHashMap();
this.inverse = new Int2IntBiMap(this);
}
private Int2IntBiMap(Int2IntBiMap inverse) {
this.map = new Int2IntOpenHashMap();
this.inverse = inverse;
}
/**
* @return the inverse of this bimap
*/
public Int2IntBiMap inverse() {
return inverse;
}
/**
* Puts the key and value into the maps.
*
* @param key key
* @param value value
* @return old value if present
* @throws IllegalArgumentException if the value already exists in the map
*/
@Override
public int put(int key, int value) {
if (containsKey(key) && value == get(key)) return value;
Preconditions.checkArgument(!containsValue(value), "value already present: %s", value);
map.put(key, value);
inverse.map.put(value, key);
return defaultReturnValue();
}
@Override
public boolean remove(int key, int value) {
map.remove(key, value);
return inverse.map.remove(key, value);
}
@Override
public int get(int key) {
return map.get(key);
}
@Override
public void clear() {
map.clear();
inverse.map.clear();
}
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
@Deprecated
public void putAll(@NotNull Map<? extends Integer, ? extends Integer> m) {
throw new UnsupportedOperationException();
}
@Override
public void defaultReturnValue(int rv) {
map.defaultReturnValue(rv);
inverse.map.defaultReturnValue(rv);
}
@Override
public int defaultReturnValue() {
return map.defaultReturnValue();
}
@Override
public ObjectSet<Entry> int2IntEntrySet() {
return map.int2IntEntrySet();
}
@Override
@NotNull
public IntSet keySet() {
return map.keySet();
}
@Override
@NotNull
public IntSet values() {
return inverse.map.keySet();
}
@Override
public boolean containsKey(int key) {
return map.containsKey(key);
}
@Override
public boolean containsValue(int value) {
return inverse.map.containsKey(value);
}
}

View File

@ -73,7 +73,44 @@
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>false</minimizeJar>
<filters>
<filter>
<artifact>it.unimi.dsi:fastutil</artifact>
<includes>
<!-- We only want int and Object maps -->
<include>it/unimi/dsi/fastutil/ints/*</include>
<include>it/unimi/dsi/fastutil/objects/*</include>
<include>it/unimi/dsi/fastutil/*.class</include>
</includes>
<excludes>
<!-- Object types -->
<exclude>it/unimi/dsi/fastutil/*/*Reference*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Boolean*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Byte*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Short*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Float*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Double*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Long*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Char*</exclude>
<!-- Map types -->
<exclude>it/unimi/dsi/fastutil/*/*Custom*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Linked*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Sorted*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Tree*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Heap*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Queue*</exclude>
<!-- Crossing fingers -->
<exclude>it/unimi/dsi/fastutil/*/*Big*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Synchronized*</exclude>
<exclude>it/unimi/dsi/fastutil/*/*Unmodifiable*</exclude>
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>it.unimi.dsi.fastutil</pattern>
<shadedPattern>us.myles.viaversion.libs.fastutil</shadedPattern>
</relocation>
<relocation>
<pattern>com.github.steveice10.opennbt</pattern>
<shadedPattern>us.myles.viaversion.libs.opennbt</shadedPattern>