Fix: NeoForge Support (#2632)

* Fix

* Fix: NeoForge may successfully made HMCL think it's Forge.

* Fix #2649

* Fix #2654 partly because MultiMC hasn't support NeoForge yet.

* Get ready for HMCL to support export and read MultiMC Modpacks with NeoForge.
This commit is contained in:
Burning_TNT 2024-01-24 00:19:49 +08:00 committed by GitHub
parent 5db3c123a0
commit f53aed9a08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 47 additions and 9 deletions

View File

@ -87,6 +87,7 @@ class AdditionalInstallersPage extends InstallersPage {
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(version.resolvePreservingPatches(repository));
String game = analyzer.getVersion(MINECRAFT).orElse(null);
String forge = analyzer.getVersion(FORGE).orElse(null);
String neoForge = analyzer.getVersion(NEO_FORGE).orElse(null);
String liteLoader = analyzer.getVersion(LITELOADER).orElse(null);
String optiFine = analyzer.getVersion(OPTIFINE).orElse(null);
String fabric = analyzer.getVersion(FABRIC).orElse(null);
@ -95,7 +96,7 @@ class AdditionalInstallersPage extends InstallersPage {
String quiltApi = analyzer.getVersion(QUILT_API).orElse(null);
InstallerItem[] libraries = group.getLibraries();
String[] versions = new String[]{game, forge, liteLoader, optiFine, fabric, fabricApi, quilt, quiltApi};
String[] versions = new String[]{game, forge, neoForge, liteLoader, optiFine, fabric, fabricApi, quilt, quiltApi};
String currentGameVersion = Lang.nonNull(getVersion("game"), game);

View File

@ -99,8 +99,9 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
if (type == null) return version;
List<Library> libraries = new ArrayList<>();
for (Library library : version.getLibraries()) {
if (type.matchLibrary(library)) {
List<Library> rawLibraries = version.getLibraries();
for (Library library : rawLibraries) {
if (type.matchLibrary(library, rawLibraries)) {
// skip
} else {
libraries.add(library);
@ -135,9 +136,10 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
Map<String, Pair<Library, String>> libraries = new HashMap<>();
for (Library library : version.resolve(null).getLibraries()) {
List<Library> rawLibraries = version.resolve(null).getLibraries();
for (Library library : rawLibraries) {
for (LibraryType type : LibraryType.values()) {
if (type.matchLibrary(library)) {
if (type.matchLibrary(library, rawLibraries)) {
libraries.put(type.getPatchId(), pair(library, type.patchVersion(version, library.getVersion())));
break;
}
@ -185,10 +187,27 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
}
return super.patchVersion(gameVersion, libraryVersion);
}
@Override
public boolean matchLibrary(Library library, List<Library> libraries) {
for (Library l : libraries) {
if (NEO_FORGE.matchLibrary(l, libraries)) {
return false;
}
}
return super.matchLibrary(library, libraries);
}
},
NEO_FORGE(true, "neoforge", Pattern.compile("net\\.neoforged\\.fancymodloader"), Pattern.compile("(core|loader)"), ModLoaderType.NEO_FORGED) {
private final Pattern NEO_FORGE_VERSION_MATCHER = Pattern.compile("^([0-9.]+)-(?<forge>[0-9.]+)(-([0-9.]+))?$");
@Override
public String patchVersion(Version gameVersion, String libraryVersion) {
Matcher matcher = NEO_FORGE_VERSION_MATCHER.matcher(libraryVersion);
if (matcher.find()) {
return matcher.group("forge");
}
String res = scanVersion(gameVersion);
if (res != null) {
return res;
@ -266,7 +285,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
return null;
}
public boolean matchLibrary(Library library) {
public boolean matchLibrary(Library library, List<Library> libraries) {
return group.matcher(library.getGroupId()).matches() && artifact.matcher(library.getArtifactId()).matches();
}

View File

@ -89,7 +89,7 @@ public final class NeoForgeInstallTask extends Task<Version> {
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(installer)) {
String installProfileText = FileUtils.readText(fs.getPath("install_profile.json"));
Map<?, ?> installProfile = JsonUtils.fromNonNullJson(installProfileText, Map.class);
if (LibraryAnalyzer.LibraryType.FORGE.getPatchId().equals(installProfile.get("profile")) && Files.exists(fs.getPath("META-INF/NEOFORGE.RSA"))) {
if (LibraryAnalyzer.LibraryType.FORGE.getPatchId().equals(installProfile.get("profile")) && (Files.exists(fs.getPath("META-INF/NEOFORGE.RSA")) || installProfileText.contains("neoforge"))) {
ForgeNewInstallProfile profile = JsonUtils.fromNonNullJson(installProfileText, ForgeNewInstallProfile.class);
if (!gameVersion.get().equals(profile.getMinecraft()))
throw new VersionMismatchException(profile.getMinecraft(), gameVersion.get());
@ -97,9 +97,12 @@ public final class NeoForgeInstallTask extends Task<Version> {
if (!neoForgeVersion.getId().equals(LibraryAnalyzer.LibraryType.FORGE.getPatchId()) || neoForgeVersion.getVersion() == null) {
throw new IOException("Invalid neoforge version.");
}
return neoForgeVersion.setId(LibraryAnalyzer.LibraryType.NEO_FORGE.getPatchId()).setVersion(neoForgeVersion.getVersion().replace(LibraryAnalyzer.LibraryType.FORGE.getPatchId(), LibraryAnalyzer.LibraryType.NEO_FORGE.getPatchId()));
return neoForgeVersion.setId(LibraryAnalyzer.LibraryType.NEO_FORGE.getPatchId())
.setVersion(
removePrefix(neoForgeVersion.getVersion().replace(LibraryAnalyzer.LibraryType.FORGE.getPatchId(), ""), "-")
);
});
} else if (LibraryAnalyzer.LibraryType.NEO_FORGE.getPatchId().equals(installProfile.get("profile"))) {
} else if (LibraryAnalyzer.LibraryType.NEO_FORGE.getPatchId().equals(installProfile.get("profile")) || "NeoForge".equals(installProfile.get("profile"))) {
ForgeNewInstallProfile profile = JsonUtils.fromNonNullJson(installProfileText, ForgeNewInstallProfile.class);
if (!gameVersion.get().equals(profile.getMinecraft()))
throw new VersionMismatchException(profile.getMinecraft(), gameVersion.get());

View File

@ -91,6 +91,8 @@ public class McbbsModpackExportTask extends Task<Void> {
addons.add(new McbbsModpackManifest.Addon(MINECRAFT.getPatchId(), gameVersion));
analyzer.getVersion(FORGE).ifPresent(forgeVersion ->
addons.add(new McbbsModpackManifest.Addon(FORGE.getPatchId(), forgeVersion)));
analyzer.getVersion(NEO_FORGE).ifPresent(neoForgeVersion ->
addons.add(new McbbsModpackManifest.Addon(NEO_FORGE.getPatchId(), neoForgeVersion)));
analyzer.getVersion(LITELOADER).ifPresent(liteLoaderVersion ->
addons.add(new McbbsModpackManifest.Addon(LITELOADER.getPatchId(), liteLoaderVersion)));
analyzer.getVersion(OPTIFINE).ifPresent(optifineVersion ->
@ -115,6 +117,7 @@ public class McbbsModpackExportTask extends Task<Void> {
// CurseForge manifest
List<CurseManifestModLoader> modLoaders = new ArrayList<>();
analyzer.getVersion(FORGE).ifPresent(forgeVersion -> modLoaders.add(new CurseManifestModLoader("forge-" + forgeVersion, true)));
analyzer.getVersion(NEO_FORGE).ifPresent(forgeVersion -> modLoaders.add(new CurseManifestModLoader("neoforge-" + forgeVersion, true)));
analyzer.getVersion(FABRIC).ifPresent(fabricVersion -> modLoaders.add(new CurseManifestModLoader("fabric-" + fabricVersion, true)));
// OptiFine and LiteLoader are not supported by CurseForge modpack.
CurseManifest curseManifest = new CurseManifest(CurseManifest.MINECRAFT_MODPACK, 1, info.getName(), info.getVersion(), info.getAuthor(), "overrides", new CurseManifestMinecraft(gameVersion, modLoaders), Collections.emptyList());

View File

@ -77,6 +77,9 @@ public class MultiMCModpackExportTask extends Task<Void> {
components.add(new MultiMCManifest.MultiMCManifestComponent(true, false, "net.minecraft", gameVersion));
analyzer.getVersion(FORGE).ifPresent(forgeVersion ->
components.add(new MultiMCManifest.MultiMCManifestComponent(false, false, "net.minecraftforge", forgeVersion)));
// MultiMC hasn't supported NeoForge yet.
// analyzer.getVersion(NEO_FORGE).ifPresent(neoForgeVersion ->
// components.add(new MultiMCManifest.MultiMCManifestComponent(false, false, "net.neoforged", neoForgeVersion)));
analyzer.getVersion(LITELOADER).ifPresent(liteLoaderVersion ->
components.add(new MultiMCManifest.MultiMCManifestComponent(false, false, "com.mumfrey.liteloader", liteLoaderVersion)));
analyzer.getVersion(FABRIC).ifPresent(fabricVersion ->

View File

@ -78,6 +78,13 @@ public final class MultiMCModpackInstallTask extends Task<Void> {
builder.version("forge", c.getVersion());
});
// MultiMC hasn't supported NeoForge yet.
// Optional<MultiMCManifest.MultiMCManifestComponent> neoForge = manifest.getMmcPack().getComponents().stream().filter(e -> e.getUid().equals("net.neoforged")).findAny();
// neoForge.ifPresent(c -> {
// if (c.getVersion() != null)
// builder.version("neoforge", c.getVersion());
// });
Optional<MultiMCManifest.MultiMCManifestComponent> liteLoader = manifest.getMmcPack().getComponents().stream().filter(e -> e.getUid().equals("com.mumfrey.liteloader")).findAny();
liteLoader.ifPresent(c -> {
if (c.getVersion() != null)

View File

@ -85,6 +85,8 @@ public class ServerModpackExportTask extends Task<Void> {
addons.add(new ServerModpackManifest.Addon(MINECRAFT.getPatchId(), gameVersion));
analyzer.getVersion(FORGE).ifPresent(forgeVersion ->
addons.add(new ServerModpackManifest.Addon(FORGE.getPatchId(), forgeVersion)));
analyzer.getVersion(NEO_FORGE).ifPresent(neoForgeVersion ->
addons.add(new ServerModpackManifest.Addon(NEO_FORGE.getPatchId(), neoForgeVersion)));
analyzer.getVersion(LITELOADER).ifPresent(liteLoaderVersion ->
addons.add(new ServerModpackManifest.Addon(LITELOADER.getPatchId(), liteLoaderVersion)));
analyzer.getVersion(OPTIFINE).ifPresent(optifineVersion ->