import { log } from './utils.js'; import { JAVA_TO_BEDROCK } from './java-block-ids.js'; const TAG = 'BlockMap'; /** * Mapping from GrabCraft Java Edition block IDs to Bedrock Edition block IDs. * GrabCraft uses format like "5:5" (blockId:dataValue) and English names. * Bedrock uses string IDs like "planks" with data values. * * Format: { javaId: "numericId:data", bedrockId: "block_name", bedrockData: number } */ const BLOCK_MAP = new Map([ // ── Air ── ['0', { bedrock: 'air', data: 0, name: 'Air' }], // ── Stone variants ── ['1', { bedrock: 'stone', data: 0, name: 'Stone' }], ['1:1', { bedrock: 'stone', data: 1, name: 'Granite' }], ['1:2', { bedrock: 'stone', data: 2, name: 'Polished Granite' }], ['1:3', { bedrock: 'stone', data: 3, name: 'Diorite' }], ['1:4', { bedrock: 'stone', data: 4, name: 'Polished Diorite' }], ['1:5', { bedrock: 'stone', data: 5, name: 'Andesite' }], ['1:6', { bedrock: 'stone', data: 6, name: 'Polished Andesite' }], // ── Grass & Dirt ── ['2', { bedrock: 'grass_block', data: 0, name: 'Grass Block' }], ['3', { bedrock: 'dirt', data: 0, name: 'Dirt' }], ['3:1', { bedrock: 'dirt', data: 1, name: 'Coarse Dirt' }], ['3:2', { bedrock: 'podzol', data: 0, name: 'Podzol' }], // ── Cobblestone ── ['4', { bedrock: 'cobblestone', data: 0, name: 'Cobblestone' }], // ── Planks ── ['5', { bedrock: 'planks', data: 0, name: 'Oak Planks' }], ['5:1', { bedrock: 'planks', data: 1, name: 'Spruce Planks' }], ['5:2', { bedrock: 'planks', data: 2, name: 'Birch Planks' }], ['5:3', { bedrock: 'planks', data: 3, name: 'Jungle Planks' }], ['5:4', { bedrock: 'planks', data: 4, name: 'Acacia Planks' }], ['5:5', { bedrock: 'planks', data: 5, name: 'Dark Oak Planks' }], // ── Saplings ── ['6', { bedrock: 'sapling', data: 0, name: 'Oak Sapling' }], ['6:1', { bedrock: 'sapling', data: 1, name: 'Spruce Sapling' }], ['6:2', { bedrock: 'sapling', data: 2, name: 'Birch Sapling' }], ['6:3', { bedrock: 'sapling', data: 3, name: 'Jungle Sapling' }], ['6:4', { bedrock: 'sapling', data: 4, name: 'Acacia Sapling' }], ['6:5', { bedrock: 'sapling', data: 5, name: 'Dark Oak Sapling' }], // ── Bedrock ── ['7', { bedrock: 'bedrock', data: 0, name: 'Bedrock' }], // ── Water & Lava ── ['8', { bedrock: 'water', data: 0, name: 'Water' }], ['9', { bedrock: 'water', data: 0, name: 'Water (stationary)' }], ['10', { bedrock: 'lava', data: 0, name: 'Lava' }], ['11', { bedrock: 'lava', data: 0, name: 'Lava (stationary)' }], // ── Sand & Gravel ── ['12', { bedrock: 'sand', data: 0, name: 'Sand' }], ['12:1', { bedrock: 'sand', data: 1, name: 'Red Sand' }], ['13', { bedrock: 'gravel', data: 0, name: 'Gravel' }], // ── Ores ── ['14', { bedrock: 'gold_ore', data: 0, name: 'Gold Ore' }], ['15', { bedrock: 'iron_ore', data: 0, name: 'Iron Ore' }], ['16', { bedrock: 'coal_ore', data: 0, name: 'Coal Ore' }], // ── Logs ── ['17', { bedrock: 'log', data: 0, name: 'Oak Log' }], ['17:1', { bedrock: 'log', data: 1, name: 'Spruce Log' }], ['17:2', { bedrock: 'log', data: 2, name: 'Birch Log' }], ['17:3', { bedrock: 'log', data: 3, name: 'Jungle Log' }], ['162', { bedrock: 'log2', data: 0, name: 'Acacia Log' }], ['162:1', { bedrock: 'log2', data: 1, name: 'Dark Oak Log' }], // ── Leaves ── ['18', { bedrock: 'leaves', data: 0, name: 'Oak Leaves' }], ['18:1', { bedrock: 'leaves', data: 1, name: 'Spruce Leaves' }], ['18:2', { bedrock: 'leaves', data: 2, name: 'Birch Leaves' }], ['18:3', { bedrock: 'leaves', data: 3, name: 'Jungle Leaves' }], ['161', { bedrock: 'leaves2', data: 0, name: 'Acacia Leaves' }], ['161:1', { bedrock: 'leaves2', data: 1, name: 'Dark Oak Leaves' }], // ── Sponge ── ['19', { bedrock: 'sponge', data: 0, name: 'Sponge' }], ['19:1', { bedrock: 'sponge', data: 1, name: 'Wet Sponge' }], // ── Glass ── ['20', { bedrock: 'glass', data: 0, name: 'Glass' }], ['102', { bedrock: 'glass_pane', data: 0, name: 'Glass Pane' }], // ── Lapis ── ['21', { bedrock: 'lapis_ore', data: 0, name: 'Lapis Lazuli Ore' }], ['22', { bedrock: 'lapis_block', data: 0, name: 'Lapis Lazuli Block' }], // ── Dispenser & Noteblock ── ['23', { bedrock: 'dispenser', data: 0, name: 'Dispenser' }], ['25', { bedrock: 'noteblock', data: 0, name: 'Note Block' }], // ── Sandstone ── ['24', { bedrock: 'sandstone', data: 0, name: 'Sandstone' }], ['24:1', { bedrock: 'sandstone', data: 1, name: 'Chiseled Sandstone' }], ['24:2', { bedrock: 'sandstone', data: 2, name: 'Smooth Sandstone' }], // ── Wool ── ['35', { bedrock: 'wool', data: 0, name: 'White Wool' }], ['35:1', { bedrock: 'wool', data: 1, name: 'Orange Wool' }], ['35:2', { bedrock: 'wool', data: 2, name: 'Magenta Wool' }], ['35:3', { bedrock: 'wool', data: 3, name: 'Light Blue Wool' }], ['35:4', { bedrock: 'wool', data: 4, name: 'Yellow Wool' }], ['35:5', { bedrock: 'wool', data: 5, name: 'Lime Wool' }], ['35:6', { bedrock: 'wool', data: 6, name: 'Pink Wool' }], ['35:7', { bedrock: 'wool', data: 7, name: 'Gray Wool' }], ['35:8', { bedrock: 'wool', data: 8, name: 'Light Gray Wool' }], ['35:9', { bedrock: 'wool', data: 9, name: 'Cyan Wool' }], ['35:10', { bedrock: 'wool', data: 10, name: 'Purple Wool' }], ['35:11', { bedrock: 'wool', data: 11, name: 'Blue Wool' }], ['35:12', { bedrock: 'wool', data: 12, name: 'Brown Wool' }], ['35:13', { bedrock: 'wool', data: 13, name: 'Green Wool' }], ['35:14', { bedrock: 'wool', data: 14, name: 'Red Wool' }], ['35:15', { bedrock: 'wool', data: 15, name: 'Black Wool' }], // ── Gold & Iron blocks ── ['41', { bedrock: 'gold_block', data: 0, name: 'Block of Gold' }], ['42', { bedrock: 'iron_block', data: 0, name: 'Block of Iron' }], // ── Slabs ── ['44', { bedrock: 'stone_block_slab', data: 0, name: 'Stone Slab' }], ['44:1', { bedrock: 'stone_block_slab', data: 1, name: 'Sandstone Slab' }], ['44:3', { bedrock: 'stone_block_slab', data: 3, name: 'Cobblestone Slab' }], ['44:4', { bedrock: 'stone_block_slab', data: 4, name: 'Brick Slab' }], ['44:5', { bedrock: 'stone_block_slab', data: 5, name: 'Stone Brick Slab' }], ['126', { bedrock: 'wooden_slab', data: 0, name: 'Oak Slab' }], ['126:1', { bedrock: 'wooden_slab', data: 1, name: 'Spruce Slab' }], ['126:2', { bedrock: 'wooden_slab', data: 2, name: 'Birch Slab' }], ['126:3', { bedrock: 'wooden_slab', data: 3, name: 'Jungle Slab' }], ['126:4', { bedrock: 'wooden_slab', data: 4, name: 'Acacia Slab' }], ['126:5', { bedrock: 'wooden_slab', data: 5, name: 'Dark Oak Slab' }], // ── Bricks ── ['45', { bedrock: 'brick_block', data: 0, name: 'Bricks' }], ['98', { bedrock: 'stonebrick', data: 0, name: 'Stone Bricks' }], ['98:1', { bedrock: 'stonebrick', data: 1, name: 'Mossy Stone Bricks' }], ['98:2', { bedrock: 'stonebrick', data: 2, name: 'Cracked Stone Bricks' }], ['98:3', { bedrock: 'stonebrick', data: 3, name: 'Chiseled Stone Bricks' }], ['112', { bedrock: 'nether_brick', data: 0, name: 'Nether Bricks' }], // ── TNT ── ['46', { bedrock: 'tnt', data: 0, name: 'TNT' }], // ── Bookshelf ── ['47', { bedrock: 'bookshelf', data: 0, name: 'Bookshelf' }], // ── Mossy Cobblestone ── ['48', { bedrock: 'mossy_cobblestone', data: 0, name: 'Mossy Cobblestone' }], // ── Obsidian ── ['49', { bedrock: 'obsidian', data: 0, name: 'Obsidian' }], // ── Torches ── ['50', { bedrock: 'torch', data: 0, name: 'Torch' }], // ── Stairs ── ['53', { bedrock: 'oak_stairs', data: 0, name: 'Oak Stairs' }], ['67', { bedrock: 'stone_stairs', data: 0, name: 'Cobblestone Stairs' }], ['108', { bedrock: 'brick_stairs', data: 0, name: 'Brick Stairs' }], ['109', { bedrock: 'stone_brick_stairs', data: 0, name: 'Stone Brick Stairs' }], ['114', { bedrock: 'nether_brick_stairs', data: 0, name: 'Nether Brick Stairs' }], ['128', { bedrock: 'sandstone_stairs', data: 0, name: 'Sandstone Stairs' }], ['134', { bedrock: 'spruce_stairs', data: 0, name: 'Spruce Stairs' }], ['135', { bedrock: 'birch_stairs', data: 0, name: 'Birch Stairs' }], ['136', { bedrock: 'jungle_stairs', data: 0, name: 'Jungle Stairs' }], ['163', { bedrock: 'acacia_stairs', data: 0, name: 'Acacia Stairs' }], ['164', { bedrock: 'dark_oak_stairs', data: 0, name: 'Dark Oak Stairs' }], ['156', { bedrock: 'quartz_stairs', data: 0, name: 'Quartz Stairs' }], // ── Chest ── ['54', { bedrock: 'chest', data: 0, name: 'Chest' }], // ── Diamond ── ['56', { bedrock: 'diamond_ore', data: 0, name: 'Diamond Ore' }], ['57', { bedrock: 'diamond_block', data: 0, name: 'Block of Diamond' }], // ── Crafting Table ── ['58', { bedrock: 'crafting_table', data: 0, name: 'Crafting Table' }], // ── Furnace ── ['61', { bedrock: 'furnace', data: 0, name: 'Furnace' }], ['62', { bedrock: 'lit_furnace', data: 0, name: 'Burning Furnace' }], // ── Doors ── ['64', { bedrock: 'wooden_door', data: 0, name: 'Oak Door' }], ['71', { bedrock: 'iron_door', data: 0, name: 'Iron Door' }], ['193', { bedrock: 'spruce_door', data: 0, name: 'Spruce Door' }], ['194', { bedrock: 'birch_door', data: 0, name: 'Birch Door' }], ['195', { bedrock: 'jungle_door', data: 0, name: 'Jungle Door' }], ['196', { bedrock: 'acacia_door', data: 0, name: 'Acacia Door' }], ['197', { bedrock: 'dark_oak_door', data: 0, name: 'Dark Oak Door' }], // ── Ladders ── ['65', { bedrock: 'ladder', data: 0, name: 'Ladder' }], // ── Rails ── ['66', { bedrock: 'rail', data: 0, name: 'Rail' }], ['27', { bedrock: 'golden_rail', data: 0, name: 'Powered Rail' }], ['28', { bedrock: 'detector_rail', data: 0, name: 'Detector Rail' }], ['157', { bedrock: 'activator_rail', data: 0, name: 'Activator Rail' }], // ── Snow & Ice ── ['78', { bedrock: 'snow_layer', data: 0, name: 'Snow Layer' }], ['79', { bedrock: 'ice', data: 0, name: 'Ice' }], ['80', { bedrock: 'snow', data: 0, name: 'Snow Block' }], ['174', { bedrock: 'packed_ice', data: 0, name: 'Packed Ice' }], // ── Cactus ── ['81', { bedrock: 'cactus', data: 0, name: 'Cactus' }], // ── Clay ── ['82', { bedrock: 'clay', data: 0, name: 'Clay' }], // ── Jukebox ── ['84', { bedrock: 'jukebox', data: 0, name: 'Jukebox' }], // ── Fences ── ['85', { bedrock: 'fence', data: 0, name: 'Oak Fence' }], ['113', { bedrock: 'nether_brick_fence', data: 0, name: 'Nether Brick Fence' }], ['188', { bedrock: 'fence', data: 1, name: 'Spruce Fence' }], ['189', { bedrock: 'fence', data: 2, name: 'Birch Fence' }], ['190', { bedrock: 'fence', data: 3, name: 'Jungle Fence' }], ['191', { bedrock: 'fence', data: 4, name: 'Acacia Fence' }], ['192', { bedrock: 'fence', data: 5, name: 'Dark Oak Fence' }], // ── Fence Gates ── ['107', { bedrock: 'fence_gate', data: 0, name: 'Oak Fence Gate' }], ['183', { bedrock: 'spruce_fence_gate', data: 0, name: 'Spruce Fence Gate' }], ['184', { bedrock: 'birch_fence_gate', data: 0, name: 'Birch Fence Gate' }], ['185', { bedrock: 'jungle_fence_gate', data: 0, name: 'Jungle Fence Gate' }], ['186', { bedrock: 'acacia_fence_gate', data: 0, name: 'Acacia Fence Gate' }], ['187', { bedrock: 'dark_oak_fence_gate', data: 0, name: 'Dark Oak Fence Gate' }], // ── Pumpkin & Melon ── ['86', { bedrock: 'pumpkin', data: 0, name: 'Pumpkin' }], ['91', { bedrock: 'lit_pumpkin', data: 0, name: 'Jack o\'Lantern' }], ['103', { bedrock: 'melon_block', data: 0, name: 'Melon Block' }], // ── Netherrack & Soul Sand ── ['87', { bedrock: 'netherrack', data: 0, name: 'Netherrack' }], ['88', { bedrock: 'soul_sand', data: 0, name: 'Soul Sand' }], // ── Glowstone ── ['89', { bedrock: 'glowstone', data: 0, name: 'Glowstone' }], // ── Stained Glass ── ['95', { bedrock: 'stained_glass', data: 0, name: 'White Stained Glass' }], ['95:1', { bedrock: 'stained_glass', data: 1, name: 'Orange Stained Glass' }], ['95:2', { bedrock: 'stained_glass', data: 2, name: 'Magenta Stained Glass' }], ['95:3', { bedrock: 'stained_glass', data: 3, name: 'Light Blue Stained Glass' }], ['95:4', { bedrock: 'stained_glass', data: 4, name: 'Yellow Stained Glass' }], ['95:5', { bedrock: 'stained_glass', data: 5, name: 'Lime Stained Glass' }], ['95:6', { bedrock: 'stained_glass', data: 6, name: 'Pink Stained Glass' }], ['95:7', { bedrock: 'stained_glass', data: 7, name: 'Gray Stained Glass' }], ['95:8', { bedrock: 'stained_glass', data: 8, name: 'Light Gray Stained Glass' }], ['95:9', { bedrock: 'stained_glass', data: 9, name: 'Cyan Stained Glass' }], ['95:10', { bedrock: 'stained_glass', data: 10, name: 'Purple Stained Glass' }], ['95:11', { bedrock: 'stained_glass', data: 11, name: 'Blue Stained Glass' }], ['95:12', { bedrock: 'stained_glass', data: 12, name: 'Brown Stained Glass' }], ['95:13', { bedrock: 'stained_glass', data: 13, name: 'Green Stained Glass' }], ['95:14', { bedrock: 'stained_glass', data: 14, name: 'Red Stained Glass' }], ['95:15', { bedrock: 'stained_glass', data: 15, name: 'Black Stained Glass' }], // ── Stained Glass Panes ── ['160', { bedrock: 'stained_glass_pane', data: 0, name: 'White Stained Glass Pane' }], ['160:1', { bedrock: 'stained_glass_pane', data: 1, name: 'Orange Stained Glass Pane' }], ['160:2', { bedrock: 'stained_glass_pane', data: 2, name: 'Magenta Stained Glass Pane' }], ['160:3', { bedrock: 'stained_glass_pane', data: 3, name: 'Light Blue Stained Glass Pane' }], ['160:4', { bedrock: 'stained_glass_pane', data: 4, name: 'Yellow Stained Glass Pane' }], ['160:5', { bedrock: 'stained_glass_pane', data: 5, name: 'Lime Stained Glass Pane' }], ['160:6', { bedrock: 'stained_glass_pane', data: 6, name: 'Pink Stained Glass Pane' }], ['160:7', { bedrock: 'stained_glass_pane', data: 7, name: 'Gray Stained Glass Pane' }], ['160:8', { bedrock: 'stained_glass_pane', data: 8, name: 'Light Gray Stained Glass Pane' }], ['160:9', { bedrock: 'stained_glass_pane', data: 9, name: 'Cyan Stained Glass Pane' }], ['160:10', { bedrock: 'stained_glass_pane', data: 10, name: 'Purple Stained Glass Pane' }], ['160:11', { bedrock: 'stained_glass_pane', data: 11, name: 'Blue Stained Glass Pane' }], ['160:12', { bedrock: 'stained_glass_pane', data: 12, name: 'Brown Stained Glass Pane' }], ['160:13', { bedrock: 'stained_glass_pane', data: 13, name: 'Green Stained Glass Pane' }], ['160:14', { bedrock: 'stained_glass_pane', data: 14, name: 'Red Stained Glass Pane' }], ['160:15', { bedrock: 'stained_glass_pane', data: 15, name: 'Black Stained Glass Pane' }], // ── Iron Bars ── ['101', { bedrock: 'iron_bars', data: 0, name: 'Iron Bars' }], // ── Quartz ── ['155', { bedrock: 'quartz_block', data: 0, name: 'Quartz Block' }], ['155:1', { bedrock: 'quartz_block', data: 1, name: 'Chiseled Quartz' }], ['155:2', { bedrock: 'quartz_block', data: 2, name: 'Pillar Quartz' }], // ── Terracotta (Hardened Clay) ── ['159', { bedrock: 'stained_hardened_clay', data: 0, name: 'White Terracotta' }], ['159:1', { bedrock: 'stained_hardened_clay', data: 1, name: 'Orange Terracotta' }], ['159:2', { bedrock: 'stained_hardened_clay', data: 2, name: 'Magenta Terracotta' }], ['159:3', { bedrock: 'stained_hardened_clay', data: 3, name: 'Light Blue Terracotta' }], ['159:4', { bedrock: 'stained_hardened_clay', data: 4, name: 'Yellow Terracotta' }], ['159:5', { bedrock: 'stained_hardened_clay', data: 5, name: 'Lime Terracotta' }], ['159:6', { bedrock: 'stained_hardened_clay', data: 6, name: 'Pink Terracotta' }], ['159:7', { bedrock: 'stained_hardened_clay', data: 7, name: 'Gray Terracotta' }], ['159:8', { bedrock: 'stained_hardened_clay', data: 8, name: 'Light Gray Terracotta' }], ['159:9', { bedrock: 'stained_hardened_clay', data: 9, name: 'Cyan Terracotta' }], ['159:10', { bedrock: 'stained_hardened_clay', data: 10, name: 'Purple Terracotta' }], ['159:11', { bedrock: 'stained_hardened_clay', data: 11, name: 'Blue Terracotta' }], ['159:12', { bedrock: 'stained_hardened_clay', data: 12, name: 'Brown Terracotta' }], ['159:13', { bedrock: 'stained_hardened_clay', data: 13, name: 'Green Terracotta' }], ['159:14', { bedrock: 'stained_hardened_clay', data: 14, name: 'Red Terracotta' }], ['159:15', { bedrock: 'stained_hardened_clay', data: 15, name: 'Black Terracotta' }], ['172', { bedrock: 'hardened_clay', data: 0, name: 'Terracotta' }], // ── Concrete ── ['251', { bedrock: 'concrete', data: 0, name: 'White Concrete' }], ['251:1', { bedrock: 'concrete', data: 1, name: 'Orange Concrete' }], ['251:2', { bedrock: 'concrete', data: 2, name: 'Magenta Concrete' }], ['251:3', { bedrock: 'concrete', data: 3, name: 'Light Blue Concrete' }], ['251:4', { bedrock: 'concrete', data: 4, name: 'Yellow Concrete' }], ['251:5', { bedrock: 'concrete', data: 5, name: 'Lime Concrete' }], ['251:6', { bedrock: 'concrete', data: 6, name: 'Pink Concrete' }], ['251:7', { bedrock: 'concrete', data: 7, name: 'Gray Concrete' }], ['251:8', { bedrock: 'concrete', data: 8, name: 'Light Gray Concrete' }], ['251:9', { bedrock: 'concrete', data: 9, name: 'Cyan Concrete' }], ['251:10', { bedrock: 'concrete', data: 10, name: 'Purple Concrete' }], ['251:11', { bedrock: 'concrete', data: 11, name: 'Blue Concrete' }], ['251:12', { bedrock: 'concrete', data: 12, name: 'Brown Concrete' }], ['251:13', { bedrock: 'concrete', data: 13, name: 'Green Concrete' }], ['251:14', { bedrock: 'concrete', data: 14, name: 'Red Concrete' }], ['251:15', { bedrock: 'concrete', data: 15, name: 'Black Concrete' }], // ── Concrete Powder ── ['252', { bedrock: 'concrete_powder', data: 0, name: 'White Concrete Powder' }], ['252:1', { bedrock: 'concrete_powder', data: 1, name: 'Orange Concrete Powder' }], ['252:2', { bedrock: 'concrete_powder', data: 2, name: 'Magenta Concrete Powder' }], ['252:3', { bedrock: 'concrete_powder', data: 3, name: 'Light Blue Concrete Powder' }], ['252:4', { bedrock: 'concrete_powder', data: 4, name: 'Yellow Concrete Powder' }], ['252:5', { bedrock: 'concrete_powder', data: 5, name: 'Lime Concrete Powder' }], ['252:6', { bedrock: 'concrete_powder', data: 6, name: 'Pink Concrete Powder' }], ['252:7', { bedrock: 'concrete_powder', data: 7, name: 'Gray Concrete Powder' }], ['252:8', { bedrock: 'concrete_powder', data: 8, name: 'Light Gray Concrete Powder' }], ['252:9', { bedrock: 'concrete_powder', data: 9, name: 'Cyan Concrete Powder' }], ['252:10', { bedrock: 'concrete_powder', data: 10, name: 'Purple Concrete Powder' }], ['252:11', { bedrock: 'concrete_powder', data: 11, name: 'Blue Concrete Powder' }], ['252:12', { bedrock: 'concrete_powder', data: 12, name: 'Brown Concrete Powder' }], ['252:13', { bedrock: 'concrete_powder', data: 13, name: 'Green Concrete Powder' }], ['252:14', { bedrock: 'concrete_powder', data: 14, name: 'Red Concrete Powder' }], ['252:15', { bedrock: 'concrete_powder', data: 15, name: 'Black Concrete Powder' }], // ── Glazed Terracotta ── ['235', { bedrock: 'white_glazed_terracotta', data: 0, name: 'White Glazed Terracotta' }], ['236', { bedrock: 'orange_glazed_terracotta', data: 0, name: 'Orange Glazed Terracotta' }], ['237', { bedrock: 'magenta_glazed_terracotta', data: 0, name: 'Magenta Glazed Terracotta' }], ['238', { bedrock: 'light_blue_glazed_terracotta', data: 0, name: 'Light Blue Glazed Terracotta' }], ['239', { bedrock: 'yellow_glazed_terracotta', data: 0, name: 'Yellow Glazed Terracotta' }], ['240', { bedrock: 'lime_glazed_terracotta', data: 0, name: 'Lime Glazed Terracotta' }], ['241', { bedrock: 'pink_glazed_terracotta', data: 0, name: 'Pink Glazed Terracotta' }], ['242', { bedrock: 'gray_glazed_terracotta', data: 0, name: 'Gray Glazed Terracotta' }], ['243', { bedrock: 'silver_glazed_terracotta', data: 0, name: 'Light Gray Glazed Terracotta' }], ['244', { bedrock: 'cyan_glazed_terracotta', data: 0, name: 'Cyan Glazed Terracotta' }], ['245', { bedrock: 'purple_glazed_terracotta', data: 0, name: 'Purple Glazed Terracotta' }], ['246', { bedrock: 'blue_glazed_terracotta', data: 0, name: 'Blue Glazed Terracotta' }], ['247', { bedrock: 'brown_glazed_terracotta', data: 0, name: 'Brown Glazed Terracotta' }], ['248', { bedrock: 'green_glazed_terracotta', data: 0, name: 'Green Glazed Terracotta' }], ['249', { bedrock: 'red_glazed_terracotta', data: 0, name: 'Red Glazed Terracotta' }], ['250', { bedrock: 'black_glazed_terracotta', data: 0, name: 'Black Glazed Terracotta' }], // ── Carpet ── ['171', { bedrock: 'carpet', data: 0, name: 'White Carpet' }], ['171:1', { bedrock: 'carpet', data: 1, name: 'Orange Carpet' }], ['171:2', { bedrock: 'carpet', data: 2, name: 'Magenta Carpet' }], ['171:3', { bedrock: 'carpet', data: 3, name: 'Light Blue Carpet' }], ['171:4', { bedrock: 'carpet', data: 4, name: 'Yellow Carpet' }], ['171:5', { bedrock: 'carpet', data: 5, name: 'Lime Carpet' }], ['171:6', { bedrock: 'carpet', data: 6, name: 'Pink Carpet' }], ['171:7', { bedrock: 'carpet', data: 7, name: 'Gray Carpet' }], ['171:8', { bedrock: 'carpet', data: 8, name: 'Light Gray Carpet' }], ['171:9', { bedrock: 'carpet', data: 9, name: 'Cyan Carpet' }], ['171:10', { bedrock: 'carpet', data: 10, name: 'Purple Carpet' }], ['171:11', { bedrock: 'carpet', data: 11, name: 'Blue Carpet' }], ['171:12', { bedrock: 'carpet', data: 12, name: 'Brown Carpet' }], ['171:13', { bedrock: 'carpet', data: 13, name: 'Green Carpet' }], ['171:14', { bedrock: 'carpet', data: 14, name: 'Red Carpet' }], ['171:15', { bedrock: 'carpet', data: 15, name: 'Black Carpet' }], // ── Redstone ── ['55', { bedrock: 'redstone_wire', data: 0, name: 'Redstone Wire' }], ['73', { bedrock: 'redstone_ore', data: 0, name: 'Redstone Ore' }], ['76', { bedrock: 'redstone_torch', data: 0, name: 'Redstone Torch' }], ['69', { bedrock: 'lever', data: 0, name: 'Lever' }], ['70', { bedrock: 'stone_pressure_plate', data: 0, name: 'Stone Pressure Plate' }], ['72', { bedrock: 'wooden_pressure_plate', data: 0, name: 'Oak Pressure Plate' }], ['77', { bedrock: 'stone_button', data: 0, name: 'Stone Button' }], ['143', { bedrock: 'wooden_button', data: 0, name: 'Oak Button' }], ['123', { bedrock: 'redstone_lamp', data: 0, name: 'Redstone Lamp' }], ['33', { bedrock: 'piston', data: 0, name: 'Piston' }], ['29', { bedrock: 'sticky_piston', data: 0, name: 'Sticky Piston' }], ['93', { bedrock: 'unpowered_repeater', data: 0, name: 'Repeater' }], ['149', { bedrock: 'unpowered_comparator', data: 0, name: 'Comparator' }], ['152', { bedrock: 'redstone_block', data: 0, name: 'Block of Redstone' }], ['151', { bedrock: 'daylight_detector', data: 0, name: 'Daylight Detector' }], ['154', { bedrock: 'hopper', data: 0, name: 'Hopper' }], ['158', { bedrock: 'dropper', data: 0, name: 'Dropper' }], ['146', { bedrock: 'trapped_chest', data: 0, name: 'Trapped Chest' }], ['147', { bedrock: 'light_weighted_pressure_plate', data: 0, name: 'Light Weighted Pressure Plate' }], ['148', { bedrock: 'heavy_weighted_pressure_plate', data: 0, name: 'Heavy Weighted Pressure Plate' }], // ── Trapdoors ── ['96', { bedrock: 'trapdoor', data: 0, name: 'Oak Trapdoor' }], ['167', { bedrock: 'iron_trapdoor', data: 0, name: 'Iron Trapdoor' }], // ── Emerald ── ['129', { bedrock: 'emerald_ore', data: 0, name: 'Emerald Ore' }], ['133', { bedrock: 'emerald_block', data: 0, name: 'Block of Emerald' }], // ── End Stone ── ['121', { bedrock: 'end_stone', data: 0, name: 'End Stone' }], ['206', { bedrock: 'end_bricks', data: 0, name: 'End Stone Bricks' }], // ── Purpur ── ['201', { bedrock: 'purpur_block', data: 0, name: 'Purpur Block' }], ['202', { bedrock: 'purpur_pillar', data: 0, name: 'Purpur Pillar' }], ['203', { bedrock: 'purpur_stairs', data: 0, name: 'Purpur Stairs' }], // ── Prismarine ── ['168', { bedrock: 'prismarine', data: 0, name: 'Prismarine' }], ['168:1', { bedrock: 'prismarine', data: 1, name: 'Prismarine Bricks' }], ['168:2', { bedrock: 'prismarine', data: 2, name: 'Dark Prismarine' }], ['169', { bedrock: 'sea_lantern', data: 0, name: 'Sea Lantern' }], // ── Hay Bale ── ['170', { bedrock: 'hay_block', data: 0, name: 'Hay Bale' }], // ── Anvil ── ['145', { bedrock: 'anvil', data: 0, name: 'Anvil' }], // ── Slime Block ── ['165', { bedrock: 'slime', data: 0, name: 'Slime Block' }], // ── Coal Block ── ['173', { bedrock: 'coal_block', data: 0, name: 'Block of Coal' }], // ── Red Sandstone ── ['179', { bedrock: 'red_sandstone', data: 0, name: 'Red Sandstone' }], ['179:1', { bedrock: 'red_sandstone', data: 1, name: 'Chiseled Red Sandstone' }], ['179:2', { bedrock: 'red_sandstone', data: 2, name: 'Smooth Red Sandstone' }], ['180', { bedrock: 'red_sandstone_stairs', data: 0, name: 'Red Sandstone Stairs' }], // ── Misc utility blocks ── ['26', { bedrock: 'bed', data: 0, name: 'Bed' }], ['30', { bedrock: 'web', data: 0, name: 'Cobweb' }], ['31', { bedrock: 'tallgrass', data: 1, name: 'Grass' }], ['31:2', { bedrock: 'tallgrass', data: 2, name: 'Fern' }], ['32', { bedrock: 'deadbush', data: 0, name: 'Dead Bush' }], ['37', { bedrock: 'yellow_flower', data: 0, name: 'Dandelion' }], ['38', { bedrock: 'red_flower', data: 0, name: 'Poppy' }], ['38:1', { bedrock: 'red_flower', data: 1, name: 'Blue Orchid' }], ['38:2', { bedrock: 'red_flower', data: 2, name: 'Allium' }], ['38:3', { bedrock: 'red_flower', data: 3, name: 'Azure Bluet' }], ['38:4', { bedrock: 'red_flower', data: 4, name: 'Red Tulip' }], ['38:5', { bedrock: 'red_flower', data: 5, name: 'Orange Tulip' }], ['38:6', { bedrock: 'red_flower', data: 6, name: 'White Tulip' }], ['38:7', { bedrock: 'red_flower', data: 7, name: 'Pink Tulip' }], ['38:8', { bedrock: 'red_flower', data: 8, name: 'Oxeye Daisy' }], ['39', { bedrock: 'brown_mushroom', data: 0, name: 'Brown Mushroom' }], ['40', { bedrock: 'red_mushroom', data: 0, name: 'Red Mushroom' }], ['83', { bedrock: 'reeds', data: 0, name: 'Sugar Cane' }], ['100', { bedrock: 'red_mushroom_block', data: 0, name: 'Red Mushroom Block' }], ['99', { bedrock: 'brown_mushroom_block', data: 0, name: 'Brown Mushroom Block' }], ['104', { bedrock: 'pumpkin_stem', data: 0, name: 'Pumpkin Stem' }], ['106', { bedrock: 'vine', data: 0, name: 'Vines' }], ['110', { bedrock: 'mycelium', data: 0, name: 'Mycelium' }], ['111', { bedrock: 'waterlily', data: 0, name: 'Lily Pad' }], ['115', { bedrock: 'nether_wart', data: 0, name: 'Nether Wart' }], ['116', { bedrock: 'enchanting_table', data: 0, name: 'Enchanting Table' }], ['117', { bedrock: 'brewing_stand', data: 0, name: 'Brewing Stand' }], ['118', { bedrock: 'cauldron', data: 0, name: 'Cauldron' }], ['120', { bedrock: 'end_portal_frame', data: 0, name: 'End Portal Frame' }], ['122', { bedrock: 'dragon_egg', data: 0, name: 'Dragon Egg' }], ['130', { bedrock: 'ender_chest', data: 0, name: 'Ender Chest' }], ['138', { bedrock: 'beacon', data: 0, name: 'Beacon' }], ['166', { bedrock: 'barrier', data: 0, name: 'Barrier' }], ['175', { bedrock: 'double_plant', data: 0, name: 'Sunflower' }], ['175:1', { bedrock: 'double_plant', data: 1, name: 'Lilac' }], ['175:2', { bedrock: 'double_plant', data: 2, name: 'Double Tallgrass' }], ['175:3', { bedrock: 'double_plant', data: 3, name: 'Large Fern' }], ['175:4', { bedrock: 'double_plant', data: 4, name: 'Rose Bush' }], ['175:5', { bedrock: 'double_plant', data: 5, name: 'Peony' }], ['198', { bedrock: 'end_rod', data: 0, name: 'End Rod' }], ['199', { bedrock: 'chorus_plant', data: 0, name: 'Chorus Plant' }], ['200', { bedrock: 'chorus_flower', data: 0, name: 'Chorus Flower' }], ['207', { bedrock: 'beetroot', data: 0, name: 'Beetroot' }], ['208', { bedrock: 'grass_path', data: 0, name: 'Grass Path' }], ['209', { bedrock: 'end_gateway', data: 0, name: 'End Gateway' }], ['213', { bedrock: 'magma', data: 0, name: 'Magma Block' }], ['214', { bedrock: 'nether_wart_block', data: 0, name: 'Nether Wart Block' }], ['215', { bedrock: 'red_nether_brick', data: 0, name: 'Red Nether Bricks' }], ['216', { bedrock: 'bone_block', data: 0, name: 'Bone Block' }], ['218', { bedrock: 'observer', data: 0, name: 'Observer' }], ['219', { bedrock: 'shulker_box', data: 0, name: 'White Shulker Box' }], // ── Walls ── ['139', { bedrock: 'cobblestone_wall', data: 0, name: 'Cobblestone Wall' }], ['139:1', { bedrock: 'cobblestone_wall', data: 1, name: 'Mossy Cobblestone Wall' }], // ── Banners ── ['176', { bedrock: 'standing_banner', data: 0, name: 'Banner' }], // ── Signs ── ['63', { bedrock: 'standing_sign', data: 0, name: 'Sign' }], ['68', { bedrock: 'wall_sign', data: 0, name: 'Wall Sign' }], // ── Flower Pot ── ['140', { bedrock: 'flower_pot', data: 0, name: 'Flower Pot' }], // ── Skull / Head ── ['144', { bedrock: 'skull', data: 0, name: 'Mob Head' }], // ── Armor Stand (entity, but GrabCraft uses it) ── ['416', { bedrock: 'air', data: 0, name: 'Armor Stand (entity)' }], ]); /** * Name-based fuzzy lookup table (lowercase name -> bedrock ID). * Built from BLOCK_MAP for fallback matching when numeric ID fails. */ const NAME_MAP = new Map(); for (const [, entry] of BLOCK_MAP) { NAME_MAP.set(entry.name.toLowerCase(), entry); } // Additional common name aliases const ALIASES = new Map([ ['dark oak wood plank', BLOCK_MAP.get('5:5')], ['oak wood plank', BLOCK_MAP.get('5')], ['spruce wood plank', BLOCK_MAP.get('5:1')], ['birch wood plank', BLOCK_MAP.get('5:2')], ['jungle wood plank', BLOCK_MAP.get('5:3')], ['acacia wood plank', BLOCK_MAP.get('5:4')], ['dark oak wood', BLOCK_MAP.get('162:1')], ['oak wood', BLOCK_MAP.get('17')], ['spruce wood', BLOCK_MAP.get('17:1')], ['birch wood', BLOCK_MAP.get('17:2')], ['jungle wood', BLOCK_MAP.get('17:3')], ['acacia wood', BLOCK_MAP.get('162')], ['stone brick', BLOCK_MAP.get('98')], ['mossy stone brick', BLOCK_MAP.get('98:1')], ['cracked stone brick', BLOCK_MAP.get('98:2')], ['chiseled stone brick', BLOCK_MAP.get('98:3')], ['brick', BLOCK_MAP.get('45')], ['nether brick', BLOCK_MAP.get('112')], ['glass pane', BLOCK_MAP.get('102')], ['cobble', BLOCK_MAP.get('4')], ['plank', BLOCK_MAP.get('5')], ['planks', BLOCK_MAP.get('5')], ['wooden plank', BLOCK_MAP.get('5')], ['wooden planks', BLOCK_MAP.get('5')], ['log', BLOCK_MAP.get('17')], ['wood', BLOCK_MAP.get('17')], ['leaves', BLOCK_MAP.get('18')], ['torch', BLOCK_MAP.get('50')], ['crafting table', BLOCK_MAP.get('58')], ['workbench', BLOCK_MAP.get('58')], ['furnace', BLOCK_MAP.get('61')], ['chest', BLOCK_MAP.get('54')], ['door', BLOCK_MAP.get('64')], ['fence', BLOCK_MAP.get('85')], ['wool', BLOCK_MAP.get('35')], ['carpet', BLOCK_MAP.get('171')], ['glass', BLOCK_MAP.get('20')], ['sand', BLOCK_MAP.get('12')], ['gravel', BLOCK_MAP.get('13')], ['dirt', BLOCK_MAP.get('3')], ['grass', BLOCK_MAP.get('2')], ['grass block', BLOCK_MAP.get('2')], ['water', BLOCK_MAP.get('8')], ['lava', BLOCK_MAP.get('10')], ['cobblestone wall', BLOCK_MAP.get('139')], ['mossy cobblestone wall', BLOCK_MAP.get('139:1')], ['redstone', BLOCK_MAP.get('55')], ['redstone lamp', BLOCK_MAP.get('123')], ['glowstone', BLOCK_MAP.get('89')], ['sea lantern', BLOCK_MAP.get('169')], ]); for (const [name, entry] of ALIASES) { if (entry) NAME_MAP.set(name, entry); } /** Track unknown blocks for reporting */ const unknownBlocks = new Map(); /** * Resolve a GrabCraft block ID and/or name to a Bedrock setblock string. * @param {string} gcId - GrabCraft numeric ID like "5:5" or "5" * @param {string} [gcName] - English name from GrabCraft for fuzzy matching * @returns {{ block: string, data: number, matched: boolean, name: string }} */ export function resolveBlock(gcId, gcName) { // Try exact numeric ID first if (gcId && BLOCK_MAP.has(gcId)) { const entry = BLOCK_MAP.get(gcId); return { block: entry.bedrock, data: entry.data, matched: true, name: entry.name }; } // Try base ID without data value if (gcId && gcId.includes(':')) { const baseId = gcId.split(':')[0]; if (BLOCK_MAP.has(baseId)) { const entry = BLOCK_MAP.get(baseId); return { block: entry.bedrock, data: entry.data, matched: true, name: entry.name }; } } // Try Java string ID (for prismarine-schematic sources) const javaId = gcId?.replace(/^minecraft:/, ''); if (javaId && JAVA_TO_BEDROCK.has(javaId)) { const entry = JAVA_TO_BEDROCK.get(javaId); return { block: entry.bedrock, data: entry.data, matched: true, name: entry.name }; } // Try name-based lookup if (gcName) { const lower = gcName.toLowerCase().trim(); if (NAME_MAP.has(lower)) { const entry = NAME_MAP.get(lower); return { block: entry.bedrock, data: entry.data, matched: true, name: entry.name }; } // Fuzzy: try removing common suffixes/prefixes const simplified = lower .replace(/\b(block of|block)\b/g, '') .replace(/\s+/g, ' ') .trim(); if (NAME_MAP.has(simplified)) { const entry = NAME_MAP.get(simplified); return { block: entry.bedrock, data: entry.data, matched: true, name: entry.name }; } // Partial match: check if any name contains the search term for (const [name, entry] of NAME_MAP) { if (name.includes(lower) || lower.includes(name)) { return { block: entry.bedrock, data: entry.data, matched: true, name: entry.name }; } } } // Track unknown block const key = `${gcId || 'unknown'}:${gcName || 'unnamed'}`; unknownBlocks.set(key, (unknownBlocks.get(key) || 0) + 1); // Fallback to stone log(TAG, `Unknown block: id=${gcId}, name=${gcName} — using stone fallback`); return { block: 'stone', data: 0, matched: false, name: gcName || `Unknown(${gcId})` }; } /** * Format a resolved block for a setblock command. * @param {{ block: string, data: number }} resolved * @returns {string} e.g. "planks 5" or "stone 0" */ export function formatBlock(resolved) { return resolved.data > 0 ? `${resolved.block} ${resolved.data}` : resolved.block; } /** * Get all unknown blocks encountered so far (for reporting). * @returns {Map} */ export function getUnknownBlocks() { return new Map(unknownBlocks); } /** * Clear the unknown blocks tracker. */ export function clearUnknownBlocks() { unknownBlocks.clear(); } /** * Get all known block mappings (for MCP resource). * @returns {Array<{ javaId: string, bedrockId: string, bedrockData: number, name: string }>} */ export function getAllBlocks() { const blocks = []; for (const [javaId, entry] of BLOCK_MAP) { blocks.push({ javaId, bedrockId: entry.bedrock, bedrockData: entry.data, name: entry.name, }); } return blocks; }