Skip to content

Commit

Permalink
Prevent depending on jars built with newer loom versions.
Browse files Browse the repository at this point in the history
  • Loading branch information
modmuss50 committed Nov 15, 2023
1 parent d0612f3 commit 49da9bc
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
public record ArtifactMetadata(boolean isFabricMod, RemapRequirements remapRequirements, @Nullable InstallerData installerData, MixinRemapType mixinRemapType) {
private static final String INSTALLER_PATH = "fabric-installer.json";

public static ArtifactMetadata create(ArtifactRef artifact) throws IOException {
public static ArtifactMetadata create(ArtifactRef artifact, String currentLoomVersion) throws IOException {
boolean isFabricMod;
RemapRequirements remapRequirements = RemapRequirements.DEFAULT;
InstallerData installerData = null;
Expand All @@ -60,13 +60,18 @@ public static ArtifactMetadata create(ArtifactRef artifact) throws IOException {
final var manifest = new Manifest(new ByteArrayInputStream(Files.readAllBytes(manifestPath)));
final Attributes mainAttributes = manifest.getMainAttributes();
final String remapValue = mainAttributes.getValue(Constants.Manifest.REMAP_KEY);
final String loomVersion = mainAttributes.getValue(Constants.Manifest.LOOM_VERSION);
final String mixinRemapType = mainAttributes.getValue(Constants.Manifest.MIXIN_REMAP_TYPE);

if (remapValue != null) {
// Support opting into and out of remapping with "Fabric-Loom-Remap" manifest entry
remapRequirements = Boolean.parseBoolean(remapValue) ? RemapRequirements.OPT_IN : RemapRequirements.OPT_OUT;
}

if (loomVersion != null) {
validateLoomVersion(loomVersion, currentLoomVersion);
}

if (mixinRemapType != null) {
try {
refmapRemapType = MixinRemapType.valueOf(mixinRemapType.toUpperCase(Locale.ROOT));
Expand All @@ -87,6 +92,25 @@ public static ArtifactMetadata create(ArtifactRef artifact) throws IOException {
return new ArtifactMetadata(isFabricMod, remapRequirements, installerData, refmapRemapType);
}

// Validates that the version matches or is less than the current loom version
private static void validateLoomVersion(String version, String currentLoomVersion) {
final String[] versionParts = version.split("\\.");
final String[] currentVersionParts = currentLoomVersion.split("\\.");

// Check major and minor version
for (int i = 0; i < 2; i++) {
final int versionPart = Integer.parseInt(versionParts[i]);
final int currentVersionPart = Integer.parseInt(currentVersionParts[i]);

if (versionPart > currentVersionPart) {
throw new IllegalStateException("Mod was built with a newer version of Loom (%s), you are using Loom (%s)".formatted(version, currentLoomVersion));
} else if (versionPart < currentVersionPart) {
// Older version, no need to check further
break;
}
}
}

public boolean shouldRemap() {
return remapRequirements().getShouldRemap().test(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@
import org.jetbrains.annotations.Nullable;

import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomGradlePlugin;
import net.fabricmc.loom.api.RemapConfigurationSettings;
import net.fabricmc.loom.configuration.RemapConfigurations;
import net.fabricmc.loom.configuration.mods.dependency.ModDependency;
import net.fabricmc.loom.configuration.mods.dependency.ModDependencyFactory;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets;
import net.fabricmc.loom.util.Checksum;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.ExceptionUtil;
import net.fabricmc.loom.util.SourceRemapper;
import net.fabricmc.loom.util.gradle.SourceSetHelper;
import net.fabricmc.loom.util.service.SharedServiceManager;
Expand Down Expand Up @@ -137,9 +139,9 @@ public static void supplyModConfigurations(Project project, SharedServiceManager
final ArtifactMetadata artifactMetadata;

try {
artifactMetadata = ArtifactMetadata.create(artifact);
artifactMetadata = ArtifactMetadata.create(artifact, LoomGradlePlugin.LOOM_VERSION);
} catch (IOException e) {
throw new UncheckedIOException("Failed to read metadata from" + artifact.path(), e);
throw ExceptionUtil.createDescriptiveWrapper(UncheckedIOException::new, "Failed to read metadata from " + artifact.path(), e);
}

if (artifactMetadata.installerData() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ import net.fabricmc.loom.configuration.mods.ArtifactRef
import static net.fabricmc.loom.configuration.mods.ArtifactMetadata.MixinRemapType.MIXIN
import static net.fabricmc.loom.configuration.mods.ArtifactMetadata.MixinRemapType.STATIC
import static net.fabricmc.loom.configuration.mods.ArtifactMetadata.RemapRequirements.*
import static net.fabricmc.loom.test.util.ZipTestUtils.*
import static net.fabricmc.loom.test.util.ZipTestUtils.createZip
import static net.fabricmc.loom.test.util.ZipTestUtils.manifest

class ArtifactMetadataTest extends Specification {
def "is fabric mod"() {
Expand Down Expand Up @@ -119,8 +120,50 @@ class ArtifactMetadataTest extends Specification {
STATIC | ["fabric.mod.json": "{}", "META-INF/MANIFEST.MF": manifest("Fabric-Loom-Mixin-Remap-Type", "static")] // Fabric mod opt-in
}

private static ArtifactMetadata createMetadata(Path zip) {
return ArtifactMetadata.create(createArtifact(zip))
// Test that a mod with the same or older version of loom can be read
def "Valid loom version"() {
given:
def zip = createMod(modLoomVersion)
when:
def metadata = createMetadata(zip, loomVersion)
then:
metadata != null
where:
loomVersion | modLoomVersion
"1.4" | "1.0.1"
"1.4" | "1.0.99"
"1.4" | "1.4"
"1.4" | "1.4.0"
"1.4" | "1.4.1"
"1.4" | "1.4.99"
"1.4" | "1.4.local"
"1.5" | "1.4.99"
"2.0" | "1.4.99"
}

// Test that a mod with the same or older version of loom can be read
def "Invalid loom version"() {
given:
def zip = createMod(modLoomVersion)
when:
def metadata = createMetadata(zip, loomVersion)
then:
def e = thrown(IllegalStateException)
e.message == "Mod was built with a newer version of Loom ($modLoomVersion), you are using Loom ($loomVersion)"
where:
loomVersion | modLoomVersion
"1.4" | "1.5"
"1.4" | "1.5.00"
"1.4" | "2.0"
"1.4" | "2.4"
}

private static Path createMod(String loomVersion) {
return createZip(["fabric.mod.json": "{}", "META-INF/MANIFEST.MF": manifest("Fabric-Loom-Version", loomVersion)])
}

private static ArtifactMetadata createMetadata(Path zip, String loomVersion = "1.4") {
return ArtifactMetadata.create(createArtifact(zip), loomVersion)
}

private static ArtifactRef createArtifact(Path zip) {
Expand Down

0 comments on commit 49da9bc

Please sign in to comment.