From 22a1dd30f5b0c70c4163c219994bbbdd695dad99 Mon Sep 17 00:00:00 2001 From: AlexIIL Date: Mon, 23 Oct 2023 12:45:16 +0100 Subject: [PATCH 1/3] Add ModEntrypoint as a plugin API, and use it almost everywhere instead of AdapterLoadableClassEntry --- .../loader/api/plugin/ModMetadataExt.java | 18 ++++++++++- .../quiltmc/loader/impl/QuiltLoaderImpl.java | 5 +-- .../impl/entrypoint/EntrypointStorage.java | 12 ++++--- .../metadata/GeneralExt2FabricMetadata.java | 11 ++++--- .../qmj/AdapterLoadableClassEntry.java | 8 ++++- .../qmj/FabricModMetadataWrapper.java | 10 +++--- .../metadata/qmj/ProvidedModMetadata.java | 2 +- .../metadata/qmj/V1ModMetadataBuilder.java | 4 +-- .../impl/metadata/qmj/V1ModMetadataImpl.java | 6 ++-- .../metadata/qmj/V1ModMetadataReader.java | 31 ++++++------------- 10 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/quiltmc/loader/api/plugin/ModMetadataExt.java b/src/main/java/org/quiltmc/loader/api/plugin/ModMetadataExt.java index 65844f534..531c3a241 100644 --- a/src/main/java/org/quiltmc/loader/api/plugin/ModMetadataExt.java +++ b/src/main/java/org/quiltmc/loader/api/plugin/ModMetadataExt.java @@ -20,7 +20,9 @@ import java.util.Collections; import java.util.Map; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import org.quiltmc.loader.api.LanguageAdapter; import org.quiltmc.loader.api.ModMetadata; import org.quiltmc.loader.api.ModMetadataToBeMovedToPlugins; import org.quiltmc.loader.api.Version; @@ -70,7 +72,21 @@ public interface ModPlugin { // Runtime - Map> getEntrypoints(); + Map> getEntrypoints(); Map languageAdapters(); + + /** Entrypoint holder. Since plugins aren't expected to read from this only creation is supported. */ + @ApiStatus.NonExtendable + public interface ModEntrypoint { + + /** @return A new {@link ModEntrypoint} using the default adapter and the given value. */ + public static ModEntrypoint create(String value) { + return new AdapterLoadableClassEntry(value); + } + + public static ModEntrypoint create(String adapter, String value) { + return new AdapterLoadableClassEntry(adapter, value); + } + } } diff --git a/src/main/java/org/quiltmc/loader/impl/QuiltLoaderImpl.java b/src/main/java/org/quiltmc/loader/impl/QuiltLoaderImpl.java index 47c8a4898..379a13877 100644 --- a/src/main/java/org/quiltmc/loader/impl/QuiltLoaderImpl.java +++ b/src/main/java/org/quiltmc/loader/impl/QuiltLoaderImpl.java @@ -65,6 +65,7 @@ import org.quiltmc.loader.api.gui.QuiltLoaderText; import org.quiltmc.loader.api.plugin.ModContainerExt; import org.quiltmc.loader.api.plugin.ModMetadataExt; +import org.quiltmc.loader.api.plugin.ModMetadataExt.ModEntrypoint; import org.quiltmc.loader.api.plugin.gui.PluginGuiTreeNode.WarningLevel; import org.quiltmc.loader.api.plugin.solver.LoadOption; import org.quiltmc.loader.api.plugin.solver.ModLoadOption; @@ -1129,8 +1130,8 @@ private void setupMods() { } } - for (Map.Entry> entry : mod.metadata().getEntrypoints().entrySet()) { - for (AdapterLoadableClassEntry e : entry.getValue()) { + for (Map.Entry> entry : mod.metadata().getEntrypoints().entrySet()) { + for (ModEntrypoint e : entry.getValue()) { entrypointStorage.add(mod, entry.getKey(), e, adapterMap); } } diff --git a/src/main/java/org/quiltmc/loader/impl/entrypoint/EntrypointStorage.java b/src/main/java/org/quiltmc/loader/impl/entrypoint/EntrypointStorage.java index 2e064c250..a068867f1 100644 --- a/src/main/java/org/quiltmc/loader/impl/entrypoint/EntrypointStorage.java +++ b/src/main/java/org/quiltmc/loader/impl/entrypoint/EntrypointStorage.java @@ -22,6 +22,7 @@ import org.quiltmc.loader.api.entrypoint.EntrypointContainer; import org.quiltmc.loader.api.entrypoint.EntrypointException; import org.quiltmc.loader.api.plugin.ModContainerExt; +import org.quiltmc.loader.api.plugin.ModMetadataExt.ModEntrypoint; import org.quiltmc.loader.impl.launch.common.QuiltLauncherBase; import org.quiltmc.loader.impl.metadata.qmj.AdapterLoadableClassEntry; import org.quiltmc.loader.impl.util.QuiltLoaderInternal; @@ -146,14 +147,15 @@ public void addDeprecated(ModContainerExt modContainer, String adapter, String v getOrCreateEntries("server").add(oe); } - public void add(ModContainerExt modContainer, String key, AdapterLoadableClassEntry metadata, Map adapterMap) throws Exception { - if (!adapterMap.containsKey(metadata.getAdapter())) { - throw new Exception("Could not find adapter '" + metadata.getAdapter() + "' (mod " + modContainer.metadata().id() + "!)"); + public void add(ModContainerExt modContainer, String key, ModEntrypoint metadata, Map adapterMap) throws Exception { + AdapterLoadableClassEntry data = (AdapterLoadableClassEntry) metadata; + if (!adapterMap.containsKey(data.getAdapter())) { + throw new Exception("Could not find adapter '" + data.getAdapter() + "' (mod " + modContainer.metadata().id() + "!)"); } - Log.debug(LogCategory.ENTRYPOINT, "Registering new-style initializer %s for mod %s (key %s)", metadata.getValue(), modContainer.metadata().id(), key); + Log.debug(LogCategory.ENTRYPOINT, "Registering new-style initializer %s for mod %s (key %s)", data.getValue(), modContainer.metadata().id(), key); getOrCreateEntries(key).add(new NewEntry( - modContainer, adapterMap.get(metadata.getAdapter()), metadata.getValue() + modContainer, adapterMap.get(data.getAdapter()), data.getValue() )); } diff --git a/src/main/java/org/quiltmc/loader/impl/metadata/GeneralExt2FabricMetadata.java b/src/main/java/org/quiltmc/loader/impl/metadata/GeneralExt2FabricMetadata.java index 95af1aa80..b51800010 100644 --- a/src/main/java/org/quiltmc/loader/impl/metadata/GeneralExt2FabricMetadata.java +++ b/src/main/java/org/quiltmc/loader/impl/metadata/GeneralExt2FabricMetadata.java @@ -28,9 +28,11 @@ import org.quiltmc.loader.api.LoaderValue; import org.quiltmc.loader.api.ModContributor; import org.quiltmc.loader.api.ModLicense; +import org.quiltmc.loader.api.ModMetadata; import org.quiltmc.loader.api.ModMetadata.ProvidedMod; import org.quiltmc.loader.api.plugin.ModContainerExt; import org.quiltmc.loader.api.plugin.ModMetadataExt; +import org.quiltmc.loader.api.plugin.ModMetadataExt.ModEntrypoint; import org.quiltmc.loader.impl.fabric.metadata.CustomValueImpl; import org.quiltmc.loader.impl.fabric.metadata.MapBackedContactInformation; import org.quiltmc.loader.impl.fabric.metadata.SimplePerson; @@ -340,20 +342,21 @@ public Collection getOldInitializers() { @Override public List getEntrypoints(String type) { List list = new ArrayList<>(); - Collection quiltList = meta.getEntrypoints().get(type); + Collection quiltList = meta.getEntrypoints().get(type); if (quiltList == null) { return list; } - for (AdapterLoadableClassEntry entrypoint : quiltList) { + for (ModEntrypoint entrypoint : quiltList) { + AdapterLoadableClassEntry data = (AdapterLoadableClassEntry) entrypoint; list.add(new EntrypointMetadata() { @Override public String getValue() { - return entrypoint.getValue(); + return data.getValue(); } @Override public String getAdapter() { - return entrypoint.getAdapter(); + return data.getAdapter(); } }); } diff --git a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/AdapterLoadableClassEntry.java b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/AdapterLoadableClassEntry.java index e2e0018bf..67d29ab95 100644 --- a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/AdapterLoadableClassEntry.java +++ b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/AdapterLoadableClassEntry.java @@ -16,6 +16,7 @@ package org.quiltmc.loader.impl.metadata.qmj; +import org.quiltmc.loader.api.plugin.ModMetadataExt.ModEntrypoint; import org.quiltmc.loader.impl.util.QuiltLoaderInternal; import org.quiltmc.loader.impl.util.QuiltLoaderInternalType; @@ -23,10 +24,15 @@ * Represents a class entry inside of that specifies a language adapter to use to load the class. */ @QuiltLoaderInternal(QuiltLoaderInternalType.LEGACY_EXPOSED) -public final class AdapterLoadableClassEntry { +public final class AdapterLoadableClassEntry implements ModEntrypoint { private final String adapter; private final String value; + public AdapterLoadableClassEntry(String value) { + this.adapter = "default"; + this.value = value; + } + public AdapterLoadableClassEntry(String adapter, String value) { this.adapter = adapter; this.value = value; diff --git a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/FabricModMetadataWrapper.java b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/FabricModMetadataWrapper.java index e51e2ab9d..da4c67090 100644 --- a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/FabricModMetadataWrapper.java +++ b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/FabricModMetadataWrapper.java @@ -58,7 +58,7 @@ public class FabricModMetadataWrapper implements InternalModMetadata { private final Collection contributors; private final List jars; private final Map customValues; - private final Map> entrypoints; + private final Map> entrypoints; private final List provides; public FabricModMetadataWrapper(FabricLoaderModMetadata fabricMeta) { @@ -79,11 +79,11 @@ public FabricModMetadataWrapper(FabricLoaderModMetadata fabricMeta) { fabricMeta.getCustomValues().forEach((key, value) -> customValues.put(key, convertCustomValue(value))); this.customValues = Collections.unmodifiableMap(customValues); - Map> e = new HashMap<>(); + Map> e = new HashMap<>(); for (String key : fabricMeta.getEntrypointKeys()) { - Collection c = new ArrayList<>(); + Collection c = new ArrayList<>(); for (EntrypointMetadata entrypoint : fabricMeta.getEntrypoints(key)) { - c.add(new AdapterLoadableClassEntry(entrypoint.getAdapter(), entrypoint.getValue())); + c.add(ModEntrypoint.create(entrypoint.getAdapter(), entrypoint.getValue())); } e.put(key, Collections.unmodifiableCollection(c)); } @@ -283,7 +283,7 @@ public Collection provides() { } @Override - public Map> getEntrypoints() { + public Map> getEntrypoints() { return entrypoints; } diff --git a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/ProvidedModMetadata.java b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/ProvidedModMetadata.java index c886edc84..3dc5eea0e 100644 --- a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/ProvidedModMetadata.java +++ b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/ProvidedModMetadata.java @@ -142,7 +142,7 @@ public Collection provides() { } @Override - public Map> getEntrypoints() { + public Map> getEntrypoints() { return metadata.getEntrypoints(); } diff --git a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataBuilder.java b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataBuilder.java index e6cd69f7b..19825fa81 100644 --- a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataBuilder.java +++ b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataBuilder.java @@ -28,6 +28,7 @@ import org.quiltmc.loader.api.ModLicense; import org.quiltmc.loader.api.ModMetadata.ProvidedMod; import org.quiltmc.loader.api.Version; +import org.quiltmc.loader.api.plugin.ModMetadataExt.ModEntrypoint; import org.quiltmc.loader.api.plugin.ModMetadataExt.ModLoadType; import org.quiltmc.loader.impl.metadata.qmj.JsonLoaderValue.ObjectImpl; import org.quiltmc.loader.impl.util.QuiltLoaderInternal; @@ -55,8 +56,7 @@ public class V1ModMetadataBuilder { /* Internal fields */ public ModLoadType loadType = ModLoadType.IF_REQUIRED; public final List provides = new ArrayList<>(); - public final Map> entrypoints = new LinkedHashMap<>(); - public final List plugins = new ArrayList<>(); + public final Map> entrypoints = new LinkedHashMap<>(); public final List jars = new ArrayList<>(); public final Map languageAdapters = new LinkedHashMap<>(); public final List repositories = new ArrayList<>(); diff --git a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataImpl.java b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataImpl.java index 3583580ac..2bc36f45f 100644 --- a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataImpl.java +++ b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataImpl.java @@ -63,8 +63,7 @@ final class V1ModMetadataImpl implements InternalModMetadata { /* Internal fields */ private final ModLoadType loadType; private final Collection provides; - private final Map> entrypoints; -// private final Collection plugins; + private final Map> entrypoints; private final Collection jars; private final Map languageAdapters; private final Collection repositories; @@ -127,7 +126,6 @@ final class V1ModMetadataImpl implements InternalModMetadata { this.loadType = builder.loadType; this.provides = Collections.unmodifiableCollection(builder.provides); this.entrypoints = Collections.unmodifiableMap(builder.entrypoints); -// this.plugins = Collections.unmodifiableCollection(builder.plugins); this.jars = Collections.unmodifiableCollection(builder.jars); this.languageAdapters = Collections.unmodifiableMap(builder.languageAdapters); this.repositories = Collections.unmodifiableCollection(builder.repositories); @@ -288,7 +286,7 @@ public Collection provides() { @Nullable @Override - public Map> getEntrypoints() { + public Map> getEntrypoints() { return this.entrypoints; } diff --git a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataReader.java b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataReader.java index 4dd30856e..4e0fdc7d8 100644 --- a/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataReader.java +++ b/src/main/java/org/quiltmc/loader/impl/metadata/qmj/V1ModMetadataReader.java @@ -48,6 +48,7 @@ import org.quiltmc.loader.api.VersionRange; import org.quiltmc.loader.api.gui.QuiltLoaderGui; import org.quiltmc.loader.api.gui.QuiltLoaderText; +import org.quiltmc.loader.api.plugin.ModMetadataExt.ModEntrypoint; import org.quiltmc.loader.api.plugin.ModMetadataExt.ModLoadType; import org.quiltmc.loader.api.plugin.QuiltPluginManager; import org.quiltmc.loader.api.plugin.gui.PluginGuiTreeNode; @@ -91,7 +92,6 @@ private static class QLKeys { static final String GROUP = add("group"); static final String VERSION = add("version"); static final String ENTRYPOINTS = add("entrypoints"); - static final String PLUGINS = add("plugins"); static final String JARS = add("jars"); static final String LANGUAGE_ADAPTERS = add("language_adapters"); static final String DEPENDS = add("depends"); @@ -179,20 +179,7 @@ private V1ModMetadataImpl readFields(JsonLoaderValue.ObjectImpl root) { throw parseException(entrypointsValue, "entrypoints must be an object"); } - readAdapterLoadableClassEntries((JsonLoaderValue.ObjectImpl) entrypointsValue, QLKeys.ENTRYPOINTS, builder.entrypoints); - } - - @Nullable - JsonLoaderValue pluginsValue = quiltLoader.get(QLKeys.PLUGINS); - - if (pluginsValue != null) { - if (pluginsValue.type() != LoaderValue.LType.ARRAY) { - throw parseException(pluginsValue, "plugins must be an array"); - } - - for (LoaderValue entry : pluginsValue.asArray()) { - builder.plugins.add(readAdapterLoadableClassEntry((JsonLoaderValue) entry, QLKeys.PLUGINS)); - } + readEntrypoints((JsonLoaderValue.ObjectImpl) entrypointsValue, QLKeys.ENTRYPOINTS, builder.entrypoints); } @Nullable @@ -636,29 +623,29 @@ private static ModLicense readLicenseObject(JsonLoaderValue licenseValue) { } } - private static void readAdapterLoadableClassEntries(JsonLoaderValue.ObjectImpl object, String inside, Map> destination) { + private static void readEntrypoints(JsonLoaderValue.ObjectImpl object, String inside, Map> destination) { for (Map.Entry entry : object.entrySet()) { String entrypointKey = entry.getKey(); LoaderValue value = entry.getValue(); // Add the entry if not already present destination.putIfAbsent(entrypointKey, new ArrayList<>()); - List entries = destination.get(entrypointKey); + List entries = destination.get(entrypointKey); switch (value.type()) { case ARRAY: for (LoaderValue entrypoint : value.asArray()) { - entries.add(readAdapterLoadableClassEntry((JsonLoaderValue) entrypoint, inside)); + entries.add(readEntrypoint((JsonLoaderValue) entrypoint, inside)); } break; default: - entries.add(readAdapterLoadableClassEntry((JsonLoaderValue) value, inside)); + entries.add(readEntrypoint((JsonLoaderValue) value, inside)); } } } - private static AdapterLoadableClassEntry readAdapterLoadableClassEntry(JsonLoaderValue entry, String inside) { + private static ModEntrypoint readEntrypoint(JsonLoaderValue entry, String inside) { switch (entry.type()) { case OBJECT: LoaderValue.LObject entryObject = entry.asObject(); @@ -681,10 +668,10 @@ private static AdapterLoadableClassEntry readAdapterLoadableClassEntry(JsonLoade throw parseException((JsonLoaderValue) value, String.format("adapter field inside \"%s\" must be a string", inside)); } - return new AdapterLoadableClassEntry(adapter.asString(), value.asString()); + return ModEntrypoint.create(adapter.asString(), value.asString()); case STRING: // Assume `default` as language adapter - return new AdapterLoadableClassEntry("default", entry.asString()); + return ModEntrypoint.create("default", entry.asString()); default: throw parseException(entry, String.format("value inside \"%s\" must be a string or object", inside)); } From 1c617bcc106858a2b43041bf4073c767e09dbe6a Mon Sep 17 00:00:00 2001 From: AlexIIL Date: Thu, 2 Nov 2023 19:05:06 +0000 Subject: [PATCH 2/3] Add ModLicense.fromIdentifier, primarily for plugins to use. --- .../org/quiltmc/loader/api/ModLicense.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/org/quiltmc/loader/api/ModLicense.java b/src/main/java/org/quiltmc/loader/api/ModLicense.java index ce0eb47f0..09034c8c8 100644 --- a/src/main/java/org/quiltmc/loader/api/ModLicense.java +++ b/src/main/java/org/quiltmc/loader/api/ModLicense.java @@ -18,9 +18,13 @@ package org.quiltmc.loader.api; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; +import org.quiltmc.loader.impl.metadata.qmj.ModLicenseImpl; /** * Representation of a license a mod may use. + * + * @see SPDX identifier */ @ApiStatus.NonExtendable public interface ModLicense { @@ -44,4 +48,18 @@ public interface ModLicense { * @return a short description of the license, empty if there is no description */ String description(); + + /** Looks up a {@link ModLicense} from the given SPDX license ID, returning null if quilt-loader is unaware of + * it. */ + @Nullable + public static ModLicense fromIdentifier(String identifier) { + return ModLicenseImpl.fromIdentifier(identifier); + } + + /** Looks up a {@link ModLicense} from the given SPDX license ID, returning a new {@link ModLicense} (with + * {@link #name()} and {@link #id()} set to the passed identifier, the other fields blank) if quilt-loader is + * unaware of it. */ + public static ModLicense fromIdentifierOrDefault(String identifier) { + return ModLicenseImpl.fromIdentifierOrDefault(identifier); + } } From 2eec90bacf688e2d62f8723555b5ffcd642aeb27 Mon Sep 17 00:00:00 2001 From: AlexIIL Date: Thu, 2 Nov 2023 19:12:22 +0000 Subject: [PATCH 3/3] Add QuiltPluginManager.loadZipNow, since we have no reason to force plugins to delay it in a task. --- .../loader/api/plugin/QuiltLoaderPlugin.java | 4 ++-- .../loader/api/plugin/QuiltPluginContext.java | 6 +++--- .../loader/api/plugin/QuiltPluginManager.java | 18 +++++++++++++++++- .../impl/plugin/QuiltPluginManagerImpl.java | 11 +++++++++-- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/quiltmc/loader/api/plugin/QuiltLoaderPlugin.java b/src/main/java/org/quiltmc/loader/api/plugin/QuiltLoaderPlugin.java index 28013f673..ac6934aad 100644 --- a/src/main/java/org/quiltmc/loader/api/plugin/QuiltLoaderPlugin.java +++ b/src/main/java/org/quiltmc/loader/api/plugin/QuiltLoaderPlugin.java @@ -46,8 +46,8 @@ * will be opened, and checked for a "quilt.mod.json" file. If one is found, then it is loaded as a quilt mod (and * possibly as a new plugin - which will be loaded instantly, rather than waiting until the next cycle). *
  • If "quilt.mod.json" couldn't be found then the zip root will be passed to - * {@link #scanZip(Path, boolean, PluginGuiTreeNode)}
  • - *
  • Otherwise it will be passed to {@link #scanUnknownFile(Path, boolean, PluginGuiTreeNode)}
  • + * {@link #scanZip(Path, ModLocation, PluginGuiTreeNode)} + *
  • Otherwise it will be passed to {@link #scanUnknownFile(Path, ModLocation, PluginGuiTreeNode)}
  • * * *
  • {@link #beforeSolve()} is called.
  • diff --git a/src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginContext.java b/src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginContext.java index 6c37aa47f..392cf41ae 100644 --- a/src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginContext.java +++ b/src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginContext.java @@ -92,7 +92,7 @@ public interface QuiltPluginContext { /** Submits a task to be completed after plugin resolution, but before the current cycle ends. The task may be * executed on a different thread, depending on loaders config options. *

    - * This should only be called by {@link QuiltLoaderPlugin#resolve(QuiltPluginContext, Object)}, + * This should only be called by {@link QuiltLoaderPlugin#resolve(TentativeLoadOption)}, * {@link QuiltLoaderPlugin#finish(org.quiltmc.loader.api.plugin.solver.ModSolveResult)}, or by any tasks that are * passed to this function during their execution. * @@ -139,12 +139,12 @@ default QuiltPluginTask addGuiRequest() { void addModLoadOption(ModLoadOption mod, PluginGuiTreeNode fileNode); /** Adds a tentative option which can be resolved later by - * {@link QuiltLoaderPlugin#resolve(QuiltPluginContext, TentativeLoadOption)}, if it is selected. + * {@link QuiltLoaderPlugin#resolve(TentativeLoadOption)}, if it is selected. * * @param option */ void addTentativeOption(T option); - /** Only callable during {@link QuiltLoaderPlugin#handleError(java.util.List)} to identify the given rule as one + /** Only callable during {@link QuiltLoaderPlugin#handleError(java.util.Collection)} to identify the given rule as one * which can be removed for the purposes of error message generation. */ void blameRule(Rule rule); } diff --git a/src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginManager.java b/src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginManager.java index e41fc59ae..2042e450b 100644 --- a/src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginManager.java +++ b/src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginManager.java @@ -62,9 +62,25 @@ public interface QuiltPluginManager { *

  • {@link NonZipException} if {@link FileSystems#newFileSystem(Path, ClassLoader)} throws a * {@link ProviderNotFoundException}.
  • * - */ + * + * @see #loadZipNow(Path) */ QuiltPluginTask loadZip(Path zip); + /** Loads the specified zip file and returns a path to the root of it's contents. + *

    + * How the given zip is loaded depends on loaders config settings - in particular the zip could be extracted to a + * temporary folder on the same filesystem as the original zip. + *

    + * WARNING: if this method allocates a new {@link FileSystem} then that will be closed, unless at least one + * of the {@link QuiltLoaderPlugin}s {@link QuiltPluginContext#lockZip(Path) locks} it, or if a chosen mod is loaded + * from it. + * + * @throws IOException if something went wrong while loading the file. + * @throws NonZipException if {@link FileSystems#newFileSystem(Path, ClassLoader)} throws a + * {@link ProviderNotFoundException}. + * @see #loadZip(Path) */ + Path loadZipNow(Path zip) throws IOException, NonZipException; + /** Creates a new in-memory read-write file system. This can be used for mods that aren't loaded from zips. * * @return The root {@link Path} of the newly allocated {@link FileSystem} */ diff --git a/src/main/java/org/quiltmc/loader/impl/plugin/QuiltPluginManagerImpl.java b/src/main/java/org/quiltmc/loader/impl/plugin/QuiltPluginManagerImpl.java index 2dad42c99..e71805545 100644 --- a/src/main/java/org/quiltmc/loader/impl/plugin/QuiltPluginManagerImpl.java +++ b/src/main/java/org/quiltmc/loader/impl/plugin/QuiltPluginManagerImpl.java @@ -239,15 +239,22 @@ private BuiltinPluginContext addBuiltinPlugin(BuiltinQuiltPlugin plugin, String public QuiltPluginTask loadZip(Path zip) { if (config.singleThreadedLoading) { try { - return QuiltPluginTask.createFinished(loadZip0(zip)); + return QuiltPluginTask.createFinished(loadZipNow(zip)); } catch (IOException | NonZipException e) { return QuiltPluginTask.createFailed(e); } } - return submit(null, () -> loadZip0(zip)); + return submit(null, () -> loadZipNow(zip)); } + /** Kept for backwards compatibility with the first versions of RGML-Quilt, as it invoked this using reflection. */ + @Deprecated private Path loadZip0(Path zip) throws IOException, NonZipException { + return loadZipNow(zip); + } + + @Override + public Path loadZipNow(Path zip) throws IOException, NonZipException { String name = zip.getFileName().toString(); try { QuiltZipPath qRoot = new QuiltZipFileSystem(name, zip, "").getRoot();