Add GUI for building and testing modpacks.
20
build-tools/build.gradle
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile project(':launcher-builder')
|
||||||
|
compile 'org.eclipse.jetty:jetty-server:9.3.1.v20150714'
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
manifest {
|
||||||
|
attributes("Main-Class": "com.skcraft.launcher.buildtools.BuildTools")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
dependencies {
|
||||||
|
exclude(dependency('org.projectlombok:lombok'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build.dependsOn(shadowJar)
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* SK's Minecraft Launcher
|
||||||
|
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||||
|
* Please see LICENSE.txt for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
|
import com.skcraft.launcher.swing.SwingHelper;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
public class BuildDialog extends JDialog {
|
||||||
|
|
||||||
|
private final JTextField versionText = new JTextField(20);
|
||||||
|
private final JTextField manifestFilenameText = new JTextField(30);
|
||||||
|
private final JCheckBox cleanCheck = new JCheckBox("Delete previously generated files first");
|
||||||
|
@Getter
|
||||||
|
private BuildOptions options;
|
||||||
|
|
||||||
|
public BuildDialog(Window parent) {
|
||||||
|
super(parent, "Build Release", ModalityType.DOCUMENT_MODAL);
|
||||||
|
|
||||||
|
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
|
initComponents();
|
||||||
|
setResizable(false);
|
||||||
|
pack();
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
JPanel container = new JPanel();
|
||||||
|
container.setLayout(new MigLayout("insets dialog"));
|
||||||
|
|
||||||
|
container.add(new JLabel("Version:"));
|
||||||
|
container.add(versionText, "span");
|
||||||
|
|
||||||
|
container.add(new JLabel("Manifest Filename:"));
|
||||||
|
container.add(manifestFilenameText, "span");
|
||||||
|
|
||||||
|
container.add(cleanCheck, "span, gapbottom 20");
|
||||||
|
|
||||||
|
JButton buildButton = new JButton("Build...");
|
||||||
|
JButton cancelButton = new JButton("Cancel");
|
||||||
|
|
||||||
|
container.add(buildButton, "tag ok, span, split 2, sizegroup bttn");
|
||||||
|
container.add(cancelButton, "tag cancel, sizegroup bttn");
|
||||||
|
|
||||||
|
add(container, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
buildButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
returnValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cancelButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void returnValue() {
|
||||||
|
String version = versionText.getText().trim();
|
||||||
|
String manifestFilename = manifestFilenameText.getText().trim();
|
||||||
|
|
||||||
|
if (version.isEmpty()) {
|
||||||
|
SwingHelper.showErrorDialog(this, "A version string must be entered.", "Error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manifestFilename.isEmpty()) {
|
||||||
|
SwingHelper.showErrorDialog(this, "A manifest filename must be entered.", "Error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
options = new BuildOptions(version, manifestFilename, cleanCheck.isSelected());
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BuildOptions showBuildDialog(Window parent, String version, String manifestName) {
|
||||||
|
BuildDialog dialog = new BuildDialog(parent);
|
||||||
|
dialog.versionText.setText(version);
|
||||||
|
dialog.manifestFilenameText.setText(manifestName);
|
||||||
|
dialog.setVisible(true);
|
||||||
|
return dialog.getOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class BuildOptions {
|
||||||
|
private final String version;
|
||||||
|
private final String manifestFilename;
|
||||||
|
private final boolean clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
* SK's Minecraft Launcher
|
||||||
|
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||||
|
* Please see LICENSE.txt for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
|
import com.beust.jcommander.JCommander;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
import com.google.common.util.concurrent.Futures;
|
||||||
|
import com.skcraft.concurrency.ObservableFuture;
|
||||||
|
import com.skcraft.launcher.Instance;
|
||||||
|
import com.skcraft.launcher.InstanceList;
|
||||||
|
import com.skcraft.launcher.Launcher;
|
||||||
|
import com.skcraft.launcher.auth.OfflineSession;
|
||||||
|
import com.skcraft.launcher.auth.Session;
|
||||||
|
import com.skcraft.launcher.builder.BuilderConfig;
|
||||||
|
import com.skcraft.launcher.buildtools.BuildDialog.BuildOptions;
|
||||||
|
import com.skcraft.launcher.dialog.ConfigurationDialog;
|
||||||
|
import com.skcraft.launcher.dialog.ConsoleFrame;
|
||||||
|
import com.skcraft.launcher.dialog.ProgressDialog;
|
||||||
|
import com.skcraft.launcher.launch.LaunchOptions;
|
||||||
|
import com.skcraft.launcher.launch.LaunchOptions.UpdatePolicy;
|
||||||
|
import com.skcraft.launcher.persistence.Persistence;
|
||||||
|
import com.skcraft.launcher.swing.SwingHelper;
|
||||||
|
import lombok.extern.java.Log;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Log
|
||||||
|
public class BuildTools {
|
||||||
|
|
||||||
|
private static DateFormat VERSION_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||||
|
private static Pattern FILENAME_SANITIZE = Pattern.compile("[^a-z0-9_\\-\\.]+");
|
||||||
|
|
||||||
|
private final Launcher launcher;
|
||||||
|
private String configFilename = "modpack.json";
|
||||||
|
private final int port;
|
||||||
|
private final File inputDir;
|
||||||
|
private final File wwwDir;
|
||||||
|
private final File distDir;
|
||||||
|
|
||||||
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
|
public BuildTools(File baseDir, int port) throws IOException {
|
||||||
|
File launcherDir = new File(baseDir, "staging/launcher");
|
||||||
|
inputDir = baseDir;
|
||||||
|
wwwDir = new File(baseDir, "staging/www");
|
||||||
|
distDir = new File(baseDir, "dist");
|
||||||
|
|
||||||
|
this.port = port;
|
||||||
|
|
||||||
|
launcherDir.mkdirs();
|
||||||
|
wwwDir.mkdirs();
|
||||||
|
|
||||||
|
launcher = new Launcher(launcherDir);
|
||||||
|
launcher.getProperties().setProperty("packageListUrl", "http://localhost:" + port + "/packages.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateManifestName() {
|
||||||
|
File file = new File(inputDir, configFilename);
|
||||||
|
if (file.exists()) {
|
||||||
|
BuilderConfig config = Persistence.read(file, BuilderConfig.class, true);
|
||||||
|
if (config != null) {
|
||||||
|
String name = Strings.nullToEmpty(config.getName());
|
||||||
|
name = name.toLowerCase();
|
||||||
|
name = FILENAME_SANITIZE.matcher(name).replaceAll("-");
|
||||||
|
name = name.trim();
|
||||||
|
if (!name.isEmpty()) {
|
||||||
|
return name + ".json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "my_modpack.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentModpackName() {
|
||||||
|
File file = new File(inputDir, configFilename);
|
||||||
|
if (file.exists()) {
|
||||||
|
BuilderConfig config = Persistence.read(file, BuilderConfig.class, true);
|
||||||
|
if (config != null) {
|
||||||
|
return config.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instance findCurrentInstsance(List<Instance> instances) {
|
||||||
|
String expected = getCurrentModpackName();
|
||||||
|
|
||||||
|
for (Instance instance : instances) {
|
||||||
|
if (instance.getName().equals(expected)) {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startHttpServer() throws Exception {
|
||||||
|
LocalHttpServerBuilder builder = new LocalHttpServerBuilder();
|
||||||
|
builder.setBaseDir(wwwDir);
|
||||||
|
builder.setPort(port);
|
||||||
|
|
||||||
|
Server server = builder.build();
|
||||||
|
server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showMainWindow() {
|
||||||
|
final ToolsFrame frame = new ToolsFrame();
|
||||||
|
|
||||||
|
frame.getBuildButton().addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
BuildOptions options = BuildDialog.showBuildDialog(frame, generateVersionFromDate(), generateManifestName());
|
||||||
|
if (options != null) {
|
||||||
|
ConsoleFrame.showMessages();
|
||||||
|
|
||||||
|
distDir.mkdirs();
|
||||||
|
ModpackBuilder runnable = new ModpackBuilder(inputDir, distDir, options.getVersion(), options.getManifestFilename(), options.isClean());
|
||||||
|
ObservableFuture<ModpackBuilder> future = new ObservableFuture<ModpackBuilder>(launcher.getExecutor().submit(runnable), runnable);
|
||||||
|
ProgressDialog.showProgress(frame, future, "Building modpack...", "Building modpack for release...");
|
||||||
|
|
||||||
|
Futures.addCallback(future, new FutureCallback<ModpackBuilder>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(ModpackBuilder result) {
|
||||||
|
SwingHelper.browseDir(distDir, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SwingHelper.addErrorDialogCallback(frame, future);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.getTestButton().addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
ConsoleFrame.showMessages();
|
||||||
|
|
||||||
|
ModpackBuilder runnable = new ModpackBuilder(inputDir, wwwDir, generateVersionFromDate(), "staging.json", false);
|
||||||
|
ObservableFuture<ModpackBuilder> future = new ObservableFuture<ModpackBuilder>(launcher.getExecutor().submit(runnable), runnable);
|
||||||
|
ProgressDialog.showProgress(frame, future, "Preparing files...", "Preparing files for launch...");
|
||||||
|
SwingHelper.addErrorDialogCallback(frame, future);
|
||||||
|
|
||||||
|
Futures.addCallback(future, new FutureCallback<ModpackBuilder>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(ModpackBuilder result) {
|
||||||
|
launchInstance(frame);
|
||||||
|
ConsoleFrame.hideMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.getOptionsButton().addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
ConfigurationDialog configDialog = new ConfigurationDialog(frame, launcher);
|
||||||
|
configDialog.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.getClearInstanceButton().addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
DirectoryRemover remover = new DirectoryRemover(launcher.getInstancesDir());
|
||||||
|
ObservableFuture<DirectoryRemover> future = new ObservableFuture<DirectoryRemover>(launcher.getExecutor().submit(remover), remover);
|
||||||
|
ProgressDialog.showProgress(frame, future, "Removing files...", "Removing files...");
|
||||||
|
SwingHelper.addErrorDialogCallback(frame, future);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.getClearWebRootButton().addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
DirectoryRemover remover = new DirectoryRemover(wwwDir);
|
||||||
|
ObservableFuture<DirectoryRemover> future = new ObservableFuture<DirectoryRemover>(launcher.getExecutor().submit(remover), remover);
|
||||||
|
ProgressDialog.showProgress(frame, future, "Removing files...", "Removing files...");
|
||||||
|
SwingHelper.addErrorDialogCallback(frame, future);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.getOpenConsoleButton().addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
ConsoleFrame.showMessages();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchInstance(final Window window) {
|
||||||
|
String expectedName = getCurrentModpackName();
|
||||||
|
|
||||||
|
final InstanceList instanceList = launcher.getInstances();
|
||||||
|
InstanceList.Enumerator loader = instanceList.createEnumerator();
|
||||||
|
ObservableFuture<InstanceList> future = new ObservableFuture<InstanceList>(launcher.getExecutor().submit(loader), loader);
|
||||||
|
ProgressDialog.showProgress(window, future, "Loading modpacks...", "Loading modpacks...");
|
||||||
|
SwingHelper.addErrorDialogCallback(window, future);
|
||||||
|
|
||||||
|
Futures.addCallback(future, new FutureCallback<InstanceList>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(InstanceList result) {
|
||||||
|
Session session = new OfflineSession("Player");
|
||||||
|
|
||||||
|
Instance instance = findCurrentInstsance(instanceList.getInstances());
|
||||||
|
|
||||||
|
if (instance != null) {
|
||||||
|
LaunchOptions options = new LaunchOptions.Builder()
|
||||||
|
.setInstance(instance)
|
||||||
|
.setUpdatePolicy(UpdatePolicy.ALWAYS_UPDATE)
|
||||||
|
.setWindow(window)
|
||||||
|
.setSession(session)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
launcher.getLaunchSupervisor().launch(options);
|
||||||
|
} else {
|
||||||
|
SwingHelper.showErrorDialog(window,
|
||||||
|
"After generating the necessary files, it appears the modpack can't be found in the " +
|
||||||
|
"launcher. Did you change modpack.json while the launcher was launching?", "Launch Error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
ToolArguments options = new ToolArguments();
|
||||||
|
new JCommander(options, args);
|
||||||
|
|
||||||
|
final BuildTools main = new BuildTools(options.getDir(), options.getPort());
|
||||||
|
main.startHttpServer();
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
main.showMainWindow();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.log(Level.WARNING, "Load failure", t);
|
||||||
|
SwingHelper.showErrorDialog(null, "Failed to launch build tools!", "Build tools error", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateVersionFromDate() {
|
||||||
|
Date today = Calendar.getInstance().getTime();
|
||||||
|
return VERSION_DATE_FORMAT.format(today);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* SK's Minecraft Launcher
|
||||||
|
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||||
|
* Please see LICENSE.txt for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
|
import com.skcraft.concurrency.ProgressObservable;
|
||||||
|
import com.skcraft.launcher.LauncherException;
|
||||||
|
import com.skcraft.launcher.LauncherUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import static com.skcraft.launcher.LauncherUtils.checkInterrupted;
|
||||||
|
|
||||||
|
public class DirectoryRemover implements Callable<DirectoryRemover>, ProgressObservable {
|
||||||
|
|
||||||
|
private final File dir;
|
||||||
|
|
||||||
|
public DirectoryRemover(File dir) {
|
||||||
|
this.dir = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DirectoryRemover call() throws Exception {
|
||||||
|
checkInterrupted();
|
||||||
|
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
|
List<File> failures = new ArrayList<File>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
LauncherUtils.interruptibleDelete(dir, failures);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
LauncherUtils.interruptibleDelete(dir, failures);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures.size() > 0) {
|
||||||
|
throw new LauncherException(failures.size() + " failed to delete", failures.size() + " file(s) failed to delete.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getProgress() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStatus() {
|
||||||
|
return "Removing files...";
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
* Please see LICENSE.txt for license information.
|
* Please see LICENSE.txt for license information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.skcraft.launcher.staging;
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.skcraft.launcher.selfupdate.LatestVersionInfo;
|
import com.skcraft.launcher.selfupdate.LatestVersionInfo;
|
@ -4,7 +4,7 @@
|
|||||||
* Please see LICENSE.txt for license information.
|
* Please see LICENSE.txt for license information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.skcraft.launcher.staging;
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
@ -47,6 +47,7 @@ public class LocalHttpServerBuilder {
|
|||||||
ResourceHandler resourceHandler = new ResourceHandler();
|
ResourceHandler resourceHandler = new ResourceHandler();
|
||||||
resourceHandler.setDirectoriesListed(true);
|
resourceHandler.setDirectoriesListed(true);
|
||||||
resourceHandler.setResourceBase(baseDir.getAbsolutePath());
|
resourceHandler.setResourceBase(baseDir.getAbsolutePath());
|
||||||
|
resourceHandler.setMinMemoryMappedContentLength(-1); // Causes file locking on Windows
|
||||||
|
|
||||||
ContextHandler rootContext = new ContextHandler();
|
ContextHandler rootContext = new ContextHandler();
|
||||||
rootContext.setContextPath("/");
|
rootContext.setContextPath("/");
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* SK's Minecraft Launcher
|
||||||
|
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||||
|
* Please see LICENSE.txt for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
|
import com.skcraft.concurrency.ProgressObservable;
|
||||||
|
import com.skcraft.launcher.LauncherException;
|
||||||
|
import com.skcraft.launcher.LauncherUtils;
|
||||||
|
import com.skcraft.launcher.builder.PackageBuilder;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
class ModpackBuilder implements Callable<ModpackBuilder>, ProgressObservable {
|
||||||
|
|
||||||
|
private final File inputDir;
|
||||||
|
private final File outputDir;
|
||||||
|
private final String version;
|
||||||
|
private final String manifestFilename;
|
||||||
|
private final boolean clean;
|
||||||
|
|
||||||
|
public ModpackBuilder(File inputDir, File outputDir, String version, String manifestFilename, boolean clean) {
|
||||||
|
this.inputDir = inputDir;
|
||||||
|
this.outputDir = outputDir;
|
||||||
|
this.version = version;
|
||||||
|
this.manifestFilename = manifestFilename;
|
||||||
|
this.clean = clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModpackBuilder call() throws Exception {
|
||||||
|
if (clean) {
|
||||||
|
List<File> failures = new ArrayList<File>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
LauncherUtils.interruptibleDelete(outputDir, failures);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
LauncherUtils.interruptibleDelete(outputDir, failures);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures.size() > 0) {
|
||||||
|
throw new LauncherException(failures.size() + " failed to delete", "There were " + failures.size() + " failures during cleaning.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
outputDir.mkdirs();
|
||||||
|
|
||||||
|
String[] args = {
|
||||||
|
"--version", version,
|
||||||
|
"--manifest-dest", new File(outputDir, manifestFilename).getAbsolutePath(),
|
||||||
|
"-i", inputDir.getAbsolutePath(),
|
||||||
|
"-o", outputDir.getAbsolutePath()
|
||||||
|
};
|
||||||
|
PackageBuilder.main(args);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getProgress() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStatus() {
|
||||||
|
return "Building modpack...";
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
* Please see LICENSE.txt for license information.
|
* Please see LICENSE.txt for license information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.skcraft.launcher.staging;
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
import org.eclipse.jetty.server.handler.AbstractHandler;
|
@ -4,7 +4,7 @@
|
|||||||
* Please see LICENSE.txt for license information.
|
* Please see LICENSE.txt for license information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.skcraft.launcher.staging;
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
import com.beust.jcommander.internal.Lists;
|
import com.beust.jcommander.internal.Lists;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* SK's Minecraft Launcher
|
||||||
|
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||||
|
* Please see LICENSE.txt for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
|
import com.beust.jcommander.Parameter;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ToolArguments {
|
||||||
|
|
||||||
|
@Parameter(names = "--dir")
|
||||||
|
private File dir = new File(".");
|
||||||
|
|
||||||
|
@Parameter(names = "--port")
|
||||||
|
private int port = 28888;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* SK's Minecraft Launcher
|
||||||
|
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||||
|
* Please see LICENSE.txt for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.skcraft.launcher.buildtools;
|
||||||
|
|
||||||
|
import com.skcraft.launcher.swing.SwingHelper;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.java.Log;
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
@Log
|
||||||
|
@Data
|
||||||
|
public class ToolsFrame extends JFrame {
|
||||||
|
|
||||||
|
private final JButton buildButton = new JButton("Build for Release", SwingHelper.readImageIcon(ToolsFrame.class, "build.png"));
|
||||||
|
private final JButton testButton = new JButton("Run Modpack", SwingHelper.readImageIcon(ToolsFrame.class, "test.png"));
|
||||||
|
private final JButton optionsButton = new JButton("Test Launcher Options", SwingHelper.readImageIcon(ToolsFrame.class, "options.png"));
|
||||||
|
private final JButton clearInstanceButton = new JButton("Delete Instance from Test Launcher", SwingHelper.readImageIcon(ToolsFrame.class, "clean.png"));
|
||||||
|
private final JButton clearWebRootButton = new JButton("Delete Generated Modpack Files", SwingHelper.readImageIcon(ToolsFrame.class, "clean.png"));
|
||||||
|
private final JButton openConsoleButton = new JButton("Re-open Console", SwingHelper.readImageIcon(ToolsFrame.class, "log.png"));
|
||||||
|
|
||||||
|
public ToolsFrame() {
|
||||||
|
super("Modpack Build Tools");
|
||||||
|
|
||||||
|
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
initComponents();
|
||||||
|
pack();
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
SwingHelper.setIconImage(this, ToolsFrame.class, "icon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
JPanel container = new JPanel();
|
||||||
|
container.setLayout(new MigLayout("fill, insets dialog, wrap 1", "", ""));
|
||||||
|
|
||||||
|
BufferedImage header = SwingHelper.readIconImage(ToolsFrame.class, "header.png");
|
||||||
|
if (header != null) {
|
||||||
|
add(new JLabel(new ImageIcon(header)), BorderLayout.NORTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
container.add(buildButton, "grow, tag ok");
|
||||||
|
container.add(testButton, "grow, tag ok");
|
||||||
|
container.add(optionsButton, "grow, tag ok");
|
||||||
|
container.add(clearInstanceButton, "grow, tag ok");
|
||||||
|
container.add(clearWebRootButton, "grow, tag ok");
|
||||||
|
container.add(openConsoleButton, "grow, tag ok");
|
||||||
|
|
||||||
|
add(container, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
After Width: | Height: | Size: 601 B |
After Width: | Height: | Size: 899 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 647 B |
After Width: | Height: | Size: 418 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 752 B |
@ -1,3 +1,3 @@
|
|||||||
rootProject.name = 'launcher-parent'
|
rootProject.name = 'launcher-parent'
|
||||||
|
|
||||||
include 'launcher', 'launcher-fancy', 'launcher-builder', 'launcher-bootstrap', 'staging-tool'
|
include 'launcher', 'launcher-fancy', 'launcher-builder', 'launcher-bootstrap', 'build-tools'
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
apply plugin: 'com.github.johnrengelman.shadow'
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compile project(':launcher-builder')
|
|
||||||
compile 'org.eclipse.jetty:jetty-server:9.3.1.v20150714'
|
|
||||||
}
|
|
||||||
|
|
||||||
shadowJar {
|
|
||||||
dependencies {
|
|
||||||
exclude(dependency('org.projectlombok:lombok'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task createDist(type: Copy) {
|
|
||||||
dependsOn jar, shadowJar
|
|
||||||
|
|
||||||
def destDir = file("${buildDir}/dist/stagingtool")
|
|
||||||
destDir.parentFile.deleteDir()
|
|
||||||
destDir.mkdirs()
|
|
||||||
|
|
||||||
destinationDir destDir
|
|
||||||
|
|
||||||
from("${buildDir}/libs/${shadowJar.baseName}-${version}-all.jar") {
|
|
||||||
rename { f -> "staging-tool.jar" }
|
|
||||||
}
|
|
||||||
|
|
||||||
from("${projectDir}/scripts")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
build.dependsOn(shadowJar)
|
|
||||||
build.dependsOn(createDist)
|
|
@ -1,35 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>How to Use</title>
|
|
||||||
<style>
|
|
||||||
body { margin: 0; padding: 20px; }
|
|
||||||
body { font-family: Calibri, Arial, sans-serif; font-size: 12pt; }
|
|
||||||
#content { max-width: 600px; }
|
|
||||||
code { background: #ccc; font-family: Consolas, monospace; font-size: 0.9em; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="content">
|
|
||||||
<h1>How to Use</h1>
|
|
||||||
|
|
||||||
<p>This tool lets you test the modpack locally.</p>
|
|
||||||
|
|
||||||
<p>It should be a <code>stagingtool</code> folder within the modpack folder.</p>
|
|
||||||
|
|
||||||
<h2>Usage</h2>
|
|
||||||
|
|
||||||
<p>Basically, whenever you want to test the modpack, use <code>build_and_launch.bat</code> to build the modpack output files, start a local web server, and open the launcher.</p>
|
|
||||||
|
|
||||||
<p>There are other files that you can run too:</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code>build.bat</code> just builds the modpack output files only</li>
|
|
||||||
<li><code>http_server.bat</code> just runs the local web server only</li>
|
|
||||||
<li><code>launch.bat</code> just runs the staging launcher only</li>
|
|
||||||
<li><code>reset_build.bat</code> deletes all the generated modpack output files, but there is rarely a situation where you would need to do this</li>
|
|
||||||
<li><code>reset_launcher.bat</code> deletes downloaded instances, so you can use the launcher as someone who hasn't yet downloaded the modpack yet</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,3 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
java -cp staging-tool.jar com.skcraft.launcher.builder.PackageBuilder --version "%DATE% %TIME%" --input ..\ --output www --manifest-dest "www/staging.json"
|
|
@ -1,14 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
call build.bat
|
|
||||||
if ERRORLEVEL 0 goto Launch
|
|
||||||
|
|
||||||
:Launch
|
|
||||||
call launch.bat
|
|
||||||
goto End
|
|
||||||
|
|
||||||
:Error
|
|
||||||
echo "ERROR -- Modpack building failed!"
|
|
||||||
pause
|
|
||||||
|
|
||||||
:End
|
|
@ -1,2 +0,0 @@
|
|||||||
@echo off
|
|
||||||
java -cp staging-tool.jar com.skcraft.launcher.staging.StagingServer --www-dir www
|
|
@ -1,5 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
mkdir launcher
|
|
||||||
cd launcher
|
|
||||||
java -cp ..\staging-tool.jar com.skcraft.launcher.staging.StagingServer --www-dir ..\www --launch
|
|
@ -1,3 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
del /f /s /q www
|
|
@ -1,3 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
del /f /s /q launcher\instances
|
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* SK's Minecraft Launcher
|
|
||||||
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
|
||||||
* Please see LICENSE.txt for license information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.skcraft.launcher.staging;
|
|
||||||
|
|
||||||
import com.beust.jcommander.Parameter;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command line arguments that the staging tool accepts.
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class StagingArguments {
|
|
||||||
|
|
||||||
@Parameter(names = "--www-dir")
|
|
||||||
private File wwwDir = new File(".");
|
|
||||||
|
|
||||||
@Parameter(names = "--port")
|
|
||||||
private Integer port = 28888;
|
|
||||||
|
|
||||||
@Parameter(names = "--launch")
|
|
||||||
private boolean launch = false;
|
|
||||||
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* SK's Minecraft Launcher
|
|
||||||
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
|
||||||
* Please see LICENSE.txt for license information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.skcraft.launcher.staging;
|
|
||||||
|
|
||||||
import com.beust.jcommander.JCommander;
|
|
||||||
import com.skcraft.launcher.Launcher;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class StagingServer {
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
StagingArguments options = new StagingArguments();
|
|
||||||
new JCommander(options, args);
|
|
||||||
|
|
||||||
File wwwDir = options.getWwwDir();
|
|
||||||
wwwDir.mkdirs();
|
|
||||||
|
|
||||||
LocalHttpServerBuilder builder = new LocalHttpServerBuilder();
|
|
||||||
builder.setBaseDir(wwwDir);
|
|
||||||
builder.setPort(options.getPort());
|
|
||||||
|
|
||||||
Server server = builder.build();
|
|
||||||
server.start();
|
|
||||||
|
|
||||||
if (options.isLaunch()) {
|
|
||||||
Launcher.main(new String[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#
|
|
||||||
# SK's Minecraft Launcher
|
|
||||||
# Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
|
||||||
# Please see LICENSE.txt for license information.
|
|
||||||
#
|
|
||||||
|
|
||||||
version=${project.version}
|
|
||||||
agentName=Minecraft
|
|
||||||
offlinePlayerName=Player
|
|
||||||
|
|
||||||
versionManifestUrl=https://s3.amazonaws.com/Minecraft.Download/versions/%1$s/%1$s.json
|
|
||||||
librariesSource=https://libraries.minecraft.net/
|
|
||||||
jarUrl=http://s3.amazonaws.com/Minecraft.Download/versions/%1$s/%1$s.jar
|
|
||||||
assetsIndexUrl=https://s3.amazonaws.com/Minecraft.Download/indexes/%s.json
|
|
||||||
assetsSource=http://resources.download.minecraft.net/
|
|
||||||
yggdrasilAuthUrl=https://authserver.mojang.com/authenticate
|
|
||||||
resetPasswordUrl=https://minecraft.net/resetpassword
|
|
||||||
|
|
||||||
newsUrl=http://localhost:28888/news.html
|
|
||||||
packageListUrl=http://localhost:28888/packages.json
|
|
||||||
selfUpdateUrl=http://localhost:28888/latest.json
|
|