mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-30 21:05:58 -05:00
Initial support for fabric.mod.json V2
This commit is contained in:
@@ -53,8 +53,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.task.RemapTaskConfiguration;
|
||||
import net.fabricmc.loom.util.ModUtils;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
|
||||
public final class IncludedJarFactory {
|
||||
private final Project project;
|
||||
@@ -143,7 +143,7 @@ public final class IncludedJarFactory {
|
||||
}
|
||||
|
||||
private File getNestableJar(final File input, final Metadata metadata) {
|
||||
if (ModUtils.isMod(input)) {
|
||||
if (FabricModJsonFactory.isModJar(input)) {
|
||||
// Input is a mod, nothing needs to be done.
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ import com.google.gson.JsonObject;
|
||||
import org.gradle.api.UncheckedIOException;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import net.fabricmc.loom.util.ModUtils;
|
||||
import net.fabricmc.loom.util.Pair;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
|
||||
public class JarNester {
|
||||
public static void nestJars(Collection<File> jars, File modJar, Logger logger) {
|
||||
@@ -49,7 +49,7 @@ public class JarNester {
|
||||
return;
|
||||
}
|
||||
|
||||
Preconditions.checkArgument(ModUtils.isMod(modJar), "Cannot nest jars into none mod jar " + modJar.getName());
|
||||
Preconditions.checkArgument(FabricModJsonFactory.isModJar(modJar), "Cannot nest jars into none mod jar " + modJar.getName());
|
||||
|
||||
try {
|
||||
ZipUtils.add(modJar.toPath(), jars.stream().map(file -> {
|
||||
@@ -69,7 +69,7 @@ public class JarNester {
|
||||
|
||||
for (File file : jars) {
|
||||
String nestedJarPath = "META-INF/jars/" + file.getName();
|
||||
Preconditions.checkArgument(ModUtils.isMod(file), "Cannot nest none mod jar: " + file.getName());
|
||||
Preconditions.checkArgument(FabricModJsonFactory.isModJar(file), "Cannot nest none mod jar: " + file.getName());
|
||||
|
||||
for (JsonElement nestedJar : nestedJars) {
|
||||
JsonObject jsonObject = nestedJar.getAsJsonObject();
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -55,7 +54,6 @@ import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.api.InterfaceInjectionExtensionAPI;
|
||||
import net.fabricmc.loom.api.RemapConfigurationSettings;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
@@ -63,10 +61,11 @@ import net.fabricmc.loom.configuration.processors.JarProcessor;
|
||||
import net.fabricmc.loom.task.GenerateSourcesTask;
|
||||
import net.fabricmc.loom.util.Checksum;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.ModUtils;
|
||||
import net.fabricmc.loom.util.Pair;
|
||||
import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJson;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.mappingio.tree.MappingTree;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
@@ -198,28 +197,15 @@ public class InterfaceInjectionProcessor implements JarProcessor, GenerateSource
|
||||
}
|
||||
|
||||
private List<InjectedInterface> getSourceInjectedInterface(SourceSet sourceSet) {
|
||||
final File fabricModJson;
|
||||
final FabricModJson fabricModJson;
|
||||
|
||||
try {
|
||||
fabricModJson = sourceSet.getResources()
|
||||
.matching(patternFilterable -> patternFilterable.include("fabric.mod.json"))
|
||||
.getSingleFile();
|
||||
} catch (IllegalStateException e) {
|
||||
// File not found
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final String jsonString;
|
||||
|
||||
try {
|
||||
jsonString = Files.readString(fabricModJson.toPath(), StandardCharsets.UTF_8);
|
||||
fabricModJson = FabricModJsonFactory.createFromSourceSetNullable(sourceSet);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read fabric.mod.json", e);
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
|
||||
final JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(jsonString, JsonObject.class);
|
||||
|
||||
return InjectedInterface.fromJson(jsonObject);
|
||||
return InjectedInterface.fromFabricModJson(fabricModJson);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -271,29 +257,18 @@ public class InterfaceInjectionProcessor implements JarProcessor, GenerateSource
|
||||
* Reads the injected interfaces contained in a mod jar, or returns empty if there is none.
|
||||
*/
|
||||
public static List<InjectedInterface> fromModJar(Path modJarPath) {
|
||||
final JsonObject jsonObject = ModUtils.getFabricModJson(modJarPath);
|
||||
|
||||
if (jsonObject == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return fromJson(jsonObject);
|
||||
return fromFabricModJson(FabricModJsonFactory.createFromZip(modJarPath));
|
||||
}
|
||||
|
||||
public static List<InjectedInterface> fromJson(JsonObject jsonObject) {
|
||||
final String modId = jsonObject.get("id").getAsString();
|
||||
public static List<InjectedInterface> fromFabricModJson(FabricModJson fabricModJson) {
|
||||
final String modId = fabricModJson.getId();
|
||||
final JsonElement jsonElement = fabricModJson.getCustom(Constants.CustomModJsonKeys.INJECTED_INTERFACE);
|
||||
|
||||
if (!jsonObject.has("custom")) {
|
||||
if (jsonElement == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final JsonObject custom = jsonObject.getAsJsonObject("custom");
|
||||
|
||||
if (!custom.has(Constants.CustomModJsonKeys.INJECTED_INTERFACE)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final JsonObject addedIfaces = custom.getAsJsonObject(Constants.CustomModJsonKeys.INJECTED_INTERFACE);
|
||||
final JsonObject addedIfaces = jsonElement.getAsJsonObject();
|
||||
|
||||
final List<InjectedInterface> result = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -25,18 +25,18 @@
|
||||
package net.fabricmc.loom.configuration.mods;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
|
||||
import net.fabricmc.accesswidener.AccessWidenerReader;
|
||||
import net.fabricmc.accesswidener.AccessWidenerRemapper;
|
||||
import net.fabricmc.accesswidener.AccessWidenerWriter;
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJson;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.loom.util.fmj.ModEnvironment;
|
||||
|
||||
public class AccessWidenerUtils {
|
||||
/**
|
||||
@@ -58,16 +58,20 @@ public class AccessWidenerUtils {
|
||||
}
|
||||
|
||||
public static AccessWidenerData readAccessWidenerData(Path inputJar) throws IOException {
|
||||
byte[] modJsonBytes = ZipUtils.unpack(inputJar, "fabric.mod.json");
|
||||
JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(new String(modJsonBytes, StandardCharsets.UTF_8), JsonObject.class);
|
||||
final FabricModJson fabricModJson = FabricModJsonFactory.createFromZip(inputJar);
|
||||
final List<String> classTweakers = fabricModJson.getClassTweakers(ModEnvironment.UNIVERSAL);
|
||||
|
||||
if (!jsonObject.has("accessWidener")) {
|
||||
if (classTweakers.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String accessWidenerPath = jsonObject.get("accessWidener").getAsString();
|
||||
byte[] accessWidener = ZipUtils.unpack(inputJar, accessWidenerPath);
|
||||
AccessWidenerReader.Header header = AccessWidenerReader.readHeader(accessWidener);
|
||||
if (classTweakers.size() != 1) {
|
||||
throw new UnsupportedOperationException("TODO: support multiple class tweakers");
|
||||
}
|
||||
|
||||
final String accessWidenerPath = classTweakers.get(0);
|
||||
final byte[] accessWidener = fabricModJson.getSource().read(accessWidenerPath);
|
||||
final AccessWidenerReader.Header header = AccessWidenerReader.readHeader(accessWidener);
|
||||
|
||||
return new AccessWidenerData(accessWidenerPath, header, accessWidener);
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ import net.fabricmc.loom.configuration.mods.dependency.ModDependency;
|
||||
import net.fabricmc.loom.configuration.mods.dependency.ModDependencyFactory;
|
||||
import net.fabricmc.loom.util.Checksum;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.ModUtils;
|
||||
import net.fabricmc.loom.util.OperatingSystem;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class ModConfigurationRemapper {
|
||||
@@ -88,7 +88,7 @@ public class ModConfigurationRemapper {
|
||||
final List<ModDependency> modDependencies = new ArrayList<>();
|
||||
|
||||
for (ArtifactRef artifact : resolveArtifacts(project, sourceConfig)) {
|
||||
if (!ModUtils.isMod(artifact.path())) {
|
||||
if (!FabricModJsonFactory.isModJar(artifact.path())) {
|
||||
artifact.applyToConfiguration(project, targetConfig);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonElement;
|
||||
import org.gradle.api.Project;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
@@ -46,8 +46,9 @@ import net.fabricmc.loom.api.RemapConfigurationSettings;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
|
||||
import net.fabricmc.loom.task.GenerateSourcesTask;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.ModUtils;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJson;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.mappingio.MappingReader;
|
||||
import net.fabricmc.mappingio.tree.MappingTree;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
@@ -70,7 +71,7 @@ public final class ModJavadocProcessor implements JarProcessor, GenerateSourcesT
|
||||
final Set<File> artifacts = entry.getSourceConfiguration().get().resolve();
|
||||
|
||||
for (File artifact : artifacts) {
|
||||
if (!ModUtils.isMod(artifact.toPath())) {
|
||||
if (!FabricModJsonFactory.isModJar(artifact.toPath())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -121,20 +122,15 @@ public final class ModJavadocProcessor implements JarProcessor, GenerateSourcesT
|
||||
public record ModJavadoc(String modId, MemoryMappingTree mappingTree) {
|
||||
@Nullable
|
||||
public static ModJavadoc fromModJar(Path path) throws IOException {
|
||||
JsonObject jsonObject = ModUtils.getFabricModJson(path);
|
||||
final FabricModJson fabricModJson = FabricModJsonFactory.createFromZip(path);
|
||||
final String modId = fabricModJson.getId();
|
||||
final JsonElement customElement = fabricModJson.getCustom(Constants.CustomModJsonKeys.PROVIDED_JAVADOC);
|
||||
|
||||
if (jsonObject == null || !jsonObject.has("custom")) {
|
||||
if (customElement == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String modId = jsonObject.get("id").getAsString();
|
||||
final JsonObject custom = jsonObject.getAsJsonObject("custom");
|
||||
|
||||
if (!custom.has(Constants.CustomModJsonKeys.PROVIDED_JAVADOC)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String javaDocPath = custom.getAsJsonPrimitive(Constants.CustomModJsonKeys.PROVIDED_JAVADOC).getAsString();
|
||||
final String javaDocPath = customElement.getAsString();
|
||||
final byte[] data = ZipUtils.unpack(path, javaDocPath);
|
||||
final MemoryMappingTree mappings = new MemoryMappingTree();
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ import net.fabricmc.accesswidener.AccessWidenerReader;
|
||||
import net.fabricmc.accesswidener.AccessWidenerRemapper;
|
||||
import net.fabricmc.accesswidener.AccessWidenerWriter;
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.build.MixinRefmapHelper;
|
||||
import net.fabricmc.loom.build.nesting.IncludedJarFactory;
|
||||
import net.fabricmc.loom.build.nesting.JarNester;
|
||||
import net.fabricmc.loom.configuration.accesswidener.AccessWidenerFile;
|
||||
@@ -67,10 +66,11 @@ import net.fabricmc.loom.extension.MixinExtension;
|
||||
import net.fabricmc.loom.task.service.TinyRemapperService;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.ExceptionUtil;
|
||||
import net.fabricmc.loom.util.ModUtils;
|
||||
import net.fabricmc.loom.util.Pair;
|
||||
import net.fabricmc.loom.util.SidedClassVisitor;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJson;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper;
|
||||
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
@@ -138,14 +138,8 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(getProject());
|
||||
final MixinExtension mixinExtension = extension.getMixin();
|
||||
|
||||
final JsonObject fabricModJson = ModUtils.getFabricModJson(getInputFile().getAsFile().get().toPath());
|
||||
|
||||
if (fabricModJson == null) {
|
||||
getProject().getLogger().warn("Could not find fabric.mod.json file in: " + getInputFile().getAsFile().get().getName());
|
||||
return;
|
||||
}
|
||||
|
||||
final Collection<String> allMixinConfigs = MixinRefmapHelper.getMixinConfigurationFiles(fabricModJson);
|
||||
final FabricModJson fabricModJson = FabricModJsonFactory.createFromZip(getInputFile().getAsFile().get().toPath());
|
||||
final Collection<String> allMixinConfigs = fabricModJson.getMixinConfigurations();
|
||||
|
||||
for (SourceSet sourceSet : mixinExtension.getMixinSourceSets()) {
|
||||
MixinExtension.MixinInformationContainer container = Objects.requireNonNull(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2018-2022 FabricMC
|
||||
* Copyright (c) 2022 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,40 +22,40 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.build;
|
||||
package net.fabricmc.loom.util.fmj;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
import static net.fabricmc.loom.util.fmj.FabricModJsonUtils.readString;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class MixinRefmapHelper {
|
||||
private MixinRefmapHelper() { }
|
||||
public abstract sealed class FabricModJson permits FabricModJsonV0, FabricModJsonV1, FabricModJsonV2 {
|
||||
protected final JsonObject jsonObject;
|
||||
private final FabricModJsonSource source;
|
||||
|
||||
private static final String FABRIC_MOD_JSON = "fabric.mod.json";
|
||||
protected FabricModJson(JsonObject jsonObject, FabricModJsonSource source) {
|
||||
this.jsonObject = Objects.requireNonNull(jsonObject);
|
||||
this.source = Objects.requireNonNull(source);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<String> getMixinConfigurationFiles(JsonObject fabricModJson) {
|
||||
JsonArray mixins = fabricModJson.getAsJsonArray("mixins");
|
||||
public abstract int getVersion();
|
||||
|
||||
if (mixins == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
public String getId() {
|
||||
return readString(jsonObject, "id");
|
||||
}
|
||||
|
||||
return StreamSupport.stream(mixins.spliterator(), false)
|
||||
.map(e -> {
|
||||
if (e instanceof JsonPrimitive str) {
|
||||
return str.getAsString();
|
||||
} else if (e instanceof JsonObject obj) {
|
||||
return obj.get("config").getAsString();
|
||||
} else {
|
||||
throw new RuntimeException("Incorrect fabric.mod.json format");
|
||||
}
|
||||
}).collect(Collectors.toSet());
|
||||
@Nullable
|
||||
public abstract JsonElement getCustom(String key);
|
||||
|
||||
public abstract List<String> getMixinConfigurations();
|
||||
|
||||
public abstract List<String> getClassTweakers(ModEnvironment modEnvironment);
|
||||
|
||||
public final FabricModJsonSource getSource() {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.fmj;
|
||||
|
||||
import static net.fabricmc.loom.util.fmj.FabricModJsonUtils.readInt;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
|
||||
public final class FabricModJsonFactory {
|
||||
private static final String FABRIC_MOD_JSON = "fabric.mod.json";
|
||||
|
||||
private FabricModJsonFactory() {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static FabricModJson create(JsonObject jsonObject, FabricModJsonSource source) {
|
||||
int schemaVersion = 0;
|
||||
|
||||
if (jsonObject.has("schemaVersion")) {
|
||||
// V0 had no schemaVersion key.
|
||||
schemaVersion = readInt(jsonObject, "schemaVersion");
|
||||
}
|
||||
|
||||
return switch (schemaVersion) {
|
||||
case 0 -> new FabricModJsonV0(jsonObject, source);
|
||||
case 1 -> new FabricModJsonV1(jsonObject, source);
|
||||
case 2 -> new FabricModJsonV2(jsonObject, source);
|
||||
default -> throw new UnsupportedOperationException(String.format("This version of fabric-loom doesn't support the newer fabric.mod.json schema version of (%s) Please update fabric-loom to be able to read this.", schemaVersion));
|
||||
};
|
||||
}
|
||||
|
||||
public static FabricModJson createFromZip(Path zipPath) {
|
||||
try {
|
||||
return create(ZipUtils.unpackGson(zipPath, FABRIC_MOD_JSON, JsonObject.class), new FabricModJsonSource.ZipSource(zipPath));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read fabric.mod.json file in zip: " + zipPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FabricModJson createFromZipNullable(Path zipPath) throws IOException {
|
||||
JsonObject jsonObject = ZipUtils.unpackGsonNullable(zipPath, FABRIC_MOD_JSON, JsonObject.class);
|
||||
|
||||
if (jsonObject == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return create(jsonObject, new FabricModJsonSource.ZipSource(zipPath));
|
||||
}
|
||||
|
||||
public static FabricModJson createFromDirectory(Path directory) throws IOException {
|
||||
final Path path = directory.resolve(FABRIC_MOD_JSON);
|
||||
|
||||
try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
|
||||
return create(LoomGradlePlugin.GSON.fromJson(reader, JsonObject.class), new FabricModJsonSource.DirectorySource(directory));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FabricModJson createFromSourceSetNullable(SourceSet sourceSet) throws IOException {
|
||||
final File file = SourceSetHelper.findFileInResource(sourceSet, FABRIC_MOD_JSON);
|
||||
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try (Reader reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) {
|
||||
return create(LoomGradlePlugin.GSON.fromJson(reader, JsonObject.class), new FabricModJsonSource.SourceSetSource(sourceSet));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isModJar(File file) {
|
||||
return isModJar(file.toPath());
|
||||
}
|
||||
|
||||
public static boolean isModJar(Path input) {
|
||||
return ZipUtils.contains(input, FABRIC_MOD_JSON);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.fmj;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
|
||||
/**
|
||||
* A mod may be a zip, directory or Gradle {@link SourceSet}
|
||||
* This abstraction allows easily reading a contained file from the mod.
|
||||
*/
|
||||
public interface FabricModJsonSource {
|
||||
byte[] read(String path) throws IOException;
|
||||
|
||||
record ZipSource(Path zipPath) implements FabricModJsonSource {
|
||||
@Override
|
||||
public byte[] read(String path) throws IOException {
|
||||
return ZipUtils.unpack(zipPath, path);
|
||||
}
|
||||
}
|
||||
|
||||
record DirectorySource(Path directoryPath) implements FabricModJsonSource {
|
||||
@Override
|
||||
public byte[] read(String path) throws IOException {
|
||||
return Files.readAllBytes(directoryPath.resolve(path));
|
||||
}
|
||||
}
|
||||
|
||||
record SourceSetSource(SourceSet sourceSet) implements FabricModJsonSource {
|
||||
@Override
|
||||
public byte[] read(String path) throws IOException {
|
||||
final File file = SourceSetHelper.findFileInResource(sourceSet, path);
|
||||
|
||||
if (file == null) {
|
||||
throw new FileNotFoundException("Could not find: " + path);
|
||||
}
|
||||
|
||||
return Files.readAllBytes(file.toPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.fmj;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
final class FabricModJsonUtils {
|
||||
private FabricModJsonUtils() {
|
||||
}
|
||||
|
||||
public static String readString(JsonObject jsonObject, String key) {
|
||||
final JsonElement element = getElement(jsonObject, key);
|
||||
ensurePrimitive(element, JsonPrimitive::isString, key);
|
||||
|
||||
return element.getAsString();
|
||||
}
|
||||
|
||||
public static int readInt(JsonObject jsonObject, String key) {
|
||||
final JsonElement element = getElement(jsonObject, key);
|
||||
ensurePrimitive(element, JsonPrimitive::isNumber, key);
|
||||
|
||||
return element.getAsInt();
|
||||
}
|
||||
|
||||
private static JsonElement getElement(JsonObject jsonObject, String key) {
|
||||
final JsonElement element = jsonObject.get(key);
|
||||
|
||||
if (element == null) {
|
||||
throw new ParseException("Unable to find json element for key (%s)", key);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
private static void ensurePrimitive(JsonElement jsonElement, Predicate<JsonPrimitive> predicate, String key) {
|
||||
if (!jsonElement.isJsonPrimitive() || !predicate.test(jsonElement.getAsJsonPrimitive())) {
|
||||
throw new ParseException("Unexpected primitive type for key (%s)", key);
|
||||
}
|
||||
}
|
||||
|
||||
static class ParseException extends RuntimeException {
|
||||
ParseException(String message, Object... args) {
|
||||
super(String.format(Locale.ROOT, message, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.fmj;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Deprecated
|
||||
public final class FabricModJsonV0 extends FabricModJson {
|
||||
FabricModJsonV0(JsonObject jsonObject, FabricModJsonSource source) {
|
||||
super(jsonObject, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JsonElement getCustom(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixinConfigurations() {
|
||||
final JsonObject mixinsObject = jsonObject.getAsJsonObject("mixins");
|
||||
|
||||
if (mixinsObject == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final List<String> mixins = new ArrayList<>();
|
||||
|
||||
for (String key : mixinsObject.keySet()) {
|
||||
final JsonElement jsonElement = mixinsObject.get(key);
|
||||
|
||||
if (jsonElement instanceof JsonArray jsonArray) {
|
||||
for (JsonElement arrayElement : jsonArray) {
|
||||
if (arrayElement instanceof JsonPrimitive jsonPrimitive && jsonPrimitive.isString()) {
|
||||
mixins.add(jsonPrimitive.getAsString());
|
||||
} else {
|
||||
throw new FabricModJsonUtils.ParseException("Expected entries in mixin %s to be an array of strings", key);
|
||||
}
|
||||
}
|
||||
} else if (jsonElement instanceof JsonPrimitive jsonPrimitive && jsonPrimitive.isString()) {
|
||||
mixins.add(jsonPrimitive.getAsString());
|
||||
} else {
|
||||
throw new FabricModJsonUtils.ParseException("Expected mixin %s to be a string or an array of strings", key);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(mixins);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getClassTweakers(ModEnvironment modEnvironment) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
101
src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV1.java
Normal file
101
src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV1.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.fmj;
|
||||
|
||||
import static net.fabricmc.loom.util.fmj.FabricModJsonUtils.readString;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class FabricModJsonV1 extends FabricModJson {
|
||||
FabricModJsonV1(JsonObject jsonObject, FabricModJsonSource source) {
|
||||
super(jsonObject, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JsonElement getCustom(String key) {
|
||||
return getCustom(jsonObject, key);
|
||||
}
|
||||
|
||||
static JsonElement getCustom(JsonObject jsonObject, String key) {
|
||||
if (!jsonObject.has("custom")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final JsonObject custom = jsonObject.getAsJsonObject("custom");
|
||||
|
||||
if (!custom.has(key)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return custom.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixinConfigurations() {
|
||||
final JsonArray mixinArray = jsonObject.getAsJsonArray("mixins");
|
||||
|
||||
if (mixinArray == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return StreamSupport.stream(mixinArray.spliterator(), false)
|
||||
.map(FabricModJsonV1::readMixinElement)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static String readMixinElement(JsonElement jsonElement) {
|
||||
if (jsonElement instanceof JsonPrimitive str) {
|
||||
return str.getAsString();
|
||||
} else if (jsonElement instanceof JsonObject obj) {
|
||||
return obj.get("config").getAsString();
|
||||
} else {
|
||||
throw new FabricModJsonUtils.ParseException("Expected mixin element to be an object or string");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getClassTweakers(ModEnvironment modEnvironment) {
|
||||
if (!jsonObject.has("accessWidener")) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return List.of(readString(jsonObject, "accessWidener"));
|
||||
}
|
||||
}
|
||||
133
src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV2.java
Normal file
133
src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonV2.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util.fmj;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public final class FabricModJsonV2 extends FabricModJson {
|
||||
FabricModJsonV2(JsonObject jsonObject, FabricModJsonSource source) {
|
||||
super(jsonObject, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JsonElement getCustom(String key) {
|
||||
return FabricModJsonV1.getCustom(jsonObject, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixinConfigurations() {
|
||||
if (!jsonObject.has("mixins")) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return getConditionalConfigs(jsonObject.get("mixins"), ModEnvironment.UNIVERSAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getClassTweakers(ModEnvironment modEnvironment) {
|
||||
if (!jsonObject.has("classTweakers")) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return getConditionalConfigs(jsonObject.get("classTweakers"), modEnvironment);
|
||||
}
|
||||
|
||||
private List<String> getConditionalConfigs(JsonElement jsonElement, ModEnvironment modEnvironment) {
|
||||
final List<String> values = new ArrayList<>();
|
||||
|
||||
if (jsonElement instanceof JsonArray jsonArray) {
|
||||
for (JsonElement arrayElement : jsonArray) {
|
||||
final String value = readConditionalConfig(arrayElement, modEnvironment);
|
||||
|
||||
if (value != null) {
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
} else if (jsonElement instanceof JsonPrimitive jsonPrimitive && jsonPrimitive.isString()) {
|
||||
final String value = readConditionalConfig(jsonPrimitive, modEnvironment);
|
||||
|
||||
if (value != null) {
|
||||
values.add(value);
|
||||
}
|
||||
} else {
|
||||
throw new FabricModJsonUtils.ParseException("Must be a string or array of strings");
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String readConditionalConfig(JsonElement jsonElement, ModEnvironment modEnvironment) {
|
||||
if (jsonElement instanceof JsonPrimitive jsonPrimitive && jsonPrimitive.isString()) {
|
||||
return jsonElement.getAsString();
|
||||
} else if (jsonElement instanceof JsonObject jsonObject) {
|
||||
final String config = FabricModJsonUtils.readString(jsonObject, "config");
|
||||
|
||||
if (!validForEnvironment(jsonObject, modEnvironment)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return config;
|
||||
} else {
|
||||
throw new FabricModJsonUtils.ParseException("Must be a string or an object");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validForEnvironment(JsonObject jsonObject, ModEnvironment modEnvironment) {
|
||||
if (!jsonObject.has("environment")) {
|
||||
// Default enabled for all envs.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(jsonObject.get("environment") instanceof JsonPrimitive jsonPrimitive) || !jsonPrimitive.isString()) {
|
||||
throw new FabricModJsonUtils.ParseException("Environment must be a string");
|
||||
}
|
||||
|
||||
final String environment = jsonPrimitive.getAsString();
|
||||
|
||||
return switch (environment) {
|
||||
case "*" -> true;
|
||||
case "client" -> modEnvironment.isClient();
|
||||
case "server" -> modEnvironment.isServer();
|
||||
default -> throw new FabricModJsonUtils.ParseException("Invalid environment type: " + environment);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2016-2022 FabricMC
|
||||
* Copyright (c) 2022 FabricMC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,34 +22,26 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.fabricmc.loom.util;
|
||||
package net.fabricmc.loom.util.fmj;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Path;
|
||||
public enum ModEnvironment {
|
||||
UNIVERSAL(true, true),
|
||||
CLIENT(true, false),
|
||||
SERVER(false, true);
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
private final boolean client;
|
||||
private final boolean server;
|
||||
|
||||
public final class ModUtils {
|
||||
private ModUtils() {
|
||||
ModEnvironment(boolean client, boolean server) {
|
||||
this.client = client;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public static boolean isMod(File file) {
|
||||
return isMod(file.toPath());
|
||||
public boolean isClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public static boolean isMod(Path input) {
|
||||
return ZipUtils.contains(input, "fabric.mod.json");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JsonObject getFabricModJson(Path path) {
|
||||
try {
|
||||
return ZipUtils.unpackGsonNullable(path, "fabric.mod.json", JsonObject.class);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to extract fabric.mod.json from " + path, e);
|
||||
}
|
||||
public boolean isServer() {
|
||||
return server;
|
||||
}
|
||||
}
|
||||
@@ -272,4 +272,16 @@ public final class SourceSetHelper {
|
||||
|
||||
return Collections.singletonList(new File(binDir, reference.sourceSet().getName()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File findFileInResource(SourceSet sourceSet, String path) {
|
||||
try {
|
||||
return sourceSet.getResources()
|
||||
.matching(patternFilterable -> patternFilterable.include(path))
|
||||
.getSingleFile();
|
||||
} catch (IllegalStateException e) {
|
||||
// File not found
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user