From a37b3ed181fb28a8d301fef9da5bc3636b86e07c Mon Sep 17 00:00:00 2001 From: Bixilon Date: Fri, 17 Jul 2020 00:09:01 +0200 Subject: [PATCH] wip: Recipes --- .../minosoft/game/datatypes/Recipes.java | 42 -- .../minosoft/game/datatypes/blocks/Block.java | 14 +- ...lockProperty.java => BlockProperties.java} | 2 +- .../game/datatypes/blocks/Blocks.java | 370 +++++++++--------- .../game/datatypes/entities/items/Items.java | 5 +- .../game/datatypes/inventory/Slot.java | 12 + .../game/datatypes/recipes/Ingredient.java | 58 +++ .../game/datatypes/recipes/Recipe.java | 88 +++++ .../datatypes/recipes/RecipeProperties.java | 52 +++ .../game/datatypes/recipes/Recipes.java | 84 ++++ .../minosoft/protocol/network/Connection.java | 4 + .../play/PacketDeclareRecipes.java | 86 ++++ .../clientbound/play/PacketUnlockRecipes.java | 27 +- .../protocol/protocol/InByteBuffer.java | 21 + .../protocol/protocol/PacketHandler.java | 3 + .../minosoft/protocol/protocol/Protocol.java | 1 + 16 files changed, 618 insertions(+), 251 deletions(-) delete mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/Recipes.java rename src/main/java/de/bixilon/minosoft/game/datatypes/blocks/{BlockProperty.java => BlockProperties.java} (99%) create mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Ingredient.java create mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Recipe.java create mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/recipes/RecipeProperties.java create mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Recipes.java create mode 100644 src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketDeclareRecipes.java diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/Recipes.java b/src/main/java/de/bixilon/minosoft/game/datatypes/Recipes.java deleted file mode 100644 index 797d423ad..000000000 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/Recipes.java +++ /dev/null @@ -1,42 +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.game.datatypes; - -public enum Recipes { - TODO(0, new ChangeableIdentifier("todo")); - - final int id; - final ChangeableIdentifier changeableIdentifier; - - Recipes(int id, ChangeableIdentifier changeableIdentifier) { - this.id = id; - this.changeableIdentifier = changeableIdentifier; - } - - public static Recipes byId(int id) { - return TODO; - } - - public static Recipes byName(String name) { - return TODO; - } - - public int getId() { - return id; - } - - public ChangeableIdentifier getChangeableIdentifier() { - return changeableIdentifier; - } -} diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/Block.java b/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/Block.java index bf724a1ad..3c8e923d1 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/Block.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/Block.java @@ -17,16 +17,16 @@ public class Block { final String mod; final String identifier; final BlockRotation rotation; - final BlockProperty[] properties; + final BlockProperties[] properties; - public Block(String mod, String identifier, BlockProperty[] properties, BlockRotation rotation) { + public Block(String mod, String identifier, BlockProperties[] properties, BlockRotation rotation) { this.mod = mod; this.identifier = identifier; this.properties = properties; this.rotation = rotation; } - public Block(String mod, String identifier, BlockProperty[] properties) { + public Block(String mod, String identifier, BlockProperties[] properties) { this.mod = mod; this.identifier = identifier; this.properties = properties; @@ -36,14 +36,14 @@ public class Block { public Block(String mod, String identifier, BlockRotation rotation) { this.mod = mod; this.identifier = identifier; - this.properties = new BlockProperty[0]; + this.properties = new BlockProperties[0]; this.rotation = rotation; } public Block(String mod, String identifier) { this.mod = mod; this.identifier = identifier; - this.properties = new BlockProperty[0]; + this.properties = new BlockProperties[0]; this.rotation = BlockRotation.NONE; } @@ -59,7 +59,7 @@ public class Block { return rotation; } - public BlockProperty[] getProperties() { + public BlockProperties[] getProperties() { return properties; } @@ -78,7 +78,7 @@ public class Block { out.append(" ("); } out.append("properties={"); - for (BlockProperty property : properties) { + for (BlockProperties property : properties) { out.append(property.name()); out.append(","); } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/BlockProperty.java b/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/BlockProperties.java similarity index 99% rename from src/main/java/de/bixilon/minosoft/game/datatypes/blocks/BlockProperty.java rename to src/main/java/de/bixilon/minosoft/game/datatypes/blocks/BlockProperties.java index 52794dc89..736eb7503 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/BlockProperty.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/BlockProperties.java @@ -13,7 +13,7 @@ package de.bixilon.minosoft.game.datatypes.blocks; -public enum BlockProperty { +public enum BlockProperties { NONE, // farmland diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/Blocks.java b/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/Blocks.java index 2abc10e75..b07614c09 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/Blocks.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/blocks/Blocks.java @@ -12,7 +12,6 @@ package de.bixilon.minosoft.game.datatypes.blocks; * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; import org.json.JSONArray; @@ -25,382 +24,382 @@ import java.util.Iterator; public class Blocks { public static Block nullBlock; static ArrayList blockList = new ArrayList<>(); - static HashMap> blockMap = new HashMap<>(); // version -> (protocolId > Item) - static HashMap> propertiesMapping = new HashMap<>(); + static HashMap> blockMap = new HashMap<>(); // version -> (protocolId > block) + static HashMap> propertiesMapping = new HashMap<>(); static HashMap rotationMapping = new HashMap<>(); static { - HashMap propertyHashMap; + HashMap propertyHashMap; propertyHashMap = new HashMap<>(); for (int i = 0; i <= 15; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("LEVEL_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("LEVEL_%d", i))); } propertiesMapping.put("level", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 5; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("HONEY_LEVEL_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("HONEY_LEVEL_%d", i))); } propertiesMapping.put("honey_level", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 15; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("POWER_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("POWER_%d", i))); } propertiesMapping.put("power", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 1; i <= 8; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("LAYERS_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("LAYERS_%d", i))); } propertiesMapping.put("layers", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 7; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("DISTANCE_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("DISTANCE_%d", i))); } propertiesMapping.put("distance", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 25; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("AGE_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("AGE_%d", i))); } propertiesMapping.put("age", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 7; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("DISTANCE_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("DISTANCE_%d", i))); } propertiesMapping.put("distance", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 7; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("MOISTURE_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("MOISTURE_%d", i))); } propertiesMapping.put("moisture", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 1; i <= 4; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("PICKLES_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("PICKLES_%d", i))); } propertiesMapping.put("pickles", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 6; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("BITES_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("BITES_%d", i))); } propertiesMapping.put("bites", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 1; i <= 4; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("DELAY_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("DELAY_%d", i))); } propertiesMapping.put("delay", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 2; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("HATCH_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("HATCH_%d", i))); } propertiesMapping.put("hatch", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 1; i <= 4; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("EGGS_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("EGGS_%d", i))); } propertiesMapping.put("eggs", propertyHashMap); propertyHashMap = new HashMap<>(); for (int i = 0; i <= 24; i++) { - propertyHashMap.put(String.valueOf(i), BlockProperty.valueOf(String.format("NOTE_%d", i))); + propertyHashMap.put(String.valueOf(i), BlockProperties.valueOf(String.format("NOTE_%d", i))); } propertiesMapping.put("note", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("0", BlockProperty.STAGE_0); - propertyHashMap.put("1", BlockProperty.STAGE_1); + propertyHashMap.put("0", BlockProperties.STAGE_0); + propertyHashMap.put("1", BlockProperties.STAGE_1); propertiesMapping.put("stage", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.EAST); - propertyHashMap.put("up", BlockProperty.EAST_UP); - propertyHashMap.put("side", BlockProperty.EAST_SIDE); - propertyHashMap.put("false", BlockProperty.NONE); - propertyHashMap.put("none", BlockProperty.NONE); + propertyHashMap.put("true", BlockProperties.EAST); + propertyHashMap.put("up", BlockProperties.EAST_UP); + propertyHashMap.put("side", BlockProperties.EAST_SIDE); + propertyHashMap.put("false", BlockProperties.NONE); + propertyHashMap.put("none", BlockProperties.NONE); propertiesMapping.put("east", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.WEST); - propertyHashMap.put("up", BlockProperty.WEST_UP); - propertyHashMap.put("side", BlockProperty.WEST_SIDE); - propertyHashMap.put("false", BlockProperty.NONE); - propertyHashMap.put("none", BlockProperty.NONE); + propertyHashMap.put("true", BlockProperties.WEST); + propertyHashMap.put("up", BlockProperties.WEST_UP); + propertyHashMap.put("side", BlockProperties.WEST_SIDE); + propertyHashMap.put("false", BlockProperties.NONE); + propertyHashMap.put("none", BlockProperties.NONE); propertiesMapping.put("west", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.SOUTH); - propertyHashMap.put("up", BlockProperty.SOUTH_UP); - propertyHashMap.put("side", BlockProperty.SOUTH_SIDE); - propertyHashMap.put("false", BlockProperty.NONE); - propertyHashMap.put("none", BlockProperty.NONE); + propertyHashMap.put("true", BlockProperties.SOUTH); + propertyHashMap.put("up", BlockProperties.SOUTH_UP); + propertyHashMap.put("side", BlockProperties.SOUTH_SIDE); + propertyHashMap.put("false", BlockProperties.NONE); + propertyHashMap.put("none", BlockProperties.NONE); propertiesMapping.put("south", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.NORTH); - propertyHashMap.put("up", BlockProperty.NORTH_UP); - propertyHashMap.put("side", BlockProperty.NORTH_SIDE); - propertyHashMap.put("false", BlockProperty.NONE); - propertyHashMap.put("none", BlockProperty.NONE); + propertyHashMap.put("true", BlockProperties.NORTH); + propertyHashMap.put("up", BlockProperties.NORTH_UP); + propertyHashMap.put("side", BlockProperties.NORTH_SIDE); + propertyHashMap.put("false", BlockProperties.NONE); + propertyHashMap.put("none", BlockProperties.NONE); propertiesMapping.put("north", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.SNOWY); - propertyHashMap.put("false", BlockProperty.NOT_SNOWY); + propertyHashMap.put("true", BlockProperties.SNOWY); + propertyHashMap.put("false", BlockProperties.NOT_SNOWY); propertiesMapping.put("snowy", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.UP); - propertyHashMap.put("false", BlockProperty.NOT_UP); + propertyHashMap.put("true", BlockProperties.UP); + propertyHashMap.put("false", BlockProperties.NOT_UP); propertiesMapping.put("up", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.DOWN); - propertyHashMap.put("false", BlockProperty.NOT_DOWN); + propertyHashMap.put("true", BlockProperties.DOWN); + propertyHashMap.put("false", BlockProperties.NOT_DOWN); propertiesMapping.put("down", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.IN_WALL); - propertyHashMap.put("false", BlockProperty.NOT_IN_WALL); + propertyHashMap.put("true", BlockProperties.IN_WALL); + propertyHashMap.put("false", BlockProperties.NOT_IN_WALL); propertiesMapping.put("in_wall", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.EXTENDED); - propertyHashMap.put("false", BlockProperty.NOT_EXTENDED); + propertyHashMap.put("true", BlockProperties.EXTENDED); + propertyHashMap.put("false", BlockProperties.NOT_EXTENDED); propertiesMapping.put("extended", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.POWERED); - propertyHashMap.put("false", BlockProperty.NOT_POWERED); + propertyHashMap.put("true", BlockProperties.POWERED); + propertyHashMap.put("false", BlockProperties.NOT_POWERED); propertiesMapping.put("powered", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.OPEN); - propertyHashMap.put("false", BlockProperty.CLOSED); + propertyHashMap.put("true", BlockProperties.OPEN); + propertyHashMap.put("false", BlockProperties.CLOSED); propertiesMapping.put("open", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.BOTTOM); - propertyHashMap.put("false", BlockProperty.NOT_BOTTOM); + propertyHashMap.put("true", BlockProperties.BOTTOM); + propertyHashMap.put("false", BlockProperties.NOT_BOTTOM); propertiesMapping.put("bottom", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.OCCUPIED); - propertyHashMap.put("false", BlockProperty.NOT_OCCUPIED); + propertyHashMap.put("true", BlockProperties.OCCUPIED); + propertyHashMap.put("false", BlockProperties.NOT_OCCUPIED); propertiesMapping.put("occupied", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.ATTACHED); - propertyHashMap.put("false", BlockProperty.NOT_ATTACHED); + propertyHashMap.put("true", BlockProperties.ATTACHED); + propertyHashMap.put("false", BlockProperties.NOT_ATTACHED); propertiesMapping.put("attached", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.DISARMED); - propertyHashMap.put("false", BlockProperty.ARMED); + propertyHashMap.put("true", BlockProperties.DISARMED); + propertyHashMap.put("false", BlockProperties.ARMED); propertiesMapping.put("disarmed", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.INVERTED); - propertyHashMap.put("false", BlockProperty.NOT_INVERTED); + propertyHashMap.put("true", BlockProperties.INVERTED); + propertyHashMap.put("false", BlockProperties.NOT_INVERTED); propertiesMapping.put("inverted", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.TRIGGERED); - propertyHashMap.put("false", BlockProperty.NOT_TRIGGERED); + propertyHashMap.put("true", BlockProperties.TRIGGERED); + propertyHashMap.put("false", BlockProperties.NOT_TRIGGERED); propertiesMapping.put("triggered", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.CONDITIONAL); - propertyHashMap.put("false", BlockProperty.UNCONDITIONAL); + propertyHashMap.put("true", BlockProperties.CONDITIONAL); + propertyHashMap.put("false", BlockProperties.UNCONDITIONAL); propertiesMapping.put("conditional", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.DRAG); - propertyHashMap.put("false", BlockProperty.NOT_DRAG); + propertyHashMap.put("true", BlockProperties.DRAG); + propertyHashMap.put("false", BlockProperties.NOT_DRAG); propertiesMapping.put("drag", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.UNSTABLE); - propertyHashMap.put("false", BlockProperty.STABLE); + propertyHashMap.put("true", BlockProperties.UNSTABLE); + propertyHashMap.put("false", BlockProperties.STABLE); propertiesMapping.put("unstable", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.HANGING); - propertyHashMap.put("false", BlockProperty.NOT_HANGING); + propertyHashMap.put("true", BlockProperties.HANGING); + propertyHashMap.put("false", BlockProperties.NOT_HANGING); propertiesMapping.put("hanging", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.HAS_BOOK); - propertyHashMap.put("false", BlockProperty.NO_BOOK); + propertyHashMap.put("true", BlockProperties.HAS_BOOK); + propertyHashMap.put("false", BlockProperties.NO_BOOK); propertiesMapping.put("has_book", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.HAS_BOTTLE_0); - propertyHashMap.put("false", BlockProperty.NO_BOTTLE_0); + propertyHashMap.put("true", BlockProperties.HAS_BOTTLE_0); + propertyHashMap.put("false", BlockProperties.NO_BOTTLE_0); propertiesMapping.put("has_bottle_0", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.HAS_BOTTLE_1); - propertyHashMap.put("false", BlockProperty.NO_BOTTLE_1); + propertyHashMap.put("true", BlockProperties.HAS_BOTTLE_1); + propertyHashMap.put("false", BlockProperties.NO_BOTTLE_1); propertiesMapping.put("has_bottle_1", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.HAS_BOTTLE_2); - propertyHashMap.put("false", BlockProperty.NO_BOTTLE_2); + propertyHashMap.put("true", BlockProperties.HAS_BOTTLE_2); + propertyHashMap.put("false", BlockProperties.NO_BOTTLE_2); propertiesMapping.put("has_bottle_2", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.PERSISTENT); - propertyHashMap.put("false", BlockProperty.NOT_PERSISTENT); + propertyHashMap.put("true", BlockProperties.PERSISTENT); + propertyHashMap.put("false", BlockProperties.NOT_PERSISTENT); propertiesMapping.put("persistent", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.LIT); - propertyHashMap.put("false", BlockProperty.UN_LIT); + propertyHashMap.put("true", BlockProperties.LIT); + propertyHashMap.put("false", BlockProperties.UN_LIT); propertiesMapping.put("lit", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.WATERLOGGED); - propertyHashMap.put("false", BlockProperty.NOT_WATERLOGGED); + propertyHashMap.put("true", BlockProperties.WATERLOGGED); + propertyHashMap.put("false", BlockProperties.NOT_WATERLOGGED); propertiesMapping.put("waterlogged", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.LOCKED); - propertyHashMap.put("false", BlockProperty.UNLOCKED); + propertyHashMap.put("true", BlockProperties.LOCKED); + propertyHashMap.put("false", BlockProperties.UNLOCKED); propertiesMapping.put("locked", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.EYE); - propertyHashMap.put("false", BlockProperty.NO_EYE); + propertyHashMap.put("true", BlockProperties.EYE); + propertyHashMap.put("false", BlockProperties.NO_EYE); propertiesMapping.put("eye", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.ENABLED); - propertyHashMap.put("false", BlockProperty.DISABLED); + propertyHashMap.put("true", BlockProperties.ENABLED); + propertyHashMap.put("false", BlockProperties.DISABLED); propertiesMapping.put("enabled", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.HAS_RECORD); - propertyHashMap.put("false", BlockProperty.HAS_NO_RECORD); + propertyHashMap.put("true", BlockProperties.HAS_RECORD); + propertyHashMap.put("false", BlockProperties.HAS_NO_RECORD); propertiesMapping.put("has_record", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.SHORT); - propertyHashMap.put("false", BlockProperty.LONG); + propertyHashMap.put("true", BlockProperties.SHORT); + propertyHashMap.put("false", BlockProperties.LONG); propertiesMapping.put("short", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("true", BlockProperty.SIGNAL_FIRE); - propertyHashMap.put("false", BlockProperty.NOT_SIGNAL_FIRE); + propertyHashMap.put("true", BlockProperties.SIGNAL_FIRE); + propertyHashMap.put("false", BlockProperties.NOT_SIGNAL_FIRE); propertiesMapping.put("signal_fire", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("harp", BlockProperty.HARP); - propertyHashMap.put("basedrum", BlockProperty.BASEDRUM); - propertyHashMap.put("snare", BlockProperty.SNARE); - propertyHashMap.put("hat", BlockProperty.HAT); - propertyHashMap.put("bass", BlockProperty.BASS); - propertyHashMap.put("flute", BlockProperty.FLUTE); - propertyHashMap.put("bell", BlockProperty.BELL); - propertyHashMap.put("guitar", BlockProperty.GUITAR); - propertyHashMap.put("chime", BlockProperty.CHIME); - propertyHashMap.put("xylophone", BlockProperty.XYLOPHONE); - propertyHashMap.put("iron_xylophone", BlockProperty.IRON_XYLOPHONE); - propertyHashMap.put("cow_bell", BlockProperty.COW_BELL); - propertyHashMap.put("didgeridoo", BlockProperty.DIDGERIDOO); - propertyHashMap.put("bit", BlockProperty.BIT); - propertyHashMap.put("banjo", BlockProperty.BANJO); - propertyHashMap.put("pling", BlockProperty.PLING); + propertyHashMap.put("harp", BlockProperties.HARP); + propertyHashMap.put("basedrum", BlockProperties.BASEDRUM); + propertyHashMap.put("snare", BlockProperties.SNARE); + propertyHashMap.put("hat", BlockProperties.HAT); + propertyHashMap.put("bass", BlockProperties.BASS); + propertyHashMap.put("flute", BlockProperties.FLUTE); + propertyHashMap.put("bell", BlockProperties.BELL); + propertyHashMap.put("guitar", BlockProperties.GUITAR); + propertyHashMap.put("chime", BlockProperties.CHIME); + propertyHashMap.put("xylophone", BlockProperties.XYLOPHONE); + propertyHashMap.put("iron_xylophone", BlockProperties.IRON_XYLOPHONE); + propertyHashMap.put("cow_bell", BlockProperties.COW_BELL); + propertyHashMap.put("didgeridoo", BlockProperties.DIDGERIDOO); + propertyHashMap.put("bit", BlockProperties.BIT); + propertyHashMap.put("banjo", BlockProperties.BANJO); + propertyHashMap.put("pling", BlockProperties.PLING); propertiesMapping.put("instrument", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("head", BlockProperty.HEAD); - propertyHashMap.put("foot", BlockProperty.FOOT); + propertyHashMap.put("head", BlockProperties.HEAD); + propertyHashMap.put("foot", BlockProperties.FOOT); propertiesMapping.put("part", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("left", BlockProperty.HINGE_LEFT); - propertyHashMap.put("right", BlockProperty.HINGE_RIGHT); + propertyHashMap.put("left", BlockProperties.HINGE_LEFT); + propertyHashMap.put("right", BlockProperties.HINGE_RIGHT); propertiesMapping.put("hinge", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("x", BlockProperty.AXIS_X); - propertyHashMap.put("y", BlockProperty.AXIS_Y); - propertyHashMap.put("z", BlockProperty.AXIS_Z); + propertyHashMap.put("x", BlockProperties.AXIS_X); + propertyHashMap.put("y", BlockProperties.AXIS_Y); + propertyHashMap.put("z", BlockProperties.AXIS_Z); propertiesMapping.put("axis", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("floor", BlockProperty.FLOOR); - propertyHashMap.put("wall", BlockProperty.WALL); - propertyHashMap.put("ceiling", BlockProperty.CEILING); + propertyHashMap.put("floor", BlockProperties.FLOOR); + propertyHashMap.put("wall", BlockProperties.WALL); + propertyHashMap.put("ceiling", BlockProperties.CEILING); propertiesMapping.put("face", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("floor", BlockProperty.FLOOR); - propertyHashMap.put("ceiling", BlockProperty.CEILING); - propertyHashMap.put("single_wall", BlockProperty.SINGLE_WALL); - propertyHashMap.put("double_wall", BlockProperty.DOUBLE_WALL); + propertyHashMap.put("floor", BlockProperties.FLOOR); + propertyHashMap.put("ceiling", BlockProperties.CEILING); + propertyHashMap.put("single_wall", BlockProperties.SINGLE_WALL); + propertyHashMap.put("double_wall", BlockProperties.DOUBLE_WALL); propertiesMapping.put("attachment", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("save", BlockProperty.SAVE); - propertyHashMap.put("load", BlockProperty.LOAD); - propertyHashMap.put("corner", BlockProperty.CORNER); - propertyHashMap.put("data", BlockProperty.DATA); - propertyHashMap.put("compare", BlockProperty.COMPARE); - propertyHashMap.put("subtract", BlockProperty.SUBTRACT); + propertyHashMap.put("save", BlockProperties.SAVE); + propertyHashMap.put("load", BlockProperties.LOAD); + propertyHashMap.put("corner", BlockProperties.CORNER); + propertyHashMap.put("data", BlockProperties.DATA); + propertyHashMap.put("compare", BlockProperties.COMPARE); + propertyHashMap.put("subtract", BlockProperties.SUBTRACT); propertiesMapping.put("mode", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("top", BlockProperty.HALF_UPPER); - propertyHashMap.put("upper", BlockProperty.HALF_UPPER); - propertyHashMap.put("bottom", BlockProperty.HALF_LOWER); - propertyHashMap.put("lower", BlockProperty.HALF_LOWER); + propertyHashMap.put("top", BlockProperties.HALF_UPPER); + propertyHashMap.put("upper", BlockProperties.HALF_UPPER); + propertyHashMap.put("bottom", BlockProperties.HALF_LOWER); + propertyHashMap.put("lower", BlockProperties.HALF_LOWER); propertiesMapping.put("half", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("none", BlockProperty.NONE); - propertyHashMap.put("small", BlockProperty.LARGE); - propertyHashMap.put("large", BlockProperty.SMALL); + propertyHashMap.put("none", BlockProperties.NONE); + propertyHashMap.put("small", BlockProperties.LARGE); + propertyHashMap.put("large", BlockProperties.SMALL); propertiesMapping.put("leaves", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("top", BlockProperty.SLAB_TOP); - propertyHashMap.put("bottom", BlockProperty.SLAB_BOTTOM); - propertyHashMap.put("double", BlockProperty.SLAB_DOUBLE); - propertyHashMap.put("normal", BlockProperty.TYPE_NORMAL); - propertyHashMap.put("sticky", BlockProperty.TYPE_STICKY); - propertyHashMap.put("single", BlockProperty.TYPE_SINGLE); - propertyHashMap.put("left", BlockProperty.TYPE_LEFT); - propertyHashMap.put("right", BlockProperty.TYPE_RIGHT); + propertyHashMap.put("top", BlockProperties.SLAB_TOP); + propertyHashMap.put("bottom", BlockProperties.SLAB_BOTTOM); + propertyHashMap.put("double", BlockProperties.SLAB_DOUBLE); + propertyHashMap.put("normal", BlockProperties.TYPE_NORMAL); + propertyHashMap.put("sticky", BlockProperties.TYPE_STICKY); + propertyHashMap.put("single", BlockProperties.TYPE_SINGLE); + propertyHashMap.put("left", BlockProperties.TYPE_LEFT); + propertyHashMap.put("right", BlockProperties.TYPE_RIGHT); propertiesMapping.put("type", propertyHashMap); propertyHashMap = new HashMap<>(); - propertyHashMap.put("straight", BlockProperty.STRAIGHT); - propertyHashMap.put("inner_left", BlockProperty.INNER_LEFT); - propertyHashMap.put("inner_right", BlockProperty.INNER_RIGHT); - propertyHashMap.put("outer_left", BlockProperty.OUTER_LEFT); - propertyHashMap.put("outer_right", BlockProperty.OUTER_RIGHT); - propertyHashMap.put("north_south", BlockProperty.NORTH_SOUTH); - propertyHashMap.put("east_west", BlockProperty.EAST_WEST); - propertyHashMap.put("south_east", BlockProperty.SOUTH_EAST); - propertyHashMap.put("south_west", BlockProperty.SOUTH_WEST); - propertyHashMap.put("north_west", BlockProperty.NORTH_WEST); - propertyHashMap.put("north_east", BlockProperty.NORTH_EAST); - propertyHashMap.put("ascending_east", BlockProperty.ASCENDING_EAST); - propertyHashMap.put("ascending_west", BlockProperty.ASCENDING_WEST); - propertyHashMap.put("ascending_north", BlockProperty.ASCENDING_NORTH); - propertyHashMap.put("ascending_south", BlockProperty.ASCENDING_SOUTH); + propertyHashMap.put("straight", BlockProperties.STRAIGHT); + propertyHashMap.put("inner_left", BlockProperties.INNER_LEFT); + propertyHashMap.put("inner_right", BlockProperties.INNER_RIGHT); + propertyHashMap.put("outer_left", BlockProperties.OUTER_LEFT); + propertyHashMap.put("outer_right", BlockProperties.OUTER_RIGHT); + propertyHashMap.put("north_south", BlockProperties.NORTH_SOUTH); + propertyHashMap.put("east_west", BlockProperties.EAST_WEST); + propertyHashMap.put("south_east", BlockProperties.SOUTH_EAST); + propertyHashMap.put("south_west", BlockProperties.SOUTH_WEST); + propertyHashMap.put("north_west", BlockProperties.NORTH_WEST); + propertyHashMap.put("north_east", BlockProperties.NORTH_EAST); + propertyHashMap.put("ascending_east", BlockProperties.ASCENDING_EAST); + propertyHashMap.put("ascending_west", BlockProperties.ASCENDING_WEST); + propertyHashMap.put("ascending_north", BlockProperties.ASCENDING_NORTH); + propertyHashMap.put("ascending_south", BlockProperties.ASCENDING_SOUTH); propertiesMapping.put("shape", propertyHashMap); rotationMapping.put("0", BlockRotation.SOUTH); @@ -436,13 +435,13 @@ public class Blocks { } public static Block getBlockByLegacy(int protocolId, int protocolMetaData) { - int itemId = protocolId << 4 | protocolMetaData; - return getBlock(itemId, ProtocolVersion.VERSION_1_12_2); + int blockId = protocolId << 4 | protocolMetaData; + return getBlock(blockId, ProtocolVersion.VERSION_1_12_2); } - public static Block getBlockByLegacy(int itemIdAndMetaData) { - return getBlock(itemIdAndMetaData, 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) { @@ -453,7 +452,7 @@ public class Blocks { } public static void load(String mod, JSONObject json, ProtocolVersion version) { - BiMap versionMapping = HashBiMap.create(); + HashBiMap versionMapping = HashBiMap.create(); for (Iterator identifiers = json.keys(); identifiers.hasNext(); ) { String identifierName = identifiers.next(); JSONObject identifierJSON = json.getJSONObject(identifierName); @@ -472,7 +471,7 @@ public class Blocks { rotation = rotationMapping.get(propertiesJSON.getString("rotation")); propertiesJSON.remove("rotation"); } - BlockProperty[] properties = new BlockProperty[propertiesJSON.length()]; + BlockProperties[] properties = new BlockProperties[propertiesJSON.length()]; int ii = 0; for (Iterator it = propertiesJSON.keys(); it.hasNext(); ) { String propertyName = it.next(); @@ -525,15 +524,15 @@ public class Blocks { } public static Block getBlock(String mod, String identifier) { - for (Block item : blockList) { - if (item.getMod().equals(mod) && item.getIdentifier().equals(identifier)) { - return item; + for (Block block : blockList) { + if (block.getMod().equals(mod) && block.getIdentifier().equals(identifier)) { + return block; } } return null; } - public static Block getBlock(String mod, String identifier, BlockProperty[] properties, BlockRotation rotation) { + public static Block getBlock(String mod, String identifier, BlockProperties[] properties, BlockRotation rotation) { for (Block block : blockList) { if (block.getMod().equals(mod) && block.getIdentifier().equals(identifier) && block.getRotation() == rotation && propertiesEquals(block.getProperties(), properties)) { return block; @@ -542,11 +541,11 @@ public class Blocks { return null; } - public static boolean propertiesEquals(BlockProperty[] one, BlockProperty[] two) { + public static boolean propertiesEquals(BlockProperties[] one, BlockProperties[] two) { if (one.length != two.length) { return false; } - for (BlockProperty property : one) { + for (BlockProperties property : one) { if (!containsElement(two, property)) { return false; } @@ -554,20 +553,21 @@ public class Blocks { return true; } - public static boolean containsElement(BlockProperty[] arr, BlockProperty value) { - for (BlockProperty property : arr) { - if (property == value) + public static boolean containsElement(BlockProperties[] arr, BlockProperties value) { + for (BlockProperties property : arr) { + if (property == value) { return true; + } } return false; } - public static int getBlockId(Block item, ProtocolVersion version) { - int itemId = blockMap.get(version).inverse().get(item); + 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 itemId >> 4; + return blockId >> 4; } - return itemId; + return blockId; } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/items/Items.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/items/Items.java index b69f4fe77..d1f7413ad 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/items/Items.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/items/Items.java @@ -13,7 +13,6 @@ package de.bixilon.minosoft.game.datatypes.entities.items; -import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; import org.json.JSONObject; @@ -25,7 +24,7 @@ import java.util.Iterator; public class Items { static ArrayList itemList = new ArrayList<>(); - static HashMap> itemMap = new HashMap<>(); // version -> (protocolId > Item) + static HashMap> itemMap = new HashMap<>(); // version -> (protocolId > Item) public static Item getItemByLegacy(int protocolId, int protocolMetaData) { int itemId = protocolId << 4; @@ -45,7 +44,7 @@ public class Items { } public static void load(String mod, JSONObject json, ProtocolVersion version) { - BiMap versionMapping = HashBiMap.create(); + HashBiMap versionMapping = HashBiMap.create(); for (Iterator identifiers = json.keys(); identifiers.hasNext(); ) { String identifierName = identifiers.next(); Item item = getItem(mod, identifierName); diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/inventory/Slot.java b/src/main/java/de/bixilon/minosoft/game/datatypes/inventory/Slot.java index 5ace6b44d..a13cf1d96 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/inventory/Slot.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/inventory/Slot.java @@ -64,4 +64,16 @@ public class Slot { } return item.toString(); // ToDo display name per Item (from language file) } + + @Override + public boolean equals(Object obj) { + if (super.equals(obj)) { + return true; + } + Slot their = (Slot) obj; + + // ToDo: check nbt + + return their.getItem().equals(getItem()) && their.getItemCount() == getItemCount() && their.getItemMetadata() == getItemMetadata(); + } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Ingredient.java b/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Ingredient.java new file mode 100644 index 000000000..94c3e5bad --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Ingredient.java @@ -0,0 +1,58 @@ +/* + * 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.recipes; + +import de.bixilon.minosoft.game.datatypes.inventory.Slot; + +public class Ingredient { + final Slot[] slot; + + public Ingredient(Slot[] slot) { + this.slot = slot; + } + + public static boolean slotEquals(Slot[] one, Slot[] two) { + if (one.length != two.length) { + return false; + } + for (Slot slot : one) { + if (!containsElement(two, slot)) { + return false; + } + } + return true; + } + + public static boolean containsElement(Slot[] arr, Slot value) { + for (Slot slot : arr) { + if (slot.equals(value)) { + return true; + } + } + return false; + } + + public Slot[] getSlot() { + return slot; + } + + @Override + public boolean equals(Object obj) { + if (super.equals(obj)) { + return true; + } + Ingredient their = (Ingredient) obj; + return slotEquals(getSlot(), their.getSlot()); + } +} diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Recipe.java b/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Recipe.java new file mode 100644 index 000000000..24c0a3145 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Recipe.java @@ -0,0 +1,88 @@ +/* + * 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.recipes; + +import de.bixilon.minosoft.game.datatypes.inventory.Slot; + +public class Recipe { + final RecipeProperties property; + Slot result; + String group; + Ingredient[] ingredients; + int height; + int width; + float experience; + int cookingTime; + + public Recipe(RecipeProperties property, String group, Ingredient[] ingredients, Slot result) { + this.property = property; + this.group = group; + this.ingredients = ingredients; + this.result = result; + } + + public Recipe(int width, int height, RecipeProperties property, String group, Ingredient[] ingredients, Slot result) { + this.width = width; + this.height = height; + this.property = property; + this.group = group; + this.ingredients = ingredients; + this.result = result; + } + + public Recipe(RecipeProperties property, String group, Ingredient ingredient, Slot result, float experience, int cookingTime) { + this.property = property; + this.group = group; + this.ingredients = new Ingredient[]{ingredient}; + this.result = result; + this.experience = experience; + this.cookingTime = cookingTime; + } + + public Recipe(RecipeProperties property) { + this.property = property; + } + + public RecipeProperties getProperty() { + return property; + } + + public Slot getResult() { + return result; + } + + public String getGroup() { + return group; + } + + public Ingredient[] getIngredients() { + return ingredients; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public float getExperience() { + return experience; + } + + public int getCookingTime() { + return cookingTime; + } +} diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/RecipeProperties.java b/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/RecipeProperties.java new file mode 100644 index 000000000..982420e74 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/RecipeProperties.java @@ -0,0 +1,52 @@ +/* + * 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.recipes; + +public enum RecipeProperties { + SHAPELESS("crafting_shapeless"), + SHAPED("crafting_shaped"), + SPECIAL_ARMOR_DYE("crafting_special_armordye"), + SPECIAL_BOOK_CLONING("crafting_special_bookcloning"), + SPECIAL_MAP_CLONING("crafting_special_mapcloning"), + SPECIAL_MAP_EXTENDING("crafting_special_mapextending"), + SPECIAL_FIREWORK_ROCKET("crafting_special_firework_rocket"), + SPECIAL_FIREWORK_STAR("crafting_special_firework_star"), + SPECIAL_FIREWORK_STAR_FADE("crafting_special_firework_star_fade"), + SPECIAL_REPAIR_ITEM("crafting_special_repairitem"), + SPECIAL_TIPPED_ARROW("crafting_special_tippedarrow"), + SPECIAL_BANNER_DUPLICATE("crafting_special_bannerduplicate"), + SPECIAL_BANNER_ADD_PATTERN("crafting_special_banneraddpattern"), + SPECIAL_SHIELD_DECORATION("crafting_special_shielddecoration"), + SPECIAL_SHULKER_BOX_COLORING("crafting_special_shulkerboxcoloring"), + SMELTING("smelting"); + + final String name; + + RecipeProperties(String name) { + this.name = name; + } + + public static RecipeProperties byName(String name) { + for (RecipeProperties recipeProperty : values()) { + if (recipeProperty.getName().equals(name)) { + return recipeProperty; + } + } + return null; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Recipes.java b/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Recipes.java new file mode 100644 index 000000000..7d67abc26 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/recipes/Recipes.java @@ -0,0 +1,84 @@ +package de.bixilon.minosoft.game.datatypes.recipes; +/* + * 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. + */ + +import com.google.common.collect.HashBiMap; +import de.bixilon.minosoft.game.datatypes.inventory.Slot; +import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; + +import java.util.ArrayList; +import java.util.HashMap; + +public class Recipes { + static ArrayList recipeList = new ArrayList<>(); + static HashBiMap recipeIdMap = HashBiMap.create(); // ids for version <= VERSION_1_12_2 + static HashMap> recipeNameMap = new HashMap<>(); // names for version >= VERSION_1_13_2 + + static { + for (ProtocolVersion version : ProtocolVersion.versionMappingArray) { + if (version.getVersionNumber() >= ProtocolVersion.VERSION_1_13_2.getVersionNumber()) { + // add to list + recipeNameMap.put(version, HashBiMap.create()); + } + } + } + + + public static Recipe getRecipeById(int id) { + return recipeIdMap.get(id); + } + + public static Recipe getRecipe(String identifier, ProtocolVersion version) { + return recipeNameMap.get(version).get(identifier); + } + + public static Recipe getRecipe(RecipeProperties property, Slot result, String group, Ingredient[] ingredients) { + for (Recipe recipe : recipeList) { + if (recipe.getProperty() == property && recipe.getResult().equals(result) && recipe.getGroup().equals(group) && ingredientsEquals(recipe.getIngredients(), ingredients)) { + return recipe; + } + } + return null; + } + + public static boolean ingredientsEquals(Ingredient[] one, Ingredient[] two) { + if (one.length != two.length) { + return false; + } + for (Ingredient ingredient : one) { + if (!containsElement(two, ingredient)) { + return false; + } + } + return true; + } + + public static boolean containsElement(Ingredient[] arr, Ingredient value) { + for (Ingredient property : arr) { + if (property.equals(value)) { + return true; + } + } + return false; + } + + // we don't want that recipes from 1 server will appear on an other. You must call this function before reconnecting do avoid issues + public static void removeCustomRecipes(ProtocolVersion version) { + recipeNameMap.get(version).clear(); + } + + public static void registerCustomRecipe(ProtocolVersion version, Recipe recipe, String identifier) { + recipeNameMap.get(version).put(identifier, recipe); + } + +} diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java b/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java index 57a60520b..6ed195514 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java +++ b/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java @@ -16,6 +16,7 @@ package de.bixilon.minosoft.protocol.network; import de.bixilon.minosoft.Minosoft; import de.bixilon.minosoft.config.GameConfiguration; import de.bixilon.minosoft.game.datatypes.Player; +import de.bixilon.minosoft.game.datatypes.recipes.Recipes; import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.protocol.modding.channels.DefaultPluginChannels; import de.bixilon.minosoft.protocol.modding.channels.PluginChannelHandler; @@ -116,6 +117,9 @@ public class Connection { if (reason == ConnectionReason.GET_VERSION) { setReason(ConnectionReason.CONNECT); connect(); + } else { + // unregister all custom recipes + Recipes.removeCustomRecipes(getVersion()); } } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketDeclareRecipes.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketDeclareRecipes.java new file mode 100644 index 000000000..545d54e18 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketDeclareRecipes.java @@ -0,0 +1,86 @@ +/* + * 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.packets.clientbound.play; + +import de.bixilon.minosoft.game.datatypes.inventory.Slot; +import de.bixilon.minosoft.game.datatypes.recipes.Ingredient; +import de.bixilon.minosoft.game.datatypes.recipes.Recipe; +import de.bixilon.minosoft.game.datatypes.recipes.RecipeProperties; +import de.bixilon.minosoft.game.datatypes.recipes.Recipes; +import de.bixilon.minosoft.logging.Log; +import de.bixilon.minosoft.protocol.packets.ClientboundPacket; +import de.bixilon.minosoft.protocol.protocol.InPacketBuffer; +import de.bixilon.minosoft.protocol.protocol.PacketHandler; + +public class PacketDeclareRecipes implements ClientboundPacket { + Recipe[] recipes; + + + @Override + public boolean read(InPacketBuffer buffer) { + switch (buffer.getVersion()) { + case VERSION_1_13_2: + recipes = new Recipe[buffer.readVarInt()]; + for (int i = 0; i < recipes.length; i++) { + Recipe recipe; + String identifier = buffer.readString(); + String name = buffer.readString(); + RecipeProperties type = RecipeProperties.byName(name); + switch (type) { + case SHAPELESS: { + String group = buffer.readString(); + Ingredient[] ingredients = buffer.readIngredientArray(buffer.readVarInt()); + Slot result = buffer.readSlot(); + recipe = new Recipe(type, group, ingredients, result); + break; + } + case SHAPED: { + int width = buffer.readVarInt(); + int height = buffer.readVarInt(); + String group = buffer.readString(); + Ingredient[] ingredients = buffer.readIngredientArray(width * height); + Slot result = buffer.readSlot(); + recipe = new Recipe(width, height, type, group, ingredients, result); + break; + } + case SMELTING: { + String group = buffer.readString(); + Ingredient ingredient = buffer.readIngredient(); + Slot result = buffer.readSlot(); + float experience = buffer.readFloat(); + int cookingTime = buffer.readVarInt(); + recipe = new Recipe(type, group, ingredient, result, experience, cookingTime); + break; + } + default: + recipe = new Recipe(type); + break; + } + Recipes.registerCustomRecipe(buffer.getVersion(), recipe, identifier); + } + return true; + } + return false; + } + + @Override + public void log() { + Log.protocol(String.format("Received unlock crafting recipe packet (recipeLength=%d)", recipes.length)); + } + + @Override + public void handle(PacketHandler h) { + h.handle(this); + } +} diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUnlockRecipes.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUnlockRecipes.java index 41570b578..cba6d2968 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUnlockRecipes.java +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketUnlockRecipes.java @@ -13,7 +13,8 @@ package de.bixilon.minosoft.protocol.packets.clientbound.play; -import de.bixilon.minosoft.game.datatypes.Recipes; +import de.bixilon.minosoft.game.datatypes.recipes.Recipe; +import de.bixilon.minosoft.game.datatypes.recipes.Recipes; import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.protocol.packets.ClientboundPacket; import de.bixilon.minosoft.protocol.protocol.InPacketBuffer; @@ -23,8 +24,8 @@ public class PacketUnlockRecipes implements ClientboundPacket { UnlockRecipeActions action; boolean isCraftingBookOpen; boolean isFilteringActive; - Recipes[] listed; - Recipes[] tagged; + Recipe[] listed; + Recipe[] tagged; @Override @@ -34,14 +35,14 @@ public class PacketUnlockRecipes implements ClientboundPacket { action = UnlockRecipeActions.byId(buffer.readVarInt()); isCraftingBookOpen = buffer.readBoolean(); isFilteringActive = buffer.readBoolean(); - listed = new Recipes[buffer.readVarInt()]; + listed = new Recipe[buffer.readVarInt()]; for (int i = 0; i < listed.length; i++) { - listed[i] = Recipes.byId(buffer.readVarInt()); + listed[i] = Recipes.getRecipeById(buffer.readVarInt()); } if (action == UnlockRecipeActions.INITIALIZE) { - tagged = new Recipes[buffer.readVarInt()]; + tagged = new Recipe[buffer.readVarInt()]; for (int i = 0; i < tagged.length; i++) { - tagged[i] = Recipes.byId(buffer.readVarInt()); + tagged[i] = Recipes.getRecipeById(buffer.readVarInt()); } } return true; @@ -49,14 +50,14 @@ public class PacketUnlockRecipes implements ClientboundPacket { action = UnlockRecipeActions.byId(buffer.readVarInt()); isCraftingBookOpen = buffer.readBoolean(); isFilteringActive = buffer.readBoolean(); - listed = new Recipes[buffer.readVarInt()]; + listed = new Recipe[buffer.readVarInt()]; for (int i = 0; i < listed.length; i++) { - listed[i] = Recipes.byName(buffer.readString()); + listed[i] = Recipes.getRecipe(buffer.readString(), buffer.getVersion()); } if (action == UnlockRecipeActions.INITIALIZE) { - tagged = new Recipes[buffer.readVarInt()]; + tagged = new Recipe[buffer.readVarInt()]; for (int i = 0; i < tagged.length; i++) { - tagged[i] = Recipes.byName(buffer.readString()); + tagged[i] = Recipes.getRecipe(buffer.readString(), buffer.getVersion()); } } return true; @@ -82,11 +83,11 @@ public class PacketUnlockRecipes implements ClientboundPacket { return isFilteringActive; } - public Recipes[] getListed() { + public Recipe[] getListed() { return listed; } - public Recipes[] getTagged() { + public Recipe[] getTagged() { return tagged; } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java index ea8389336..9e1352c8c 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java @@ -21,6 +21,7 @@ import de.bixilon.minosoft.game.datatypes.entities.items.Items; import de.bixilon.minosoft.game.datatypes.entities.meta.EntityMetaData; import de.bixilon.minosoft.game.datatypes.inventory.Slot; import de.bixilon.minosoft.game.datatypes.particle.*; +import de.bixilon.minosoft.game.datatypes.recipes.Ingredient; import de.bixilon.minosoft.game.datatypes.world.BlockPosition; import de.bixilon.minosoft.nbt.tag.CompoundTag; import de.bixilon.minosoft.util.BitByte; @@ -403,4 +404,24 @@ public class InByteBuffer { } return ret; } + + public Ingredient readIngredient() { + return new Ingredient(readSlotArray(readVarInt())); + } + + public Ingredient[] readIngredientArray(int length) { + Ingredient[] ret = new Ingredient[length]; + for (int i = 0; i < length; i++) { + ret[i] = readIngredient(); + } + return ret; + } + + public Slot[] readSlotArray(int length) { + Slot[] res = new Slot[length]; + for (int i = 0; i < length; i++) { + res[i] = readSlot(); + } + return res; + } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java index 0b0edbad5..54a5bc1ba 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java @@ -590,4 +590,7 @@ public class PacketHandler { public void handle(PacketTags pkg) { //ToDo } + + public void handle(PacketDeclareRecipes pkg) { + } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java index 08c581077..32624ffd7 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java @@ -148,6 +148,7 @@ public abstract class Protocol implements ProtocolInterface { packetClassMapping.put(Packets.Clientbound.PLAY_NBT_QUERY_RESPONSE, PacketNBTQueryResponse.class); packetClassMapping.put(Packets.Clientbound.PLAY_FACE_PLAYER, PacketFacePlayer.class); packetClassMapping.put(Packets.Clientbound.PLAY_TAGS, PacketTags.class); + packetClassMapping.put(Packets.Clientbound.PLAY_DECLARE_RECIPES, PacketDeclareRecipes.class); } public static ProtocolVersion getLowestVersionSupported() {