From a75d755df8e0c551cd40701017018719667ff6eb Mon Sep 17 00:00:00 2001 From: SHsuperCM Date: Thu, 27 Oct 2022 15:45:43 +0300 Subject: 22w43a Bandage --- build.gradle | 6 +-- .../defaults/cit/types/TypeEnchantment.java | 11 +++--- .../defaults/mixin/common/ModelLoaderMixin.java | 14 +++---- .../defaults/mixin/common/ResourceFinderMixin.java | 23 +++++++++++ .../mixin/common/SpriteAtlasTextureMixin.java | 21 ----------- .../mixin/types/item/ModelLoaderMixin.java | 23 +++++------ gradle.properties | 10 ++--- .../fabric/citresewn/mixin/ModelLoaderMixin.java | 7 +++- .../AbstractFileResourcePackMixin.java | 44 +++++----------------- .../fabric/citresewn/pack/PackParser.java | 11 +++--- 10 files changed, 71 insertions(+), 99 deletions(-) create mode 100644 defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/ResourceFinderMixin.java delete mode 100644 defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/SpriteAtlasTextureMixin.java diff --git a/build.gradle b/build.gradle index 81f6b2a..72c85f8 100644 --- a/build.gradle +++ b/build.gradle @@ -27,9 +27,9 @@ allprojects { fletchingTable.fungible project.fungible - modImplementation fabricApi.module("fabric-api-base", "${project.fabric_api}") - modImplementation fabricApi.module("fabric-resource-loader-v0", "${project.fabric_api}") - modImplementation fabricApi.module("fabric-command-api-v2", "${project.fabric_api}") + modCompileOnly fabricApi.module("fabric-api-base", "${project.fabric_api}") + modCompileOnly fabricApi.module("fabric-resource-loader-v0", "${project.fabric_api}") + modCompileOnly fabricApi.module("fabric-command-api-v2", "${project.fabric_api}") modCompileOnly("com.terraformersmc:modmenu:${project.modmenu}") { exclude(group: "net.fabricmc.fabric-api") diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeEnchantment.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeEnchantment.java index 1d20201..692d55b 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeEnchantment.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeEnchantment.java @@ -7,8 +7,7 @@ import net.minecraft.client.render.*; import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; import net.minecraft.util.Util; -import net.minecraft.util.math.Matrix4f; -import net.minecraft.util.math.Vec3f; +import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; import shcm.shsupercm.fabric.citresewn.api.CITGlobalProperties; import shcm.shsupercm.fabric.citresewn.api.CITTypeContainer; @@ -311,10 +310,10 @@ public class TypeEnchantment extends CITType { float l = Util.getMeasuringTimeMs() * CITResewnDefaultsConfig.INSTANCE.type_enchantment_scroll_multiplier * speed; float x = (l % 110000f) / 110000f; float y = (l % 30000f) / 30000f; - Matrix4f matrix4f = Matrix4f.translate(-x, y, 0.0f); - matrix4f.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion(rotation)); - matrix4f.multiply(Matrix4f.scale(scale, scale, scale)); - setTextureMatrix(matrix4f); + setTextureMatrix(new Matrix4f() + .translation(-x, y, 0.0f) + .rotateZ(rotation) + .scale(scale)); setShaderColor(r, g, b, a * methodIntensity.intensity); } diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/ModelLoaderMixin.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/ModelLoaderMixin.java index a1e8e54..a652bd9 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/ModelLoaderMixin.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/ModelLoaderMixin.java @@ -1,16 +1,14 @@ package shcm.shsupercm.fabric.citresewn.defaults.mixin.common; import com.mojang.datafixers.util.Either; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.render.model.json.JsonUnbakedModel; import net.minecraft.client.render.model.json.ModelOverride; import net.minecraft.client.util.SpriteIdentifier; -import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; import org.apache.commons.io.IOUtils; -import org.spongepowered.asm.mixin.Final; 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; @@ -28,12 +26,10 @@ import java.util.stream.Collectors; */ @Mixin(ModelLoader.class) public class ModelLoaderMixin { - @Shadow @Final private ResourceManager resourceManager; - @Inject(method = "loadModelFromJson", cancellable = true, at = @At("HEAD")) public void citresewn$forceLiteralResewnModelIdentifier(Identifier id, CallbackInfoReturnable cir) { if (id instanceof ResewnItemModelIdentifier) { - try (InputStream is = resourceManager.getResource(id).orElseThrow().getInputStream()) { + try (InputStream is = MinecraftClient.getInstance().getResourceManager().getResource(id).orElseThrow().getInputStream()) { JsonUnbakedModel json = JsonUnbakedModel.deserialize(IOUtils.toString(is, StandardCharsets.UTF_8)); json.id = id.toString(); json.id = json.id.substring(0, json.id.length() - 5); @@ -44,7 +40,7 @@ public class ModelLoaderMixin { String originalPath = left.get().getTextureId().getPath(); String[] split = originalPath.split("/"); if (originalPath.startsWith("./") || (split.length > 2 && split[1].equals("cit"))) { - Identifier resolvedIdentifier = CITType.resolveAsset(id, originalPath, "textures", ".png", resourceManager); + Identifier resolvedIdentifier = CITType.resolveAsset(id, originalPath, "textures", ".png", MinecraftClient.getInstance().getResourceManager()); if (resolvedIdentifier != null) return Either.left(new SpriteIdentifier(left.get().getAtlasId(), resolvedIdentifier)); } @@ -56,7 +52,7 @@ public class ModelLoaderMixin { if (parentId != null) { String[] parentIdPathSplit = parentId.getPath().split("/"); if (parentId.getPath().startsWith("./") || (parentIdPathSplit.length > 2 && parentIdPathSplit[1].equals("cit"))) { - parentId = CITType.resolveAsset(id, parentId.getPath(), "models", ".json", resourceManager); + parentId = CITType.resolveAsset(id, parentId.getPath(), "models", ".json", MinecraftClient.getInstance().getResourceManager()); if (parentId != null) ((JsonUnbakedModelAccessor) json).setParentId(new ResewnItemModelIdentifier(parentId)); } @@ -65,7 +61,7 @@ public class ModelLoaderMixin { json.getOverrides().replaceAll(override -> { String[] modelIdPathSplit = override.getModelId().getPath().split("/"); if (override.getModelId().getPath().startsWith("./") || (modelIdPathSplit.length > 2 && modelIdPathSplit[1].equals("cit"))) { - Identifier resolvedOverridePath = CITType.resolveAsset(id, override.getModelId().getPath(), "models", ".json", resourceManager); + Identifier resolvedOverridePath = CITType.resolveAsset(id, override.getModelId().getPath(), "models", ".json", MinecraftClient.getInstance().getResourceManager()); if (resolvedOverridePath != null) return new ModelOverride(new ResewnItemModelIdentifier(resolvedOverridePath), override.streamConditions().collect(Collectors.toList())); } diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/ResourceFinderMixin.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/ResourceFinderMixin.java new file mode 100644 index 0000000..7893760 --- /dev/null +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/ResourceFinderMixin.java @@ -0,0 +1,23 @@ +package shcm.shsupercm.fabric.citresewn.defaults.mixin.common; + +import net.minecraft.resource.ResourceFinder; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Final; +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; + +@Mixin(ResourceFinder.class) +public class ResourceFinderMixin { + + @Shadow @Final private String fileExtension; + + @Inject(method = "toResourcePath", cancellable = true, at = + @At("HEAD")) + private void citresewn$forceAbsoluteTextureIdentifier(Identifier id, CallbackInfoReturnable cir) { + if (id.getPath().endsWith(".png") && this.fileExtension.equals(".png")) + cir.setReturnValue(id); + } +} diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/SpriteAtlasTextureMixin.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/SpriteAtlasTextureMixin.java deleted file mode 100644 index 0e05a42..0000000 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/common/SpriteAtlasTextureMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package shcm.shsupercm.fabric.citresewn.defaults.mixin.common; - -import net.minecraft.client.texture.SpriteAtlasTexture; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Final; -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; - -@Mixin(SpriteAtlasTexture.class) -public class SpriteAtlasTextureMixin { - @Shadow @Final private static String PNG_EXTENSION; - - @Inject(method = "getTexturePath", cancellable = true, at = @At("HEAD")) - public void citresewn$forceAbsoluteTextureIdentifier(Identifier id, CallbackInfoReturnable cir) { - if (id.getPath().endsWith(PNG_EXTENSION)) - cir.setReturnValue(id); - } -} diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/item/ModelLoaderMixin.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/item/ModelLoaderMixin.java index 68d6bfc..4385f96 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/item/ModelLoaderMixin.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/item/ModelLoaderMixin.java @@ -3,12 +3,11 @@ package shcm.shsupercm.fabric.citresewn.defaults.mixin.types.item; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.ModelLoader; -import net.minecraft.client.render.model.SpriteAtlasManager; import net.minecraft.client.render.model.UnbakedModel; import net.minecraft.client.render.model.json.JsonUnbakedModel; import net.minecraft.client.render.model.json.ModelOverride; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.resource.ResourceManager; +import net.minecraft.client.texture.Sprite; +import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.util.Identifier; import net.minecraft.util.profiler.Profiler; import org.spongepowered.asm.mixin.Final; @@ -18,13 +17,13 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import shcm.shsupercm.fabric.citresewn.CITResewn; import shcm.shsupercm.fabric.citresewn.cit.CIT; import shcm.shsupercm.fabric.citresewn.defaults.cit.types.TypeItem; import shcm.shsupercm.fabric.citresewn.defaults.common.ResewnItemModelIdentifier; import java.util.*; +import java.util.function.BiFunction; import static shcm.shsupercm.fabric.citresewn.CITResewn.info; import static shcm.shsupercm.fabric.citresewn.defaults.cit.types.TypeItem.CONTAINER; @@ -38,7 +37,7 @@ public class ModelLoaderMixin { @Inject(method = "", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V")) - public void citresewn$addTypeItemModels(ResourceManager resourceManager, BlockColors blockColors, Profiler profiler, int i, CallbackInfo ci) { + public void citresewn$addTypeItemModels(BlockColors blockColors, Profiler profiler, Map map, Map map2, CallbackInfo ci) { profiler.swap("citresewn:type_item_models"); if (!CONTAINER.active()) return; @@ -46,7 +45,7 @@ public class ModelLoaderMixin { info("Loading item CIT models..."); for (CIT cit : CONTAINER.loaded) try { - cit.type.loadUnbakedAssets(resourceManager); + //cit.type.loadUnbakedAssets(resourceManager); for (JsonUnbakedModel unbakedModel : cit.type.unbakedAssets.values()) { ResewnItemModelIdentifier id = new ResewnItemModelIdentifier(unbakedModel.id); @@ -61,12 +60,11 @@ public class ModelLoaderMixin { TypeItem.GENERATED_SUB_CITS_SEEN.clear(); } - @Inject(method = "upload", at = @At("RETURN")) - public void citresewn$linkTypeItemModels(TextureManager textureManager, Profiler profiler, CallbackInfoReturnable cir) { + @Inject(method = "bake", at = @At("RETURN")) + public void citresewn$linkTypeItemModels(BiFunction spriteLoader, CallbackInfo ci) { if (!CONTAINER.active()) return; - profiler.push("citresewn:type_item_linking"); info("Linking baked models to item CITs..."); for (CIT cit : CONTAINER.loaded) { @@ -83,13 +81,12 @@ public class ModelLoaderMixin { } cit.type.unbakedAssets = null; } - - profiler.pop(); } @ModifyArg(method = "loadModelFromJson", at = - @At(value = "INVOKE", target = "Lnet/minecraft/resource/ResourceManager;openAsReader(Lnet/minecraft/util/Identifier;)Ljava/io/BufferedReader;")) - public Identifier citresewn$fixDuplicatePrefixSuffix(Identifier original) { + @At(value = "INVOKE", ordinal = 1, target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;")) + public Object citresewn$fixDuplicatePrefixSuffix(Object key) { + Identifier original = (Identifier) key; if (CONTAINER.active() && original.getPath().startsWith("models/models/") && original.getPath().endsWith(".json.json") && original.getPath().contains("cit")) return new Identifier(original.getNamespace(), original.getPath().substring(7, original.getPath().length() - 5)); diff --git a/gradle.properties b/gradle.properties index cb57d7b..9a7be84 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,13 +3,13 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html -minecraft_version=1.19.2 -publish_minecraft_versions=1.19,1.19.1,1.19.2 -yarn_mappings=1.19.2+build.8 -loader_version=0.14.9 +minecraft_version=22w43a +publish_minecraft_versions=1.19.3 +yarn_mappings=22w43a+build.3 +loader_version=0.14.10 fungible=1.2+mc1.19.2 -fabric_api=0.60.0+1.19.2 +fabric_api=0.65.1+1.19.3 modmenu=4.0.6 cloth=8.0.75 diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ModelLoaderMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ModelLoaderMixin.java index df11ac9..215c596 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ModelLoaderMixin.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/ModelLoaderMixin.java @@ -1,5 +1,6 @@ package shcm.shsupercm.fabric.citresewn.mixin; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.render.model.ModelLoader; import net.minecraft.resource.ResourceManager; @@ -10,6 +11,8 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import shcm.shsupercm.fabric.citresewn.cit.ActiveCITs; +import java.util.Map; + /** * Initializes the (re)loading of active cits in the resource manager. * @see ActiveCITs @@ -21,9 +24,9 @@ public class ModelLoaderMixin { */ @Inject(method = "", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/util/profiler/Profiler;push(Ljava/lang/String;)V")) - private void citresewn$loadCITs(ResourceManager resourceManager, BlockColors blockColors, Profiler profiler, int i, CallbackInfo ci) { + private void citresewn$loadCITs(BlockColors blockColors, Profiler profiler, Map jsonUnbakedModels, Map blockStates, CallbackInfo ci) { profiler.push("citresewn:reloading_cits"); - ActiveCITs.load(resourceManager, profiler); + ActiveCITs.load(MinecraftClient.getInstance().getResourceManager(), profiler); profiler.pop(); } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/broken_paths/AbstractFileResourcePackMixin.java b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/broken_paths/AbstractFileResourcePackMixin.java index b241fff..673ddbf 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/broken_paths/AbstractFileResourcePackMixin.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/mixin/broken_paths/AbstractFileResourcePackMixin.java @@ -1,26 +1,17 @@ package shcm.shsupercm.fabric.citresewn.mixin.broken_paths; import net.minecraft.resource.AbstractFileResourcePack; -import net.minecraft.resource.DirectoryResourcePack; import net.minecraft.resource.ResourcePack; -import net.minecraft.resource.ZipResourcePack; +import net.minecraft.resource.ResourceType; import net.minecraft.resource.metadata.PackResourceMetadata; import net.minecraft.resource.metadata.ResourceMetadataReader; -import net.minecraft.util.Identifier; import net.minecraft.util.InvalidIdentifierException; -import org.spongepowered.asm.mixin.Final; 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 shcm.shsupercm.fabric.citresewn.config.BrokenPaths; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.zip.ZipFile; - /** * Adds a resourcepack compatibility error message when broken paths are enabled and are detected in a pack. * @see BrokenPaths @@ -28,32 +19,17 @@ import java.util.zip.ZipFile; */ @Mixin(AbstractFileResourcePack.class) public abstract class AbstractFileResourcePackMixin implements ResourcePack { - @Shadow @Final protected File base; - @SuppressWarnings({"unchecked", "ConstantConditions", "EqualsBetweenInconvertibleTypes"}) + @SuppressWarnings({"unchecked"}) @Inject(method = "parseMetadata(Lnet/minecraft/resource/metadata/ResourceMetadataReader;)Ljava/lang/Object;", cancellable = true, at = @At("RETURN")) public void citresewn$brokenpaths$parseMetadata(ResourceMetadataReader metaReader, CallbackInfoReturnable cir) { - if (cir.getReturnValue() != null) - try { - if (this.getClass().equals(ZipResourcePack.class)) { - try (ZipFile zipFile = new ZipFile(base)) { - zipFile.stream() - .forEach(entry -> { - if (entry.getName().startsWith("assets") && !entry.getName().endsWith(".DS_Store")) - new Identifier("minecraft", entry.getName()); - }); - } - } else if (this.getClass().equals(DirectoryResourcePack.class)) { - final Path assets = new File(base, "assets").toPath(); - Files.walk(assets) - .forEach(fullPath -> { - String path = assets.relativize(fullPath).toString().replace('\\', '/'); - if (!path.endsWith(".DS_Store")) - new Identifier("minecraft", path); - }); - } - } catch (InvalidIdentifierException e) { - cir.setReturnValue((T) new PackResourceMetadata(cir.getReturnValue().getDescription(), Integer.MAX_VALUE - 53)); - } catch (Exception ignored) {} + if (cir.getReturnValue() != null) try { + for (String namespace : getNamespaces(ResourceType.CLIENT_RESOURCES)) { + findResources(ResourceType.CLIENT_RESOURCES, namespace, "", (identifier, inputStreamInputSupplier) -> { + }); + } + } catch (InvalidIdentifierException e) { + cir.setReturnValue((T) new PackResourceMetadata(cir.getReturnValue().getDescription(), Integer.MAX_VALUE - 53)); + } catch (Exception ignored) { } } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java index ffc242f..590f5a0 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java @@ -1,9 +1,6 @@ package shcm.shsupercm.fabric.citresewn.pack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.resource.ResourcePack; -import net.minecraft.resource.ResourceType; +import net.minecraft.resource.*; import net.minecraft.util.Identifier; import shcm.shsupercm.fabric.citresewn.CITResewn; import shcm.shsupercm.fabric.citresewn.cit.builtin.conditions.core.FallbackCondition; @@ -18,6 +15,7 @@ import shcm.shsupercm.fabric.citresewn.pack.format.PropertyKey; import shcm.shsupercm.fabric.citresewn.pack.format.PropertyValue; import java.io.FileNotFoundException; +import java.io.InputStream; import java.util.*; import java.util.stream.Collectors; @@ -44,8 +42,9 @@ public final class PackParser { private PackParser() {} for (String root : ROOTS) { Identifier identifier = new Identifier(namespace, root + "/cit.properties"); try { - if (pack.contains(ResourceType.CLIENT_RESOURCES, identifier)) - globalProperties.load(pack.getName(), identifier, pack.open(ResourceType.CLIENT_RESOURCES, identifier)); + InputSupplier citPropertiesSupplier = pack.open(ResourceType.CLIENT_RESOURCES, identifier); + if (citPropertiesSupplier != null) + globalProperties.load(pack.getName(), identifier, citPropertiesSupplier.get()); } catch (FileNotFoundException ignored) { } catch (Exception e) { CITResewn.logErrorLoading("Errored while loading global properties: " + identifier + " from " + pack.getName()); -- cgit