From 3669fa1deed1bf0ee0a18f516bcd8d0aca076020 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Fri, 31 Jul 2020 22:21:53 +0200 Subject: [PATCH] wip snapshot support, version flattening update --- .../java/de/bixilon/minosoft/Minosoft.java | 14 +- .../datatypes/entities/meta/EggMetaData.java | 4 +- .../entities/meta/EnderPearlMetaData.java | 4 +- .../meta/ExperienceBottleMetaData.java | 4 +- .../entities/meta/EyeOfEnderMetaData.java | 4 +- .../entities/meta/ItemedFireballMetaData.java | 4 +- .../entities/meta/SnowballMetaData.java | 4 +- .../datatypes/objectLoader/ObjectLoader.java | 5 +- .../datatypes/objectLoader/blocks/Blocks.java | 59 ++-- .../datatypes/objectLoader/items/Items.java | 4 - .../objectLoader/versions/LegacyVersion.java | 59 ++++ .../objectLoader/versions/Version.java | 306 ++++++++++++++++++ .../objectLoader/versions/Versions.java | 92 ++++++ .../protocol/PacketDataException.java | 20 -- .../protocol/protocol/ProtocolDefinition.java | 2 + 15 files changed, 499 insertions(+), 86 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/LegacyVersion.java create mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/Version.java create mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/Versions.java delete mode 100644 src/main/java/de/bixilon/minosoft/protocol/protocol/PacketDataException.java diff --git a/src/main/java/de/bixilon/minosoft/Minosoft.java b/src/main/java/de/bixilon/minosoft/Minosoft.java index 153dc228d..a499c09c5 100644 --- a/src/main/java/de/bixilon/minosoft/Minosoft.java +++ b/src/main/java/de/bixilon/minosoft/Minosoft.java @@ -16,13 +16,14 @@ package de.bixilon.minosoft; import de.bixilon.minosoft.config.Configuration; import de.bixilon.minosoft.config.GameConfiguration; import de.bixilon.minosoft.game.datatypes.Player; -import de.bixilon.minosoft.game.datatypes.objectLoader.ObjectLoader; +import de.bixilon.minosoft.game.datatypes.objectLoader.versions.Versions; import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.logging.LogLevel; import de.bixilon.minosoft.mojang.api.MojangAccount; import de.bixilon.minosoft.protocol.network.Connection; import de.bixilon.minosoft.util.FolderUtil; import de.bixilon.minosoft.util.OSUtil; +import de.bixilon.minosoft.util.Util; import java.io.File; import java.io.IOException; @@ -54,10 +55,13 @@ public class Minosoft { Log.info("Checking assets..."); checkAssets(); Log.info("Assets checking done"); - Log.info("Loading all mappings..."); - long mappingsStart = System.currentTimeMillis(); - ObjectLoader.loadMappings(); - Log.info(String.format("Mappings loaded within %sms", (System.currentTimeMillis() - mappingsStart))); + Log.info("Loading versions.json..."); + try { + Versions.load(Util.readJsonFromFile(Config.homeDir + "assets/mapping/versions.json")); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } checkClientToken(); diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EggMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EggMetaData.java index 8ee36bbe9..24700ce15 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EggMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EggMetaData.java @@ -13,7 +13,7 @@ package de.bixilon.minosoft.game.datatypes.entities.meta; import de.bixilon.minosoft.game.datatypes.inventory.Slot; -import de.bixilon.minosoft.game.datatypes.objectLoader.items.Items; +import de.bixilon.minosoft.game.datatypes.objectLoader.items.Item; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; public class EggMetaData extends ItemedThrowableMetaData { @@ -26,7 +26,7 @@ public class EggMetaData extends ItemedThrowableMetaData { public Slot getItem() { Slot superSlot = super.getItem(); if (superSlot == null) { - return new Slot(Items.getItem("minecraft", "egg")); + return new Slot(new Item("minecraft", "egg")); } return superSlot; } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EnderPearlMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EnderPearlMetaData.java index 813c62cf8..b4c44a3fe 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EnderPearlMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EnderPearlMetaData.java @@ -13,7 +13,7 @@ package de.bixilon.minosoft.game.datatypes.entities.meta; import de.bixilon.minosoft.game.datatypes.inventory.Slot; -import de.bixilon.minosoft.game.datatypes.objectLoader.items.Items; +import de.bixilon.minosoft.game.datatypes.objectLoader.items.Item; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; public class EnderPearlMetaData extends ItemedThrowableMetaData { @@ -26,7 +26,7 @@ public class EnderPearlMetaData extends ItemedThrowableMetaData { public Slot getItem() { Slot superSlot = super.getItem(); if (superSlot == null) { - return new Slot(Items.getItem("minecraft", "ender_pearl")); + return new Slot(new Item("minecraft", "ender_pearl")); } return superSlot; } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ExperienceBottleMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ExperienceBottleMetaData.java index 845976b0f..88792c92c 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ExperienceBottleMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ExperienceBottleMetaData.java @@ -13,7 +13,7 @@ package de.bixilon.minosoft.game.datatypes.entities.meta; import de.bixilon.minosoft.game.datatypes.inventory.Slot; -import de.bixilon.minosoft.game.datatypes.objectLoader.items.Items; +import de.bixilon.minosoft.game.datatypes.objectLoader.items.Item; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; public class ExperienceBottleMetaData extends ItemedThrowableMetaData { @@ -26,7 +26,7 @@ public class ExperienceBottleMetaData extends ItemedThrowableMetaData { public Slot getItem() { Slot superSlot = super.getItem(); if (superSlot == null) { - return new Slot(Items.getItem("minecraft", "experience_bottle")); + return new Slot(new Item("minecraft", "experience_bottle")); } return superSlot; } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EyeOfEnderMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EyeOfEnderMetaData.java index fb8ef3af8..0f1e74535 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EyeOfEnderMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EyeOfEnderMetaData.java @@ -13,7 +13,7 @@ package de.bixilon.minosoft.game.datatypes.entities.meta; import de.bixilon.minosoft.game.datatypes.inventory.Slot; -import de.bixilon.minosoft.game.datatypes.objectLoader.items.Items; +import de.bixilon.minosoft.game.datatypes.objectLoader.items.Item; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; public class EyeOfEnderMetaData extends EntityMetaData { @@ -23,7 +23,7 @@ public class EyeOfEnderMetaData extends EntityMetaData { } public Slot getItem() { - Slot defaultValue = new Slot(Items.getItem("minecraft", "ender_eye")); + Slot defaultValue = new Slot(new Item("minecraft", "ender_eye")); if (version.getVersionNumber() < ProtocolVersion.VERSION_1_14_4.getVersionNumber()) { return defaultValue; } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ItemedFireballMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ItemedFireballMetaData.java index 64b8047af..b01da24d1 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ItemedFireballMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ItemedFireballMetaData.java @@ -13,7 +13,7 @@ package de.bixilon.minosoft.game.datatypes.entities.meta; import de.bixilon.minosoft.game.datatypes.inventory.Slot; -import de.bixilon.minosoft.game.datatypes.objectLoader.items.Items; +import de.bixilon.minosoft.game.datatypes.objectLoader.items.Item; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; public class ItemedFireballMetaData extends AbstractFireballMetaData { @@ -23,7 +23,7 @@ public class ItemedFireballMetaData extends AbstractFireballMetaData { } public Slot getItem() { - final Slot defaultValue = new Slot(Items.getItem("minecraft", "fire_charge")); + final Slot defaultValue = new Slot(new Item("minecraft", "fire_charge")); if (version.getVersionNumber() <= ProtocolVersion.VERSION_1_14_4.getVersionNumber()) { return defaultValue; } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/SnowballMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/SnowballMetaData.java index bac8c8eff..8338b95d4 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/SnowballMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/SnowballMetaData.java @@ -13,7 +13,7 @@ package de.bixilon.minosoft.game.datatypes.entities.meta; import de.bixilon.minosoft.game.datatypes.inventory.Slot; -import de.bixilon.minosoft.game.datatypes.objectLoader.items.Items; +import de.bixilon.minosoft.game.datatypes.objectLoader.items.Item; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; public class SnowballMetaData extends ItemedThrowableMetaData { @@ -26,7 +26,7 @@ public class SnowballMetaData extends ItemedThrowableMetaData { public Slot getItem() { Slot superSlot = super.getItem(); if (superSlot == null) { - return new Slot(Items.getItem("minecraft", "snowball")); + return new Slot(new Item("minecraft", "snowball")); } return superSlot; } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/ObjectLoader.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/ObjectLoader.java index 5a233e123..cf51c8f72 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/ObjectLoader.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/ObjectLoader.java @@ -17,7 +17,6 @@ import com.google.gson.JsonObject; import de.bixilon.minosoft.Config; import de.bixilon.minosoft.game.datatypes.Mappings; import de.bixilon.minosoft.game.datatypes.objectLoader.blockIds.BlockIds; -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.dimensions.Dimensions; import de.bixilon.minosoft.game.datatypes.objectLoader.effects.MobEffects; @@ -66,15 +65,13 @@ public class ObjectLoader { } break; case BLOCKS: - Blocks.load(mod, modJSON, version); + Blocks.load(mod, modJSON, false); break; } } } 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/Blocks.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/blocks/Blocks.java index 6643a1a07..0b69ddaf4 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 @@ -21,9 +21,7 @@ import java.util.HashMap; import java.util.HashSet; public class Blocks { - public static Block nullBlock; - static HashSet blockList = new HashSet<>(); - static HashMap> blockMap = new HashMap<>(); // version -> (protocolId > block) + public static final Block nullBlock = new Block("minecraft", "air"); static HashMap> propertiesMapping = new HashMap<>(); static HashMap rotationMapping = new HashMap<>(); @@ -462,24 +460,7 @@ public class Blocks { rotationMapping.put("east_west", BlockRotation.EAST_WEST); } - public static Block getBlockByLegacy(int protocolId, int protocolMetaData) { - int blockId = protocolId << 4 | protocolMetaData; - return getBlock(blockId, ProtocolVersion.VERSION_1_12_2); - } - - - public static Block getBlockByLegacy(int blockIdAndMetaData) { - return getBlock(blockIdAndMetaData, ProtocolVersion.VERSION_1_12_2); - } - - public static Block getBlock(int protocolId, ProtocolVersion version) { - if (version.getVersionNumber() < ProtocolVersion.VERSION_1_12_2.getVersionNumber()) { - version = ProtocolVersion.VERSION_1_12_2; - } - return blockMap.get(version).get(protocolId); - } - - public static void load(String mod, JsonObject json, ProtocolVersion version) { + public static HashBiMap load(String mod, JsonObject json, boolean meta) { HashBiMap versionMapping = HashBiMap.create(); for (String identifierName : json.keySet()) { JsonObject identifierJSON = json.getAsJsonObject(identifierName); @@ -517,19 +498,18 @@ public class Blocks { // no properties, directly add block block = new Block(mod, identifierName); } - int blockId = getBlockId(statesJSON, version); - checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping, version); + int blockId = getBlockId(statesJSON, meta); + checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping); versionMapping.put(blockId, block); - blockList.add(block); } } - blockMap.put(version, versionMapping); + return versionMapping; } - private static int getBlockId(JsonObject json, ProtocolVersion version) { + private static int getBlockId(JsonObject json, boolean meta) { int blockId = json.get("id").getAsInt(); - if (version.getVersionNumber() <= ProtocolVersion.VERSION_1_12_2.getVersionNumber()) { + if (meta) { // old format (with metadata) blockId <<= 4; if (json.has("meta")) { @@ -539,24 +519,21 @@ public class Blocks { return blockId; } - public static void checkAndCrashIfBlockIsIn(int blockId, String identifierName, HashBiMap versionMapping, ProtocolVersion version) { + public static void checkAndCrashIfBlockIsIn(int blockId, String identifierName, HashBiMap versionMapping) { if (versionMapping.containsKey(blockId)) { - String blockIdString; - if (version == ProtocolVersion.VERSION_1_12_2) { - blockIdString = String.format("%d:%d", blockId >> 4, blockId & 0xF); - } else { - blockIdString = String.valueOf(blockId); - } - throw new RuntimeException(String.format("Block Id %s is already present for %s! (identifier=%s, version=%s)", blockIdString, versionMapping.get(blockId), identifierName, version)); + throw new RuntimeException(String.format("Block Id %s is already present for %d! (identifier=%s)", blockId, versionMapping.get(blockId), identifierName)); } } + public static Block getBlock(int v, ProtocolVersion a) { + return null; + } - public static int getBlockId(Block block, ProtocolVersion version) { - int blockId = blockMap.get(version).inverse().get(block); - if (version.getVersionNumber() <= ProtocolVersion.VERSION_1_12_2.getVersionNumber()) { - return blockId >> 4; - } - return blockId; + public static Block getBlockByLegacy(int v, int w) { + return null; + } + + public static Block getBlockByLegacy(int i) { + return null; } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/items/Items.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/items/Items.java index 5bb87778a..8e9bce7e0 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/items/Items.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/items/Items.java @@ -61,10 +61,6 @@ public class Items { itemMap.put(version, versionMapping); } - public static Item getItem(String mod, String identifier) { - return new Item(mod, identifier); - } - public static int getItemId(Item item, ProtocolVersion version) { if (version.getVersionNumber() < ProtocolVersion.VERSION_1_12_2.getVersionNumber()) { version = ProtocolVersion.VERSION_1_12_2; diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/LegacyVersion.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/LegacyVersion.java new file mode 100644 index 000000000..5e91f4e4c --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/LegacyVersion.java @@ -0,0 +1,59 @@ +/* + * Codename Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.game.datatypes.objectLoader.versions; + +import com.google.common.collect.HashBiMap; +import com.google.gson.JsonObject; +import de.bixilon.minosoft.game.datatypes.Mappings; +import de.bixilon.minosoft.game.datatypes.objectLoader.motives.Motive; +import de.bixilon.minosoft.game.datatypes.objectLoader.particle.Particle; +import de.bixilon.minosoft.game.datatypes.objectLoader.statistics.Statistic; + +public class LegacyVersion extends Version { + HashBiMap motiveIdentifierMap; + HashBiMap particleIdentifierMap; + HashBiMap statisticIdentifierMap; + + public LegacyVersion() { + super("legacy", -2, null, null); + } + + @Override + public Motive getMotiveByIdentifier(String identifier) { + return motiveIdentifierMap.get(identifier); + } + + @Override + public Statistic getStatisticByIdentifier(String identifier) { + return statisticIdentifierMap.get(identifier); + } + + @Override + public Particle getParticleByIdentifier(String identifier) { + return particleIdentifierMap.get(identifier); + } + + @Override + public void load(Mappings type, JsonObject data) { + super.load(type, data); + } + + @Override + public void unload() { + super.unload(); + motiveIdentifierMap.clear(); + particleIdentifierMap.clear(); + statisticIdentifierMap.clear(); + } +} diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/Version.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/Version.java new file mode 100644 index 000000000..87d548221 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/Version.java @@ -0,0 +1,306 @@ +/* + * Codename Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.game.datatypes.objectLoader.versions; + +import com.google.common.collect.HashBiMap; +import com.google.gson.JsonObject; +import de.bixilon.minosoft.game.datatypes.Mappings; +import de.bixilon.minosoft.game.datatypes.objectLoader.blockIds.BlockId; +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.dimensions.Dimension; +import de.bixilon.minosoft.game.datatypes.objectLoader.effects.MobEffect; +import de.bixilon.minosoft.game.datatypes.objectLoader.enchantments.Enchantment; +import de.bixilon.minosoft.game.datatypes.objectLoader.items.Item; +import de.bixilon.minosoft.game.datatypes.objectLoader.motives.Motive; +import de.bixilon.minosoft.game.datatypes.objectLoader.particle.Particle; +import de.bixilon.minosoft.game.datatypes.objectLoader.statistics.Statistic; +import de.bixilon.minosoft.protocol.protocol.Packets; + +import static de.bixilon.minosoft.protocol.protocol.ProtocolDefinition.FLATTING_VERSION_ID; + +public class Version { + final String versionName; + final int protocolVersion; + + final HashBiMap serverboundPacketMapping; + final HashBiMap clientboundPacketMapping; + + HashBiMap itemMap; + HashBiMap entityMap; + HashBiMap motiveIdMap; + HashBiMap mobEffectMap; + HashBiMap dimensionMap; + HashBiMap blockMap; + HashBiMap blockIdMap; + HashBiMap enchantmentMap; + HashBiMap particleIdMap; + HashBiMap statisticIdMap; + + public Version(String versionName, int protocolVersion, HashBiMap serverboundPacketMapping, HashBiMap clientboundPacketMapping) { + this.versionName = versionName; + this.protocolVersion = protocolVersion; + this.serverboundPacketMapping = serverboundPacketMapping; + this.clientboundPacketMapping = clientboundPacketMapping; + } + + public String getVersionName() { + return versionName; + } + + public int getProtocolVersion() { + return protocolVersion; + } + + public Packets.Clientbound getPacketByCommand(int command) { // state must be play! + return clientboundPacketMapping.inverse().get(command); + } + + public int getCommandByPacket(Packets.Serverbound packet) { + return serverboundPacketMapping.get(packet); + } + + public int getCommandByPacket(Packets.Clientbound packet) { + return clientboundPacketMapping.get(packet); + } + + public HashBiMap getClientboundPacketMapping() { + return clientboundPacketMapping; + } + + public HashBiMap getServerboundPacketMapping() { + return serverboundPacketMapping; + } + + @Override + public int hashCode() { + return getProtocolVersion(); + } + + public Item getItemById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getItemById(protocolId); + } + return itemMap.get(protocolId); + } + + public int getItemId(Item item) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getItemId(item); + } + return itemMap.inverse().get(item); + } + + public String getEntityIdentifierById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getEntityIdentifierById(protocolId); + } + return entityMap.get(protocolId); + } + + public Motive getMotiveById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getMotiveById(protocolId); + } + return motiveIdMap.get(protocolId); + } + + public Motive getMotiveByIdentifier(String identifier) { + if (identifier.contains(":")) { + String[] splitted = identifier.split(":", 2); + if (!splitted[0].equals("minecraft")) { + return null; + } + identifier = splitted[1]; + } + // 1.7.x + return Versions.legacyVersion.getMotiveByIdentifier(identifier); + } + + public MobEffect getMobEffectById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getMobEffectById(protocolId); + } + return mobEffectMap.get(protocolId); + } + + public Dimension getDimensionById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getDimensionById(protocolId); + } + return dimensionMap.get(protocolId); + } + + public Block getBlockById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getBlockById(protocolId); + } + return blockMap.get(protocolId); + } + + public Block getBlockByIdAndMetaData(int protocolId, int metaData) { + return getBlockById((protocolId << 4) | metaData); + } + + public BlockId getBlockIdById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getBlockIdById(protocolId); + } + return blockIdMap.get(protocolId); + } + + public Enchantment getEnchantmentById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getEnchantmentById(protocolId); + } + return enchantmentMap.get(protocolId); + } + + public Particle getParticleById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getParticleById(protocolId); + } + return particleIdMap.get(protocolId); + } + + public Particle getParticleByIdentifier(String identifier) { + if (identifier.contains(":")) { + String[] splitted = identifier.split(":", 2); + if (!splitted[0].equals("minecraft")) { + return null; + } + identifier = splitted[1]; + } + return Versions.legacyVersion.getParticleByIdentifier(identifier); + } + + public Statistic getStatisticById(int protocolId) { + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format + return Versions.legacyVersion.getStatisticById(protocolId); + } + return statisticIdMap.get(protocolId); + } + + public Statistic getStatisticByIdentifier(String identifier) { + if (identifier.contains(":")) { + String[] splitted = identifier.split(":", 2); + if (!splitted[0].equals("minecraft")) { + return null; + } + identifier = splitted[1]; + } + return Versions.legacyVersion.getStatisticByIdentifier(identifier); + } + + public void load(Mappings type, JsonObject data) { + switch (type) { + case REGISTRIES: + JsonObject itemJson = data.getAsJsonObject("item").getAsJsonObject("entries"); + for (String identifier : itemJson.keySet()) { + Item item = new Item("minecraft", identifier); + JsonObject identifierJSON = itemJson.getAsJsonObject(identifier); + int itemId = identifierJSON.get("id").getAsInt(); + if (getProtocolVersion() < FLATTING_VERSION_ID) { + // old format (with metadata) + itemId <<= 4; + if (identifierJSON.has("meta")) { + itemId |= identifierJSON.get("meta").getAsInt(); + } + } + itemMap.put(itemId, item); + } + + JsonObject entityJson = data.getAsJsonObject("entity_type").getAsJsonObject("entries"); + for (String identifier : entityJson.keySet()) { + entityMap.put(entityJson.getAsJsonObject(identifier).get("id").getAsInt(), identifier); + } + + + JsonObject enchantmentJson = data.getAsJsonObject("enchantment").getAsJsonObject("entries"); + for (String identifier : enchantmentJson.keySet()) { + Enchantment enchantment = new Enchantment("minecraft", identifier); + enchantmentMap.put(enchantmentJson.getAsJsonObject(identifier).get("id").getAsInt(), enchantment); + } + + JsonObject statisticJson = data.getAsJsonObject("custom_stat").getAsJsonObject("entries"); + for (String identifier : statisticJson.keySet()) { + Statistic statistic = new Statistic("minecraft", identifier); + statisticIdMap.put(statisticJson.getAsJsonObject(identifier).get("id").getAsInt(), statistic); + } + + JsonObject blockIdJson = data.getAsJsonObject("block").getAsJsonObject("entries"); + for (String identifier : blockIdJson.keySet()) { + BlockId blockId = new BlockId("minecraft", identifier); + blockIdMap.put(blockIdJson.getAsJsonObject(identifier).get("id").getAsInt(), blockId); + } + + JsonObject motiveJson = data.getAsJsonObject("motive").getAsJsonObject("entries"); + for (String identifier : motiveJson.keySet()) { + Motive motive = new Motive("minecraft", identifier); + motiveIdMap.put(motiveJson.getAsJsonObject(identifier).get("id").getAsInt(), motive); + } + + JsonObject particleJson = data.getAsJsonObject("particle_type").getAsJsonObject("entries"); + for (String identifier : particleJson.keySet()) { + Particle particle = new Particle("minecraft", identifier); + particleIdMap.put(particleJson.getAsJsonObject(identifier).get("id").getAsInt(), particle); + } + + JsonObject mobEffectJson = data.getAsJsonObject("mob_effect").getAsJsonObject("entries"); + for (String identifier : mobEffectJson.keySet()) { + MobEffect mobEffect = new MobEffect("minecraft", identifier); + mobEffectMap.put(mobEffectJson.getAsJsonObject(identifier).get("id").getAsInt(), mobEffect); + } + if (data.has("dimension_type")) { + JsonObject dimensionJson = data.getAsJsonObject("dimension_type").getAsJsonObject("entries"); + for (String identifier : dimensionJson.keySet()) { + Dimension dimension = new Dimension("minecraft", identifier, dimensionJson.getAsJsonObject(identifier).get("has_skylight").getAsBoolean()); + dimensionMap.put(dimensionJson.getAsJsonObject(identifier).get("id").getAsInt(), dimension); + } + } + break; + case BLOCKS: + blockMap = Blocks.load("minecraft", data, getProtocolVersion() < FLATTING_VERSION_ID); + break; + } + } + + public void unload() { + serverboundPacketMapping.clear(); + clientboundPacketMapping.clear(); + + itemMap.clear(); + entityMap.clear(); + motiveIdMap.clear(); + mobEffectMap.clear(); + dimensionMap.clear(); + blockMap.clear(); + blockIdMap.clear(); + enchantmentMap.clear(); + particleIdMap.clear(); + statisticIdMap.clear(); + } + +} diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/Versions.java b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/Versions.java new file mode 100644 index 000000000..c211afca0 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/objectLoader/versions/Versions.java @@ -0,0 +1,92 @@ +/* + * Codename Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.game.datatypes.objectLoader.versions; + +import com.google.common.collect.HashBiMap; +import com.google.gson.JsonObject; +import de.bixilon.minosoft.game.datatypes.Mappings; +import de.bixilon.minosoft.protocol.protocol.Packets; + +import java.util.HashSet; + +import static de.bixilon.minosoft.protocol.protocol.ProtocolDefinition.FLATTING_VERSION_ID; + +public class Versions { + + final static Version legacyVersion = new LegacyVersion(); // used for 1.7.x - 1.12.2 mapping + static HashBiMap versionMap = HashBiMap.create(); + static HashSet loadedVersion = new HashSet<>(); + + public static Version getVersionById(int protocolId) { + return versionMap.get(protocolId); + } + + public static void load(JsonObject json) { + for (String protocolId : json.keySet()) { + loadVersion(json, protocolId); + } + } + + public static void loadVersion(JsonObject json, String protocolIdString) { + JsonObject versionJson = json.getAsJsonObject(protocolIdString); + String versionName = versionJson.get("name").getAsString(); + int protocolId = Integer.parseInt(protocolIdString); + if (versionMap.containsKey(protocolId)) { + // already loaded, skip + return; + } + + HashBiMap serverboundPacketMapping; + HashBiMap clientboundPacketMapping; + if (versionJson.get("mapping").isJsonPrimitive()) { + // inherits or copies mapping from an other version + if (!versionMap.containsKey(protocolId)) { + loadVersion(json, versionJson.get("mapping").getAsString()); + } + Version parent = versionMap.get(versionJson.get("mapping").getAsInt()); + serverboundPacketMapping = parent.getServerboundPacketMapping(); + clientboundPacketMapping = parent.getClientboundPacketMapping(); + } else { + JsonObject mappingJson = versionJson.getAsJsonObject("mapping"); + serverboundPacketMapping = HashBiMap.create(); + for (String packetName : mappingJson.getAsJsonObject("serverbound").keySet()) { + serverboundPacketMapping.put(Packets.Serverbound.valueOf(packetName), mappingJson.getAsJsonObject("serverbound").get(packetName).getAsInt()); + } + clientboundPacketMapping = HashBiMap.create(); + for (String packetName : mappingJson.getAsJsonObject("clientbound").keySet()) { + clientboundPacketMapping.put(Packets.Clientbound.valueOf(packetName), mappingJson.getAsJsonObject("clientbound").get(packetName).getAsInt()); + } + } + Version version = new Version(versionName, protocolId, serverboundPacketMapping, clientboundPacketMapping); + versionMap.put(version.getProtocolVersion(), version); + } + + public static void loadVersionMappings(Mappings type, JsonObject data, int protocolId) { + Version version = versionMap.get(protocolId); + version.load(type, data); + loadedVersion.add(version); + } + + public static void unloadUnnecessaryVersions(int necessary) { + if (necessary >= FLATTING_VERSION_ID) { + legacyVersion.unload(); + } + for (Version version : loadedVersion) { + if (version.getProtocolVersion() == necessary) { + continue; + } + version.unload(); + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketDataException.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketDataException.java deleted file mode 100644 index f40337dcd..000000000 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketDataException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Codename Minosoft - * Copyright (C) 2020 Moritz Zwerger - * - * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.protocol.protocol; - -public class PacketDataException extends Exception { - public PacketDataException(String message) { - super(message); - } -} diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java index 307e1620a..7c0f0f790 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java @@ -20,4 +20,6 @@ public final class ProtocolDefinition { public static final float ANGLE_CALCULATION_CONSTANT = 360.0F / 256.0F; public static final int PLAYER_INVENTORY_ID = 0; + + public static final int FLATTING_VERSION_ID = 346; }