diff options
11 files changed, 177 insertions, 80 deletions
diff --git a/build.gradle b/build.gradle index a611ca3..73290da 100644 --- a/build.gradle +++ b/build.gradle @@ -17,11 +17,13 @@ dependencies { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - modApi("com.terraformersmc:modmenu:2.0.6") { + modCompileOnly fabricApi.module("fabric-resource-loader-v0", "0.39.2+1.17") + + modCompileOnly("com.terraformersmc:modmenu:2.0.6") { exclude(group: "net.fabricmc.fabric-api") } - modApi("me.shedaniel.cloth:cloth-config-fabric:5.0.38") { + modCompileOnly("me.shedaniel.cloth:cloth-config-fabric:5.0.38") { exclude(group: "net.fabricmc.fabric-api") } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/ActiveCITs.java b/src/main/java/shcm/shsupercm/fabric/citresewn/ActiveCITs.java index 3069585..7d1d33e 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/ActiveCITs.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/ActiveCITs.java @@ -25,7 +25,7 @@ public class ActiveCITs { public ActiveCITs(Collection<CIT> cits) { this.cits = cits; - for (CIT cit : cits.stream().sorted(Comparator.<CIT>comparingInt(cit -> cit.weight).reversed().thenComparing(cit -> cit.propertiesIdentifier.getPath())).collect(Collectors.toList())) { + for (CIT cit : cits.stream().sorted(Comparator.<CIT>comparingInt(cit -> cit.weight).reversed().thenComparing(cit -> cit.propertiesIdentifier.toString())).collect(Collectors.toList())) { if (cit instanceof CITItem item) for (Item type : item.items) citItems.computeIfAbsent(type, t -> new ArrayList<>()).add(item); @@ -34,7 +34,7 @@ public class ActiveCITs { if (type instanceof ArmorItem armorType) citArmor.computeIfAbsent(armorType, t -> new ArrayList<>()).add(armor); else - CITResewn.logErrorLoading("Skipping item type: " + Registry.ITEM.getId(type) + " is not armor in " + cit.pack.resourcePack.getName() + " -> " + cit.propertiesIdentifier.getPath()); + CITResewn.logErrorLoading("Ignoring item type: " + Registry.ITEM.getId(type) + " is not armor in " + cit.pack.resourcePack.getName() + " -> " + cit.propertiesIdentifier.toString()); else if (cit instanceof CITElytra) citElytra.add((CITElytra) cit); else if (cit instanceof CITEnchantment) diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnMixinConfiguration.java b/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnMixinConfiguration.java index e3d8243..4247494 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnMixinConfiguration.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/config/CITResewnMixinConfiguration.java @@ -1,5 +1,6 @@ package shcm.shsupercm.fabric.citresewn.config; +import net.fabricmc.loader.api.FabricLoader; import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; @@ -28,6 +29,9 @@ public class CITResewnMixinConfiguration implements IMixinConfigPlugin { if (mixinClassName.startsWith("broken_paths")) return broken_paths; + if (mixinClassName.equals("core.GroupResourcePackAccessor")) + return FabricLoader.getInstance().isModLoaded("fabric-resource-loader-v0"); + return true; } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/ex/CITLoadException.java b/src/main/java/shcm/shsupercm/fabric/citresewn/ex/CITLoadException.java index 0a3c54c..c40bc80 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/ex/CITLoadException.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/ex/CITLoadException.java @@ -8,6 +8,6 @@ import net.minecraft.util.Identifier; */ public class CITLoadException extends Exception { public CITLoadException(ResourcePack resourcePack, Identifier identifier, String message) { - super("Couldn't load CIT: " + message + " in " + resourcePack.getName() + " -> " + identifier.getPath()); + super("Couldn't load CIT: " + message + " in " + resourcePack.getName() + " -> " + identifier.toString()); } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/ex/CITParseException.java b/src/main/java/shcm/shsupercm/fabric/citresewn/ex/CITParseException.java index d44fa5b..95bc386 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/ex/CITParseException.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/ex/CITParseException.java @@ -8,6 +8,6 @@ import net.minecraft.util.Identifier; */ public class CITParseException extends Exception { public CITParseException(ResourcePack resourcePack, Identifier identifier, String message) { - super("Skipped CIT: " + message + " in " + resourcePack.getName() + " -> " + identifier.getPath()); + super("Skipped CIT: " + message + " in " + resourcePack.getName() + " -> " + identifier.toString()); } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/GroupResourcePackAccessor.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/GroupResourcePackAccessor.java new file mode 100644 index 0000000..7ab1c16 --- /dev/null +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/GroupResourcePackAccessor.java @@ -0,0 +1,14 @@ +package shcm.shsupercm.fabric.citresewn.mixin.core; + +import net.fabricmc.fabric.api.resource.ModResourcePack; +import net.fabricmc.fabric.impl.resource.loader.GroupResourcePack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +/* if (FabricLoader.getInstance().isModLoaded("fabric-resource-loader-v0")) */ @Mixin(GroupResourcePack.class) +public interface GroupResourcePackAccessor { + @Accessor + List<ModResourcePack> getPacks(); +} diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/ModelLoaderMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/ModelLoaderMixin.java index 0ece247..e6ac888 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/ModelLoaderMixin.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/ModelLoaderMixin.java @@ -61,7 +61,7 @@ public abstract class ModelLoaderMixin { info("Loading CIT Resewn.."); info("Parsing CITs..."); - Collection<CIT> parsed = CITParser.parse(resourceManager.streamResourcePacks().collect(Collectors.toCollection(ArrayList::new))); + Collection<CIT> parsed = CITParser.parseCITs(resourceManager.streamResourcePacks().collect(Collectors.toCollection(ArrayList::new))); if (parsed.size() > 0) { info("Loading CITItem models.."); diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/ZipResourcePackMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/ZipResourcePackMixin.java new file mode 100644 index 0000000..7acbcb7 --- /dev/null +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/core/ZipResourcePackMixin.java @@ -0,0 +1,60 @@ +package shcm.shsupercm.fabric.citresewn.mixin.core; + +import com.google.common.collect.Lists; +import net.minecraft.resource.ResourceType; +import net.minecraft.resource.ZipResourcePack; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.function.Predicate; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +@Mixin(ZipResourcePack.class) +public abstract class ZipResourcePackMixin { + @Shadow protected abstract ZipFile getZipFile() throws IOException; + + @Inject(method = "findResources", cancellable = true, at = @At("HEAD")) + public void fixDepthBug(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter, CallbackInfoReturnable<Collection<Identifier>> cir) { + if (maxDepth != Integer.MAX_VALUE - 53) + return; + + ZipFile zipFile2; + try { + zipFile2 = this.getZipFile(); + } catch (IOException var15) { + cir.setReturnValue(Collections.emptySet()); return; + } + + Enumeration<? extends ZipEntry> enumeration = zipFile2.entries(); + List<Identifier> list = Lists.newArrayList(); + String var10000 = type.getDirectory(); + String string = var10000 + "/" + namespace + "/"; + String string2 = string + prefix + "/"; + + while(enumeration.hasMoreElements()) { + ZipEntry zipEntry = enumeration.nextElement(); + if (!zipEntry.isDirectory()) { + String string3 = zipEntry.getName(); + if (!string3.endsWith(".mcmeta") && string3.startsWith(string2)) { + String string4 = string3.substring(string.length()); + String[] strings = string4.split("/"); + if (pathFilter.test(strings[strings.length - 1])) { + list.add(new Identifier(namespace, string4)); + } + } + } + } + + cir.setReturnValue(list); return; + } +} diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/CITParser.java b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/CITParser.java index ee7c938..5a2d427 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/CITParser.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/CITParser.java @@ -1,21 +1,30 @@ package shcm.shsupercm.fabric.citresewn.pack; +import net.fabricmc.fabric.impl.resource.loader.GroupResourcePack; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.resource.ResourcePack; import net.minecraft.resource.ResourceType; -import net.minecraft.resource.ZipResourcePack; import net.minecraft.util.Identifier; import org.apache.commons.io.IOUtils; import shcm.shsupercm.fabric.citresewn.CITResewn; +import shcm.shsupercm.fabric.citresewn.ex.CITLoadException; import shcm.shsupercm.fabric.citresewn.ex.CITParseException; +import shcm.shsupercm.fabric.citresewn.mixin.core.GroupResourcePackAccessor; import shcm.shsupercm.fabric.citresewn.pack.cits.*; import java.io.InputStream; import java.util.*; -import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; -public class CITParser { private CITParser() {} +/** + * Parses cits from resourcepacks + */ +public final class CITParser { private CITParser() {} + /** + * CIT type registry. + */ public static final Map<String, CITConstructor> REGISTRY = new HashMap<>(); - static { REGISTRY.put("item", CITItem::new); REGISTRY.put("armor", CITArmor::new); @@ -28,74 +37,82 @@ public class CITParser { private CITParser() {} * @param packs packs to parse * @return a collection of parsed CITs */ - public static Collection<CIT> parse(Collection<ResourcePack> packs) { - Collection<CIT> cits = new ArrayList<>(); + public static Collection<CIT> parseCITs(Collection<ResourcePack> packs) { + return packs.stream() + .map(CITParser::parse) + .flatMap(Collection::stream) + .flatMap(pack -> pack.cits.stream()) + .collect(Collectors.toList()); + } - // load cit resourcepack entries - Map<ResourcePack, Set<Identifier>> citPacks = new HashMap<>(); - final Predicate<String> isProperties = s -> s.endsWith(".properties"); - Identifier citresewnCITSettingsIdentifier = new Identifier("minecraft", "citresewn/cit.properties"), mcpatcherCITSettingsIdentifier = new Identifier("minecraft", "mcpatcher/cit.properties"), optifineCITSettingsIdentifier = new Identifier("minecraft", "optifine/cit.properties"); - for (ResourcePack pack : packs) { - //bugfix for zip resourcepack checking depth incorrectly - final int maxDepth = pack instanceof ZipResourcePack ? 0 : Integer.MAX_VALUE; + /** + * Parses a resourcepack into a possible collection of citpacks that are contained within. + * @param resourcePack pack to parse + * @return a collection of CITPacks or an empty collection if resourcepack contains none + */ + public static Collection<CITPack> parse(ResourcePack resourcePack) { + if (FabricLoader.getInstance().isModLoaded("fabric-resource-loader-v0")) { + Collection<CITPack> group = parseFabricGroup(resourcePack); + if (group != null) + return group; + } - Set<Identifier> packIdentifiers = new HashSet<>(); - packIdentifiers.addAll(pack.findResources(ResourceType.CLIENT_RESOURCES, "minecraft", "citresewn/cit", maxDepth, isProperties)); - if (pack.contains(ResourceType.CLIENT_RESOURCES, citresewnCITSettingsIdentifier)) - packIdentifiers.add(citresewnCITSettingsIdentifier); - packIdentifiers.addAll(pack.findResources(ResourceType.CLIENT_RESOURCES, "minecraft", "mcpatcher/cit", maxDepth, isProperties)); - if (pack.contains(ResourceType.CLIENT_RESOURCES, mcpatcherCITSettingsIdentifier)) - packIdentifiers.add(mcpatcherCITSettingsIdentifier); - packIdentifiers.addAll(pack.findResources(ResourceType.CLIENT_RESOURCES, "minecraft", "optifine/cit", maxDepth, isProperties)); - if (pack.contains(ResourceType.CLIENT_RESOURCES, optifineCITSettingsIdentifier)) - packIdentifiers.add(optifineCITSettingsIdentifier); + final CITPack citPack = new CITPack(resourcePack); - if (packIdentifiers.size() > 0) - citPacks.put(pack, packIdentifiers); + Collection<Identifier> packProperties = new ArrayList<>(); + for (String namespace : resourcePack.getNamespaces(ResourceType.CLIENT_RESOURCES)) { + packProperties.addAll(resourcePack.findResources(ResourceType.CLIENT_RESOURCES, namespace, "citresewn/cit", Integer.MAX_VALUE - 53, s -> s.endsWith(".properties"))); + packProperties.addAll(resourcePack.findResources(ResourceType.CLIENT_RESOURCES, namespace, "optifine/cit", Integer.MAX_VALUE - 53, s -> s.endsWith(".properties"))); + packProperties.addAll(resourcePack.findResources(ResourceType.CLIENT_RESOURCES, namespace, "mcpatcher/cit", Integer.MAX_VALUE - 53, s -> s.endsWith(".properties"))); } - for (Map.Entry<ResourcePack, Set<Identifier>> citPackEntry : citPacks.entrySet()) { - CITPack citPack = new CITPack(citPackEntry.getKey()); - InputStream is = null; - Properties citProperties = new Properties(); - try { - if (citPackEntry.getValue().remove(mcpatcherCITSettingsIdentifier)) - is = citPackEntry.getKey().open(ResourceType.CLIENT_RESOURCES, mcpatcherCITSettingsIdentifier); - else if (citPackEntry.getValue().remove(mcpatcherCITSettingsIdentifier)) - is = citPackEntry.getKey().open(ResourceType.CLIENT_RESOURCES, mcpatcherCITSettingsIdentifier); - else if (citPackEntry.getValue().remove(mcpatcherCITSettingsIdentifier)) - is = citPackEntry.getKey().open(ResourceType.CLIENT_RESOURCES, mcpatcherCITSettingsIdentifier); - - if (is != null) { - citProperties.load(is); - citPack.loadProperties(citProperties); + boolean readCitProperties = false; + for (Iterator<Identifier> iterator = packProperties.iterator(); iterator.hasNext(); ) { + Identifier propertiesIdentifier = iterator.next(); + if (propertiesIdentifier.getPath().substring(propertiesIdentifier.getPath().indexOf("cit/") + 4).equals("cit.properties")) { + if (!readCitProperties) { + Properties citProperties = new Properties(); + try (InputStream is = resourcePack.open(ResourceType.CLIENT_RESOURCES, propertiesIdentifier)) { + citProperties.load(is); + citPack.loadProperties(citProperties); + readCitProperties = true; + } catch (Exception e) { + CITResewn.logErrorLoading(new CITLoadException(resourcePack, propertiesIdentifier, e.getMessage()).getMessage()); + } } - } catch (Exception e) { - CITResewn.logErrorLoading(e.getMessage()); - } finally { - IOUtils.closeQuietly(is); + iterator.remove(); } + } + packProperties.stream() + .flatMap(citIdentifier -> { + try (InputStream is = resourcePack.open(ResourceType.CLIENT_RESOURCES, citIdentifier)) { + Properties citProperties = new Properties(); + citProperties.load(is); - for (Identifier citIdentifier : citPackEntry.getValue()) { - try { - citProperties = new Properties(); - citProperties.load(is = citPackEntry.getKey().open(ResourceType.CLIENT_RESOURCES, citIdentifier)); + CITConstructor type = REGISTRY.get(citProperties.getProperty("type", "item")); + if (type == null) + throw new CITParseException(citPack.resourcePack, citIdentifier, "Unknown cit type \"" + citProperties.getProperty("type") + "\""); - CITConstructor type = REGISTRY.get(citProperties.getProperty("type", "item")); - if (type == null) - throw new CITParseException(citPack.resourcePack, citIdentifier, "Unknown cit type \"" + citProperties.getProperty("type") + "\""); - citPack.cits.add(type.cit(citPack, citIdentifier, citProperties)); - } catch (Exception e) { - CITResewn.logErrorLoading(e.getMessage()); - } finally { - IOUtils.closeQuietly(is); - } - } - cits.addAll(citPack.cits); - } + return Stream.of(type.cit(citPack, citIdentifier, citProperties)); + } catch (Exception e) { + CITResewn.logErrorLoading(e.getMessage()); + return Stream.empty(); + } + }) + .collect(Collectors.toCollection(() -> citPack.cits)); + + return citPack.cits.isEmpty() ? Collections.emptySet() : Collections.singleton(citPack); + } + + public static Collection<CITPack> parseFabricGroup(ResourcePack resourcePack) { + if (!(resourcePack instanceof GroupResourcePack)) + return null; - return cits; + return ((GroupResourcePackAccessor) resourcePack).getPacks().stream() + .map(CITParser::parse) + .flatMap(Collection::stream) + .collect(Collectors.toList()); } public interface CITConstructor { diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITItem.java b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITItem.java index 7df8a17..a12c190 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITItem.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/cits/CITItem.java @@ -222,7 +222,7 @@ public class CITItem extends CIT { }; if (replacement != null) { - CITResewn.logWarnLoading("CIT Warning: Using deprecated sub item id \"" + subItem + "\" instead of \"" + replacement + "\" in " + pack.resourcePack.getName() + " -> " + propertiesIdentifier.getPath()); + CITResewn.logWarnLoading("CIT Warning: Using deprecated sub item id \"" + subItem + "\" instead of \"" + replacement + "\" in " + pack.resourcePack.getName() + " -> " + propertiesIdentifier.toString()); return new Identifier("minecraft", "item/" + replacement); } diff --git a/src/main/resources/citresewn.mixins.json b/src/main/resources/citresewn.mixins.json index ccf70eb..49a3a19 100644 --- a/src/main/resources/citresewn.mixins.json +++ b/src/main/resources/citresewn.mixins.json @@ -5,19 +5,19 @@ "compatibilityLevel": "JAVA_16", "plugin": "shcm.shsupercm.fabric.citresewn.config.CITResewnMixinConfiguration", "mixins": [ - "core.ModelLoaderMixin", - "core.SpriteAtlasTextureMixin", - "core.JsonUnbakedModelAccessor", - "core.NbtCompoundAccessor", - - "cititem.ItemRendererMixin", - "citarmor.ArmorFeatureRendererMixin", - "citelytra.ElytraFeatureRendererMixin", - "broken_paths.AbstractFileResourcePackMixin", - "broken_paths.ReloadableResourceManagerImplMixin", "broken_paths.IdentifierMixin", - "broken_paths.ResourcePackCompatibilityMixin" + "broken_paths.ReloadableResourceManagerImplMixin", + "broken_paths.ResourcePackCompatibilityMixin", + "citarmor.ArmorFeatureRendererMixin", + "citelytra.ElytraFeatureRendererMixin", + "cititem.ItemRendererMixin", + "core.GroupResourcePackAccessor", + "core.JsonUnbakedModelAccessor", + "core.ModelLoaderMixin", + "core.NbtCompoundAccessor", + "core.SpriteAtlasTextureMixin", + "core.ZipResourcePackMixin" ], "injectors": { "defaultRequire": 1 |