From 4de9022e3c964b30ce76afee3d7af718c09c6f6d Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 4 Nov 2023 09:00:57 -0400 Subject: [PATCH] Warn if keySet is used by a mod when dynamic resources is on --- .../dynresources/ModelBakeEventHelper.java | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java b/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java index fed07281..73ec5bd6 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java @@ -61,6 +61,47 @@ public class ModelBakeEventHelper { } } + private static final Set WARNED_MOD_IDS = new HashSet<>(); + + /** + * Create a model registry that warns if keySet, entrySet, values are accessed. + * @param modId the mod that the event is being fired for + * @return a wrapper around the model registry + */ + private Map createWarningRegistry(String modId) { + return new ForwardingMap() { + @Override + protected Map delegate() { + return modelRegistry; + } + + private void logWarning() { + if(!WARNED_MOD_IDS.add(modId)) + return; + ModernFix.LOGGER.warn("Mod '{}' is accessing Map#keySet/entrySet/values on the model registry map inside its event handler." + + " This probably won't work as expected with dynamic resources on. Prefer using Map#get/put and constructing ModelResourceLocations another way.", modId); + } + + @Override + public Set keySet() { + logWarning(); + return super.keySet(); + } + + @Override + public Set> entrySet() { + logWarning(); + return super.entrySet(); + } + + @Override + public Collection values() { + logWarning(); + return super.values(); + } + }; + } + public Map wrapRegistry(String modId) { final Set modIdsToInclude = new HashSet<>(); modIdsToInclude.add(modId); @@ -69,7 +110,7 @@ public class ModelBakeEventHelper { } catch(IllegalArgumentException ignored) { /* sanity check */ } modIdsToInclude.remove("minecraft"); if(modIdsToInclude.stream().noneMatch(INCOMPATIBLE_MODS::contains)) - return this.modelRegistry; + return createWarningRegistry(modId); Set ourModelLocations = Sets.filter(this.topLevelModelLocations, loc -> modIdsToInclude.contains(loc.getNamespace())); BakedModel missingModel = modelRegistry.get(ModelBakery.MISSING_MODEL_LOCATION); return new ForwardingMap() {