diff --git a/adapters/fabric/build.gradle b/adapters/fabric/build.gradle index f055c2a72..24b6b7a28 100644 --- a/adapters/fabric/build.gradle +++ b/adapters/fabric/build.gradle @@ -201,6 +201,7 @@ dependencies { libs.asm, libs.lru, libs.caffeine, + 'com.fulcrumgenomics:jlibdeflate:0.2.0', libs.dom4j, libs.jaxen ] diff --git a/adapters/forge/build.gradle b/adapters/forge/build.gradle index a10f2349f..1dca2a8d7 100644 --- a/adapters/forge/build.gradle +++ b/adapters/forge/build.gradle @@ -200,6 +200,7 @@ dependencies { libs.asm, libs.lru, libs.caffeine, + 'com.fulcrumgenomics:jlibdeflate:0.2.0', libs.dom4j, libs.jaxen ] diff --git a/adapters/modded-common/src/main/resources/pack.mcmeta b/adapters/modded-common/src/main/resources/pack.mcmeta new file mode 100644 index 000000000..1189047ea --- /dev/null +++ b/adapters/modded-common/src/main/resources/pack.mcmeta @@ -0,0 +1,7 @@ +{ + "pack": { + "description": "Iris client resources and mod data", + "min_format": [88, 0], + "max_format": [107, 1] + } +} diff --git a/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedPackMetadataTest.java b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedPackMetadataTest.java new file mode 100644 index 000000000..48d82911c --- /dev/null +++ b/adapters/modded-common/src/test/java/art/arcane/iris/modded/ModdedPackMetadataTest.java @@ -0,0 +1,45 @@ +package art.arcane.iris.modded; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.mojang.serialization.JsonOps; +import net.minecraft.SharedConstants; +import net.minecraft.server.Bootstrap; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.metadata.pack.PackMetadataSection; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class ModdedPackMetadataTest { + @BeforeClass + public static void bootstrapMinecraftRegistries() { + SharedConstants.tryDetectVersion(); + Bootstrap.bootStrap(); + } + + @Test + public void metadataLoadsClientResourcesAndServerDataForCurrentMinecraft() throws IOException { + try (InputStream resource = ModdedPackMetadataTest.class.getResourceAsStream("/pack.mcmeta")) { + assertNotNull(resource); + try (InputStreamReader reader = new InputStreamReader(resource, StandardCharsets.UTF_8)) { + JsonObject metadata = JsonParser.parseReader(reader).getAsJsonObject(); + for (PackType type : PackType.values()) { + PackMetadataSection section = PackMetadataSection.forPackType(type).codec() + .parse(JsonOps.INSTANCE, metadata.get("pack")).getOrThrow(); + assertEquals("Iris client resources and mod data", section.description().getString()); + assertTrue(type.toString(), section.supportedFormats().isValueInRange( + SharedConstants.getCurrentVersion().packVersion(type))); + } + } + } + } +} diff --git a/adapters/neoforge/build.gradle b/adapters/neoforge/build.gradle index b995a63d0..fe8632d69 100644 --- a/adapters/neoforge/build.gradle +++ b/adapters/neoforge/build.gradle @@ -173,6 +173,7 @@ dependencies { libs.asm, libs.lru, libs.caffeine, + 'com.fulcrumgenomics:jlibdeflate:0.2.0', libs.dom4j, libs.jaxen ] diff --git a/build.gradle b/build.gradle index 345871505..ccd014dad 100644 --- a/build.gradle +++ b/build.gradle @@ -576,6 +576,14 @@ tasks.named('check').configure { } List commonModdedArtifactEntries = [ + 'pack.mcmeta', + 'com/fulcrumgenomics/jlibdeflate/LibdeflateDecompressor.class', + 'com/fulcrumgenomics/jlibdeflate/LibdeflateException.class', + 'native/linux-aarch64/libjlibdeflate.so', + 'native/linux-x86_64/libjlibdeflate.so', + 'native/osx-aarch64/libjlibdeflate.dylib', + 'native/osx-x86_64/libjlibdeflate.dylib', + 'native/windows-x86_64/jlibdeflate.dll', 'META-INF/iris/generation-kernels/catalog.tsv', 'META-INF/iris/generation-kernels/abi-1.revision', 'META-INF/services/art.arcane.iris.localization.IrisMessageContributor', diff --git a/buildSrc/src/main/java/ModdedArtifactVerifier.java b/buildSrc/src/main/java/ModdedArtifactVerifier.java index a77cd67fd..f2a10102b 100644 --- a/buildSrc/src/main/java/ModdedArtifactVerifier.java +++ b/buildSrc/src/main/java/ModdedArtifactVerifier.java @@ -85,6 +85,11 @@ public final class ModdedArtifactVerifier { throw new GradleException(artifact.getName() + " is missing " + requiredEntry); } } + if (jar.getJarEntry("assets/irisworldgen/lang/en_us.json") != null + && jar.getJarEntry("pack.mcmeta") == null) { + throw new GradleException(artifact.getName() + + " ships Iris client language resources without pack.mcmeta"); + } Set bundledRuntimeEntries = new LinkedHashSet<>(); Set privateReferenceClasses = new LinkedHashSet<>(); diff --git a/buildSrc/src/test/java/ModdedArtifactVerifierTest.java b/buildSrc/src/test/java/ModdedArtifactVerifierTest.java index 3517999ee..efb9303d2 100644 --- a/buildSrc/src/test/java/ModdedArtifactVerifierTest.java +++ b/buildSrc/src/test/java/ModdedArtifactVerifierTest.java @@ -44,6 +44,28 @@ public class ModdedArtifactVerifierTest { ModdedArtifactVerifier.verify(artifact, REQUIRED_ENTRIES); } + @Test + public void rejectsClientLanguagesWithoutPackMetadata() throws Exception { + Map entries = validEntries(); + entries.put("assets/irisworldgen/lang/en_us.json", "{}".getBytes(StandardCharsets.UTF_8)); + File artifact = createArtifact(entries); + + GradleException failure = assertThrows(GradleException.class, + () -> ModdedArtifactVerifier.verify(artifact, REQUIRED_ENTRIES)); + assertTrue(failure.getMessage().contains("client language resources without pack.mcmeta")); + } + + @Test + public void acceptsClientLanguagesWithPackMetadata() throws Exception { + Map entries = validEntries(); + entries.put("assets/irisworldgen/lang/en_us.json", "{}".getBytes(StandardCharsets.UTF_8)); + entries.put("pack.mcmeta", ("{\"pack\":{\"description\":\"Iris\"," + + "\"min_format\":[88,0],\"max_format\":[107,1]}}") + .getBytes(StandardCharsets.UTF_8)); + + ModdedArtifactVerifier.verify(createArtifact(entries), REQUIRED_ENTRIES); + } + @Test public void rejectsRelocatedRuntimeReference() throws Exception { Map entries = validEntries();