diff --git a/build-tools/build.gradle b/build-tools/build.gradle new file mode 100644 index 0000000..4259bbc --- /dev/null +++ b/build-tools/build.gradle @@ -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) diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/BuildDialog.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/BuildDialog.java new file mode 100644 index 0000000..91ad7e6 --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/BuildDialog.java @@ -0,0 +1,105 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham 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; + } + +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/BuildTools.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/BuildTools.java new file mode 100644 index 0000000..75a3278 --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/BuildTools.java @@ -0,0 +1,282 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham 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 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 future = new ObservableFuture(launcher.getExecutor().submit(runnable), runnable); + ProgressDialog.showProgress(frame, future, "Building modpack...", "Building modpack for release..."); + + Futures.addCallback(future, new FutureCallback() { + @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 future = new ObservableFuture(launcher.getExecutor().submit(runnable), runnable); + ProgressDialog.showProgress(frame, future, "Preparing files...", "Preparing files for launch..."); + SwingHelper.addErrorDialogCallback(frame, future); + + Futures.addCallback(future, new FutureCallback() { + @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 future = new ObservableFuture(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 future = new ObservableFuture(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 future = new ObservableFuture(launcher.getExecutor().submit(loader), loader); + ProgressDialog.showProgress(window, future, "Loading modpacks...", "Loading modpacks..."); + SwingHelper.addErrorDialogCallback(window, future); + + Futures.addCallback(future, new FutureCallback() { + @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); + } + +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/DirectoryRemover.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/DirectoryRemover.java new file mode 100644 index 0000000..1ba9072 --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/DirectoryRemover.java @@ -0,0 +1,60 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham 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, ProgressObservable { + + private final File dir; + + public DirectoryRemover(File dir) { + this.dir = dir; + } + + @Override + public DirectoryRemover call() throws Exception { + checkInterrupted(); + + Thread.sleep(1000); + + List failures = new ArrayList(); + + 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..."; + } +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/LatestHandler.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/LatestHandler.java new file mode 100644 index 0000000..d4ecc0b --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/LatestHandler.java @@ -0,0 +1,41 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham and contributors + * Please see LICENSE.txt for license information. + */ + +package com.skcraft.launcher.buildtools; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.skcraft.launcher.selfupdate.LatestVersionInfo; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.handler.AbstractHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URL; + +public class LatestHandler extends AbstractHandler { + + private final ObjectMapper mapper; + + public LatestHandler(ObjectMapper mapper) { + this.mapper = mapper; + } + + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + response.setContentType("text/plain; charset=utf-8"); + response.setStatus(HttpServletResponse.SC_OK); + + LatestVersionInfo info = new LatestVersionInfo(); + info.setVersion("0.0.0"); + info.setUrl(new URL("http://localhost")); + mapper.writeValue(response.getWriter(), info); + + baseRequest.setHandled(true); + } + +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/LocalHttpServerBuilder.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/LocalHttpServerBuilder.java new file mode 100644 index 0000000..bb78ad3 --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/LocalHttpServerBuilder.java @@ -0,0 +1,78 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham and contributors + * Please see LICENSE.txt for license information. + */ + +package com.skcraft.launcher.buildtools; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.server.handler.ResourceHandler; +import org.eclipse.jetty.server.handler.gzip.GzipHandler; + +import java.io.File; + +public class LocalHttpServerBuilder { + + private File baseDir = new File("."); + private int port = 28888; + + public File getBaseDir() { + return baseDir; + } + + public LocalHttpServerBuilder setBaseDir(File baseDir) { + this.baseDir = baseDir; + return this; + } + + public int getPort() { + return port; + } + + public LocalHttpServerBuilder setPort(int port) { + this.port = port; + return this; + } + + public Server build() throws Exception { + Server server = new Server(port); + + ObjectMapper mapper = new ObjectMapper(); + + ResourceHandler resourceHandler = new ResourceHandler(); + resourceHandler.setDirectoriesListed(true); + resourceHandler.setResourceBase(baseDir.getAbsolutePath()); + resourceHandler.setMinMemoryMappedContentLength(-1); // Causes file locking on Windows + + ContextHandler rootContext = new ContextHandler(); + rootContext.setContextPath("/"); + rootContext.setHandler(resourceHandler); + + ContextHandler packagesContext = new ContextHandler("/packages.json"); + packagesContext.setAllowNullPathInfo(true); + packagesContext.setHandler(new PackagesHandler(mapper, baseDir)); + + ContextHandler latestContext = new ContextHandler("/latest.json"); + latestContext.setAllowNullPathInfo(true); + latestContext.setHandler(new LatestHandler(mapper)); + + ContextHandler newsContext = new ContextHandler("/news.html"); + newsContext.setAllowNullPathInfo(true); + newsContext.setHandler(new NewsHandler()); + + ContextHandlerCollection contexts = new ContextHandlerCollection(); + contexts.setHandlers(new Handler[]{packagesContext, latestContext, newsContext, rootContext}); + + GzipHandler gzip = new GzipHandler(); + server.setHandler(gzip); + gzip.setHandler(contexts); + + return server; + } + +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/ModpackBuilder.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/ModpackBuilder.java new file mode 100644 index 0000000..3f0764a --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/ModpackBuilder.java @@ -0,0 +1,76 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham 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, 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 failures = new ArrayList(); + + 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..."; + } +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/NewsHandler.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/NewsHandler.java new file mode 100644 index 0000000..83e9338 --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/NewsHandler.java @@ -0,0 +1,39 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham and contributors + * Please see LICENSE.txt for license information. + */ + +package com.skcraft.launcher.buildtools; + +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.handler.AbstractHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +public class NewsHandler extends AbstractHandler { + + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + response.setContentType("text/html; charset=utf-8"); + response.setStatus(HttpServletResponse.SC_OK); + + PrintWriter writer = response.getWriter(); + writer.write(""); + writer.write(""); + writer.write(""); + writer.write("Staging Tool"); + writer.write(""); + writer.write(""); + writer.write("

Welcome to the staging tool!

"); + writer.write(""); + writer.write(""); + + baseRequest.setHandled(true); + } + +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/PackagesHandler.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/PackagesHandler.java new file mode 100644 index 0000000..797b111 --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/PackagesHandler.java @@ -0,0 +1,66 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham and contributors + * Please see LICENSE.txt for license information. + */ + +package com.skcraft.launcher.buildtools; + +import com.beust.jcommander.internal.Lists; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.skcraft.launcher.model.modpack.Manifest; +import com.skcraft.launcher.model.modpack.ManifestInfo; +import com.skcraft.launcher.model.modpack.PackageList; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.handler.AbstractHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.List; + +public class PackagesHandler extends AbstractHandler { + + private final ObjectMapper mapper; + private final File baseDir; + + public PackagesHandler(ObjectMapper mapper, File baseDir) { + this.mapper = mapper; + this.baseDir = baseDir; + } + + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + response.setContentType("text/plain; charset=utf-8"); + response.setStatus(HttpServletResponse.SC_OK); + + List packages = Lists.newArrayList(); + PackageList packageList = new PackageList(); + packageList.setPackages(packages); + + File[] files = baseDir.listFiles(new PackageFileFilter()); + if (files != null) { + for (File file : files) { + Manifest manifest = mapper.readValue(file, Manifest.class); + ManifestInfo info = new ManifestInfo(); + info.setName(manifest.getName()); + info.setTitle(manifest.getTitle()); + info.setVersion(manifest.getVersion()); + info.setLocation(file.getName()); + packages.add(info); + } + } + + mapper.writeValue(response.getWriter(), packageList); + baseRequest.setHandled(true); + } + + private static class PackageFileFilter implements FileFilter { + @Override + public boolean accept(File pathname) { + return pathname.getName().toLowerCase().endsWith(".json"); + } + } +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/ToolArguments.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/ToolArguments.java new file mode 100644 index 0000000..67dbfa5 --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/ToolArguments.java @@ -0,0 +1,23 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham 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; + +} diff --git a/build-tools/src/main/java/com/skcraft/launcher/buildtools/ToolsFrame.java b/build-tools/src/main/java/com/skcraft/launcher/buildtools/ToolsFrame.java new file mode 100644 index 0000000..b471c9b --- /dev/null +++ b/build-tools/src/main/java/com/skcraft/launcher/buildtools/ToolsFrame.java @@ -0,0 +1,59 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham 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); + } + +} diff --git a/build-tools/src/main/resources/com/skcraft/launcher/buildtools/build.png b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/build.png new file mode 100644 index 0000000..9360f7d --- /dev/null +++ b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/build.png Binary files differ diff --git a/build-tools/src/main/resources/com/skcraft/launcher/buildtools/clean.png b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/clean.png new file mode 100644 index 0000000..2c5d827 --- /dev/null +++ b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/clean.png Binary files differ diff --git a/build-tools/src/main/resources/com/skcraft/launcher/buildtools/header.png b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/header.png new file mode 100644 index 0000000..f58b1a0 --- /dev/null +++ b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/header.png Binary files differ diff --git a/build-tools/src/main/resources/com/skcraft/launcher/buildtools/icon.png b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/icon.png new file mode 100644 index 0000000..03aa713 --- /dev/null +++ b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/icon.png Binary files differ diff --git a/build-tools/src/main/resources/com/skcraft/launcher/buildtools/log.png b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/log.png new file mode 100644 index 0000000..296df88 --- /dev/null +++ b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/log.png Binary files differ diff --git a/build-tools/src/main/resources/com/skcraft/launcher/buildtools/options.png b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/options.png new file mode 100644 index 0000000..39b0a41 --- /dev/null +++ b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/options.png Binary files differ diff --git a/build-tools/src/main/resources/com/skcraft/launcher/buildtools/test.png b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/test.png new file mode 100644 index 0000000..7acd97a --- /dev/null +++ b/build-tools/src/main/resources/com/skcraft/launcher/buildtools/test.png Binary files differ diff --git a/settings.gradle b/settings.gradle index fabc5b8..a88f495 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ rootProject.name = 'launcher-parent' -include 'launcher', 'launcher-fancy', 'launcher-builder', 'launcher-bootstrap', 'staging-tool' +include 'launcher', 'launcher-fancy', 'launcher-builder', 'launcher-bootstrap', 'build-tools' diff --git a/staging-tool/build.gradle b/staging-tool/build.gradle deleted file mode 100644 index 43934e0..0000000 --- a/staging-tool/build.gradle +++ /dev/null @@ -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) diff --git a/staging-tool/scripts/HOW_TO_USE.html b/staging-tool/scripts/HOW_TO_USE.html deleted file mode 100644 index 4b1bfe5..0000000 --- a/staging-tool/scripts/HOW_TO_USE.html +++ /dev/null @@ -1,35 +0,0 @@ - - - -How to Use - - - -
-

How to Use

- -

This tool lets you test the modpack locally.

- -

It should be a stagingtool folder within the modpack folder.

- -

Usage

- -

Basically, whenever you want to test the modpack, use build_and_launch.bat to build the modpack output files, start a local web server, and open the launcher.

- -

There are other files that you can run too:

- -
    -
  • build.bat just builds the modpack output files only
  • -
  • http_server.bat just runs the local web server only
  • -
  • launch.bat just runs the staging launcher only
  • -
  • reset_build.bat deletes all the generated modpack output files, but there is rarely a situation where you would need to do this
  • -
  • reset_launcher.bat deletes downloaded instances, so you can use the launcher as someone who hasn't yet downloaded the modpack yet
  • -
-
- - \ No newline at end of file diff --git a/staging-tool/scripts/build.bat b/staging-tool/scripts/build.bat deleted file mode 100644 index 2fbba1d..0000000 --- a/staging-tool/scripts/build.bat +++ /dev/null @@ -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" \ No newline at end of file diff --git a/staging-tool/scripts/build_and_launch.bat b/staging-tool/scripts/build_and_launch.bat deleted file mode 100644 index 00cf748..0000000 --- a/staging-tool/scripts/build_and_launch.bat +++ /dev/null @@ -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 \ No newline at end of file diff --git a/staging-tool/scripts/http_server.bat b/staging-tool/scripts/http_server.bat deleted file mode 100644 index 946b03e..0000000 --- a/staging-tool/scripts/http_server.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -java -cp staging-tool.jar com.skcraft.launcher.staging.StagingServer --www-dir www \ No newline at end of file diff --git a/staging-tool/scripts/launch.bat b/staging-tool/scripts/launch.bat deleted file mode 100644 index b180f7c..0000000 --- a/staging-tool/scripts/launch.bat +++ /dev/null @@ -1,5 +0,0 @@ -@echo off - -mkdir launcher -cd launcher -java -cp ..\staging-tool.jar com.skcraft.launcher.staging.StagingServer --www-dir ..\www --launch \ No newline at end of file diff --git a/staging-tool/scripts/reset_build.bat b/staging-tool/scripts/reset_build.bat deleted file mode 100644 index 223e0de..0000000 --- a/staging-tool/scripts/reset_build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off - -del /f /s /q www \ No newline at end of file diff --git a/staging-tool/scripts/reset_launcher.bat b/staging-tool/scripts/reset_launcher.bat deleted file mode 100644 index b286db3..0000000 --- a/staging-tool/scripts/reset_launcher.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off - -del /f /s /q launcher\instances \ No newline at end of file diff --git a/staging-tool/src/main/java/com/skcraft/launcher/staging/LatestHandler.java b/staging-tool/src/main/java/com/skcraft/launcher/staging/LatestHandler.java deleted file mode 100644 index b0ff28a..0000000 --- a/staging-tool/src/main/java/com/skcraft/launcher/staging/LatestHandler.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SK's Minecraft Launcher - * Copyright (C) 2010-2014 Albert Pham and contributors - * Please see LICENSE.txt for license information. - */ - -package com.skcraft.launcher.staging; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.skcraft.launcher.selfupdate.LatestVersionInfo; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.AbstractHandler; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.URL; - -public class LatestHandler extends AbstractHandler { - - private final ObjectMapper mapper; - - public LatestHandler(ObjectMapper mapper) { - this.mapper = mapper; - } - - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - response.setContentType("text/plain; charset=utf-8"); - response.setStatus(HttpServletResponse.SC_OK); - - LatestVersionInfo info = new LatestVersionInfo(); - info.setVersion("0.0.0"); - info.setUrl(new URL("http://localhost")); - mapper.writeValue(response.getWriter(), info); - - baseRequest.setHandled(true); - } - -} diff --git a/staging-tool/src/main/java/com/skcraft/launcher/staging/LocalHttpServerBuilder.java b/staging-tool/src/main/java/com/skcraft/launcher/staging/LocalHttpServerBuilder.java deleted file mode 100644 index 175740b..0000000 --- a/staging-tool/src/main/java/com/skcraft/launcher/staging/LocalHttpServerBuilder.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SK's Minecraft Launcher - * Copyright (C) 2010-2014 Albert Pham and contributors - * Please see LICENSE.txt for license information. - */ - -package com.skcraft.launcher.staging; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.ResourceHandler; -import org.eclipse.jetty.server.handler.gzip.GzipHandler; - -import java.io.File; - -public class LocalHttpServerBuilder { - - private File baseDir = new File("."); - private int port = 28888; - - public File getBaseDir() { - return baseDir; - } - - public LocalHttpServerBuilder setBaseDir(File baseDir) { - this.baseDir = baseDir; - return this; - } - - public int getPort() { - return port; - } - - public LocalHttpServerBuilder setPort(int port) { - this.port = port; - return this; - } - - public Server build() throws Exception { - Server server = new Server(port); - - ObjectMapper mapper = new ObjectMapper(); - - ResourceHandler resourceHandler = new ResourceHandler(); - resourceHandler.setDirectoriesListed(true); - resourceHandler.setResourceBase(baseDir.getAbsolutePath()); - - ContextHandler rootContext = new ContextHandler(); - rootContext.setContextPath("/"); - rootContext.setHandler(resourceHandler); - - ContextHandler packagesContext = new ContextHandler("/packages.json"); - packagesContext.setAllowNullPathInfo(true); - packagesContext.setHandler(new PackagesHandler(mapper, baseDir)); - - ContextHandler latestContext = new ContextHandler("/latest.json"); - latestContext.setAllowNullPathInfo(true); - latestContext.setHandler(new LatestHandler(mapper)); - - ContextHandler newsContext = new ContextHandler("/news.html"); - newsContext.setAllowNullPathInfo(true); - newsContext.setHandler(new NewsHandler()); - - ContextHandlerCollection contexts = new ContextHandlerCollection(); - contexts.setHandlers(new Handler[]{packagesContext, latestContext, newsContext, rootContext}); - - GzipHandler gzip = new GzipHandler(); - server.setHandler(gzip); - gzip.setHandler(contexts); - - return server; - } - -} diff --git a/staging-tool/src/main/java/com/skcraft/launcher/staging/NewsHandler.java b/staging-tool/src/main/java/com/skcraft/launcher/staging/NewsHandler.java deleted file mode 100644 index 08e9cac..0000000 --- a/staging-tool/src/main/java/com/skcraft/launcher/staging/NewsHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SK's Minecraft Launcher - * Copyright (C) 2010-2014 Albert Pham and contributors - * Please see LICENSE.txt for license information. - */ - -package com.skcraft.launcher.staging; - -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.AbstractHandler; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.PrintWriter; - -public class NewsHandler extends AbstractHandler { - - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - response.setContentType("text/html; charset=utf-8"); - response.setStatus(HttpServletResponse.SC_OK); - - PrintWriter writer = response.getWriter(); - writer.write(""); - writer.write(""); - writer.write(""); - writer.write("Staging Tool"); - writer.write(""); - writer.write(""); - writer.write("

Welcome to the staging tool!

"); - writer.write(""); - writer.write(""); - - baseRequest.setHandled(true); - } - -} diff --git a/staging-tool/src/main/java/com/skcraft/launcher/staging/PackagesHandler.java b/staging-tool/src/main/java/com/skcraft/launcher/staging/PackagesHandler.java deleted file mode 100644 index 9e63019..0000000 --- a/staging-tool/src/main/java/com/skcraft/launcher/staging/PackagesHandler.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SK's Minecraft Launcher - * Copyright (C) 2010-2014 Albert Pham and contributors - * Please see LICENSE.txt for license information. - */ - -package com.skcraft.launcher.staging; - -import com.beust.jcommander.internal.Lists; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.skcraft.launcher.model.modpack.Manifest; -import com.skcraft.launcher.model.modpack.ManifestInfo; -import com.skcraft.launcher.model.modpack.PackageList; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.AbstractHandler; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.util.List; - -public class PackagesHandler extends AbstractHandler { - - private final ObjectMapper mapper; - private final File baseDir; - - public PackagesHandler(ObjectMapper mapper, File baseDir) { - this.mapper = mapper; - this.baseDir = baseDir; - } - - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - response.setContentType("text/plain; charset=utf-8"); - response.setStatus(HttpServletResponse.SC_OK); - - List packages = Lists.newArrayList(); - PackageList packageList = new PackageList(); - packageList.setPackages(packages); - - File[] files = baseDir.listFiles(new PackageFileFilter()); - if (files != null) { - for (File file : files) { - Manifest manifest = mapper.readValue(file, Manifest.class); - ManifestInfo info = new ManifestInfo(); - info.setName(manifest.getName()); - info.setTitle(manifest.getTitle()); - info.setVersion(manifest.getVersion()); - info.setLocation(file.getName()); - packages.add(info); - } - } - - mapper.writeValue(response.getWriter(), packageList); - baseRequest.setHandled(true); - } - - private static class PackageFileFilter implements FileFilter { - @Override - public boolean accept(File pathname) { - return pathname.getName().toLowerCase().endsWith(".json"); - } - } -} diff --git a/staging-tool/src/main/java/com/skcraft/launcher/staging/StagingArguments.java b/staging-tool/src/main/java/com/skcraft/launcher/staging/StagingArguments.java deleted file mode 100644 index 9395d55..0000000 --- a/staging-tool/src/main/java/com/skcraft/launcher/staging/StagingArguments.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SK's Minecraft Launcher - * Copyright (C) 2010-2014 Albert Pham 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; - -} diff --git a/staging-tool/src/main/java/com/skcraft/launcher/staging/StagingServer.java b/staging-tool/src/main/java/com/skcraft/launcher/staging/StagingServer.java deleted file mode 100644 index 34e561c..0000000 --- a/staging-tool/src/main/java/com/skcraft/launcher/staging/StagingServer.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SK's Minecraft Launcher - * Copyright (C) 2010-2014 Albert Pham 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]); - } - } - -} diff --git a/staging-tool/src/main/resources/com/skcraft/launcher/launcher.properties b/staging-tool/src/main/resources/com/skcraft/launcher/launcher.properties deleted file mode 100644 index 10a62df..0000000 --- a/staging-tool/src/main/resources/com/skcraft/launcher/launcher.properties +++ /dev/null @@ -1,21 +0,0 @@ -# -# SK's Minecraft Launcher -# Copyright (C) 2010-2014 Albert Pham 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