feat: Cleanroom 自动安装 (#4272)
Co-authored-by: Zkitefly <64117916+zkitefly@users.noreply.github.com> Co-authored-by: Glavo <zjx001202@gmail.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.download;
|
||||
|
||||
import org.jackhuang.hmcl.download.cleanroom.CleanroomVersionList;
|
||||
import org.jackhuang.hmcl.download.fabric.FabricAPIVersionList;
|
||||
import org.jackhuang.hmcl.download.fabric.FabricVersionList;
|
||||
import org.jackhuang.hmcl.download.forge.ForgeBMCLVersionList;
|
||||
@@ -43,6 +44,7 @@ public final class BMCLAPIDownloadProvider implements DownloadProvider {
|
||||
private final FabricVersionList fabric;
|
||||
private final FabricAPIVersionList fabricApi;
|
||||
private final ForgeBMCLVersionList forge;
|
||||
private final CleanroomVersionList cleanroom;
|
||||
private final NeoForgeBMCLVersionList neoforge;
|
||||
private final LiteLoaderBMCLVersionList liteLoader;
|
||||
private final OptiFineBMCLVersionList optifine;
|
||||
@@ -56,6 +58,7 @@ public final class BMCLAPIDownloadProvider implements DownloadProvider {
|
||||
this.fabric = new FabricVersionList(this);
|
||||
this.fabricApi = new FabricAPIVersionList(this);
|
||||
this.forge = new ForgeBMCLVersionList(apiRoot);
|
||||
this.cleanroom = new CleanroomVersionList(this);
|
||||
this.neoforge = new NeoForgeBMCLVersionList(apiRoot);
|
||||
this.liteLoader = new LiteLoaderBMCLVersionList(this);
|
||||
this.optifine = new OptiFineBMCLVersionList(apiRoot);
|
||||
@@ -78,6 +81,8 @@ public final class BMCLAPIDownloadProvider implements DownloadProvider {
|
||||
pair("https://maven.fabricmc.net", apiRoot + "/maven"),
|
||||
pair("https://authlib-injector.yushi.moe", apiRoot + "/mirrors/authlib-injector"),
|
||||
pair("https://repo1.maven.org/maven2", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public"),
|
||||
pair("https://repo.maven.apache.org/maven2", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public"),
|
||||
pair("https://hmcl-dev.github.io/metadata/cleanroom", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/cleanroom"),
|
||||
pair("https://zkitefly.github.io/unlisted-versions-of-minecraft", "https://alist.8mi.tech/d/mirror/unlisted-versions-of-minecraft/Auto")
|
||||
// // https://github.com/mcmod-info-mirror/mcim-rust-api
|
||||
// pair("https://api.modrinth.com", "https://mod.mcimirror.top/modrinth"),
|
||||
@@ -113,6 +118,8 @@ public final class BMCLAPIDownloadProvider implements DownloadProvider {
|
||||
return fabricApi;
|
||||
case "forge":
|
||||
return forge;
|
||||
case "cleanroom":
|
||||
return cleanroom;
|
||||
case "neoforge":
|
||||
return neoforge;
|
||||
case "liteloader":
|
||||
|
||||
@@ -122,7 +122,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
/**
|
||||
* Remove library by library id
|
||||
*
|
||||
* @param libraryId patch id or "forge"/"optifine"/"liteloader"/"fabric"/"quilt"/"neoforge"
|
||||
* @param libraryId patch id or "forge"/"optifine"/"liteloader"/"fabric"/"quilt"/"neoforge"/"cleanroom"
|
||||
* @return this
|
||||
*/
|
||||
public LibraryAnalyzer removeLibrary(String libraryId) {
|
||||
@@ -172,6 +172,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
String mainClass = resolvedVersion.getMainClass();
|
||||
return mainClass != null && (LAUNCH_WRAPPER_MAIN.equals(mainClass)
|
||||
|| mainClass.startsWith("net.minecraftforge")
|
||||
|| mainClass.startsWith("top.outlands") //Cleanroom
|
||||
|| mainClass.startsWith("net.fabricmc")
|
||||
|| mainClass.startsWith("org.quiltmc")
|
||||
|| mainClass.startsWith("cpw.mods"));
|
||||
@@ -212,6 +213,7 @@ public final class LibraryAnalyzer implements Iterable<LibraryAnalyzer.LibraryMa
|
||||
return super.matchLibrary(library, libraries);
|
||||
}
|
||||
},
|
||||
CLEANROOM(true, "cleanroom", "com\\.cleanroommc", "cleanroom", ModLoaderType.CLEANROOM),
|
||||
NEO_FORGE(true, "neoforge", "net\\.neoforged\\.fancymodloader", "(core|loader)", ModLoaderType.NEO_FORGED) {
|
||||
private final Pattern NEO_FORGE_VERSION_MATCHER = Pattern.compile("^([0-9.]+)-(?<forge>[0-9.]+)(-([0-9.]+))?$");
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.download;
|
||||
|
||||
import org.jackhuang.hmcl.download.cleanroom.CleanroomVersionList;
|
||||
import org.jackhuang.hmcl.download.fabric.FabricAPIVersionList;
|
||||
import org.jackhuang.hmcl.download.fabric.FabricVersionList;
|
||||
import org.jackhuang.hmcl.download.forge.ForgeVersionList;
|
||||
@@ -37,6 +38,7 @@ public class MojangDownloadProvider implements DownloadProvider {
|
||||
private final FabricAPIVersionList fabricApi;
|
||||
private final ForgeVersionList forge;
|
||||
private final NeoForgeOfficialVersionList neoforge;
|
||||
private final CleanroomVersionList cleanroom;
|
||||
private final LiteLoaderVersionList liteLoader;
|
||||
private final OptiFineBMCLVersionList optifine;
|
||||
private final QuiltVersionList quilt;
|
||||
@@ -51,6 +53,7 @@ public class MojangDownloadProvider implements DownloadProvider {
|
||||
this.fabricApi = new FabricAPIVersionList(this);
|
||||
this.forge = new ForgeVersionList(this);
|
||||
this.neoforge = new NeoForgeOfficialVersionList(this);
|
||||
this.cleanroom = new CleanroomVersionList(this);
|
||||
this.liteLoader = new LiteLoaderVersionList(this);
|
||||
this.optifine = new OptiFineBMCLVersionList(apiRoot);
|
||||
this.quilt = new QuiltVersionList(this);
|
||||
@@ -78,6 +81,8 @@ public class MojangDownloadProvider implements DownloadProvider {
|
||||
return fabricApi;
|
||||
case "forge":
|
||||
return forge;
|
||||
case "cleanroom":
|
||||
return cleanroom;
|
||||
case "neoforge":
|
||||
return neoforge;
|
||||
case "liteloader":
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.download.cleanroom;
|
||||
|
||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.download.UnsupportedInstallationException;
|
||||
import org.jackhuang.hmcl.download.VersionMismatchException;
|
||||
import org.jackhuang.hmcl.download.forge.ForgeNewInstallTask;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public final class CleanroomInstallTask extends Task<Version> {
|
||||
|
||||
private final DefaultDependencyManager dependencyManager;
|
||||
private final Version version;
|
||||
private Path installer;
|
||||
private final CleanroomRemoteVersion remote;
|
||||
private FileDownloadTask dependent;
|
||||
private Task<Version> task;
|
||||
|
||||
public CleanroomInstallTask(DefaultDependencyManager dependencyManager, Version version, CleanroomRemoteVersion remoteVersion) {
|
||||
this.dependencyManager = dependencyManager;
|
||||
this.version = version;
|
||||
this.remote = remoteVersion;
|
||||
setSignificance(TaskSignificance.MODERATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doPreExecute() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preExecute() throws Exception {
|
||||
installer = Files.createTempFile("cleanroom-installer", ".jar");
|
||||
|
||||
dependent = new FileDownloadTask(
|
||||
dependencyManager.getDownloadProvider().injectURLsWithCandidates(remote.getUrls()),
|
||||
installer, null);
|
||||
dependent.setCacheRepository(dependencyManager.getCacheRepository());
|
||||
dependent.setCaching(true);
|
||||
dependent.addIntegrityCheckHandler(FileDownloadTask.ZIP_INTEGRITY_CHECK_HANDLER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doPostExecute() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postExecute() throws Exception {
|
||||
Files.deleteIfExists(installer);
|
||||
setResult(task.getResult());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task<?>> getDependents() {
|
||||
return Collections.singleton(dependent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task<?>> getDependencies() {
|
||||
return Collections.singleton(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws IOException, VersionMismatchException, UnsupportedInstallationException {
|
||||
task = new ForgeNewInstallTask(dependencyManager, version, remote.getSelfVersion(), installer).thenApplyAsync((version) -> version.setId(LibraryAnalyzer.LibraryType.CLEANROOM.getPatchId()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.download.cleanroom;
|
||||
|
||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
public class CleanroomRemoteVersion extends RemoteVersion {
|
||||
public CleanroomRemoteVersion(String gameVersion, String selfVersion, Instant releaseDate, List<String> url) {
|
||||
super(LibraryAnalyzer.LibraryType.CLEANROOM.getPatchId(), gameVersion, selfVersion, releaseDate, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task<Version> getInstallTask(DefaultDependencyManager dependencyManager, Version baseVersion) {
|
||||
return new CleanroomInstallTask(dependencyManager, baseVersion, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.download.cleanroom;
|
||||
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.download.VersionList;
|
||||
import org.jackhuang.hmcl.task.GetTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
|
||||
public final class CleanroomVersionList extends VersionList<CleanroomRemoteVersion> {
|
||||
private final DownloadProvider downloadProvider;
|
||||
private static final String LOADER_LIST_URL = "https://hmcl-dev.github.io/metadata/cleanroom/index.json";
|
||||
private static final String INSTALLER_URL = "https://hmcl-dev.github.io/metadata/cleanroom/files/cleanroom-%s-installer.jar";
|
||||
|
||||
public CleanroomVersionList(DownloadProvider downloadProvider) {
|
||||
this.downloadProvider = downloadProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task<?> refreshAsync() {
|
||||
return Task.allOf(
|
||||
new GetTask(downloadProvider.injectURLWithCandidates(LOADER_LIST_URL)).thenGetJsonAsync(ReleaseResult[].class)
|
||||
).thenAcceptAsync(results -> {
|
||||
lock.writeLock().lock();
|
||||
|
||||
try {
|
||||
versions.clear();
|
||||
for (ReleaseResult version : results.get(0)) {
|
||||
versions.put("1.12.2", new CleanroomRemoteVersion(
|
||||
"1.12.2", version.name, Instant.parse(version.created_at),
|
||||
Collections.singletonList(
|
||||
String.format(INSTALLER_URL, version.name)
|
||||
)
|
||||
));
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class ReleaseResult {
|
||||
String name;
|
||||
String created_at;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.gson.UUIDTypeAdapter;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.io.Unzipper;
|
||||
import org.jackhuang.hmcl.util.platform.Bits;
|
||||
import org.jackhuang.hmcl.util.platform.*;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
@@ -41,8 +40,8 @@ import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.Pair.pair;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
@@ -247,6 +246,10 @@ public class DefaultLauncher extends Launcher {
|
||||
|
||||
Set<String> classpath = repository.getClasspath(version);
|
||||
|
||||
if (analyzer.has(LibraryAnalyzer.LibraryType.CLEANROOM)) {
|
||||
classpath.removeIf(c -> c.contains("2.9.4-nightly-20150209"));
|
||||
}
|
||||
|
||||
File jar = repository.getVersionJar(version);
|
||||
if (!jar.exists() || !jar.isFile())
|
||||
throw new IOException("Minecraft jar does not exist");
|
||||
@@ -551,6 +554,9 @@ public class DefaultLauncher extends Launcher {
|
||||
if (analyzer.has(LibraryAnalyzer.LibraryType.FORGE)) {
|
||||
env.put("INST_FORGE", "1");
|
||||
}
|
||||
if (analyzer.has(LibraryAnalyzer.LibraryType.CLEANROOM)) {
|
||||
env.put("INST_CLEANROOM", "1");
|
||||
}
|
||||
if (analyzer.has(LibraryAnalyzer.LibraryType.NEO_FORGE)) {
|
||||
env.put("INST_NEOFORGE", "1");
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.jackhuang.hmcl.mod;
|
||||
public enum ModLoaderType {
|
||||
UNKNOWN,
|
||||
FORGE,
|
||||
CLEANROOM,
|
||||
NEO_FORGED,
|
||||
FABRIC,
|
||||
QUILT,
|
||||
|
||||
@@ -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(CLEANROOM).ifPresent(cleanroomVersion ->
|
||||
addons.add(new McbbsModpackManifest.Addon(CLEANROOM.getPatchId(), cleanroomVersion)));
|
||||
analyzer.getVersion(NEO_FORGE).ifPresent(neoForgeVersion ->
|
||||
addons.add(new McbbsModpackManifest.Addon(NEO_FORGE.getPatchId(), neoForgeVersion)));
|
||||
analyzer.getVersion(LITELOADER).ifPresent(liteLoaderVersion ->
|
||||
|
||||
Reference in New Issue
Block a user