Add fileApi option in modpackInfoPage

This commit is contained in:
huanghongxun
2019-11-12 17:49:26 +08:00
parent 4e0ffc8d1e
commit 956b4e4a6a
9 changed files with 230 additions and 117 deletions

View File

@@ -65,6 +65,7 @@ public final class ExportWizardProvider implements WizardProvider {
File modpackFile = (File) settings.get(ModpackInfoPage.MODPACK_FILE);
String modpackName = (String) settings.get(ModpackInfoPage.MODPACK_NAME);
String modpackAuthor = (String) settings.get(ModpackInfoPage.MODPACK_AUTHOR);
String modpackFileApi = (String) settings.get(ModpackInfoPage.MODPACK_FILE_API);
String modpackVersion = (String) settings.get(ModpackInfoPage.MODPACK_VERSION);
String modpackDescription = (String) settings.get(ModpackInfoPage.MODPACK_DESCRIPTION);
String modpackType = (String) settings.get(ModpackTypeSelectionPage.MODPACK_TYPE);
@@ -76,7 +77,7 @@ public final class ExportWizardProvider implements WizardProvider {
case ModpackTypeSelectionPage.MODPACK_TYPE_MULTIMC:
return exportAsMultiMC(whitelist, modpackFile, modpackName, modpackAuthor, modpackVersion, modpackDescription);
case ModpackTypeSelectionPage.MODPACK_TYPE_SERVER:
return exportAsServer(whitelist, modpackFile, modpackName, modpackAuthor, modpackVersion, modpackDescription);
return exportAsServer(whitelist, modpackFile, modpackName, modpackAuthor, modpackVersion, modpackDescription, modpackFileApi);
default:
throw new IllegalStateException("Unrecognized modpack type " + modpackType);
}
@@ -180,13 +181,13 @@ public final class ExportWizardProvider implements WizardProvider {
};
}
private Task<?> exportAsServer(List<String> whitelist, File modpackFile, String modpackName, String modpackAuthor, String modpackVersion, String modpackDescription) {
private Task<?> exportAsServer(List<String> whitelist, File modpackFile, String modpackName, String modpackAuthor, String modpackVersion, String modpackDescription, String modpackFileApi) {
return new Task<Void>() {
Task<?> dependency;
@Override
public void execute() {
dependency = new ServerModpackExportTask(profile.getRepository(), version, whitelist, modpackName, modpackAuthor, modpackVersion, modpackDescription, modpackFile);
dependency = new ServerModpackExportTask(profile.getRepository(), version, whitelist, modpackName, modpackAuthor, modpackVersion, modpackDescription, modpackFileApi, modpackFile);
}
@Override
@@ -198,9 +199,9 @@ public final class ExportWizardProvider implements WizardProvider {
@Override
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
switch (step) {
case 0: return new ModpackInfoPage(controller, version);
case 1: return new ModpackFileSelectionPage(controller, profile, version, ModAdviser::suggestMod);
case 2: return new ModpackTypeSelectionPage(controller);
case 0: return new ModpackTypeSelectionPage(controller);
case 1: return new ModpackInfoPage(controller, version);
case 2: return new ModpackFileSelectionPage(controller, profile, version, ModAdviser::suggestMod);
default: throw new IllegalArgumentException("step");
}
}

View File

@@ -146,7 +146,7 @@ public final class ModpackFileSelectionPage extends StackPane implements WizardP
LinkedList<String> list = new LinkedList<>();
getFilesNeeded(rootNode, "minecraft", list);
controller.getSettings().put(MODPACK_FILE_SELECTION, list);
controller.onNext();
controller.onFinish();
}
@Override

View File

@@ -21,63 +21,69 @@ import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextArea;
import com.jfoenix.controls.JFXTextField;
import com.jfoenix.controls.JFXToggleButton;
import com.jfoenix.validation.RequiredFieldValidator;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.text.TextAlignment;
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.Launcher;
import org.jackhuang.hmcl.auth.Account;
import org.jackhuang.hmcl.setting.Accounts;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.construct.ComponentList;
import org.jackhuang.hmcl.ui.construct.Validator;
import org.jackhuang.hmcl.ui.wizard.WizardController;
import org.jackhuang.hmcl.ui.wizard.WizardPage;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.jackhuang.hmcl.ui.export.ModpackTypeSelectionPage.*;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class ModpackInfoPage extends StackPane implements WizardPage {
public final class ModpackInfoPage extends Control implements WizardPage {
private final WizardController controller;
@FXML
private Label lblVersionName;
@FXML
private JFXTextField txtModpackName;
@FXML
private JFXTextField txtModpackAuthor;
@FXML
private JFXTextField txtModpackVersion;
@FXML
private JFXTextArea txtModpackDescription;
@FXML
private JFXToggleButton chkIncludeLauncher;
@FXML
private JFXButton btnNext;
@FXML
private ScrollPane scroll;
private final boolean canIncludeLauncher;
private final boolean showFileApi;
private SimpleStringProperty versionName = new SimpleStringProperty();
private SimpleStringProperty modpackName = new SimpleStringProperty();
private SimpleStringProperty modpackFileApi = new SimpleStringProperty();
private SimpleStringProperty modpackAuthor = new SimpleStringProperty();
private SimpleStringProperty modpackVersion = new SimpleStringProperty("1.0");
private SimpleStringProperty modpackDescription = new SimpleStringProperty();
private SimpleBooleanProperty includingLauncher = new SimpleBooleanProperty();
private ObjectProperty<EventHandler<? super MouseEvent>> next = new SimpleObjectProperty<>();
public ModpackInfoPage(WizardController controller, String version) {
this.controller = controller;
FXUtils.loadFXML(this, "/assets/fxml/modpack/info.fxml");
FXUtils.smoothScrolling(scroll);
txtModpackName.setText(version);
txtModpackName.textProperty().addListener(e -> checkValidation());
txtModpackAuthor.textProperty().addListener(e -> checkValidation());
txtModpackVersion.textProperty().addListener(e -> checkValidation());
txtModpackAuthor.setText(Optional.ofNullable(Accounts.getSelectedAccount()).map(Account::getUsername).orElse(""));
lblVersionName.setText(version);
modpackName.set(version);
modpackAuthor.set(Optional.ofNullable(Accounts.getSelectedAccount()).map(Account::getUsername).orElse(""));
versionName.set(version);
List<File> launcherJar = Launcher.getCurrentJarFiles();
if (launcherJar == null)
chkIncludeLauncher.setDisable(true);
}
canIncludeLauncher = launcherJar != null;
showFileApi = controller.getSettings().get(MODPACK_TYPE) == MODPACK_TYPE_SERVER;
private void checkValidation() {
btnNext.setDisable(!txtModpackName.validate() || !txtModpackVersion.validate() || !txtModpackAuthor.validate());
next.set(e -> onNext());
}
@FXML
@@ -90,12 +96,13 @@ public final class ModpackInfoPage extends StackPane implements WizardPage {
controller.onEnd();
return;
}
controller.getSettings().put(MODPACK_NAME, txtModpackName.getText());
controller.getSettings().put(MODPACK_VERSION, txtModpackVersion.getText());
controller.getSettings().put(MODPACK_AUTHOR, txtModpackAuthor.getText());
controller.getSettings().put(MODPACK_NAME, modpackName.get());
controller.getSettings().put(MODPACK_FILE_API, modpackFileApi.get());
controller.getSettings().put(MODPACK_VERSION, modpackVersion.get());
controller.getSettings().put(MODPACK_AUTHOR, modpackAuthor.get());
controller.getSettings().put(MODPACK_FILE, file);
controller.getSettings().put(MODPACK_DESCRIPTION, txtModpackDescription.getText());
controller.getSettings().put(MODPACK_INCLUDE_LAUNCHER, chkIncludeLauncher.isSelected());
controller.getSettings().put(MODPACK_DESCRIPTION, modpackDescription.get());
controller.getSettings().put(MODPACK_INCLUDE_LAUNCHER, includingLauncher.get());
controller.onNext();
}
@@ -114,10 +121,175 @@ public final class ModpackInfoPage extends StackPane implements WizardPage {
return i18n("modpack.wizard.step.1.title");
}
@Override
protected Skin<?> createDefaultSkin() {
return new ModpackInfoPageSkin(this);
}
public static final String MODPACK_NAME = "modpack.name";
public static final String MODPACK_FILE_API = "modpack.file_api";
public static final String MODPACK_VERSION = "modpack.version";
public static final String MODPACK_AUTHOR = "archive.author";
public static final String MODPACK_DESCRIPTION = "modpack.description";
public static final String MODPACK_INCLUDE_LAUNCHER = "modpack.include_launcher";
public static final String MODPACK_FILE = "modpack.file";
public static class ModpackInfoPageSkin extends SkinBase<ModpackInfoPage> {
private final JFXTextField txtModpackName;
private final JFXTextField txtModpackFileApi;
private final JFXTextField txtModpackAuthor;
private final JFXTextField txtModpackVersion;
public ModpackInfoPageSkin(ModpackInfoPage skinnable) {
super(skinnable);
Insets insets = new Insets(5, 0, 12, 0);
Insets componentListMargin = new Insets(16, 0, 16, 0);
ScrollPane scroll = new ScrollPane();
scroll.setFitToWidth(true);
scroll.setFitToHeight(true);
getChildren().setAll(scroll);
{
BorderPane borderPane = new BorderPane();
borderPane.setStyle("-fx-padding: 16;");
scroll.setContent(borderPane);
if (skinnable.controller.getSettings().get(MODPACK_TYPE) == MODPACK_TYPE_SERVER) {
Hyperlink hyperlink = new Hyperlink(i18n("modpack.wizard.step.initialization.server"));
hyperlink.setOnMouseClicked(e -> {
FXUtils.openLink("https://hmcl.huangyuhui.net/api/redirect/server-modpack");
});
borderPane.setTop(hyperlink);
} else {
Label label = new Label(i18n("modpack.wizard.step.initialization.warning"));
label.setWrapText(true);
label.setTextAlignment(TextAlignment.JUSTIFY);
borderPane.setTop(label);
}
{
ComponentList list = new ComponentList();
BorderPane.setMargin(list, componentListMargin);
borderPane.setCenter(list);
{
BorderPane borderPane1 = new BorderPane();
borderPane1.setLeft(new Label(i18n("modpack.wizard.step.initialization.exported_version")));
Label versionNameLabel = new Label();
versionNameLabel.textProperty().bind(skinnable.versionName);
borderPane1.setRight(versionNameLabel);
list.getContent().add(borderPane1);
}
{
txtModpackName = new JFXTextField();
txtModpackName.textProperty().bindBidirectional(skinnable.modpackName);
txtModpackName.setLabelFloat(true);
txtModpackName.setPromptText(i18n("modpack.name"));
RequiredFieldValidator validator = new RequiredFieldValidator();
validator.setMessage(i18n("modpack.not_a_valid_name"));
txtModpackName.getValidators().add(validator);
StackPane.setMargin(txtModpackName, insets);
list.getContent().add(txtModpackName);
}
if (skinnable.showFileApi) {
txtModpackFileApi = new JFXTextField();
txtModpackFileApi.textProperty().bindBidirectional(skinnable.modpackFileApi);
txtModpackFileApi.setLabelFloat(true);
txtModpackFileApi.setPromptText(i18n("modpack.file_api"));
RequiredFieldValidator validator = new RequiredFieldValidator();
txtModpackFileApi.getValidators().add(validator);
txtModpackFileApi.getValidators().add(new Validator(s -> {
try {
new URL(s).toURI();
return true;
} catch (IOException | URISyntaxException e) {
return false;
}
}));
StackPane.setMargin(txtModpackFileApi, insets);
list.getContent().add(txtModpackFileApi);
} else {
txtModpackFileApi = null;
}
{
txtModpackAuthor = new JFXTextField();
txtModpackAuthor.textProperty().bindBidirectional(skinnable.modpackAuthor);
txtModpackAuthor.setLabelFloat(true);
txtModpackAuthor.setPromptText(i18n("archive.author"));
RequiredFieldValidator validator = new RequiredFieldValidator();
txtModpackAuthor.getValidators().add(validator);
StackPane.setMargin(txtModpackAuthor, insets);
list.getContent().add(txtModpackAuthor);
}
{
txtModpackVersion = new JFXTextField();
txtModpackVersion.textProperty().bindBidirectional(skinnable.modpackVersion);
txtModpackVersion.setLabelFloat(true);
txtModpackVersion.setPromptText(i18n("archive.version"));
RequiredFieldValidator validator = new RequiredFieldValidator();
txtModpackVersion.getValidators().add(validator);
StackPane.setMargin(txtModpackVersion, insets);
list.getContent().add(txtModpackVersion);
}
{
JFXTextArea area = new JFXTextArea();
area.textProperty().bindBidirectional(skinnable.modpackDescription);
area.setLabelFloat(true);
area.setPromptText(i18n("modpack.desc"));
area.setMinHeight(400);
StackPane.setMargin(area, insets);
list.getContent().add(area);
}
if (skinnable.controller.getSettings().get(MODPACK_TYPE) == MODPACK_TYPE_HMCL) {
BorderPane borderPane1 = new BorderPane();
borderPane1.setLeft(new Label(i18n("modpack.wizard.step.initialization.include_launcher")));
list.getContent().add(borderPane1);
JFXToggleButton button = new JFXToggleButton();
button.setDisable(!skinnable.canIncludeLauncher);
button.selectedProperty().bindBidirectional(skinnable.includingLauncher);
button.setSize(8);
button.setMinHeight(16);
button.setMaxHeight(16);
borderPane1.setRight(button);
}
}
{
HBox hbox = new HBox();
hbox.setAlignment(Pos.CENTER_RIGHT);
borderPane.setBottom(hbox);
JFXButton nextButton = new JFXButton();
nextButton.onMouseClickedProperty().bind(skinnable.next);
nextButton.setPrefWidth(100);
nextButton.setPrefHeight(40);
nextButton.setButtonType(JFXButton.ButtonType.RAISED);
nextButton.setText(i18n("wizard.next"));
nextButton.getStyleClass().add("jfx-button-raised");
if (skinnable.showFileApi) {
nextButton.disableProperty().bind(Bindings.createBooleanBinding(() ->
!txtModpackName.validate() || !txtModpackVersion.validate() || !txtModpackAuthor.validate() || !txtModpackFileApi.validate(),
txtModpackName.textProperty(), txtModpackAuthor.textProperty(), txtModpackVersion.textProperty(), txtModpackFileApi.textProperty()));
} else {
nextButton.disableProperty().bind(Bindings.createBooleanBinding(() ->
!txtModpackName.validate() || !txtModpackVersion.validate() || !txtModpackAuthor.validate(),
txtModpackName.textProperty(), txtModpackAuthor.textProperty(), txtModpackVersion.textProperty()));
}
hbox.getChildren().add(nextButton);
}
}
FXUtils.smoothScrolling(scroll);
}
}
}

View File

@@ -47,7 +47,7 @@ public final class ModpackTypeSelectionPage extends StackPane implements WizardP
String type = types[i];
buttons[i].setOnMouseClicked(e -> {
controller.getSettings().put(MODPACK_TYPE, type);
controller.onFinish();
controller.onNext();
});
}
}

View File

@@ -1,69 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.*?>
<?import com.jfoenix.validation.RequiredFieldValidator?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.jackhuang.hmcl.ui.construct.ComponentList?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane">
<fx:define>
<Insets fx:id="insets" top="5" bottom="12"/>
<Insets fx:id="componetListMargin" top="16" bottom="16" />
</fx:define>
<ScrollPane fx:id="scroll" fitToWidth="true" fitToHeight="true">
<BorderPane style="-fx-padding: 16;">
<top>
<Label wrapText="true" textAlignment="JUSTIFY" text="%modpack.wizard.step.initialization.warning"/>
</top>
<center>
<ComponentList BorderPane.margin="$componetListMargin">
<BorderPane>
<left>
<Label text="%modpack.wizard.step.initialization.exported_version" />
</left>
<right>
<Label fx:id="lblVersionName"/>
</right>
</BorderPane>
<JFXTextField labelFloat="true" promptText="%modpack.name" fx:id="txtModpackName"
StackPane.margin="$insets">
<validators>
<RequiredFieldValidator message="%modpack.not_a_valid_name"/>
</validators>
</JFXTextField>
<JFXTextField labelFloat="true" promptText="%archive.author" fx:id="txtModpackAuthor"
StackPane.margin="$insets">
<validators>
<RequiredFieldValidator/>
</validators>
</JFXTextField>
<JFXTextField labelFloat="true" promptText="%archive.version" fx:id="txtModpackVersion" text="1.0"
StackPane.margin="$insets">
<validators>
<RequiredFieldValidator/>
</validators>
</JFXTextField>
<JFXTextArea labelFloat="true" promptText="%modpack.desc" fx:id="txtModpackDescription"
StackPane.margin="$insets" minHeight="400" />
<BorderPane>
<left>
<Label text="%modpack.wizard.step.initialization.include_launcher"/>
</left>
<right>
<JFXToggleButton fx:id="chkIncludeLauncher" size="7" maxHeight="10.0" minHeight="10.0"/>
</right>
</BorderPane>
</ComponentList>
</center>
<bottom>
<HBox alignment="CENTER_RIGHT">
<JFXButton fx:id="btnNext" onMouseClicked="#onNext" prefWidth="100" prefHeight="40" buttonType="RAISED"
text="%wizard.next" styleClass="jfx-button-raised"/>
</HBox>
</bottom>
</BorderPane>
</ScrollPane>
</fx:root>

View File

@@ -228,6 +228,7 @@ modpack.description=Description
modpack.enter_name=Enter a name for this modpack.
modpack.export=Export Modpack
modpack.export.as=Export Modpack As...
modpack.file_api=Modpack Download Link Prefix
modpack.files.blueprints=BuildCraft blueprints
modpack.files.config=Mod configs
modpack.files.dumps=NEI debug output
@@ -276,6 +277,7 @@ modpack.wizard.step.initialization.exported_version=Exported game version
modpack.wizard.step.initialization.include_launcher=Include the launcher
modpack.wizard.step.initialization.save=Export to...
modpack.wizard.step.initialization.warning=Before creating a modpack, you should ensure that the game can launch successfully,\nand that your Minecraft is a release version.\nDo NOT add mods which cannot be redistributed.
modpack.wizard.step.initialization.server=Click here for more information about server auto-update modpack
mods=Mods
mods.add=Install mods

View File

@@ -225,6 +225,7 @@ modpack.description=整合包描述
modpack.enter_name=給遊戲取個你喜歡的名字
modpack.export=匯出整合包
modpack.export.as=請選擇整合包類型。若你無法決定,請選擇 HMCL 類型。
modpack.file_api=整合包下載連結前綴
modpack.files.blueprints=BuildCraft 藍圖
modpack.files.config=Mod 模組設定檔案
modpack.files.dumps=NEI 調校輸出
@@ -273,6 +274,7 @@ modpack.wizard.step.initialization.exported_version=要匯出的遊戲版本
modpack.wizard.step.initialization.include_launcher=包含啟動器
modpack.wizard.step.initialization.save=選擇要匯出到的遊戲整合包位置
modpack.wizard.step.initialization.warning=在製作整合包前,請您確認您選擇的版本可以正常啟動,\n並保證您的 Minecraft 是正式版而非快照版,\n而且不應將不允許非官方途徑傳播的 Mod 模組、材質包等納入整合包。\n整合包會儲存您目前的下載來源設定
modpack.wizard.step.initialization.server=點擊此處查看有關伺服器自動更新整合包的製作教學
mods=模組管理
mods.add=新增模組

View File

@@ -226,6 +226,7 @@ modpack.description=整合包描述
modpack.enter_name=给游戏起个你喜欢的名字
modpack.export=导出整合包
modpack.export.as=请选择整合包类型。若你无法决定,请选择 HMCL 类型。
modpack.file_api=整合包下载链接前缀
modpack.files.blueprints=BuildCraft 蓝图
modpack.files.config=Mod 配置文件
modpack.files.dumps=NEI 调试输出
@@ -274,6 +275,7 @@ modpack.wizard.step.initialization.exported_version=要导出的游戏版本
modpack.wizard.step.initialization.include_launcher=包含启动器
modpack.wizard.step.initialization.save=选择要导出到的游戏整合包位置
modpack.wizard.step.initialization.warning=在制作整合包前,请您确认您选择的版本可以正常启动,\n并保证您的 Minecraft 是正式版而非快照版,\n而且不应当将不允许非官方途径传播的 Mod、材质包等纳入整合包。\n整合包会保存您目前的下载源设置
modpack.wizard.step.initialization.server=点击此处查看有关服务器自动更新整合包的制作教程
mods=模组管理
mods.add=添加模组

View File

@@ -25,6 +25,7 @@ import org.jackhuang.hmcl.mod.Modpack;
import org.jackhuang.hmcl.mod.ModpackConfiguration;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.Zipper;
@@ -48,8 +49,9 @@ public class ServerModpackExportTask extends Task<Void> {
private final String modpackAuthor;
private final String modpackVersion;
private final String modpackDescription;
private final String modpackFileApi;
public ServerModpackExportTask(DefaultGameRepository repository, String versionId, List<String> whitelist, String modpackName, String modpackAuthor, String modpackVersion, String modpackDescription, File output) {
public ServerModpackExportTask(DefaultGameRepository repository, String versionId, List<String> whitelist, String modpackName, String modpackAuthor, String modpackVersion, String modpackDescription, String modpackFileApi, File output) {
this.repository = repository;
this.versionId = versionId;
this.whitelist = whitelist;
@@ -58,6 +60,7 @@ public class ServerModpackExportTask extends Task<Void> {
this.modpackAuthor = modpackAuthor;
this.modpackVersion = modpackVersion;
this.modpackDescription = modpackDescription;
this.modpackFileApi = modpackFileApi;
onDone().register(event -> {
if (event.isFailed()) output.delete();
@@ -73,7 +76,7 @@ public class ServerModpackExportTask extends Task<Void> {
try (Zipper zip = new Zipper(output.toPath())) {
Path runDirectory = repository.getRunDirectory(versionId).toPath();
List<ModpackConfiguration.FileInformation> files = new ArrayList<>();
zip.putDirectory(runDirectory, ".minecraft", path -> {
zip.putDirectory(runDirectory, "overrides", path -> {
if (Modpack.acceptFile(path, blackList, whitelist)) {
Path file = runDirectory.resolve(path);
if (Files.isRegularFile(file)) {
@@ -99,7 +102,7 @@ public class ServerModpackExportTask extends Task<Void> {
addons.add(new ServerModpackManifest.Addon(OPTIFINE.getPatchId(), optifineVersion)));
analyzer.getVersion(FABRIC).ifPresent(fabricVersion ->
addons.add(new ServerModpackManifest.Addon(FABRIC.getPatchId(), fabricVersion)));
ServerModpackManifest manifest = new ServerModpackManifest(modpackName, modpackAuthor, modpackVersion, modpackDescription, "", files, addons);
ServerModpackManifest manifest = new ServerModpackManifest(modpackName, modpackAuthor, modpackVersion, modpackDescription, StringUtils.removeSuffix(modpackFileApi, "/"), files, addons);
zip.putTextFile(JsonUtils.GSON.toJson(manifest), "server-manifest.json");
}
}