diff --git a/Launcher/runtime/dialog/dialog.js b/Launcher/runtime/dialog/dialog.js index 78ec989..dafd79b 100644 --- a/Launcher/runtime/dialog/dialog.js +++ b/Launcher/runtime/dialog/dialog.js @@ -138,10 +138,14 @@ function verifyLauncher(e) { processing.resetOverlay(); overlay.show(processing.overlay, function(event) makeLauncherRequest(function(result) { + if (result.binary !== null) { + LauncherRequest.update(Launcher.getConfig(), result); + return; + } + + // Parse response settings.lastSign = result.sign; settings.lastProfiles = result.profiles; - - // Init offline if set if (settings.offline) { initOffline(); } diff --git a/Launcher/runtime/dialog/overlay/processing/processing.js b/Launcher/runtime/dialog/overlay/processing/processing.js index 885ced0..d6c4629 100644 --- a/Launcher/runtime/dialog/overlay/processing/processing.js +++ b/Launcher/runtime/dialog/overlay/processing/processing.js @@ -62,6 +62,7 @@ // Return last sign and profiles return { + binary: null, sign: settings.lastSign, profiles: settings.lastProfiles }; diff --git a/Launcher/source/request/update/LauncherRequest.java b/Launcher/source/request/update/LauncherRequest.java index cb68630..bf20496 100644 --- a/Launcher/source/request/update/LauncherRequest.java +++ b/Launcher/source/request/update/LauncherRequest.java @@ -1,6 +1,8 @@ package launcher.request.update; +import java.io.IOException; import java.nio.file.Path; +import java.security.SignatureException; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Collections; @@ -57,29 +59,8 @@ output.flush(); if (shouldUpdate) { byte[] binary = input.readByteArray(0); - SecurityHelper.verifySign(binary, sign, publicKey); - - // Prepare process builder to start new instance (java -jar works for Launch4J's EXE too) - List args = new ArrayList<>(8); - args.add(IOHelper.resolveJavaBin(null).toString()); - if (LogHelper.isDebugEnabled()) { - args.add(ClientLauncher.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled()))); - } - if (Config.ADDRESS_OVERRIDE != null) { - args.add(ClientLauncher.jvmProperty(Config.ADDRESS_OVERRIDE_PROPERTY, Config.ADDRESS_OVERRIDE)); - } - args.add("-jar"); - args.add(BINARY_PATH.toString()); - ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[args.size()])); - builder.inheritIO(); - - // Rewrite and start new instance - IOHelper.write(BINARY_PATH, binary); - builder.start(); - - // Kill current instance - JVMHelper.RUNTIME.exit(255); - throw new AssertionError("Why Launcher wasn't restarted?!"); + SecurityHelper.verifySign(binary, sign, config.publicKey); + return new Result(binary, sign, Collections.emptyList()); } // Read clients profiles list @@ -90,19 +71,52 @@ } // Return request result - return new Result(sign, profiles); + return new Result(null, sign, profiles); + } + + public static void update(Config config, Result result) throws SignatureException, IOException { + SecurityHelper.verifySign(result.binary, result.sign, config.publicKey); + + // Prepare process builder to start new instance (java -jar works for Launch4J's EXE too) + List args = new ArrayList<>(8); + args.add(IOHelper.resolveJavaBin(null).toString()); + if (LogHelper.isDebugEnabled()) { + args.add(ClientLauncher.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled()))); + } + if (Config.ADDRESS_OVERRIDE != null) { + args.add(ClientLauncher.jvmProperty(Config.ADDRESS_OVERRIDE_PROPERTY, Config.ADDRESS_OVERRIDE)); + } + args.add("-jar"); + args.add(BINARY_PATH.toString()); + ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[args.size()])); + builder.inheritIO(); + + // Rewrite and start new instance + IOHelper.write(BINARY_PATH, result.binary); + builder.start(); + + // Kill current instance + JVMHelper.RUNTIME.exit(255); + throw new AssertionError("Why Launcher wasn't restarted?!"); } public static final class Result { @LauncherAPI public final List> profiles; + private final byte[] binary; private final byte[] sign; - private Result(byte[] sign, List> profiles) { + private Result(byte[] binary, byte[] sign, List> profiles) { + this.binary = binary == null ? null : binary.clone(); this.sign = sign.clone(); this.profiles = Collections.unmodifiableList(profiles); } @LauncherAPI + public byte[] getBinary() { + return binary == null ? null : binary.clone(); + } + + @LauncherAPI public byte[] getSign() { return sign.clone(); }