From 11ef9fb0c00df2a6ee0740c174e52eba72aafe68 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 13 May 2020 00:17:15 +0100 Subject: [PATCH] Item-from-string parsing no longer depends on ItemIds after this is done I'm banning the constant() function. --- resources/item_from_string_bc_map.json | 810 ++++++++++++++++++ src/command/defaults/GiveCommand.php | 4 +- src/item/Item.php | 2 +- src/item/ItemFactory.php | 38 - src/item/LegacyStringToItemParser.php | 117 +++ src/world/World.php | 9 +- src/world/generator/Flat.php | 6 +- tests/phpunit/item/ItemFactoryTest.php | 29 - .../item/LegacyStringToItemParserTest.php | 58 ++ 9 files changed, 996 insertions(+), 77 deletions(-) create mode 100644 resources/item_from_string_bc_map.json create mode 100644 src/item/LegacyStringToItemParser.php create mode 100644 tests/phpunit/item/LegacyStringToItemParserTest.php diff --git a/resources/item_from_string_bc_map.json b/resources/item_from_string_bc_map.json new file mode 100644 index 000000000..34de8fbbe --- /dev/null +++ b/resources/item_from_string_bc_map.json @@ -0,0 +1,810 @@ +{ + "acacia_button": -140, + "acacia_door": 430, + "acacia_door_block": 196, + "acacia_fence_gate": 187, + "acacia_pressure_plate": -150, + "acacia_sign": 475, + "acacia_stairs": 163, + "acacia_standing_sign": -190, + "acacia_trapdoor": -145, + "acacia_wall_sign": -191, + "activator_rail": 126, + "air": 0, + "andesite_stairs": -171, + "anvil": 145, + "apple": 260, + "apple_enchanted": 466, + "appleenchanted": 466, + "armor_stand": 425, + "arrow": 262, + "baked_potato": 393, + "balloon": 448, + "bamboo": -163, + "bamboo_sapling": -164, + "banner": 446, + "banner_pattern": 434, + "barrel": -203, + "barrier": -161, + "beacon": 138, + "bed": 355, + "bed_block": 26, + "bedrock": 7, + "beef": 363, + "beetroot": 457, + "beetroot_block": 244, + "beetroot_seeds": 458, + "beetroot_soup": 459, + "bell": -206, + "birch_button": -141, + "birch_door": 428, + "birch_door_block": 194, + "birch_fence_gate": 184, + "birch_pressure_plate": -151, + "birch_sign": 473, + "birch_stairs": 135, + "birch_standing_sign": -186, + "birch_trapdoor": -146, + "birch_wall_sign": -187, + "black_glazed_terracotta": 235, + "blast_furnace": -196, + "blaze_powder": 377, + "blaze_rod": 369, + "bleach": 451, + "blue_glazed_terracotta": 231, + "blue_ice": -11, + "boat": 333, + "bone": 352, + "bone_block": 216, + "book": 340, + "bookshelf": 47, + "bottle_o_enchanting": 384, + "bow": 261, + "bowl": 281, + "bread": 297, + "brewing_stand": 379, + "brewing_stand_block": 117, + "brick": 336, + "brick_block": 45, + "brick_stairs": 108, + "brown_glazed_terracotta": 232, + "brown_mushroom": 39, + "brown_mushroom_block": 99, + "bubble_column": -160, + "bucket": 325, + "burning_furnace": 62, + "cactus": 81, + "cake": 354, + "cake_block": 92, + "campfire": -209, + "carpet": 171, + "carrot": 391, + "carrot_block": 141, + "carrot_on_a_stick": 398, + "carrotonastick": 398, + "carrots": 141, + "cartography_table": -200, + "carved_pumpkin": -155, + "cauldron": 380, + "cauldron_block": 118, + "chain_boots": 305, + "chain_chestplate": 303, + "chain_command_block": 189, + "chain_helmet": 302, + "chain_leggings": 304, + "chainmail_boots": 305, + "chainmail_chestplate": 303, + "chainmail_helmet": 302, + "chainmail_leggings": 304, + "chemical_heat": 192, + "chemistry_table": 238, + "chest": 54, + "chest_minecart": 342, + "chicken": 365, + "chorus_flower": 200, + "chorus_fruit": 432, + "chorus_fruit_popped": 433, + "chorus_plant": 240, + "clay": 337, + "clay_ball": 337, + "clay_block": 82, + "clock": 347, + "clownfish": 461, + "coal": 263, + "coal_block": 173, + "coal_ore": 16, + "cobblestone": 4, + "cobblestone_stairs": 67, + "cobblestone_wall": 139, + "cobweb": 30, + "cocoa": 127, + "cocoa_block": 127, + "colored_torch_bp": 204, + "colored_torch_rg": 202, + "command_block": 137, + "command_block_minecart": 443, + "comparator": 404, + "comparator_block": 149, + "compass": 345, + "composter": -213, + "compound": 499, + "concrete": 236, + "concrete_powder": 237, + "concretepowder": 237, + "conduit": -157, + "cooked_beef": 364, + "cooked_chicken": 366, + "cooked_fish": 350, + "cooked_mutton": 424, + "cooked_porkchop": 320, + "cooked_rabbit": 412, + "cooked_salmon": 463, + "cookie": 357, + "coral": -131, + "coral_block": -132, + "coral_fan": -133, + "coral_fan_dead": -134, + "coral_fan_hang": -135, + "coral_fan_hang2": -136, + "coral_fan_hang3": -137, + "crafting_table": 58, + "crossbow": 471, + "cyan_glazed_terracotta": 229, + "dandelion": 37, + "dark_oak_button": -142, + "dark_oak_door": 431, + "dark_oak_door_block": 197, + "dark_oak_fence_gate": 186, + "dark_oak_pressure_plate": -152, + "dark_oak_stairs": 164, + "dark_oak_trapdoor": -147, + "dark_prismarine_stairs": -3, + "darkoak_sign": 476, + "darkoak_standing_sign": -192, + "darkoak_wall_sign": -193, + "daylight_detector": 151, + "daylight_detector_inverted": 178, + "daylight_sensor": 151, + "daylight_sensor_inverted": 178, + "dead_bush": 32, + "deadbush": 32, + "detector_rail": 28, + "diamond": 264, + "diamond_axe": 279, + "diamond_block": 57, + "diamond_boots": 313, + "diamond_chestplate": 311, + "diamond_helmet": 310, + "diamond_hoe": 293, + "diamond_horse_armor": 419, + "diamond_leggings": 312, + "diamond_ore": 56, + "diamond_pickaxe": 278, + "diamond_shovel": 277, + "diamond_sword": 276, + "diorite_stairs": -170, + "dirt": 3, + "dispenser": 23, + "double_plant": 175, + "double_stone_slab": 43, + "double_stone_slab2": 181, + "double_stone_slab3": -167, + "double_stone_slab4": -168, + "double_wooden_slab": 157, + "dragon_breath": 437, + "dragon_egg": 122, + "dried_kelp": 464, + "dried_kelp_block": -139, + "dropper": 125, + "dye": 351, + "egg": 344, + "element_0": 36, + "element_1": -12, + "element_10": -21, + "element_100": -111, + "element_101": -112, + "element_102": -113, + "element_103": -114, + "element_104": -115, + "element_105": -116, + "element_106": -117, + "element_107": -118, + "element_108": -119, + "element_109": -120, + "element_11": -22, + "element_110": -121, + "element_111": -122, + "element_112": -123, + "element_113": -124, + "element_114": -125, + "element_115": -126, + "element_116": -127, + "element_117": -128, + "element_118": -129, + "element_12": -23, + "element_13": -24, + "element_14": -25, + "element_15": -26, + "element_16": -27, + "element_17": -28, + "element_18": -29, + "element_19": -30, + "element_2": -13, + "element_20": -31, + "element_21": -32, + "element_22": -33, + "element_23": -34, + "element_24": -35, + "element_25": -36, + "element_26": -37, + "element_27": -38, + "element_28": -39, + "element_29": -40, + "element_3": -14, + "element_30": -41, + "element_31": -42, + "element_32": -43, + "element_33": -44, + "element_34": -45, + "element_35": -46, + "element_36": -47, + "element_37": -48, + "element_38": -49, + "element_39": -50, + "element_4": -15, + "element_40": -51, + "element_41": -52, + "element_42": -53, + "element_43": -54, + "element_44": -55, + "element_45": -56, + "element_46": -57, + "element_47": -58, + "element_48": -59, + "element_49": -60, + "element_5": -16, + "element_50": -61, + "element_51": -62, + "element_52": -63, + "element_53": -64, + "element_54": -65, + "element_55": -66, + "element_56": -67, + "element_57": -68, + "element_58": -69, + "element_59": -70, + "element_6": -17, + "element_60": -71, + "element_61": -72, + "element_62": -73, + "element_63": -74, + "element_64": -75, + "element_65": -76, + "element_66": -77, + "element_67": -78, + "element_68": -79, + "element_69": -80, + "element_7": -18, + "element_70": -81, + "element_71": -82, + "element_72": -83, + "element_73": -84, + "element_74": -85, + "element_75": -86, + "element_76": -87, + "element_77": -88, + "element_78": -89, + "element_79": -90, + "element_8": -19, + "element_80": -91, + "element_81": -92, + "element_82": -93, + "element_83": -94, + "element_84": -95, + "element_85": -96, + "element_86": -97, + "element_87": -98, + "element_88": -99, + "element_89": -100, + "element_9": -20, + "element_90": -101, + "element_91": -102, + "element_92": -103, + "element_93": -104, + "element_94": -105, + "element_95": -106, + "element_96": -107, + "element_97": -108, + "element_98": -109, + "element_99": -110, + "elytra": 444, + "emerald": 388, + "emerald_block": 133, + "emerald_ore": 129, + "empty_map": 395, + "emptymap": 395, + "enchanted_book": 403, + "enchanted_golden_apple": 466, + "enchanting_table": 116, + "enchantment_table": 116, + "end_brick_stairs": -178, + "end_bricks": 206, + "end_crystal": 426, + "end_gateway": 209, + "end_portal": 119, + "end_portal_frame": 120, + "end_rod": 208, + "end_stone": 121, + "ender_chest": 130, + "ender_eye": 381, + "ender_pearl": 368, + "experience_bottle": 384, + "farmland": 60, + "feather": 288, + "fence": 85, + "fence_gate": 107, + "fermented_spider_eye": 376, + "filled_map": 358, + "fire": 51, + "fire_charge": 385, + "fireball": 385, + "fireworks": 401, + "fireworks_charge": 402, + "fireworkscharge": 402, + "fish": 349, + "fishing_rod": 346, + "fletching_table": -201, + "flint": 318, + "flint_and_steel": 259, + "flint_steel": 259, + "flower_pot": 390, + "flower_pot_block": 140, + "flowing_lava": 10, + "flowing_water": 8, + "frame": 389, + "frame_block": 199, + "frosted_ice": 207, + "furnace": 61, + "ghast_tear": 370, + "glass": 20, + "glass_bottle": 374, + "glass_pane": 102, + "glistering_melon": 382, + "glow_stick": 166, + "glowing_obsidian": 246, + "glowing_redstone_ore": 74, + "glowingobsidian": 246, + "glowstone": 89, + "glowstone_dust": 348, + "gold_axe": 286, + "gold_block": 41, + "gold_boots": 317, + "gold_chestplate": 315, + "gold_helmet": 314, + "gold_hoe": 294, + "gold_horse_armor": 418, + "gold_ingot": 266, + "gold_leggings": 316, + "gold_nugget": 371, + "gold_ore": 14, + "gold_pickaxe": 285, + "gold_shovel": 284, + "gold_sword": 283, + "golden_apple": 322, + "golden_axe": 286, + "golden_boots": 317, + "golden_carrot": 396, + "golden_chestplate": 315, + "golden_helmet": 314, + "golden_hoe": 294, + "golden_horse_armor": 418, + "golden_leggings": 316, + "golden_nugget": 371, + "golden_pickaxe": 285, + "golden_rail": 27, + "golden_shovel": 284, + "golden_sword": 283, + "granite_stairs": -169, + "grass": 2, + "grass_path": 198, + "gravel": 13, + "gray_glazed_terracotta": 227, + "green_glazed_terracotta": 233, + "grindstone": -195, + "gunpowder": 289, + "hard_glass": 253, + "hard_glass_pane": 190, + "hard_stained_glass": 254, + "hard_stained_glass_pane": 191, + "hardened_clay": 172, + "hay_bale": 170, + "hay_block": 170, + "heart_of_the_sea": 467, + "heavy_weighted_pressure_plate": 148, + "hopper": 410, + "hopper_block": 154, + "hopper_minecart": 408, + "horse_armor_diamond": 419, + "horse_armor_gold": 418, + "horse_armor_iron": 417, + "horse_armor_leather": 416, + "horsearmordiamond": 419, + "horsearmorgold": 418, + "horsearmoriron": 417, + "horsearmorleather": 416, + "ice": 79, + "ice_bomb": 453, + "info_update": 248, + "info_update2": 249, + "invisible_bedrock": 95, + "invisiblebedrock": 95, + "iron_axe": 258, + "iron_bars": 101, + "iron_block": 42, + "iron_boots": 309, + "iron_chestplate": 307, + "iron_door": 330, + "iron_door_block": 71, + "iron_helmet": 306, + "iron_hoe": 292, + "iron_horse_armor": 417, + "iron_ingot": 265, + "iron_leggings": 308, + "iron_nugget": 452, + "iron_ore": 15, + "iron_pickaxe": 257, + "iron_shovel": 256, + "iron_sword": 267, + "iron_trapdoor": 167, + "item_frame": 389, + "item_frame_block": 199, + "jack_o_lantern": 91, + "jigsaw": -211, + "jukebox": 84, + "jungle_button": -143, + "jungle_door": 429, + "jungle_door_block": 195, + "jungle_fence_gate": 185, + "jungle_pressure_plate": -153, + "jungle_sign": 474, + "jungle_stairs": 136, + "jungle_standing_sign": -188, + "jungle_trapdoor": -148, + "jungle_wall_sign": -189, + "kelp": 335, + "kelp_block": -138, + "ladder": 65, + "lantern": -208, + "lapis_block": 22, + "lapis_ore": 21, + "lava": 11, + "lava_cauldron": -210, + "lead": 420, + "leather": 334, + "leather_boots": 301, + "leather_cap": 298, + "leather_chestplate": 299, + "leather_helmet": 298, + "leather_horse_armor": 416, + "leather_leggings": 300, + "leather_pants": 300, + "leather_tunic": 299, + "leaves": 18, + "leaves2": 161, + "lectern": -194, + "lever": 69, + "light_blue_glazed_terracotta": 223, + "light_weighted_pressure_plate": 147, + "lily_pad": 111, + "lime_glazed_terracotta": 225, + "lingering_potion": 441, + "lit_blast_furnace": -214, + "lit_furnace": 62, + "lit_pumpkin": 91, + "lit_redstone_lamp": 124, + "lit_redstone_ore": 74, + "lit_redstone_torch": 76, + "lit_smoker": -199, + "log": 17, + "log2": 162, + "loom": -204, + "magenta_glazed_terracotta": 222, + "magma": 213, + "magma_cream": 378, + "map": 395, + "medicine": 447, + "melon": 360, + "melon_block": 103, + "melon_seeds": 362, + "melon_slice": 360, + "melon_stem": 105, + "minecart": 328, + "minecart_with_chest": 342, + "minecart_with_command_block": 443, + "minecart_with_hopper": 408, + "minecart_with_tnt": 407, + "mob_head": 397, + "mob_head_block": 144, + "mob_spawner": 52, + "monster_egg": 97, + "monster_spawner": 52, + "moss_stone": 48, + "mossy_cobblestone": 48, + "mossy_cobblestone_stairs": -179, + "mossy_stone_brick_stairs": -175, + "moving_block": 250, + "movingblock": 250, + "mushroom_stew": 282, + "mutton": 423, + "mutton_cooked": 424, + "mutton_raw": 423, + "muttoncooked": 424, + "muttonraw": 423, + "mycelium": 110, + "name_tag": 421, + "nametag": 421, + "nautilus_shell": 465, + "nether_brick": 405, + "nether_brick_block": 112, + "nether_brick_fence": 113, + "nether_brick_stairs": 114, + "nether_quartz": 406, + "nether_quartz_ore": 153, + "nether_reactor": 247, + "nether_star": 399, + "nether_wart": 372, + "nether_wart_block": 214, + "nether_wart_plant": 115, + "netherbrick": 405, + "netherrack": 87, + "netherreactor": 247, + "netherstar": 399, + "normal_stone_stairs": -180, + "note_block": 25, + "noteblock": 25, + "oak_door": 324, + "oak_door_block": 64, + "oak_fence_gate": 107, + "oak_stairs": 53, + "observer": 251, + "obsidian": 49, + "orange_glazed_terracotta": 221, + "packed_ice": 174, + "painting": 321, + "paper": 339, + "phantom_membrane": 470, + "pink_glazed_terracotta": 226, + "piston": 33, + "piston_arm_collision": 34, + "pistonarmcollision": 34, + "planks": 5, + "podzol": 243, + "poisonous_potato": 394, + "polished_andesite_stairs": -174, + "polished_diorite_stairs": -173, + "polished_granite_stairs": -172, + "poppy": 38, + "porkchop": 319, + "portal": 90, + "potato": 392, + "potato_block": 142, + "potatoes": 142, + "potion": 373, + "powered_comparator": 150, + "powered_rail": 27, + "powered_repeater": 94, + "prismarine": 168, + "prismarine_bricks_stairs": -4, + "prismarine_crystals": 422, + "prismarine_shard": 409, + "prismarine_stairs": -2, + "pufferfish": 462, + "pumpkin": 86, + "pumpkin_pie": 400, + "pumpkin_seeds": 361, + "pumpkin_stem": 104, + "purple_glazed_terracotta": 219, + "purpur_block": 201, + "purpur_stairs": 203, + "quartz": 406, + "quartz_block": 155, + "quartz_ore": 153, + "quartz_stairs": 156, + "rabbit": 411, + "rabbit_foot": 414, + "rabbit_hide": 415, + "rabbit_stew": 413, + "rail": 66, + "rapid_fertilizer": 449, + "raw_beef": 363, + "raw_chicken": 365, + "raw_fish": 349, + "raw_mutton": 423, + "raw_porkchop": 319, + "raw_rabbit": 411, + "raw_salmon": 460, + "record_11": 510, + "record_13": 500, + "record_blocks": 502, + "record_cat": 501, + "record_chirp": 503, + "record_far": 504, + "record_mall": 505, + "record_mellohi": 506, + "record_stal": 507, + "record_strad": 508, + "record_wait": 511, + "record_ward": 509, + "red_flower": 38, + "red_glazed_terracotta": 234, + "red_mushroom": 40, + "red_mushroom_block": 100, + "red_nether_brick": 215, + "red_nether_brick_stairs": -184, + "red_sandstone": 179, + "red_sandstone_stairs": 180, + "redstone": 331, + "redstone_block": 152, + "redstone_dust": 331, + "redstone_lamp": 123, + "redstone_ore": 73, + "redstone_torch": 76, + "redstone_wire": 55, + "reeds": 338, + "reeds_block": 83, + "repeater": 356, + "repeater_block": 93, + "repeating_command_block": 188, + "reserved6": 255, + "rotten_flesh": 367, + "saddle": 329, + "salmon": 460, + "sand": 12, + "sandstone": 24, + "sandstone_stairs": 128, + "sapling": 6, + "scaffolding": -165, + "sea_lantern": 169, + "sea_pickle": -156, + "seagrass": -130, + "sealantern": 169, + "seeds": 295, + "shears": 359, + "shield": 513, + "shulker_box": 218, + "shulker_shell": 445, + "sign": 323, + "sign_post": 63, + "silver_glazed_terracotta": 228, + "skull": 397, + "skull_block": 144, + "slime": 165, + "slime_ball": 341, + "slime_block": 165, + "slimeball": 341, + "smithing_table": -202, + "smoker": -198, + "smooth_quartz_stairs": -185, + "smooth_red_sandstone_stairs": -176, + "smooth_sandstone_stairs": -177, + "smooth_stone": -183, + "snow": 80, + "snow_block": 80, + "snow_layer": 78, + "snowball": 332, + "soul_sand": 88, + "sparkler": 442, + "spawn_egg": 383, + "speckled_melon": 382, + "spider_eye": 375, + "splash_potion": 438, + "sponge": 19, + "spruce_button": -144, + "spruce_door": 427, + "spruce_door_block": 193, + "spruce_fence_gate": 183, + "spruce_pressure_plate": -154, + "spruce_sign": 472, + "spruce_stairs": 134, + "spruce_standing_sign": -181, + "spruce_trapdoor": -149, + "spruce_wall_sign": -182, + "stained_clay": 159, + "stained_glass": 241, + "stained_glass_pane": 160, + "stained_hardened_clay": 159, + "standing_banner": 176, + "standing_sign": 63, + "steak": 364, + "stick": 280, + "sticky_piston": 29, + "still_lava": 11, + "still_water": 9, + "stone": 1, + "stone_axe": 275, + "stone_brick": 98, + "stone_brick_stairs": 109, + "stone_bricks": 98, + "stone_button": 77, + "stone_hoe": 291, + "stone_pickaxe": 274, + "stone_pressure_plate": 70, + "stone_shovel": 273, + "stone_slab": 44, + "stone_slab2": 182, + "stone_slab3": -162, + "stone_slab4": -166, + "stone_stairs": 67, + "stone_sword": 272, + "stone_wall": 139, + "stonebrick": 98, + "stonecutter": 245, + "stonecutter_block": -197, + "string": 287, + "stripped_acacia_log": -8, + "stripped_birch_log": -6, + "stripped_dark_oak_log": -9, + "stripped_jungle_log": -7, + "stripped_oak_log": -10, + "stripped_spruce_log": -5, + "structure_block": 252, + "sugar": 353, + "sugarcane": 338, + "sugarcane_block": 83, + "sweet_berries": 477, + "sweet_berry_bush": -207, + "tall_grass": 31, + "tallgrass": 31, + "terracotta": 159, + "tnt": 46, + "tnt_minecart": 407, + "torch": 50, + "totem": 450, + "trapdoor": 96, + "trapped_chest": 146, + "trident": 455, + "trip_wire": 132, + "tripwire": 132, + "tripwire_hook": 131, + "turtle_egg": -159, + "turtle_helmet": 469, + "turtle_shell_piece": 468, + "underwater_torch": 239, + "undyed_shulker_box": 205, + "unlit_redstone_torch": 75, + "unpowered_comparator": 149, + "unpowered_repeater": 93, + "vine": 106, + "vines": 106, + "wall_banner": 177, + "wall_sign": 68, + "water": 9, + "water_lily": 111, + "waterlily": 111, + "web": 30, + "wheat": 296, + "wheat_block": 59, + "wheat_seeds": 295, + "white_glazed_terracotta": 220, + "wood": 17, + "wood2": 162, + "wooden_axe": 271, + "wooden_button": 143, + "wooden_door": 324, + "wooden_door_block": 64, + "wooden_hoe": 290, + "wooden_pickaxe": 270, + "wooden_planks": 5, + "wooden_pressure_plate": 72, + "wooden_shovel": 269, + "wooden_slab": 158, + "wooden_stairs": 53, + "wooden_sword": 268, + "wooden_trapdoor": 96, + "wool": 35, + "workbench": 58, + "writable_book": 386, + "written_book": 387, + "yellow_flower": 37, + "yellow_glazed_terracotta": 224 +} diff --git a/src/command/defaults/GiveCommand.php b/src/command/defaults/GiveCommand.php index 1b0c0bbf5..a3632fa4c 100644 --- a/src/command/defaults/GiveCommand.php +++ b/src/command/defaults/GiveCommand.php @@ -26,7 +26,7 @@ namespace pocketmine\command\defaults; use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\command\utils\InvalidCommandSyntaxException; -use pocketmine\item\ItemFactory; +use pocketmine\item\LegacyStringToItemParser; use pocketmine\lang\TranslationContainer; use pocketmine\nbt\JsonNbtParser; use pocketmine\nbt\NbtDataException; @@ -62,7 +62,7 @@ class GiveCommand extends VanillaCommand{ } try{ - $item = ItemFactory::getInstance()->fromString($args[1]); + $item = LegacyStringToItemParser::getInstance()->parse($args[1]); }catch(\InvalidArgumentException $e){ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.give.item.notFound", [$args[1]])); return true; diff --git a/src/item/Item.php b/src/item/Item.php index 7dca64d85..b8f186479 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -667,7 +667,7 @@ class Item implements \JsonSerializable{ $item = ItemFactory::getInstance()->get($idTag->getValue(), $meta, $count); }elseif($idTag instanceof StringTag){ //PC item save format try{ - $item = ItemFactory::getInstance()->fromString($idTag->getValue() . ":$meta"); + $item = LegacyStringToItemParser::getInstance()->parse($idTag->getValue() . ":$meta"); }catch(\InvalidArgumentException $e){ //TODO: improve error handling return ItemFactory::air(); diff --git a/src/item/ItemFactory.php b/src/item/ItemFactory.php index 0f00937d3..e197fe24b 100644 --- a/src/item/ItemFactory.php +++ b/src/item/ItemFactory.php @@ -34,14 +34,7 @@ use pocketmine\entity\Living; use pocketmine\inventory\ArmorInventory; use pocketmine\nbt\tag\CompoundTag; use pocketmine\utils\SingletonTrait; -use function constant; -use function defined; -use function explode; use function is_a; -use function is_numeric; -use function str_replace; -use function strtoupper; -use function trim; /** * Manages Item instance creation and registration @@ -431,37 +424,6 @@ class ItemFactory{ return $item; } - /** - * Tries to parse the specified string into Item types. - * - * Example accepted formats: - * - `diamond_pickaxe:5` - * - `minecraft:string` - * - `351:4 (lapis lazuli ID:meta)` - * - * @throws \InvalidArgumentException if the given string cannot be parsed as an item identifier - */ - public function fromString(string $str) : Item{ - $b = explode(":", str_replace([" ", "minecraft:"], ["_", ""], trim($str))); - if(!isset($b[1])){ - $meta = 0; - }elseif(is_numeric($b[1])){ - $meta = (int) $b[1]; - }else{ - throw new \InvalidArgumentException("Unable to parse \"" . $b[1] . "\" from \"" . $str . "\" as a valid meta value"); - } - - if(is_numeric($b[0])){ - $item = $this->get((int) $b[0], $meta); - }elseif(defined(ItemIds::class . "::" . strtoupper($b[0]))){ - $item = $this->get(constant(ItemIds::class . "::" . strtoupper($b[0])), $meta); - }else{ - throw new \InvalidArgumentException("Unable to resolve \"" . $str . "\" to a valid item"); - } - - return $item; - } - public static function air() : Item{ return self::$air ?? (self::$air = self::getInstance()->get(ItemIds::AIR, 0, 0)); } diff --git a/src/item/LegacyStringToItemParser.php b/src/item/LegacyStringToItemParser.php new file mode 100644 index 000000000..ea5eb5c22 --- /dev/null +++ b/src/item/LegacyStringToItemParser.php @@ -0,0 +1,117 @@ + $id){ + if(!is_string($name) or !is_int($id)) throw new AssumptionFailedError("Invalid mappings format, expected string keys and int values"); + $result->addMapping($name, $id); + } + + return $result; + } + + /** + * @var int[] + * @phpstan-var array + */ + private $map = []; + + public function __construct(ItemFactory $itemFactory){ + $this->itemFactory = $itemFactory; + } + + public function addMapping(string $alias, int $id) : void{ + $this->map[$alias] = $id; + } + + /** + * Tries to parse the specified string into Item types. + * + * Example accepted formats: + * - `diamond_pickaxe:5` + * - `minecraft:string` + * - `351:4 (lapis lazuli ID:meta)` + * + * @throws \InvalidArgumentException if the given string cannot be parsed as an item identifier + */ + public function parse(string $input) : Item{ + $key = $this->reprocess($input); + $b = explode(":", $key); + + if(!isset($b[1])){ + $meta = 0; + }elseif(is_numeric($b[1])){ + $meta = (int) $b[1]; + }else{ + throw new \InvalidArgumentException("Unable to parse \"" . $b[1] . "\" from \"" . $input . "\" as a valid meta value"); + } + + if(is_numeric($b[0])){ + $item = $this->itemFactory->get((int) $b[0], $meta); + }elseif(isset($this->map[strtolower($b[0])])){ + $item = $this->itemFactory->get($this->map[strtolower($b[0])], $meta); + }else{ + throw new \InvalidArgumentException("Unable to resolve \"" . $input . "\" to a valid item"); + } + + return $item; + } + + protected function reprocess(string $input) : string{ + return str_replace([" ", "minecraft:"], ["_", ""], trim($input)); + } +} diff --git a/src/world/World.php b/src/world/World.php index 496446190..626d46a9e 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -49,6 +49,7 @@ use pocketmine\event\world\WorldSaveEvent; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\item\ItemUseResult; +use pocketmine\item\LegacyStringToItemParser; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\network\mcpe\protocol\BlockActorDataPacket; @@ -1449,9 +1450,9 @@ class World implements ChunkManager{ if($player->isAdventure(true) and !$ev->isCancelled()){ $canBreak = false; - $itemFactory = ItemFactory::getInstance(); + $itemParser = LegacyStringToItemParser::getInstance(); foreach($item->getCanDestroy() as $v){ - $entry = $itemFactory->fromString($v); + $entry = $itemParser->parse($v); if($entry->getBlock()->isSameType($target)){ $canBreak = true; break; @@ -1583,9 +1584,9 @@ class World implements ChunkManager{ $ev = new BlockPlaceEvent($player, $hand, $blockReplace, $blockClicked, $item); if($player->isAdventure(true) and !$ev->isCancelled()){ $canPlace = false; - $itemFactory = ItemFactory::getInstance(); + $itemParser = LegacyStringToItemParser::getInstance(); foreach($item->getCanPlaceOn() as $v){ - $entry = $itemFactory->fromString($v); + $entry = $itemParser->parse($v); if($entry->getBlock()->isSameType($blockClicked)){ $canPlace = true; break; diff --git a/src/world/generator/Flat.php b/src/world/generator/Flat.php index 59c09e652..716986c57 100644 --- a/src/world/generator/Flat.php +++ b/src/world/generator/Flat.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace pocketmine\world\generator; use pocketmine\block\VanillaBlocks; -use pocketmine\item\ItemFactory; +use pocketmine\item\LegacyStringToItemParser; use pocketmine\world\ChunkManager; use pocketmine\world\format\Chunk; use pocketmine\world\generator\object\OreType; @@ -99,7 +99,7 @@ class Flat extends Generator{ $result = []; $split = array_map('\trim', explode(',', $layers)); $y = 0; - $itemFactory = ItemFactory::getInstance(); + $itemParser = LegacyStringToItemParser::getInstance(); foreach($split as $line){ preg_match('#^(?:(\d+)[x|*])?(.+)$#', $line, $matches); if(count($matches) !== 3){ @@ -108,7 +108,7 @@ class Flat extends Generator{ $cnt = $matches[1] !== "" ? (int) $matches[1] : 1; try{ - $b = $itemFactory->fromString($matches[2])->getBlock(); + $b = $itemParser->parse($matches[2])->getBlock(); }catch(\InvalidArgumentException $e){ throw new InvalidGeneratorOptionsException("Invalid preset layer \"$line\": " . $e->getMessage(), 0, $e); } diff --git a/tests/phpunit/item/ItemFactoryTest.php b/tests/phpunit/item/ItemFactoryTest.php index 723eed6c8..3ae28fb27 100644 --- a/tests/phpunit/item/ItemFactoryTest.php +++ b/tests/phpunit/item/ItemFactoryTest.php @@ -37,35 +37,6 @@ class ItemFactoryTest extends TestCase{ } } - /** - * @return mixed[][] - * @phpstan-return list - */ - public function itemFromStringProvider() : array{ - return [ - ["dye:4", ItemIds::DYE, 4], - ["351", ItemIds::DYE, 0], - ["351:4", ItemIds::DYE, 4], - ["stone:3", ItemIds::STONE, 3], - ["minecraft:string", ItemIds::STRING, 0], - ["diamond_pickaxe", ItemIds::DIAMOND_PICKAXE, 0], - ["diamond_pickaxe:5", ItemIds::DIAMOND_PICKAXE, 5] - ]; - } - - /** - * @dataProvider itemFromStringProvider - * @param string $string - * @param int $id - * @param int $meta - */ - public function testFromStringSingle(string $string, int $id, int $meta) : void{ - $item = ItemFactory::getInstance()->fromString($string); - - self::assertEquals($id, $item->getId()); - self::assertEquals($meta, $item->getMeta()); - } - /** * Test that durable items are correctly created by the item factory */ diff --git a/tests/phpunit/item/LegacyStringToItemParserTest.php b/tests/phpunit/item/LegacyStringToItemParserTest.php new file mode 100644 index 000000000..56e356552 --- /dev/null +++ b/tests/phpunit/item/LegacyStringToItemParserTest.php @@ -0,0 +1,58 @@ + + */ + public function itemFromStringProvider() : array{ + return [ + ["dye:4", ItemIds::DYE, 4], + ["351", ItemIds::DYE, 0], + ["351:4", ItemIds::DYE, 4], + ["stone:3", ItemIds::STONE, 3], + ["minecraft:string", ItemIds::STRING, 0], + ["diamond_pickaxe", ItemIds::DIAMOND_PICKAXE, 0], + ["diamond_pickaxe:5", ItemIds::DIAMOND_PICKAXE, 5] + ]; + } + + /** + * @dataProvider itemFromStringProvider + * @param string $string + * @param int $id + * @param int $meta + */ + public function testFromStringSingle(string $string, int $id, int $meta) : void{ + $item = LegacyStringToItemParser::getInstance()->parse($string); + + self::assertEquals($id, $item->getId()); + self::assertEquals($meta, $item->getMeta()); + } +}