Mod matching release WIP

This commit is contained in:
Anuken
2026-09-16 15:40:41 -04:00
parent ca90af5f56
commit acf891e419
3 changed files with 76 additions and 4 deletions
+24
View File
@@ -1,9 +1,15 @@
package mindustry.mod;
import arc.struct.*;
import arc.util.*;
import mindustry.ui.dialogs.*;
/** Mod listing as a data class. */
public class ModListing{
public String repo, name, internalName, author, lastUpdated, description, minGameVersion, version, iconHash = "";
public boolean hasScripts, hasJava, iosCompatible, legacyCompatible, hasIcon;
/** game build -> release ID + mod version */
public @Nullable ArrayMap<String, ModRelease> releases;
public String[] contentTypes = {};
public int stars;
@@ -22,4 +28,22 @@ public class ModListing{
", stars=" + stars +
'}';
}
public @Nullable ModRelease getMatchingRelease(){
if(releases == null) return null;
for(int i = 0; i < releases.size; i ++){
String key = releases.keys[i];
if(ModsDialog.matchesGameVersion(ModsDialog.parseVersion(key))){
return releases.values[i];
}
}
return null;
}
public static class ModRelease{
/** Github release ID */
public String id = "";
/** Actual mod version string in release's mod.json */
public String version = "";
}
}
@@ -17,6 +17,7 @@ import arc.util.Http.*;
import arc.util.io.*;
import arc.util.serialization.*;
import arc.util.serialization.Jval.*;
import mindustry.core.*;
import mindustry.ctype.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
@@ -26,10 +27,13 @@ import mindustry.mod.Mods.*;
import mindustry.ui.*;
import java.util.*;
import java.util.regex.*;
import static mindustry.Vars.*;
public class ModsDialog extends BaseDialog{
private static final Pattern modVersionPattern = Pattern.compile("\\[[vb](\\d+)(?:\\.(\\d+))?\\]");
public ModBrowserDialog browser;
protected float modImportProgress;
@@ -686,4 +690,51 @@ public class ModsDialog extends BaseDialog{
}, this::importFail);
}
}
/** @return {major, minor} parsed from a leading/trailing "[v{major}]" or "[v{major}.{minor}]" tag, or null if none is found at either end (or the numbers are unparseable). */
public static @Nullable int[] parseVersionTag(String str){
if(str == null) return null;
Matcher m = modVersionPattern.matcher(str);
while(m.find()){
if(m.start() == 0 || m.end() == str.length()){
int major = Strings.parseInt(m.group(1));
if(major == Integer.MIN_VALUE) return null;
int minor = m.group(2) != null ? Strings.parseInt(m.group(2)) : 0;
if(minor == Integer.MIN_VALUE) return null;
return new int[]{major, minor};
}
}
return null;
}
public static @Nullable int[] parseVersion(String str){
if(str == null || str.isEmpty()) return null;
int dot = str.indexOf('.');
String majorStr = dot == -1 ? str : str.substring(0, dot);
String minorStr = dot == -1 ? null : str.substring(dot + 1);
if(majorStr.isEmpty() || (dot != -1 && (minorStr.isEmpty() || str.indexOf('.', dot + 1) != -1))) return null;
int major = Strings.parseInt(majorStr);
if(major == Integer.MIN_VALUE) return null;
int minor = minorStr != null ? Strings.parseInt(minorStr) : 0;
if(minor == Integer.MIN_VALUE) return null;
return new int[]{major, minor};
}
/** @return whether the specified release name and its tags match the current game build (e.g. "Bingus Mod [v160]" should only match build 160) */
public static boolean matchesGameVersion(String releaseTitle){
return matchesGameVersion(parseVersionTag(releaseTitle));
}
public static boolean matchesGameVersion(@Nullable int[] tag){
//version not specified, matches anything.
if(tag == null) return true;
//must match exactly; custom builds (-1) do not match.
//for revisions, either match if the revision is unspecified (v160 -> matches ALL 160.x builds), OR, if it is specified, match the exact version (the mod author must have had a good reason for it)
return Version.build == tag[0] && (tag[1] == 0 || Version.revision == tag[1]);
}
}