choosing files for modpack
This commit is contained in:
@@ -26,7 +26,7 @@ if (!hasProperty('mainClass')) {
|
||||
ext.mainClass = 'org.jackhuang.hellominecraft.launcher.Main'
|
||||
}
|
||||
|
||||
def buildnumber = System.getenv("BUILD_NUMBER") == null ? ".7" : "."+System.getenv("BUILD_NUMBER")
|
||||
def buildnumber = System.getenv("BUILD_NUMBER") == null ? ".8" : "."+System.getenv("BUILD_NUMBER")
|
||||
|
||||
String mavenGroupId = 'HMCL'
|
||||
String mavenVersion = '2.3.5' + buildnumber
|
||||
|
||||
@@ -47,7 +47,6 @@ import org.jackhuang.hellominecraft.lookandfeel.HelloMinecraftLookAndFeel;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import rx.concurrency.Schedulers;
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersion;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersions;
|
||||
import rx.Observable;
|
||||
@@ -119,16 +120,9 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean downloadMinecraftJarTo(String id, File mvt) {
|
||||
public Task downloadMinecraftJarTo(String id, File mvt) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".jar"))
|
||||
.start())
|
||||
return true;
|
||||
else {
|
||||
mvt.delete();
|
||||
return false;
|
||||
}
|
||||
return new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,10 +20,10 @@ package org.jackhuang.hellominecraft.launcher.core.mod;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
@@ -32,10 +32,13 @@ import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.functions.BiFunction;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.ZipEngine;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftVersionRequest;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.ResultProgressHandle;
|
||||
|
||||
/**
|
||||
* A mod pack(*.zip) includes these things:
|
||||
@@ -57,61 +60,112 @@ import org.jackhuang.hellominecraft.utils.version.MinecraftVersionRequest;
|
||||
*/
|
||||
public final class ModpackManager {
|
||||
|
||||
public static void install(File input, IMinecraftService service, String id) throws IOException, FileAlreadyExistsException {
|
||||
File versions = new File(service.baseDirectory(), "versions");
|
||||
File oldFile = new File(versions, "minecraft"), newFile = null;
|
||||
if (oldFile.exists()) {
|
||||
newFile = new File(versions, "minecraft-" + System.currentTimeMillis());
|
||||
if (newFile.isDirectory())
|
||||
FileUtils.deleteDirectory(newFile);
|
||||
else if (newFile.isFile())
|
||||
newFile.delete();
|
||||
oldFile.renameTo(newFile);
|
||||
}
|
||||
public static Task install(File input, IMinecraftService service, String id) {
|
||||
return new Task() {
|
||||
Collection<Task> c = new ArrayList<>();
|
||||
|
||||
File preVersion = new File(versions, id), preVersionRenamed = null;
|
||||
if (preVersion.exists()) {
|
||||
String preId = id + "-" + System.currentTimeMillis();
|
||||
preVersion.renameTo(preVersionRenamed = new File(versions, preId));
|
||||
new File(preVersionRenamed, id + ".json").renameTo(new File(preVersionRenamed, preId + ".json"));
|
||||
new File(preVersionRenamed, id + ".jar").renameTo(new File(preVersionRenamed, preId + ".jar"));
|
||||
}
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
File versions = new File(service.baseDirectory(), "versions");
|
||||
File oldFile = new File(versions, "minecraft"), newFile = null;
|
||||
if (oldFile.exists()) {
|
||||
newFile = new File(versions, "minecraft-" + System.currentTimeMillis());
|
||||
if (newFile.isDirectory())
|
||||
FileUtils.deleteDirectory(newFile);
|
||||
else if (newFile.isFile())
|
||||
newFile.delete();
|
||||
oldFile.renameTo(newFile);
|
||||
}
|
||||
|
||||
try {
|
||||
AtomicInteger b = new AtomicInteger(0);
|
||||
HMCLog.log("Decompressing modpack");
|
||||
Compressor.unzip(input, versions, t -> {
|
||||
if (t.equals("minecraft/pack.json"))
|
||||
b.incrementAndGet();
|
||||
return true;
|
||||
}, true);
|
||||
if (b.get() < 1)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_json"));
|
||||
File nowFile = new File(versions, id);
|
||||
oldFile.renameTo(nowFile);
|
||||
File preVersion = new File(versions, id), preVersionRenamed = null;
|
||||
if (preVersion.exists()) {
|
||||
HMCLog.log("Backing up the game");
|
||||
String preId = id + "-" + System.currentTimeMillis();
|
||||
preVersion.renameTo(preVersionRenamed = new File(versions, preId));
|
||||
new File(preVersionRenamed, id + ".json").renameTo(new File(preVersionRenamed, preId + ".json"));
|
||||
new File(preVersionRenamed, id + ".jar").renameTo(new File(preVersionRenamed, preId + ".jar"));
|
||||
}
|
||||
|
||||
File json = new File(nowFile, "pack.json");
|
||||
MinecraftVersion mv = C.gson.fromJson(FileUtils.readFileToString(json), MinecraftVersion.class);
|
||||
if (mv.jar == null)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_jar"));
|
||||
service.download().downloadMinecraftJarTo(mv.jar, new File(nowFile, id + ".jar"));
|
||||
mv.jar = null;
|
||||
FileUtils.writeStringToFile(json, C.gsonPrettyPrinting.toJson(mv));
|
||||
json.renameTo(new File(nowFile, id + ".json"));
|
||||
try {
|
||||
AtomicInteger b = new AtomicInteger(0);
|
||||
HMCLog.log("Decompressing modpack");
|
||||
Compressor.unzip(input, versions, t -> {
|
||||
if (t.equals("minecraft/pack.json"))
|
||||
b.incrementAndGet();
|
||||
return true;
|
||||
}, true);
|
||||
if (b.get() < 1)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_json"));
|
||||
File nowFile = new File(versions, id);
|
||||
oldFile.renameTo(nowFile);
|
||||
|
||||
if (preVersionRenamed != null) {
|
||||
File presaves = new File(preVersionRenamed, "saves");
|
||||
File saves = new File(nowFile, "saves");
|
||||
if (presaves.exists()) {
|
||||
FileUtils.deleteDirectory(saves);
|
||||
FileUtils.copyDirectory(presaves, saves);
|
||||
File json = new File(nowFile, "pack.json");
|
||||
MinecraftVersion mv = C.gson.fromJson(FileUtils.readFileToString(json), MinecraftVersion.class);
|
||||
if (mv.jar == null)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_jar"));
|
||||
|
||||
c.add(service.download().downloadMinecraftJarTo(mv.jar, new File(nowFile, id + ".jar")));
|
||||
mv.jar = null;
|
||||
FileUtils.writeStringToFile(json, C.gsonPrettyPrinting.toJson(mv));
|
||||
json.renameTo(new File(nowFile, id + ".json"));
|
||||
|
||||
if (preVersionRenamed != null) {
|
||||
HMCLog.log("Restoring saves");
|
||||
File presaves = new File(preVersionRenamed, "saves");
|
||||
File saves = new File(nowFile, "saves");
|
||||
if (presaves.exists()) {
|
||||
FileUtils.deleteDirectory(saves);
|
||||
FileUtils.copyDirectory(presaves, saves);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
FileUtils.deleteDirectoryQuietly(oldFile);
|
||||
if (newFile != null)
|
||||
newFile.renameTo(oldFile);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
FileUtils.deleteDirectoryQuietly(oldFile);
|
||||
if (newFile != null)
|
||||
newFile.renameTo(oldFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("modpack.install.task");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public static final List<String> MODPACK_BLACK_LIST = Arrays.asList(new String[] { "usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "TCNodeTracker", "screenshots", "natives", "native" });
|
||||
public static final List<String> MODPACK_SUGGESTED_BLACK_LIST = Arrays.asList(new String[] { "saves", "servers.dat", "options.txt", "optionsshaders.txt", "mods/VoxelMods" });
|
||||
|
||||
/**
|
||||
* < String, Boolean, Boolean >: Folder/File name, Is Directory,
|
||||
* Return 0: non blocked, 1: non shown, 2: suggested, checked.
|
||||
*/
|
||||
public static final BiFunction<String, Boolean, Integer> MODPACK_PREDICATE = (String x, Boolean y) -> {
|
||||
if (ModpackManager.MODPACK_BLACK_LIST_PREDICATE.apply(x, y))
|
||||
return 1;
|
||||
if (ModpackManager.MODPACK_SUGGESTED_BLACK_LIST_PREDICATE.apply(x, y))
|
||||
return 2;
|
||||
return 0;
|
||||
};
|
||||
|
||||
public static final BiFunction<String, Boolean, Boolean> MODPACK_BLACK_LIST_PREDICATE = modpackPredicateMaker(MODPACK_BLACK_LIST);
|
||||
public static final BiFunction<String, Boolean, Boolean> MODPACK_SUGGESTED_BLACK_LIST_PREDICATE = modpackPredicateMaker(MODPACK_SUGGESTED_BLACK_LIST);
|
||||
|
||||
private static BiFunction<String, Boolean, Boolean> modpackPredicateMaker(List<String> l) {
|
||||
return (String x, Boolean y) -> {
|
||||
for (String s : l)
|
||||
if (y) {
|
||||
if (x.startsWith(s + "/"))
|
||||
return true;
|
||||
} else if (x.equals(s))
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,7 +179,7 @@ public final class ModpackManager {
|
||||
* @throws IOException if create tmp directory failed
|
||||
*/
|
||||
public static void export(File output, IMinecraftProvider provider, String version, List<String> blacklist) throws IOException, GameException {
|
||||
ArrayList<String> b = new ArrayList<>(Arrays.asList(new String[] { "usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "TCNodeTracker" }));
|
||||
ArrayList<String> b = new ArrayList<>(MODPACK_BLACK_LIST);
|
||||
if (blacklist != null)
|
||||
b.addAll(blacklist);
|
||||
HMCLog.log("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersion;
|
||||
import rx.Observable;
|
||||
|
||||
@@ -39,7 +40,7 @@ public abstract class IMinecraftDownloadService extends IMinecraftBasicService {
|
||||
|
||||
public abstract boolean downloadMinecraftJar(String id);
|
||||
|
||||
public abstract boolean downloadMinecraftJarTo(String id, File f);
|
||||
public abstract Task downloadMinecraftJarTo(String id, File f);
|
||||
|
||||
public abstract boolean downloadMinecraftVersionJson(String id);
|
||||
|
||||
|
||||
@@ -116,11 +116,12 @@ public final class Profile {
|
||||
public String getSelectedVersion() {
|
||||
String v = selectedMinecraftVersion;
|
||||
if (StrUtils.isBlank(v) || service.version().getVersionById(v) == null) {
|
||||
v = service.version().getOneVersion().id;
|
||||
if (v != null)
|
||||
if (service.version().getVersionCount() > 0)
|
||||
v = service.version().getOneVersion().id;
|
||||
if (StrUtils.isNotBlank(v))
|
||||
setSelectedMinecraftVersion(v);
|
||||
}
|
||||
return v;
|
||||
return StrUtils.isBlank(v) ? null : v;
|
||||
}
|
||||
|
||||
public transient final EventHandler<String> selectedVersionChangedEvent = new EventHandler<>(this);
|
||||
|
||||
@@ -1149,31 +1149,14 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
|
||||
if (fc.getSelectedFile() == null)
|
||||
return;
|
||||
String suggestedModpackId = JOptionPane.showInputDialog("Please enter your favourite game name", FileUtils.getBaseName(fc.getSelectedFile().getName()));
|
||||
TaskWindow.getInstance().addTask(new TaskRunnable(C.i18n("modpack.install.task"), () -> {
|
||||
try {
|
||||
ModpackManager.install(fc.getSelectedFile(), getProfile().service(), suggestedModpackId);
|
||||
} catch (IOException ex) {
|
||||
MessageBox.Show(C.i18n("modpack.install_error"));
|
||||
HMCLog.err("Failed to install modpack", ex);
|
||||
}
|
||||
})).start();
|
||||
TaskWindow.getInstance().addTask(ModpackManager.install(fc.getSelectedFile(), getProfile().service(), suggestedModpackId)).start();
|
||||
refreshVersions();
|
||||
}//GEN-LAST:event_btnImportModpackActionPerformed
|
||||
|
||||
private void btnExportModpackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExportModpackActionPerformed
|
||||
Map settings = (Map) WizardDisplayer.showWizard(new ModpackWizard(getProfile().service().version()).createWizard());
|
||||
if (settings != null)
|
||||
TaskWindow.getInstance().addTask(new TaskRunnable(C.i18n("modpack.save.task"),
|
||||
() -> {
|
||||
try {
|
||||
ModpackManager.export(new File((String) settings.get(ModpackInitializationPanel.KEY_MODPACK_LOCATION)),
|
||||
getProfile().service().version(),
|
||||
(String) settings.get(ModpackInitializationPanel.KEY_GAME_VERSION),
|
||||
((Boolean) settings.get(ModpackInitializationPanel.KEY_SAVE) == false) ? Arrays.asList("saves") : null);
|
||||
} catch (IOException | GameException ex) {
|
||||
MessageBox.Show(C.i18n("modpack.export_error"));
|
||||
HMCLog.err("Failed to export modpack", ex);
|
||||
}
|
||||
})).start();
|
||||
if (getProfile().service().version().getVersionCount() <= 0)
|
||||
return;
|
||||
WizardDisplayer.showWizard(new ModpackWizard(getProfile().service()).createWizard());
|
||||
}//GEN-LAST:event_btnExportModpackActionPerformed
|
||||
|
||||
// </editor-fold>
|
||||
@@ -1229,7 +1212,6 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
|
||||
cboJavaItemStateChanged(new ItemEvent(cboJava, 0, cboJava.getSelectedItem(), ItemEvent.SELECTED));
|
||||
|
||||
loadVersions();
|
||||
loadMinecraftVersion();
|
||||
}
|
||||
|
||||
void loadVersions() {
|
||||
@@ -1248,6 +1230,8 @@ public final class GameSettingsPanel extends AnimatedPanel implements DropTarget
|
||||
cboVersions.setSelectedIndex(index);
|
||||
|
||||
reloadMods();
|
||||
|
||||
loadMinecraftVersion();
|
||||
}
|
||||
|
||||
void loadMinecraftVersion() {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="400" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="1" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTree" name="jTree1">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* 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 {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.views.modpack;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import org.jackhuang.hellominecraft.utils.functions.BiFunction;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.views.checktree.CheckBoxTreeCellRenderer;
|
||||
import org.jackhuang.hellominecraft.utils.views.checktree.CheckBoxTreeNode;
|
||||
import org.jackhuang.hellominecraft.utils.views.checktree.CheckBoxTreeNodeSelectionListener;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.WizardController;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ModpackFileSelectionPanel extends javax.swing.JPanel {
|
||||
|
||||
private final WizardController controller;
|
||||
private final Map wizardData;
|
||||
private final BiFunction<String, Boolean, Integer> blackList;
|
||||
private final Set<String> bannedFiles = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Creates new form ModpackFileSelectionPanel
|
||||
*
|
||||
* @param blackList Return 0: non blocked, 1: non shown, 2: suggested,
|
||||
* checked
|
||||
*/
|
||||
public ModpackFileSelectionPanel(WizardController controller, Map wizardData, File gameDir, BiFunction<String, Boolean, Integer> blackList) {
|
||||
initComponents();
|
||||
|
||||
this.controller = controller;
|
||||
this.wizardData = wizardData;
|
||||
this.blackList = blackList;
|
||||
|
||||
CheckBoxTreeNode root = create(gameDir, "minecraft");
|
||||
|
||||
jTree1.setModel(new DefaultTreeModel(root));
|
||||
jTree1.setCellRenderer(new CheckBoxTreeCellRenderer());
|
||||
jTree1.addMouseListener(new CheckBoxTreeNodeSelectionListener());
|
||||
|
||||
wizardData.put("blackList", root);
|
||||
}
|
||||
|
||||
CheckBoxTreeNode create(File file, String basePath) {
|
||||
int state = 0;
|
||||
if (basePath.length() > "minecraft/".length())
|
||||
if ((state = blackList.apply(basePath.substring("minecraft/".length()) + (file.isDirectory() ? "/" : ""), file.isDirectory())) == 1)
|
||||
return null;
|
||||
CheckBoxTreeNode node = new CheckBoxTreeNode(FileUtils.getName(basePath));
|
||||
if (state == 2)
|
||||
node.setSelected(true);
|
||||
|
||||
if (file.isDirectory()) {
|
||||
File[] f = file.listFiles();
|
||||
for (File subFile : f) {
|
||||
CheckBoxTreeNode subNode = create(subFile, basePath + "/" + subFile.getName());
|
||||
if (subNode != null) {
|
||||
subNode.setSelected(subNode.isSelected() | node.isSelected());
|
||||
node.add(subNode);
|
||||
}
|
||||
}
|
||||
if (!node.children().hasMoreElements())
|
||||
return null;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is
|
||||
* always regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
jTree1 = new javax.swing.JTree();
|
||||
|
||||
jScrollPane1.setViewportView(jTree1);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JTree jTree1;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -29,7 +29,6 @@
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblGameVersion" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="chkSave" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="67" max="32767" attributes="0"/>
|
||||
@@ -44,7 +43,7 @@
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="92" max="32767" attributes="0"/>
|
||||
<EmptySpace pref="120" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblModpackLocation" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboModpackLocation" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
@@ -56,8 +55,6 @@
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cboGameVersion" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="chkSave" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@@ -101,14 +98,6 @@
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<String>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkSave">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="允许导出存档"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="chkSaveItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
|
||||
@@ -32,7 +32,6 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
|
||||
public static final String KEY_GAME_VERSION = "gameVersion";
|
||||
public static final String KEY_MODPACK_LOCATION = "modpackLocation";
|
||||
public static final String KEY_SAVE = "save";
|
||||
|
||||
private final WizardController controller;
|
||||
private final Map wizardData;
|
||||
@@ -47,18 +46,15 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
this.wizardData = wizardData;
|
||||
wizardData.put(KEY_GAME_VERSION, versions);
|
||||
|
||||
wizardData.put(KEY_SAVE, false);
|
||||
|
||||
configureComboContents();
|
||||
controller.setProblem(C.i18n("modpack.not_a_valid_location"));
|
||||
|
||||
controller.setForwardNavigationMode(WizardController.MODE_CAN_FINISH);
|
||||
}
|
||||
|
||||
private void configureComboContents() {
|
||||
String[] versions = (String[]) wizardData.get(KEY_GAME_VERSION);
|
||||
cboGameVersion.setModel(new DefaultComboBoxModel<>(versions));
|
||||
|
||||
if (versions.length > 0)
|
||||
wizardData.put(KEY_GAME_VERSION, versions[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +72,6 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
cboModpackLocation = new javax.swing.JButton();
|
||||
lblGameVersion = new javax.swing.JLabel();
|
||||
cboGameVersion = new javax.swing.JComboBox<>();
|
||||
chkSave = new javax.swing.JCheckBox();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
|
||||
lblModpackLocation.setText(C.i18n("modpack.save")); // NOI18N
|
||||
@@ -102,13 +97,6 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
chkSave.setText("允许导出存档");
|
||||
chkSave.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
chkSaveItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel1.setText(C.i18n("modpack.warning")); // NOI18N
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
@@ -127,7 +115,6 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblGameVersion)
|
||||
.addComponent(chkSave)
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(0, 67, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
@@ -137,7 +124,7 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 92, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 120, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblModpackLocation)
|
||||
.addComponent(cboModpackLocation))
|
||||
@@ -147,8 +134,6 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
.addComponent(lblGameVersion)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cboGameVersion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(chkSave)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
@@ -173,10 +158,6 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
controller.setProblem(null);
|
||||
}//GEN-LAST:event_txtModpackLocationCaretUpdate
|
||||
|
||||
private void chkSaveItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_chkSaveItemStateChanged
|
||||
wizardData.put(KEY_SAVE, chkSave.isSelected());
|
||||
}//GEN-LAST:event_chkSaveItemStateChanged
|
||||
|
||||
private void cboGameVersionItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboGameVersionItemStateChanged
|
||||
wizardData.put(KEY_GAME_VERSION, cboGameVersion.getSelectedItem());
|
||||
}//GEN-LAST:event_cboGameVersionItemStateChanged
|
||||
@@ -184,7 +165,6 @@ public class ModpackInitializationPanel extends javax.swing.JPanel {
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JComboBox<String> cboGameVersion;
|
||||
private javax.swing.JButton cboModpackLocation;
|
||||
private javax.swing.JCheckBox chkSave;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel lblGameVersion;
|
||||
private javax.swing.JLabel lblModpackLocation;
|
||||
|
||||
@@ -17,14 +17,29 @@
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.views.modpack;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.JComponent;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.mod.ModpackManager;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.views.checktree.CheckBoxTreeNode;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.DeferredWizardResult;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.ResultProgressHandle;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.Summary;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.WizardBranchController;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.WizardController;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.WizardException;
|
||||
import org.jackhuang.hellominecraft.utils.views.wizard.spi.WizardPanelProvider;
|
||||
|
||||
/**
|
||||
@@ -33,18 +48,62 @@ import org.jackhuang.hellominecraft.utils.views.wizard.spi.WizardPanelProvider;
|
||||
*/
|
||||
public class ModpackWizard extends WizardBranchController {
|
||||
|
||||
public ModpackWizard(IMinecraftProvider provider) {
|
||||
super(new WizardPanelProvider(C.i18n("modpack.wizard"), new String[] { C.i18n("modpack.wizard.step.1") }, new String[] { C.i18n("modpack.wizard.step.1.title") }) {
|
||||
static void process(CheckBoxTreeNode node, String basePath, List<String> list) {
|
||||
if (node.isSelected()) {
|
||||
if (basePath.length() > "minecraft/".length())
|
||||
list.add(basePath.substring("minecraft/".length()));
|
||||
return;
|
||||
}
|
||||
Enumeration<CheckBoxTreeNode> e = node.children();
|
||||
for (; e.hasMoreElements();) {
|
||||
CheckBoxTreeNode n = e.nextElement();
|
||||
process(n, basePath + "/" + n.getUserObject(), list);
|
||||
}
|
||||
}
|
||||
|
||||
public ModpackWizard(IMinecraftService service) {
|
||||
super(new WizardPanelProvider(C.i18n("modpack.wizard"), new String[] { C.i18n("modpack.wizard.step.1"), C.i18n("modpack.wizard.step.2") }, new String[] { C.i18n("modpack.wizard.step.1.title"), C.i18n("modpack.wizard.step.2.title") }) {
|
||||
|
||||
@Override
|
||||
protected Object finish(Map settings) throws WizardException {
|
||||
return new DeferredWizardResult(false) {
|
||||
@Override
|
||||
public void start(Map settings, ResultProgressHandle progress) {
|
||||
progress.setBusy("Processing modpack");
|
||||
ArrayList<String> blackList = new ArrayList<>(ModpackManager.MODPACK_BLACK_LIST);
|
||||
CheckBoxTreeNode root = (CheckBoxTreeNode) settings.get("blackList");
|
||||
process(root, "minecraft", blackList);
|
||||
try {
|
||||
File loc = new File((String) settings.get(ModpackInitializationPanel.KEY_MODPACK_LOCATION));
|
||||
ModpackManager.export(loc,
|
||||
service.version(),
|
||||
(String) settings.get(ModpackInitializationPanel.KEY_GAME_VERSION),
|
||||
blackList);
|
||||
progress.finished(Summary.create(C.i18n("modpack.export_finished") + ": " + loc.getAbsolutePath(), null));
|
||||
} catch (IOException | GameException ex) {
|
||||
HMCLog.err("Failed to export modpack", ex);
|
||||
progress.failed(C.i18n("modpack.export_error") + ": " + ex.getClass().getName() + ", " + ex.getLocalizedMessage(), true);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createPanel(WizardController controller, String id, Map settings) {
|
||||
switch (indexOfStep(id)) {
|
||||
case 0:
|
||||
String[] s = new String[provider.getVersionCount()];
|
||||
Iterator<MinecraftVersion> it = provider.getVersions().iterator();
|
||||
String[] s = new String[service.version().getVersionCount()];
|
||||
Iterator<MinecraftVersion> it = service.version().getVersions().iterator();
|
||||
for (int i = 0; i < s.length; i++)
|
||||
s[i] = it.next().id;
|
||||
|
||||
controller.setForwardNavigationMode(WizardController.MODE_CAN_CONTINUE);
|
||||
|
||||
return new ModpackInitializationPanel(controller, settings, s);
|
||||
case 1:
|
||||
controller.setForwardNavigationMode(WizardController.MODE_CAN_FINISH);
|
||||
|
||||
return new ModpackFileSelectionPanel(controller, settings, service.baseDirectory(), ModpackManager.MODPACK_PREDICATE);
|
||||
default:
|
||||
throw new IllegalArgumentException(id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user