From d7bf4f527aa9708249909edddbeee685fc376d63 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sat, 25 Jul 2020 17:23:57 +0200 Subject: [PATCH] fix some mappings problems, improve performance --- .../java/de/bixilon/minosoft/Minosoft.java | 3 + .../datatypes/objectLoader/blocks/Block.java | 27 ++++--- .../datatypes/objectLoader/blocks/Blocks.java | 72 ++++--------------- .../enchantments/Enchantment.java | 3 +- .../enchantments/Enchantments.java | 7 +- .../objectLoader/entities/items/Item.java | 17 +++++ .../objectLoader/entities/items/Items.java | 19 ++--- .../objectLoader/statistics/Statistics.java | 5 -- .../de/bixilon/minosoft/util/ChunkUtil.java | 6 +- 9 files changed, 61 insertions(+), 98 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/Minosoft.java b/src/main/java/de/bixilon/minosoft/Minosoft.java index 6e85ce792..a7440b3ce 100644 --- a/src/main/java/de/bixilon/minosoft/Minosoft.java +++ b/src/main/java/de/bixilon/minosoft/Minosoft.java @@ -18,6 +18,7 @@ import de.bixilon.minosoft.config.Configuration; import de.bixilon.minosoft.config.GameConfiguration; import de.bixilon.minosoft.game.datatypes.Mappings; import de.bixilon.minosoft.game.datatypes.Player; +import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block; import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Blocks; import de.bixilon.minosoft.game.datatypes.objectLoader.enchantments.Enchantments; import de.bixilon.minosoft.game.datatypes.objectLoader.entities.Entities; @@ -162,6 +163,8 @@ public class Minosoft { } Log.verbose(String.format("Loaded mappings for version %s in %dms (%s)", version, (System.currentTimeMillis() - startTime), version.getReleaseName())); } + // end, we must set the nullBlock + Blocks.nullBlock = new Block("minecraft", "air"); } catch (IOException e) { Log.fatal("Error occurred while loading version mapping: " + e.getLocalizedMessage()); System.exit(1); diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Block.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Block.java index d6101b3eb..40dc361fa 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Block.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Block.java @@ -13,20 +13,22 @@ package de.bixilon.minosoft.game.datatypes.objectLoader.blocks; +import java.util.HashSet; + public class Block { final String mod; final String identifier; final BlockRotation rotation; - final BlockProperties[] properties; + final HashSet properties; - public Block(String mod, String identifier, BlockProperties[] properties, BlockRotation rotation) { + public Block(String mod, String identifier, HashSet properties, BlockRotation rotation) { this.mod = mod; this.identifier = identifier; this.properties = properties; this.rotation = rotation; } - public Block(String mod, String identifier, BlockProperties[] properties) { + public Block(String mod, String identifier, HashSet properties) { this.mod = mod; this.identifier = identifier; this.properties = properties; @@ -36,14 +38,14 @@ public class Block { public Block(String mod, String identifier, BlockRotation rotation) { this.mod = mod; this.identifier = identifier; - this.properties = new BlockProperties[0]; + this.properties = new HashSet<>(); this.rotation = rotation; } public Block(String mod, String identifier) { this.mod = mod; this.identifier = identifier; - this.properties = new BlockProperties[0]; + this.properties = new HashSet<>(); this.rotation = BlockRotation.NONE; } @@ -59,7 +61,7 @@ public class Block { return rotation; } - public BlockProperties[] getProperties() { + public HashSet getProperties() { return properties; } @@ -71,7 +73,7 @@ public class Block { out.append("rotation="); out.append(getRotation()); } - if (properties.length > 0) { + if (properties.size() > 0) { if (out.length() > 0) { out.append(" ,"); } else { @@ -94,7 +96,11 @@ public class Block { @Override public int hashCode() { - return mod.hashCode() * identifier.hashCode(); + int ret = mod.hashCode() * identifier.hashCode() * rotation.hashCode(); + if (properties.size() > 0) { + ret *= properties.hashCode(); + } + return ret; } @Override @@ -102,7 +108,10 @@ public class Block { if (super.equals(obj)) { return true; } + if (hashCode() != obj.hashCode()) { + return false; + } Block their = (Block) obj; - return getMod().equals(their.getMod()) && getIdentifier().equals(their.getIdentifier()) && getRotation() == their.getRotation() && Blocks.propertiesEquals(getProperties(), their.getProperties()); + return getIdentifier().equals(their.getIdentifier()) && getRotation() == their.getRotation() && getProperties().equals(their.getProperties()) && getMod().equals(their.getMod()); } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Blocks.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Blocks.java index cdbb28b15..6ade9ad61 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Blocks.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Blocks.java @@ -17,12 +17,12 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; -import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; public class Blocks { public static Block nullBlock; - static ArrayList blockList = new ArrayList<>(); + static HashSet blockList = new HashSet<>(); static HashMap> blockMap = new HashMap<>(); // version -> (protocolId > block) static HashMap> propertiesMapping = new HashMap<>(); static HashMap rotationMapping = new HashMap<>(); @@ -460,6 +460,7 @@ public class Blocks { JsonArray statesArray = identifierJSON.getAsJsonArray("states"); for (int i = 0; i < statesArray.size(); i++) { JsonObject statesJSON = statesArray.get(i).getAsJsonObject(); + Block block; if (statesJSON.has("properties")) { // properties are optional JsonObject propertiesJSON = statesJSON.getAsJsonObject("properties"); @@ -471,8 +472,7 @@ public class Blocks { rotation = rotationMapping.get(propertiesJSON.get("rotation").getAsString()); propertiesJSON.remove("rotation"); } - BlockProperties[] properties = new BlockProperties[propertiesJSON.size()]; - int ii = 0; + HashSet properties = new HashSet<>(); for (String propertyName : propertiesJSON.keySet()) { if (propertiesMapping.get(propertyName) == null) { throw new RuntimeException(String.format("Unknown block property: %s (identifier=%s)", propertyName, identifierName)); @@ -480,51 +480,24 @@ public class Blocks { if (propertiesMapping.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()) == null) { throw new RuntimeException(String.format("Unknown block property: %s -> %s (identifier=%s)", propertyName, propertiesJSON.get(propertyName).getAsString(), identifierName)); } - properties[ii] = propertiesMapping.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()); - ii++; + properties.add(propertiesMapping.get(propertyName).get(propertiesJSON.get(propertyName).getAsString())); } - Block block = new Block(mod, identifierName, properties, rotation); - if (blockList.contains(block)) { - block = blockList.get(blockList.indexOf(block)); - } - - if (block == null) { - // does not exist. create - block = new Block(mod, identifierName, properties, rotation); - blockList.add(block); - } - - // set nullBlock - if (block.getIdentifier().equals("air")) { - nullBlock = block; - } - - int blockId = getBlockId(statesJSON, version); - checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping, version); - versionMapping.put(blockId, block); + block = new Block(mod, identifierName, properties, rotation); } else { // no properties, directly add block - Block block = new Block(mod, identifierName); - if (blockList.contains(block)) { - block = blockList.get(blockList.indexOf(block)); - } - - if (block == null) { - // does not exist. create - block = new Block(mod, identifierName); - blockList.add(block); - } - - int blockId = getBlockId(statesJSON, version); - checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping, version); - versionMapping.put(blockId, block); + block = new Block(mod, identifierName); } + int blockId = getBlockId(statesJSON, version); + checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping, version); + versionMapping.put(blockId, block); + blockList.add(block); } } blockMap.put(version, versionMapping); } + private static int getBlockId(JsonObject json, ProtocolVersion version) { int blockId = json.get("id").getAsInt(); if (version.getVersionNumber() <= ProtocolVersion.VERSION_1_12_2.getVersionNumber()) { @@ -537,27 +510,6 @@ public class Blocks { return blockId; } - public static boolean propertiesEquals(BlockProperties[] one, BlockProperties[] two) { - if (one.length != two.length) { - return false; - } - for (BlockProperties property : one) { - if (!containsElement(two, property)) { - return false; - } - } - return true; - } - - public static boolean containsElement(BlockProperties[] arr, BlockProperties value) { - for (BlockProperties property : arr) { - if (property == value) { - return true; - } - } - return false; - } - public static void checkAndCrashIfBlockIsIn(int blockId, String identifierName, HashBiMap versionMapping, ProtocolVersion version) { if (versionMapping.containsKey(blockId)) { String blockIdString; diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/enchantments/Enchantment.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/enchantments/Enchantment.java index 2e4982b72..1575b3aaf 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/enchantments/Enchantment.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/enchantments/Enchantment.java @@ -40,6 +40,7 @@ public class Enchantment { if (super.equals(obj)) { return true; } - return toString().equals(obj.toString()); + Enchantment their = (Enchantment) obj; + return getIdentifier().equals(their.getIdentifier()) && getMod().equals(their.getMod()); } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/enchantments/Enchantments.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/enchantments/Enchantments.java index 4f8176774..e6a9d5641 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/enchantments/Enchantments.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/enchantments/Enchantments.java @@ -17,15 +17,13 @@ import com.google.common.collect.HashBiMap; import com.google.gson.JsonObject; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; -import java.util.ArrayList; import java.util.HashMap; public class Enchantments { - static ArrayList enchantmentList = new ArrayList<>(); static HashMap> enchantmentMap = new HashMap<>(); - public static Enchantment getEnchantmentBdyId(int protocolId, ProtocolVersion version) { + public static Enchantment getEnchantmentById(int protocolId, ProtocolVersion version) { if (version.getVersionNumber() < ProtocolVersion.VERSION_1_12_2.getVersionNumber()) { version = ProtocolVersion.VERSION_1_12_2; } @@ -36,9 +34,6 @@ public class Enchantments { HashBiMap versionMapping = HashBiMap.create(); for (String identifierName : json.keySet()) { Enchantment enchantment = new Enchantment(mod, identifierName); - if (enchantmentList.contains(enchantment)) { - enchantment = enchantmentList.get(enchantmentList.indexOf(enchantment)); - } versionMapping.put(json.getAsJsonObject(identifierName).get("id").getAsInt(), enchantment); } enchantmentMap.put(version, versionMapping); diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/entities/items/Item.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/entities/items/Item.java index 76a5113fb..6f6269b3a 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/entities/items/Item.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/entities/items/Item.java @@ -34,4 +34,21 @@ public class Item { public String toString() { return String.format("%s:%s", getMod(), getIdentifier()); } + + @Override + public int hashCode() { + return mod.hashCode() * identifier.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (super.equals(obj)) { + return true; + } + if (hashCode() != obj.hashCode()) { + return false; + } + Item their = (Item) obj; + return getIdentifier().equals(their.getIdentifier()) && getMod().equals(their.getMod()); + } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/entities/items/Items.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/entities/items/Items.java index 23f592972..9e8ee4d52 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/entities/items/Items.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/entities/items/Items.java @@ -17,12 +17,12 @@ import com.google.common.collect.HashBiMap; import com.google.gson.JsonObject; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; -import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; public class Items { - static ArrayList itemList = new ArrayList<>(); + static HashSet itemList = new HashSet<>(); static HashMap> itemMap = new HashMap<>(); // version -> (protocolId > Item) public static Item getItemByLegacy(int protocolId, int protocolMetaData) { @@ -45,12 +45,8 @@ public class Items { public static void load(String mod, JsonObject json, ProtocolVersion version) { HashBiMap versionMapping = HashBiMap.create(); for (String identifierName : json.keySet()) { - Item item = getItem(mod, identifierName); - if (item == null) { - // does not exist. create - item = new Item(mod, identifierName); - itemList.add(item); - } + Item item = new Item(mod, identifierName); + itemList.add(item); JsonObject identifierJSON = json.getAsJsonObject(identifierName); int itemId = identifierJSON.get("id").getAsInt(); if (version.getVersionNumber() <= ProtocolVersion.VERSION_1_12_2.getVersionNumber()) { @@ -66,12 +62,7 @@ public class Items { } public static Item getItem(String mod, String identifier) { - for (Item item : itemList) { - if (item.getMod().equals(mod) && item.getIdentifier().equals(identifier)) { - return item; - } - } - return null; + return new Item(mod, identifier); } public static int getItemId(Item item, ProtocolVersion version) { diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/statistics/Statistics.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/statistics/Statistics.java index 40e19da96..bca1191d9 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/statistics/Statistics.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/statistics/Statistics.java @@ -17,12 +17,10 @@ import com.google.common.collect.HashBiMap; import com.google.gson.JsonObject; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; -import java.util.ArrayList; import java.util.HashMap; public class Statistics { - static ArrayList statisticList = new ArrayList<>(); static HashMap> statisticsIdMap = new HashMap<>(); static HashMap> statisticsIdentifierMap = new HashMap<>(); @@ -45,9 +43,6 @@ public class Statistics { HashBiMap versionIdentifierMapping = HashBiMap.create(); for (String identifierName : json.keySet()) { Statistic statistic = new Statistic(mod, identifierName); - if (statisticList.contains(statistic)) { - statistic = statisticList.get(statisticList.indexOf(statistic)); - } if (json.getAsJsonObject(identifierName).has("id")) { versionIdMapping.put(json.getAsJsonObject(identifierName).get("id").getAsInt(), statistic); } else { diff --git a/src/main/java/de/bixilon/minosoft/util/ChunkUtil.java b/src/main/java/de/bixilon/minosoft/util/ChunkUtil.java index 097de64f3..cb5f28b47 100644 --- a/src/main/java/de/bixilon/minosoft/util/ChunkUtil.java +++ b/src/main/java/de/bixilon/minosoft/util/ChunkUtil.java @@ -82,7 +82,7 @@ public class ChunkUtil { // ToDo light, biome Block block = Blocks.getBlockByLegacy(singeBlockId, singleMeta); - if (block == Blocks.nullBlock) { + if (block.equals(Blocks.nullBlock)) { arrayPos++; continue; } @@ -130,7 +130,7 @@ public class ChunkUtil { for (int nibbleZ = 0; nibbleZ < 16; nibbleZ++) { for (int nibbleX = 0; nibbleX < 16; nibbleX++) { Block block = Blocks.getBlockByLegacy(blockData[arrayPos]); - if (block == Blocks.nullBlock) { + if (block.equals(Blocks.nullBlock)) { arrayPos++; continue; } @@ -186,7 +186,7 @@ public class ChunkUtil { blockId &= individualValueMask; Block block = palette.byId(blockId); - if (block == Blocks.nullBlock) { + if (block.equals(Blocks.nullBlock)) { continue; } blockMap.put(new ChunkNibbleLocation(nibbleX, nibbleY, nibbleZ), block);