Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import io.github.projectunified.mcserverupdater.UpdateBuilder;

import java.io.IOException;
import java.util.stream.Collectors;

public class UpdaterConfig extends MyYaml {

Expand Down Expand Up @@ -54,6 +53,7 @@ public class UpdaterConfig extends MyYaml {
public YamlSection plugins_updater_profile;
public YamlSection plugins_updater_path;
public YamlSection plugins_updater_version;
public YamlSection plugins_updater_loaders;
public YamlSection plugins_updater_async;
public YamlSection plugins_updater_web_database;
public YamlSection plugins_updater_web_database_min_usages;
Expand Down Expand Up @@ -204,6 +204,10 @@ public UpdaterConfig() throws IOException, DuplicateKeyException, YamlReaderExce
plugins_updater_version = put(name, "plugins-updater", "version").setComments("The Minecraft version to check and download plugins for.",
"If left empty, taken from server-updater.version above, if also empty, taken from general.yml, if also empty, taken from server jar.",
"Currently only relevant for Modrinth plugins.");
plugins_updater_loaders = put(name, "plugins-updater", "loaders")
.setComments("The list of software's to update minecraft plugins.",
"If left empty, taken from server-updater.software above. I multiple values are specified it will prioritize the fist one.",
"Currently only relevant for Modrinth plugins.");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an API endpoint that returns the available loaders that we can include here, so the user can view a valid list of available loaders to use?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is https://api.modrinth.com/v3/tag/loader but without parsing & filtering it's not shown nicely.
Probably specifying manually would make sense if we go that route

plugins_updater_async = put(name, "plugins-updater", "async").setDefValues("true").setComments(
"Asynchronously checks for updates.",
"Normally this should be faster than checking for updates synchronously, thus it should be enabled.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,9 @@ public static boolean installPlugin(String command) throws Exception {
String mcVersion = updaterConfig.plugins_updater_version.asString();
if (mcVersion == null) mcVersion = Server.getMCVersion();

List<String> loaders = updaterConfig.plugins_updater_loaders.asStringList();
if (loaders.isEmpty()) loaders = List.of(updaterConfig.server_software.asString());

String repo = "spigot";
if(input.startsWith(repo)){
int spigotId = Integer.parseInt(input.replace(repo, "").trim());
Expand Down Expand Up @@ -427,7 +430,7 @@ public static boolean installPlugin(String command) throws Exception {
MinecraftPlugin plugin2 = new MinecraftPlugin(new File(pluginsDir + "/" + tempName).getAbsolutePath(),
tempName, "0", "", 0, 0, "");
plugin2.setModrinthId(input.replace(repo, "").trim());
result = new ResourceFinder().findPluginByModrinthId(plugin2, mcVersion);
result = new ResourceFinder().findPluginByModrinthId(loaders, plugin2, mcVersion);
}
/*
Nothing of the above worked thus do search by name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.io.File;
import java.time.Instant;
import java.util.List;


public class ModrinthAPI {
Expand All @@ -38,16 +39,16 @@ private boolean isInt(String s) {
*/
public SearchResult searchUpdateMod(InstalledModLoader modLoader, MinecraftMod mod, String mcVersion) {
if (mod.modrinthId == null && !isInt(mod.curseforgeId)) mod.modrinthId = mod.curseforgeId; // Slug
SearchResult res = searchUpdate((modLoader.isFabric || modLoader.isQuilt ? "fabric" : "forge"),mod.modrinthId,mcVersion, mod.installationPath, mod.forceLatest);
SearchResult res = searchUpdate((modLoader.isFabric || modLoader.isQuilt ? List.of("fabric") : List.of("forge")),mod.modrinthId,mcVersion, mod.installationPath, mod.forceLatest);
res.mod = mod;
return res;
}
public SearchResult searchUpdatePlugin(MinecraftPlugin plugin, String mcVersion) { //TODO: probably don't hardcode spigot and papermc
return searchUpdate("spigot\",\"paper", plugin.getModrinthId(), mcVersion, plugin.getInstallationPath(), false);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Osiris-Team Plugin updating worked only for spigot/paper because it was hardcoded here. Now it also works for velocity and specific paper forks like Folia. It get's the loader either via server-updater.loader or if smt is specified plugins-updater.loaders where you can specify multiple ones.

@Osiris-Team Osiris-Team Jul 14, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay it seems counterintuitive to be able to provide multiple mod loaders from a user-perspective, because usually the server only has one loader, thus I'd like to keep these options away from the user and under the hood as API implementation details.

Instead it would be great to enhance the automatic detection in InstalledModLoader.java to include the detection for new mod loaders.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you want a general logic it can be complicated quite quickly, e.g you would have only supply folia for folia, Purpur > Paper > Spigot for Purpur.
Not sure if that's really feasible in that PR.

It would be nice when it correctly updates FAWE through with the paper build on paper.

What's your (simple) idea for that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also wonder if you are open in merging that and creating an issue for moving that to internal again. With proper handling

@Osiris-Team Osiris-Team Jul 15, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Zoriot I'd like to see this implemented in this PR directly 👍. I'm not sure the implementation is that complicated. We could even remove or simplify the auto detection to instead just check what the user entered in the server-updater software section of the config, and use that to determine the compatible mod loader.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understandable. What's your proposed solution to make preferred option/handling possible?

Add a (optional) fiel to the field where we safe the data about plugins? E.g. https://modrinth.com/plugin/fastasyncworldedit/versions needs that, on a Paper (Fork) it should always install the paper version not the spigot version.

@Osiris-Team Osiris-Team Jul 16, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Zoriot Why not just install the best match automatically? For example If the server is paper we prefer paper mod/plugin builds and only fallback on spigot if needed.

public SearchResult searchUpdatePlugin(List<String> loaders, MinecraftPlugin plugin, String mcVersion) {
return searchUpdate(loaders, plugin.getModrinthId(), mcVersion, plugin.getInstallationPath(), false);
}
private SearchResult searchUpdate(String loader, String id, String mcVersion, String installPath, boolean forceLatest) {
private SearchResult searchUpdate(List<String> loaders, String id, String mcVersion, String installPath, boolean forceLatest) {

String url = baseUrl + "/project/" + id + "/version?loaders=[\"" + loader + "\"]&game_versions=[\"" + mcVersion + "\"]";
String url = baseUrl + "/project/" + id + "/version?loaders=[\"" + String.join( "\",\"", loaders) + "\"]&game_versions=[\"" + mcVersion + "\"]";
url = new UtilsURL().clean(url);
Exception exception = null;
String latest = null;
Expand All @@ -67,7 +68,7 @@ private SearchResult searchUpdate(String loader, String id, String mcVersion, St
if (!isInt(id)) { // Try another url, with slug replaced _ with -
url = baseUrl + "/project/" + id.replace("_", "-")
+ "/version?loaders=[\"" +
loader + "\"]" + (forceLatest ? "" : "&game_versions=[\"" + mcVersion + "\"]");
String.join( "\",\"", loaders) + "\"]" + (forceLatest ? "" : "&game_versions=[\"" + mcVersion + "\"]");
AL.debug(this.getClass(), url);
release = Json.getAsJsonArray(url)
.get(0).getAsJsonObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import com.osiris.autoplug.client.tasks.updater.search.spigot.SpigotSearchById;
import com.osiris.autoplug.client.tasks.updater.search.spigot.SpigotSearchByName;

import java.util.List;

public class ResourceFinder {

/**
Expand Down Expand Up @@ -77,8 +79,8 @@ public SearchResult findPluginByBukkitId(MinecraftPlugin plugin) {
sr.plugin = plugin;
return sr;
}
public SearchResult findPluginByModrinthId(MinecraftPlugin plugin, String mcVersion) {
SearchResult sr = new ModrinthAPI().searchUpdatePlugin(plugin, mcVersion);
public SearchResult findPluginByModrinthId(List<String> loaders, MinecraftPlugin plugin, String mcVersion) {
SearchResult sr = new ModrinthAPI().searchUpdatePlugin(loaders, plugin, mcVersion);
sr.plugin = plugin;
return sr;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ else if (installedPlugin.getVersion() == null || installedPlugin.getVersion().tr
if (mcVersion == null) updaterConfig.server_updater_version.asString();
if (mcVersion == null) mcVersion = Server.getMCVersion();

List<String> loaders = updaterConfig.plugins_updater_loaders.asStringList();
if (loaders.isEmpty()) loaders = List.of(updaterConfig.server_software.asString());

for (MinecraftPlugin pl :
includedPlugins) {
try {
Expand All @@ -325,7 +328,8 @@ else if (installedPlugin.getVersion() == null || installedPlugin.getVersion().tr
} else if (pl.getModrinthId() != null) { // MODRINTH PLUGIN
sizeModrinthPlugins++;
String finalMcVersion = mcVersion;
activeFutures.add(executorService.submit(() -> new ResourceFinder().findPluginByModrinthId(pl, finalMcVersion)));
List<String> finalLoaders = loaders;
activeFutures.add(executorService.submit(() -> new ResourceFinder().findPluginByModrinthId(finalLoaders, pl, finalMcVersion)));
} else {
sizeUnknownPlugins++; // UNKNOWN PLUGIN
pl.setIgnoreContentType(true); // TODO temporary workaround for xamazon-json content type curseforge/bukkit issue: https://github.com/Osiris-Team/AutoPlug-Client/issues/109
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertSame;

Expand All @@ -36,7 +37,7 @@ void testModrinth() throws IOException {
UtilsTest.init();
MinecraftPlugin pl = new MinecraftPlugin("./plugins/", "BMMarker", "0.0.0", "Miraculixx", 0, 0, null);
pl.modrinthId = "a8UoyV2h";
SearchResult sr = new ModrinthAPI().searchUpdatePlugin(pl, "1.21.1");
SearchResult sr = new ModrinthAPI().searchUpdatePlugin(List.of("paper"), pl, "1.21.1");
assertSame(SearchResult.Type.UPDATE_AVAILABLE, sr.type);
}
}
Loading