From e5338688bb2d29daab45b470336c42c31340c4b8 Mon Sep 17 00:00:00 2001 From: Connor Hartley Date: Thu, 7 Oct 2021 23:26:14 +1300 Subject: [PATCH] Replace use of concurrenthashmap in entity tracker and block storage (#2705) --- api/build.gradle.kts | 2 ++ .../api/data/MappingDataLoader.java | 4 ++-- .../kotlin/via.shadow-conventions.gradle.kts | 6 ++++++ .../data/entity/EntityTrackerBase.java | 11 +++++------ .../metadata/MetadataRewriter1_11To1_10.java | 3 +-- .../storage/EntityTracker1_11.java | 14 ++++++-------- .../blockconnections/ConnectionData.java | 14 +++++++------- .../data/EntityTypeRewriter.java | 2 +- .../packets/WorldPackets.java | 2 +- .../storage/BlockStorage.java | 5 +++-- .../data/MappingData.java | 4 ++-- .../storage/EntityTracker1_14.java | 19 +++++++++---------- .../protocol1_9to1_8/ItemRewriter.java | 2 +- .../protocol1_9to1_8/sounds/Effect.java | 2 +- .../storage/EntityTracker1_9.java | 17 +++++++++-------- .../viaversion/rewriter/EntityRewriter.java | 2 +- gradle/libs.versions.toml | 5 ++++- 17 files changed, 61 insertions(+), 53 deletions(-) diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 5115a5953..09f6ac8d4 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -13,6 +13,8 @@ dependencies { targetConfiguration = "shadow" } api(libs.fastutil) + api(libs.flare) + api(libs.flareFastutil) api(libs.openNBT) api(libs.gson) diff --git a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java index 34d6a1d15..0b7012f24 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java +++ b/api/src/main/java/com/viaversion/viaversion/api/data/MappingDataLoader.java @@ -217,7 +217,7 @@ public class MappingDataLoader { * @return map with indexes hashed by their id value */ public static Object2IntMap indexedObjectToMap(JsonObject object) { - Object2IntMap map = new Object2IntOpenHashMap<>(object.size(), 1F); + Object2IntMap map = new Object2IntOpenHashMap<>(object.size(), .99F); map.defaultReturnValue(-1); for (Map.Entry entry : object.entrySet()) { map.put(entry.getValue().getAsString(), Integer.parseInt(entry.getKey())); @@ -232,7 +232,7 @@ public class MappingDataLoader { * @return map with indexes hashed by their id value */ public static Object2IntMap arrayToMap(JsonArray array) { - Object2IntMap map = new Object2IntOpenHashMap<>(array.size(), 1F); + Object2IntMap map = new Object2IntOpenHashMap<>(array.size(), .99F); map.defaultReturnValue(-1); for (int i = 0; i < array.size(); i++) { map.put(array.get(i).getAsString(), i); diff --git a/build-logic/src/main/kotlin/via.shadow-conventions.gradle.kts b/build-logic/src/main/kotlin/via.shadow-conventions.gradle.kts index aee71dfca..8021f6fcb 100644 --- a/build-logic/src/main/kotlin/via.shadow-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/via.shadow-conventions.gradle.kts @@ -29,6 +29,7 @@ fun ShadowJar.configureRelocations() { relocate("com.google.gson", "com.viaversion.viaversion.libs.gson") relocate("com.github.steveice10.opennbt", "com.viaversion.viaversion.libs.opennbt") relocate("it.unimi.dsi.fastutil", "com.viaversion.viaversion.libs.fastutil") + relocate("space.vectrix.flare", "com.viaversion.viaversion.libs.flare") } fun ShadowJar.configureExcludes() { @@ -52,4 +53,9 @@ fun ShadowJar.configureExcludes() { exclude("it/unimi/dsi/fastutil/*/*Synchronized*") exclude("it/unimi/dsi/fastutil/*/*Unmodifiable*") exclude("it/unimi/dsi/fastutil/io/*") + // Flare - only need int maps + exclude("space/vectrix/flare/fastutil/*Double*") + exclude("space/vectrix/flare/fastutil/*Float*") + exclude("space/vectrix/flare/fastutil/*Long*") + exclude("space/vectrix/flare/fastutil/*Short*") } diff --git a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java index 0a5741206..54c93e6d3 100644 --- a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java +++ b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java @@ -24,14 +24,13 @@ import com.viaversion.viaversion.api.data.entity.ClientEntityIdChangeListener; import com.viaversion.viaversion.api.data.entity.EntityTracker; import com.viaversion.viaversion.api.data.entity.StoredEntityData; import com.viaversion.viaversion.api.minecraft.entities.EntityType; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import space.vectrix.flare.fastutil.Int2ObjectSyncMap; public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeListener { - private final Map entityTypes = new ConcurrentHashMap<>(); - private final Map entityData; + private final Int2ObjectMap entityTypes = Int2ObjectSyncMap.hashmap(); + private final Int2ObjectMap entityData; private final UserConnection connection; private final EntityType playerType; private int clientEntityId = -1; @@ -46,7 +45,7 @@ public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeLis public EntityTrackerBase(UserConnection connection, @Nullable EntityType playerType, boolean storesEntityData) { this.connection = connection; this.playerType = playerType; - this.entityData = storesEntityData ? new ConcurrentHashMap<>() : null; + this.entityData = storesEntityData ? Int2ObjectSyncMap.hashmap() : null; } @Override diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11to1_10/metadata/MetadataRewriter1_11To1_10.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11to1_10/metadata/MetadataRewriter1_11To1_10.java index cba6a60c9..c4848fdfa 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11to1_10/metadata/MetadataRewriter1_11To1_10.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11to1_10/metadata/MetadataRewriter1_11To1_10.java @@ -126,8 +126,7 @@ public class MetadataRewriter1_11To1_10 extends EntityRewriter holograms = Sets.newConcurrentHashSet(); + private final IntSet holograms = Int2ObjectSyncMap.hashset(); public EntityTracker1_11(UserConnection user) { super(user, EntityType.PLAYER); @@ -35,12 +34,11 @@ public class EntityTracker1_11 extends EntityTrackerBase { public void removeEntity(int entityId) { super.removeEntity(entityId); - if (isHologram(entityId)) - removeHologram(entityId); + removeHologram(entityId); } - public void addHologram(int entId) { - holograms.add(entId); + public boolean addHologram(int entId) { + return holograms.add(entId); } public boolean isHologram(int entId) { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java index 5cdd823cd..e2098c0ac 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/blockconnections/ConnectionData.java @@ -38,22 +38,22 @@ 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 it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; 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 BlockChangeRecord1_8[] EMPTY_RECORDS = new BlockChangeRecord1_8[0]; public static BlockConnectionProvider blockConnectionProvider; - static Int2ObjectMap idToKey = new Int2ObjectOpenHashMap<>(8582, 1F); - static Map keyToId = new HashMap<>(8582, 1F); + static Int2ObjectMap idToKey = new Int2ObjectOpenHashMap<>(8582, .99F); + static Object2IntMap keyToId = new Object2IntOpenHashMap<>(8582, .99F); static Int2ObjectMap connectionHandlerMap = new Int2ObjectOpenHashMap<>(1); static Int2ObjectMap blockConnectionData = new Int2ObjectOpenHashMap<>(1); - static IntSet occludingStates = new IntOpenHashSet(377, 1F); + static IntSet occludingStates = new IntOpenHashSet(377, .99F); public static void update(UserConnection user, Position position) { for (BlockFace face : BlockFace.values()) { @@ -231,10 +231,10 @@ public class ConnectionData { keyToId.put(key, id); } - connectionHandlerMap = new Int2ObjectOpenHashMap<>(3650, 1F); + connectionHandlerMap = new Int2ObjectOpenHashMap<>(3650, .99F); if (!Via.getConfig().isReduceBlockStorageMemory()) { - blockConnectionData = new Int2ObjectOpenHashMap<>(1146, 1F); + blockConnectionData = new Int2ObjectOpenHashMap<>(1146, .99F); JsonObject mappingBlockConnections = MappingDataLoader.loadData("blockConnections.json"); for (Entry entry : mappingBlockConnections.entrySet()) { int id = keyToId.get(entry.getKey()); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/data/EntityTypeRewriter.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/data/EntityTypeRewriter.java index 48dc88cfc..8c573576c 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/data/EntityTypeRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/data/EntityTypeRewriter.java @@ -21,7 +21,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; public class EntityTypeRewriter { - private static final Int2IntMap ENTITY_TYPES = new Int2IntOpenHashMap(83, 1F); + private static final Int2IntMap ENTITY_TYPES = new Int2IntOpenHashMap(83, .99F); static { ENTITY_TYPES.defaultReturnValue(-1); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index a4a5e916d..c33526eca 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java @@ -50,7 +50,7 @@ import java.util.List; import java.util.Optional; public class WorldPackets { - private static final IntSet VALID_BIOMES = new IntOpenHashSet(70, 1F); + private static final IntSet VALID_BIOMES = new IntOpenHashSet(70, .99F); static { // Client will crash if it receives a invalid biome id diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java index 73b2967a4..5ede7f119 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java @@ -21,14 +21,15 @@ import com.viaversion.viaversion.api.connection.StorableObject; import com.viaversion.viaversion.api.minecraft.Position; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; +import space.vectrix.flare.SyncMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; // TODO Fix memory leak lolz (only a smol one tho) public class BlockStorage implements StorableObject { - private static final IntSet WHITELIST = new IntOpenHashSet(46, 1F); - private final Map blocks = new ConcurrentHashMap<>(); + private static final IntSet WHITELIST = new IntOpenHashSet(46, .99F); + private final Map blocks = SyncMap.hashmap(); static { // Flower pots diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/data/MappingData.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/data/MappingData.java index 52fa738b4..88b52a360 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/data/MappingData.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/data/MappingData.java @@ -47,7 +47,7 @@ public class MappingData extends MappingDataBase { JsonObject heightMapData = MappingDataLoader.loadData("heightMapData-1.14.json"); JsonArray motionBlocking = heightMapData.getAsJsonArray("MOTION_BLOCKING"); - this.motionBlocking = new IntOpenHashSet(motionBlocking.size(), 1F); + this.motionBlocking = new IntOpenHashSet(motionBlocking.size(), .99F); for (JsonElement blockState : motionBlocking) { String key = blockState.getAsString(); Integer id = blockStateMap.get(key); @@ -59,7 +59,7 @@ public class MappingData extends MappingDataBase { } if (Via.getConfig().isNonFullBlockLightFix()) { - nonFullBlocks = new IntOpenHashSet(1611, 1F); + nonFullBlocks = new IntOpenHashSet(1611, .99F); for (Map.Entry blockstates : oldMappings.getAsJsonObject("blockstates").entrySet()) { final String state = blockstates.getValue().getAsString(); if (state.contains("_slab") || state.contains("_stairs") || state.contains("_wall[")) { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/storage/EntityTracker1_14.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/storage/EntityTracker1_14.java index 05805f4af..e3d4ce6fc 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/storage/EntityTracker1_14.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/storage/EntityTracker1_14.java @@ -20,15 +20,14 @@ package com.viaversion.viaversion.protocols.protocol1_14to1_13_2.storage; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.entities.Entity1_14Types; import com.viaversion.viaversion.data.entity.EntityTrackerBase; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import space.vectrix.flare.fastutil.Int2ObjectSyncMap; public class EntityTracker1_14 extends EntityTrackerBase { - private final Map insentientData = new ConcurrentHashMap<>(); + private final Int2ObjectMap insentientData = Int2ObjectSyncMap.hashmap(); // 0x1 = sleeping, 0x2 = riptide - private final Map sleepingAndRiptideData = new ConcurrentHashMap<>(); - private final Map playerEntityFlags = new ConcurrentHashMap<>(); + private final Int2ObjectMap sleepingAndRiptideData = Int2ObjectSyncMap.hashmap(); + private final Int2ObjectMap playerEntityFlags = Int2ObjectSyncMap.hashmap(); private int latestTradeWindowId; private boolean forceSendCenterChunk = true; private int chunkCenterX, chunkCenterZ; @@ -52,7 +51,7 @@ public class EntityTracker1_14 extends EntityTrackerBase { } public void setInsentientData(int entity, byte value) { - insentientData.put(entity, value); + insentientData.put(entity, (Byte) value); } private static byte zeroIfNull(Byte val) { @@ -69,7 +68,7 @@ public class EntityTracker1_14 extends EntityTrackerBase { if (newValue == 0) { sleepingAndRiptideData.remove(player); } else { - sleepingAndRiptideData.put(player, newValue); + sleepingAndRiptideData.put(player, (Byte) newValue); } } @@ -82,7 +81,7 @@ public class EntityTracker1_14 extends EntityTrackerBase { if (newValue == 0) { sleepingAndRiptideData.remove(player); } else { - sleepingAndRiptideData.put(player, newValue); + sleepingAndRiptideData.put(player, (Byte) newValue); } } @@ -91,7 +90,7 @@ public class EntityTracker1_14 extends EntityTrackerBase { } public void setEntityFlags(int player, byte data) { - playerEntityFlags.put(player, data); + playerEntityFlags.put(player, (Byte) data); } public int getLatestTradeWindowId() { diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/ItemRewriter.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/ItemRewriter.java index c09342b86..5b9dcef86 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/ItemRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/ItemRewriter.java @@ -36,7 +36,7 @@ public class ItemRewriter { private static final Map POTION_NAME_TO_ID = new HashMap<>(); private static final Map POTION_ID_TO_NAME = new HashMap<>(); - private static final Int2IntMap POTION_INDEX = new Int2IntOpenHashMap(36, 1F); + private static final Int2IntMap POTION_INDEX = new Int2IntOpenHashMap(36, .99F); static { /* Entities */ diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/sounds/Effect.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/sounds/Effect.java index 225b521fb..6bbb98208 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/sounds/Effect.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/sounds/Effect.java @@ -22,7 +22,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; public class Effect { - private static final Int2IntMap EFFECTS = new Int2IntOpenHashMap(19, 1F); + private static final Int2IntMap EFFECTS = new Int2IntOpenHashMap(19, .99F); static { addRewrite(1005, 1010); //Play music disc diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/storage/EntityTracker1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/storage/EntityTracker1_9.java index b539cf4a0..e3eef2cbc 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/storage/EntityTracker1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/storage/EntityTracker1_9.java @@ -18,7 +18,6 @@ package com.viaversion.viaversion.protocols.protocol1_9to1_8.storage; import com.google.common.cache.CacheBuilder; -import com.google.common.collect.Sets; import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.legacy.bossbar.BossBar; @@ -40,20 +39,22 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.chat.GameMode; import com.viaversion.viaversion.protocols.protocol1_9to1_8.metadata.MetadataRewriter1_9To1_8; import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BossBarProvider; import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.EntityIdProvider; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.IntSet; +import space.vectrix.flare.fastutil.Int2ObjectSyncMap; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; public class EntityTracker1_9 extends EntityTrackerBase { public static final String WITHER_TRANSLATABLE = "{\"translate\":\"entity.WitherBoss.name\"}"; public static final String DRAGON_TRANSLATABLE = "{\"translate\":\"entity.EnderDragon.name\"}"; - private final Map uuidMap = new ConcurrentHashMap<>(); - private final Map> metadataBuffer = new ConcurrentHashMap<>(); - private final Map vehicleMap = new ConcurrentHashMap<>(); - private final Map bossBarMap = new ConcurrentHashMap<>(); - private final Set validBlocking = Sets.newConcurrentHashSet(); - private final Set knownHolograms = Sets.newConcurrentHashSet(); + private final Int2ObjectMap uuidMap = Int2ObjectSyncMap.hashmap(); + private final Int2ObjectMap> metadataBuffer = Int2ObjectSyncMap.hashmap(); + private final Int2ObjectMap vehicleMap = Int2ObjectSyncMap.hashmap(); + private final Int2ObjectMap bossBarMap = Int2ObjectSyncMap.hashmap(); + private final IntSet validBlocking = Int2ObjectSyncMap.hashset(); + private final Set knownHolograms = Int2ObjectSyncMap.hashset(); private final Set blockInteractions = Collections.newSetFromMap(CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterAccess(250, TimeUnit.MILLISECONDS) diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java b/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java index 2634a2073..bee550eac 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/EntityRewriter.java @@ -196,7 +196,7 @@ public abstract class EntityRewriter extends RewriterBase */ public & EntityType> void mapTypes(EntityType[] oldTypes, Class newTypeClass) { if (typeMappings == null) { - typeMappings = new Int2IntOpenHashMap(oldTypes.length, 1F); + typeMappings = new Int2IntOpenHashMap(oldTypes.length, .99F); typeMappings.defaultReturnValue(-1); } for (EntityType oldType : oldTypes) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 90b3a6f0f..fdb9b78a4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,8 @@ metadata.format.version = "1.1" adventure = "4.9.1" gson = "2.8.8" -fastutil = "8.3.1" +fastutil = "8.5.6" +flare = "1.0.0" openNBT = "2.0-SNAPSHOT" javassist = "3.28.0-GA" @@ -34,6 +35,8 @@ adventureTextSerializerLegacy = { group = "net.kyori", name = "adventure-text-se gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } fastutil = { group = "it.unimi.dsi", name = "fastutil", version.ref = "fastutil" } +flare = { group = "space.vectrix.flare", name = "flare", version.ref = "flare" } +flareFastutil = { group = "space.vectrix.flare", name = "flare-fastutil", version.ref = "flare" } openNBT = { group = "com.viaversion", name = "opennbt", version.ref = "openNBT" } javassist = { group = "org.javassist", name = "javassist", version.ref = "javassist" }