From 4a2dcd0b22abfbd49a62bbd11ab69aa7a211dec9 Mon Sep 17 00:00:00 2001 From: Eclipse-Sol Date: Sat, 18 Apr 2026 12:53:06 -0400 Subject: [PATCH] Automate the collection of legacy IDs for very old shaderpacks. (#1631) --- .../net/coderbot/iris/shaderpack/IdMap.java | 31 ++-- .../coderbot/iris/shaderpack/LegacyIdMap.java | 136 ++++-------------- 2 files changed, 42 insertions(+), 125 deletions(-) diff --git a/src/main/java/net/coderbot/iris/shaderpack/IdMap.java b/src/main/java/net/coderbot/iris/shaderpack/IdMap.java index 1512ccce7..686acf211 100644 --- a/src/main/java/net/coderbot/iris/shaderpack/IdMap.java +++ b/src/main/java/net/coderbot/iris/shaderpack/IdMap.java @@ -72,8 +72,8 @@ public class IdMap { // Pack has a 1.7.10 section resolvedDefines = environmentDefines; loadProperties(shaderPath, "block.properties", shaderPackOptions, environmentDefines).ifPresent(blockProperties -> { - blockPropertiesMap = parseBlockMap(blockProperties); - blockRenderTypeMap = parseRenderTypeMap(blockProperties); + blockPropertiesMap = parseBlockMap(blockProperties, "block.", "block.properties"); + blockRenderTypeMap = parseRenderTypeMap(blockProperties, "layer.", "block.properties"); }); } else { // No 1.7.10 section, use modern MC_VERSION and convert entries @@ -90,9 +90,8 @@ public class IdMap { resolvedDefines = modernDefines; loadProperties(shaderPath, "block.properties", shaderPackOptions, modernDefines).ifPresent(blockProperties -> { - blockPropertiesMap = parseBlockMap(blockProperties); - blockRenderTypeMap = parseRenderTypeMap(blockProperties); - blockPropertiesMap = LegacyIdMap.convertModernBlockEntries(blockPropertiesMap); + blockPropertiesMap = parseBlockMap(blockProperties, "block.", "block.properties"); + blockRenderTypeMap = parseRenderTypeMap(blockProperties, "layer.", "block.properties"); }); } @@ -300,14 +299,14 @@ public class IdMap { return Object2IntMaps.unmodifiable(idMap); } - private static Int2ObjectMap> parseBlockMap(Properties properties) { + private static Int2ObjectMap> parseBlockMap(Properties properties, String keyPrefix, String fileName) { Int2ObjectMap> entriesById = new Int2ObjectOpenHashMap<>(); properties.forEach((keyObject, valueObject) -> { final String key = (String) keyObject; StringBuilder value = new StringBuilder((String) valueObject); - if (!key.startsWith("block.")) { + if (!key.startsWith(keyPrefix)) { // Not a valid line, ignore it return; } @@ -315,10 +314,10 @@ public class IdMap { final int intId; try { - intId = Integer.parseInt(key.substring("block.".length())); + intId = Integer.parseInt(key.substring(keyPrefix.length())); } catch (NumberFormatException e) { // Not a valid property line - Iris.logger.warn("Failed to parse line in " + "block.properties" + ": invalid key " + key); + Iris.logger.warn("Failed to parse line in " + fileName + ": invalid key " + key); return; } @@ -335,7 +334,7 @@ public class IdMap { } // Parse identifiers - for (String part : parseIdentifierList(value.toString(), "block.properties", key)) { + for (String part : parseIdentifierList(value.toString(), fileName, key)) { if (part.isEmpty()) { continue; } @@ -343,7 +342,7 @@ public class IdMap { try { entries.add(BlockEntry.parse(part)); } catch (Exception e) { - Iris.logger.warn("Unexpected error while parsing an entry from " + "block.properties" + " for the key " + key + ":", e); + Iris.logger.warn("Unexpected error while parsing an entry from " + fileName + " for the key " + key + ":", e); } } @@ -358,29 +357,29 @@ public class IdMap { * * This feature is used by Chocapic v9 and Wisdom Shaders. Otherwise, it is a rarely-used feature. */ - private static Map parseRenderTypeMap(Properties properties) { + private static Map parseRenderTypeMap(Properties properties, String keyPrefix, String fileName) { Map overrides = new HashMap<>(); properties.forEach((keyObject, valueObject) -> { String key = (String) keyObject; String value = (String) valueObject; - if (!key.startsWith("layer.")) { + if (!key.startsWith(keyPrefix)) { // Not a valid line, ignore it return; } // Note: We have to remove the prefix "layer." because fromString expects "cutout", not "layer.cutout". - String keyWithoutPrefix = key.substring("layer.".length()); + String keyWithoutPrefix = key.substring(keyPrefix.length()); BlockRenderType renderType = BlockRenderType.fromString(keyWithoutPrefix).orElse(null); if (renderType == null) { - Iris.logger.warn("Failed to parse line in " + "block.properties" + ": invalid block render type: " + key); + Iris.logger.warn("Failed to parse line in " + fileName + ": invalid block render type: " + key); return; } - for (String part : parseIdentifierList(value, "block.properties", key)) { + for (String part : parseIdentifierList(value, fileName, key)) { // Note: NamespacedId performs no validation on the content. That will need to be done by whatever is // converting these things to ResourceLocations. overrides.put(new NamespacedId(part), renderType); diff --git a/src/main/java/net/coderbot/iris/shaderpack/LegacyIdMap.java b/src/main/java/net/coderbot/iris/shaderpack/LegacyIdMap.java index 8f789e4f1..620dec991 100644 --- a/src/main/java/net/coderbot/iris/shaderpack/LegacyIdMap.java +++ b/src/main/java/net/coderbot/iris/shaderpack/LegacyIdMap.java @@ -1,131 +1,49 @@ package net.coderbot.iris.shaderpack; -import com.google.common.collect.ImmutableList; -import it.unimi.dsi.fastutil.Function; +import cpw.mods.fml.common.registry.GameData; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.coderbot.iris.shaderpack.materialmap.BlockEntry; import net.coderbot.iris.shaderpack.materialmap.NamespacedId; +import net.minecraft.block.Block; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; public class LegacyIdMap { - private static final ImmutableList COLORS = - ImmutableList.of("white", "orange", "magenta", "light_blue", "yellow", "lime", "pink", "gray", - "light_gray", "cyan", "purple", "blue", "brown", "green", "red", "black"); - - private static final ImmutableList WOOD_TYPES = - ImmutableList.of("oak", "birch", "jungle", "spruce", "acacia", "dark_oak"); - - private static final Map MODERN_TO_LEGACY_BLOCK_IDS = Map.of( - "grass", "tallgrass", - "grass_block", "grass" - ); + /** + * Fills the block ID map with all vanilla blocks in the case where block.properties is not found. + * + * ShadersMod passed block IDs as a signed byte, so IDs 128-255 wrapped to -128 to -1. + * For example, emerald_block (ID 133) becomes -123. Shader packs like SEUS v11 were written + * against this behavior, so we replicate it here. + */ public static void addLegacyValues(Int2ObjectMap> blockIdMap) { - add(blockIdMap, 1, block("stone"), block("granite"), block("diorite"), block("andesite")); - add(blockIdMap, 2, block("grass_block")); - add(blockIdMap, 4, block("cobblestone")); - - add(blockIdMap, 50, block("torch")); - add(blockIdMap, 89, block("glowstone")); - - // TODO: what about inactive redstone lamps? - add(blockIdMap, 124, block("redstone_lamp")); - - add(blockIdMap, 12, block("sand")); - add(blockIdMap, 24, block("sandstone")); - - add(blockIdMap, 41, block("gold_block")); - add(blockIdMap, 42, block("iron_block")); - add(blockIdMap, 57, block("diamond_block")); - // Apparently this is what SEUS v11 expects? Maybe old shadersmod was buggy. - add(blockIdMap, -123, block("emerald_block")); - - addMany(blockIdMap, 35, COLORS, color -> block(color + "_wool")); - - // NB: Use the "still" IDs for water and lava, since some shader packs don't properly support the "flowing" - // versions: https://github.com/IrisShaders/Iris/issues/1462 - add(blockIdMap, 9, block("water")); - add(blockIdMap, 11, block("lava")); - add(blockIdMap, 79, block("ice")); - - addMany(blockIdMap, 18, WOOD_TYPES, woodType -> block(woodType + "_leaves")); - - addMany(blockIdMap, 95, COLORS, color -> block(color + "_stained_glass")); - addMany(blockIdMap, 160, COLORS, color -> block(color + "_stained_glass_pane")); - - // Short grass / bush - add(blockIdMap, 31, block("grass"), block("seagrass"), block("sweet_berry_bush")); - - // Crops (59 = wheat), but we include carrots and potatoes too. - add(blockIdMap, 59, block("wheat"), block("carrots"), block("potatoes")); - - // Small flowers - add(blockIdMap, 37, block("dandelion"), block("poppy"), block("blue_orchid"), - block("allium"), block("azure_bluet"), block("red_tulip"), block("pink_tulip"), - block("white_tulip"), block("orange_tulip"), block("oxeye_daisy"), - block("cornflower"), block("lily_of_the_valley"), block("wither_rose")); - - // Big tall grass / flowers - // Also include seagrass here - add(blockIdMap, 175, block("sunflower"), block("lilac"), block("tall_grass"), - block("large_fern"), block("rose_bush"), block("peony"), block("tall_seagrass")); - - // Fire - add(blockIdMap, 51, block("fire")); - - // Lily pad - add(blockIdMap, 111, block("lily_pad")); - - // TODO: 76 -> redstone_torch (on) - } - - public static Int2ObjectMap> convertModernBlockEntries(Int2ObjectMap> blockIdMap) { - Int2ObjectMap> converted = new Int2ObjectOpenHashMap<>(); - - blockIdMap.forEach((intId, entries) -> { - List convertedEntries = new ArrayList<>(entries.size()); - for (BlockEntry entry : entries) { - NamespacedId id = entry.getId(); - if (!"minecraft".equals(id.getNamespace())) { - convertedEntries.add(entry); - continue; - } - - String convertedName = MODERN_TO_LEGACY_BLOCK_IDS.get(id.getName()); - if (convertedName == null) { - convertedEntries.add(entry); - continue; - } - - convertedEntries.add(new BlockEntry(new NamespacedId(id.getNamespace(), convertedName), entry.getMetas())); + for (String name : (Iterable) GameData.getBlockRegistry().getKeys()) { + // Only include vanilla minecraft blocks + if (!name.startsWith("minecraft:")) { + continue; } - converted.put(intId, Collections.unmodifiableList(convertedEntries)); - }); - return converted; - } + final Block block = (Block) GameData.getBlockRegistry().getObject(name); + if (block == null) { + continue; + } - private static BlockEntry block(String name) { - return new BlockEntry(new NamespacedId("minecraft", name), Collections.emptySet()); - } + final int id = GameData.getBlockRegistry().getIDForObject(block); + if (id <= 0 || id > 255) { + continue; + } - private static void addMany(Int2ObjectMap> blockIdMap, int id, List prefixes, Function toId) { - List entries = new ArrayList<>(); + // Apply signed byte overflow + final int overflowId = (byte) id; - for (String prefix : prefixes) { - entries.add(toId.apply(prefix)); + final String blockName = name.substring("minecraft:".length()); + final BlockEntry entry = new BlockEntry(new NamespacedId("minecraft", blockName), Collections.emptySet()); + + blockIdMap.computeIfAbsent(overflowId, k -> new ArrayList<>()).add(entry); } - - blockIdMap.put(id, entries); - } - - private static void add(Int2ObjectMap> blockIdMap, int id, BlockEntry... entries) { - blockIdMap.put(id, Arrays.asList(entries)); } }