Skip to content

Server 整合包支持优先从 Modrinth 下载资源 #3760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
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
@@ -77,6 +77,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
private final SimpleStringProperty launchArguments = new SimpleStringProperty("");
private final SimpleStringProperty javaArguments = new SimpleStringProperty("");
private final SimpleStringProperty mcbbsThreadId = new SimpleStringProperty("");
private final SimpleBooleanProperty priorityModrinthDownload = new SimpleBooleanProperty();

public ModpackInfoPage(WizardController controller, HMCLGameRepository gameRepository, String version) {
this.controller = controller;
@@ -119,6 +120,7 @@ private void onNext() {
exportInfo.setLaunchArguments(launchArguments.get());
exportInfo.setJavaArguments(javaArguments.get());
exportInfo.setAuthlibInjectorServer(authlibInjectorServer.get());
exportInfo.setPriorityModrinthDownload(priorityModrinthDownload.get());

if (StringUtils.isNotBlank(mcbbsThreadId.get())) {
exportInfo.setOrigins(Collections.singletonList(new McbbsModpackManifest.Origin(
@@ -363,6 +365,19 @@ public ModpackInfoPageSkin(ModpackInfoPage skinnable) {
button.setMaxHeight(16);
pane.setRight(button);
}

if (skinnable.options.isRequirePriorityModrinthDownload()) {
BorderPane pane = new BorderPane();
pane.setLeft(new Label(i18n("modpack.wizard.step.initialization.server.priority_modrinth_download")));
list.getContent().add(pane);

JFXToggleButton button = new JFXToggleButton();
button.selectedProperty().bindBidirectional(skinnable.priorityModrinthDownload);
button.setSize(8);
button.setMinHeight(16);
button.setMaxHeight(16);
pane.setRight(button);
}
}

{
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
@@ -912,6 +912,7 @@ modpack.wizard.step.initialization.warning=Before making a modpack, please make
\n\
Keep in mind that you are not allowed to add mods and resource packs that explicitly state they could not to be distributed or put in a modpack.
modpack.wizard.step.initialization.server=Click here for more information on how to make a server modpack that can be automatically updated.
modpack.wizard.step.initialization.server.priority_modrinth_download=Priority download resources from Modrinth

modrinth.category.adventure=Adventure
modrinth.category.audio=Audio
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_es.properties
Original file line number Diff line number Diff line change
@@ -916,6 +916,7 @@ modpack.wizard.step.initialization.warning=Antes de hacer un modpack, por favor
\n\
Ten en cuenta que no se te permite añadir mods y paquetes de recursos que se digan explícitamente que no se pueden distribuir o poner en un modpack.
modpack.wizard.step.initialization.server=Haga clic aquí para ver más tutoriales para hacer un modpack de servidor que se pueda actualizar automáticamente.
modpack.wizard.step.initialization.server.priority_modrinth_download=Prioridad para descargar recursos de Modrinth

modrinth.category.adventure=Aventura
modrinth.category.audio=Audio
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_ja.properties
Original file line number Diff line number Diff line change
@@ -644,6 +644,7 @@ modpack.wizard.step.initialization.include_launcher=ランチャーを含める
modpack.wizard.step.initialization.save=エクスポート先...
modpack.wizard.step.initialization.warning=modpackを作成する前に、ゲームが正常に起動できること、および\nMinecraftがリリースバージョンであることを確認する必要があります。\n再配布できないmodを追加しないでください。
modpack.wizard.step.initialization.server=サーバーの自動更新modpackの詳細については、ここをクリックしてください
modpack.wizard.step.initialization.server.priority_modrinth_download=Modrinthからリソースを優先的にダウンロード

modrinth.category.adventure=Adventure
modrinth.category.cursed=Cursed
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_ru.properties
Original file line number Diff line number Diff line change
@@ -915,6 +915,7 @@ modpack.wizard.step.initialization.warning=Перед созданием мод
\n\
Помните, что вам не разрешается добавлять моды и пакет ресурсов, в которых явно указано, что они не подлежат распространению или помещению в модпак.
modpack.wizard.step.initialization.server=Нажмите здесь для получения дополнительных руководств по созданию модпака на сервере, который может автообновляться.
modpack.wizard.step.initialization.server.priority_modrinth_download=Приоритетная загрузка ресурсов из Modrinth

modrinth.category.adventure=Приключение
modrinth.category.audio=Аудио
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
@@ -726,6 +726,7 @@ modpack.wizard.step.initialization.include_launcher=包含啟動器
modpack.wizard.step.initialization.save=選取要匯出到的遊戲模組包位置
modpack.wizard.step.initialization.warning=在製作模組包前,請你確認你選取的實例可以正常啟動,\n並保證你的 Minecraft 是正式版而非快照,\n而且不應將不允許非官方途徑傳播的模組、資源 (紋理) 包等納入模組包。\n模組包會儲存你目前的下載來源設定。
modpack.wizard.step.initialization.server=點選此處查看有關伺服器自動更新模組包的製作教學
modpack.wizard.step.initialization.server.priority_modrinth_download=優先從 modrinth 下載資源

modrinth.category.adventure=冒險
modrinth.category.audio=聲音
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
@@ -737,6 +737,7 @@ modpack.wizard.step.initialization.include_launcher=包含启动器
modpack.wizard.step.initialization.save=选择要导出到的游戏整合包位置
modpack.wizard.step.initialization.warning=在制作整合包前,请你确认你选择的版本可以正常启动,\n并保证你的 Minecraft 是正式版而非快照,\n而且不应当将不允许非官方途径传播的模组、资源 (纹理) 包等纳入整合包。\n整合包会保存你目前的下载源设置。\n如遇到问题,你可以点击右上角帮助按钮进行求助。
modpack.wizard.step.initialization.server=点击此处查看有关服务器自动更新整合包的制作教程
modpack.wizard.step.initialization.server.priority_modrinth_download=优先从 Modrinth 下载资源

modrinth.category.adventure=冒险
modrinth.category.audio=声音
Original file line number Diff line number Diff line change
@@ -29,6 +29,8 @@ public class ModpackExportInfo {

private List<McbbsModpackManifest.Origin> origins = new ArrayList<>();

private boolean priorityModrinthDownload;

public ModpackExportInfo() {}

public List<String> getWhitelist() {
@@ -186,6 +188,14 @@ public ModpackExportInfo setOrigins(List<McbbsModpackManifest.Origin> origins) {
return this;
}

public boolean isPriorityModrinthDownload() {
return priorityModrinthDownload;
}

public void setPriorityModrinthDownload(boolean priorityModrinthDownload) {
this.priorityModrinthDownload = priorityModrinthDownload;
}

public ModpackExportInfo validate() throws NullPointerException {
return this;
}
@@ -200,6 +210,7 @@ public static class Options {
private boolean requireLaunchArguments;
private boolean requireJavaArguments;
private boolean requireOrigins;
private boolean requirePriorityModrinthDownload;

public Options() {
}
@@ -240,6 +251,10 @@ public boolean isRequireOrigins() {
return requireOrigins;
}

public boolean isRequirePriorityModrinthDownload() {
return requirePriorityModrinthDownload;
}

public Options requireUrl() {
requireUrl = true;
return this;
@@ -281,5 +296,9 @@ public Options requireOrigins() {
return this;
}

public Options requirePriorityModrinthDownload() {
requirePriorityModrinthDownload = true;
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -102,10 +102,13 @@ public SearchResult search(String gameVersion, @Nullable RemoteModRepository.Cat
@Override
public Optional<RemoteMod.Version> getRemoteVersionByLocalFile(LocalModFile localModFile, Path file) throws IOException {
String sha1 = DigestUtils.digestToString("SHA-1", file);
return getRemoteVersionByHash(sha1, "sha1");
}

public Optional<RemoteMod.Version> getRemoteVersionByHash(String hash, String algorithm) throws IOException {
try {
ProjectVersion mod = HttpRequest.GET(PREFIX + "/v2/version_file/" + sha1,
pair("algorithm", "sha1"))
ProjectVersion mod = HttpRequest.GET(PREFIX + "/v2/version_file/" + hash,
pair("algorithm", algorithm))
.getJson(ProjectVersion.class);
return mod.toVersion();
} catch (ResponseCodeException e) {
Original file line number Diff line number Diff line change
@@ -22,6 +22,8 @@
import org.jackhuang.hmcl.download.GameBuilder;
import org.jackhuang.hmcl.game.DefaultGameRepository;
import org.jackhuang.hmcl.mod.ModpackConfiguration;
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
import org.jackhuang.hmcl.mod.RemoteMod;
import org.jackhuang.hmcl.task.FileDownloadTask;
import org.jackhuang.hmcl.task.GetTask;
import org.jackhuang.hmcl.task.Task;
@@ -152,11 +154,35 @@ public void execute() throws Exception {

if (download) {
total++;
dependencies.add(new FileDownloadTask(
new URL(remoteManifest.getFileApi() + "/overrides/" + NetworkUtils.encodeLocation(file.getPath())),
actualPath.toFile(),
new FileDownloadTask.IntegrityCheck("SHA-1", file.getHash()))
.withCounter("hmcl.modpack.download"));

FileDownloadTask task;
if (remoteManifest.isPriorityModrinthDownload()) {
String path = file.getPath();
if (path.startsWith("mods/") || path.startsWith("resourcepacks/") || path.startsWith("shaderpacks/")) {
try {
Optional<RemoteMod.Version> modrinthVersion = ModrinthRemoteModRepository.MODS.getRemoteVersionByHash(file.getHash(), "sha1");
if (modrinthVersion.isPresent() && modrinthVersion.get().getFile() != null) {
task = new FileDownloadTask(
new URL(modrinthVersion.get().getFile().getUrl()),
actualPath.toFile()
);
task.setCacheRepository(dependencyManager.getCacheRepository());
task.setCaching(true);
dependencies.add(0, task.withCounter("hmcl.modpack.download"));
continue;
}
} catch (IOException ignored) {
}
}
}

// Traditional download as fallback
URL downloadUrl = new URL(remoteManifest.getFileApi() + "/overrides/" + NetworkUtils.encodeLocation(file.getPath()));
task = new FileDownloadTask(downloadUrl, actualPath.toFile(),
new FileDownloadTask.IntegrityCheck("SHA-1", file.getHash()));
task.setCacheRepository(dependencyManager.getCacheRepository());
task.setCaching(true);
dependencies.add(task.withCounter("hmcl.modpack.download"));
}
}

Original file line number Diff line number Diff line change
@@ -95,11 +95,20 @@ public void execute() throws Exception {
addons.add(new ServerModpackManifest.Addon(FABRIC.getPatchId(), fabricVersion)));
analyzer.getVersion(QUILT).ifPresent(quiltVersion ->
addons.add(new ServerModpackManifest.Addon(QUILT.getPatchId(), quiltVersion)));
ServerModpackManifest manifest = new ServerModpackManifest(exportInfo.getName(), exportInfo.getAuthor(), exportInfo.getVersion(), exportInfo.getDescription(), StringUtils.removeSuffix(exportInfo.getFileApi(), "/"), files, addons);
ServerModpackManifest manifest = new ServerModpackManifest(
exportInfo.getName(),
exportInfo.getAuthor(),
exportInfo.getVersion(),
exportInfo.getDescription(),
StringUtils.removeSuffix(exportInfo.getFileApi(), "/"),
files,
addons,
exportInfo.isPriorityModrinthDownload());
zip.putTextFile(JsonUtils.GSON.toJson(manifest), "server-manifest.json");
}
}

public static final ModpackExportInfo.Options OPTION = new ModpackExportInfo.Options()
.requireFileApi(false);
.requireFileApi(false)
.requirePriorityModrinthDownload();
}
Original file line number Diff line number Diff line change
@@ -43,19 +43,21 @@ public class ServerModpackManifest implements ModpackManifest, Validation {
private final String fileApi;
private final List<ModpackConfiguration.FileInformation> files;
private final List<Addon> addons;
private final boolean priorityModrinthDownload;

public ServerModpackManifest() {
this("", "", "", "", "", Collections.emptyList(), Collections.emptyList());
this("", "", "", "", "", Collections.emptyList(), Collections.emptyList(), false);
}

public ServerModpackManifest(String name, String author, String version, String description, String fileApi, List<ModpackConfiguration.FileInformation> files, List<Addon> addons) {
public ServerModpackManifest(String name, String author, String version, String description, String fileApi, List<ModpackConfiguration.FileInformation> files, List<Addon> addons, boolean priorityModrinthDownload) {
this.name = name;
this.author = author;
this.version = version;
this.description = description;
this.fileApi = fileApi;
this.files = files;
this.addons = addons;
this.priorityModrinthDownload = priorityModrinthDownload;
}

public String getName() {
@@ -86,6 +88,10 @@ public List<Addon> getAddons() {
return addons;
}

public boolean isPriorityModrinthDownload() {
return priorityModrinthDownload;
}

@Override
public ModpackProvider getProvider() {
return ServerModpackProvider.INSTANCE;