diff --git a/LaunchServer/build.gradle b/LaunchServer/build.gradle index ec76c121..153f9abd 100644 --- a/LaunchServer/build.gradle +++ b/LaunchServer/build.gradle @@ -23,7 +23,7 @@ } jar { - dependsOn parent.childProjects.Launcher.tasks.build, parent.childProjects.Launcher.tasks.genRuntimeJS, parent.childProjects.Launcher.tasks.jar + dependsOn parent.childProjects.Launcher.tasks.build from { configurations.pack.collect { it.isDirectory() ? it : zipTree(it) } } from(parent.childProjects.Launcher.tasks.jar.archivePath, parent.childProjects.Launcher.tasks.genRuntimeJS.archivePath) manifest.attributes("Main-Class": mainClassName, @@ -35,7 +35,7 @@ } dependencies { - pack project(':libLauncher') // pack + bundle project(':libLauncher') bundle 'org.ow2.asm:asm-commons:7.0' bundle 'org.ow2.asm:asm-util:7.0' bundle 'mysql:mysql-connector-java:8.0.13' @@ -60,8 +60,6 @@ pack project(':libLauncher') // pack compileOnly('net.sf.launch4j:launch4j:3.12') { // need user exclude group: '*' } - - //compile 'org.mozilla:rhino:1.7.10' will be module } task hikari(type: Copy) { @@ -75,4 +73,10 @@ task dumpLibs(type: Copy) { from configurations.bundleOnly } -build.dependsOn tasks.dumpLibs +task dumpClientLibs(type: Copy) { + dependsOn parent.childProjects.Launcher.tasks.build + into "$buildDir/libs/launcher-libraries" + from parent.childProjects.Launcher.tasks.dumpLibs.destinationDir +} + +build.dependsOn tasks.dumpLibs, tasks.dumpClientLibs diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java index 6963cb9c..e134fbc3 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java @@ -140,7 +140,8 @@ public static final class Config { public boolean isWarningMissArchJava; public boolean enabledProGuard; public boolean stripLineNumbers; - + public boolean deleteTempFiles; + public String startScript; @@ -259,6 +260,8 @@ public static void main(String... args) throws Throwable { public final Path dir; + public final Path launcherLibraries; + public final List args; public final Path configFile; @@ -326,6 +329,11 @@ public static void main(String... args) throws Throwable { public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecException { this.dir = dir; + launcherLibraries = dir.resolve("launcher-libraries"); + if (!Files.isDirectory(launcherLibraries)) { + Files.deleteIfExists(launcherLibraries); + Files.createDirectory(launcherLibraries); + } this.args = Arrays.asList(args); configFile = dir.resolve("LaunchServer.conf"); publicKeyFile = dir.resolve("public.key"); @@ -459,6 +467,9 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE // Set launcher EXE binary launcherBinary = new JARLauncherBinary(this); launcherEXEBinary = binary(); + + launcherBinary.init(); + launcherEXEBinary.init(); syncLauncherBinaries(); // Sync updates dir @@ -576,9 +587,11 @@ private void generateConfigIfNotExists() throws IOException { newConfig.whitelistRejectString = "Вас нет в белом списке"; newConfig.threadCoreCount = 0; // on your own - newConfig.enabledProGuard = true; - newConfig.stripLineNumbers = false; newConfig.threadCount = JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors() >= 4 ? JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors() / 2 : JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors(); + + newConfig.enabledProGuard = true; + newConfig.stripLineNumbers = true; + newConfig.deleteTempFiles = true; // Set server address LogHelper.println("LaunchServer address: "); newConfig.setAddress(commandHandler.readLine()); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/StarterAgent.java b/LaunchServer/src/main/java/ru/gravit/launchserver/StarterAgent.java index 30db3252..9f6fb300 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/StarterAgent.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/StarterAgent.java @@ -12,12 +12,12 @@ import java.util.Collections; import java.util.jar.JarFile; -public class StarterAgent { +public final class StarterAgent { - public static final class StarterVisitor extends SimpleFileVisitor { - private Instrumentation inst; + private static final class StarterVisitor extends SimpleFileVisitor { + private final Instrumentation inst; - public StarterVisitor(Instrumentation inst) { + private StarterVisitor(Instrumentation inst) { this.inst = inst; } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/EXEL4JLauncherBinary.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/EXEL4JLauncherBinary.java index a70fa951..e69b17d0 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/EXEL4JLauncherBinary.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/EXEL4JLauncherBinary.java @@ -41,7 +41,6 @@ public void clear() { public EXEL4JLauncherBinary(LaunchServer server) { super(server, server.dir.resolve(server.config.binaryName + ".exe")); faviconFile = server.dir.resolve("favicon.ico"); - //setConfig(); } @Override diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JAConfigurator.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JAConfigurator.java index f893eab2..26084680 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JAConfigurator.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JAConfigurator.java @@ -23,7 +23,6 @@ public class JAConfigurator implements AutoCloseable { public JAConfigurator(String configclass, MainBuildTask jarLauncherBinary) throws NotFoundException { pool = new ClassPool(false); - pool.insertClassPath(jarLauncherBinary.cleanJar.toFile().getAbsolutePath()); pool.appendSystemPath(); classname = configclass; ctClass = pool.get(classname); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java index a0caa387..6d207969 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/JARLauncherBinary.java @@ -4,37 +4,57 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; import ru.gravit.launcher.Launcher; import ru.gravit.launchserver.LaunchServer; +import ru.gravit.launchserver.binary.tasks.AttachJarsTask; import ru.gravit.launchserver.binary.tasks.LauncherBuildTask; import ru.gravit.launchserver.binary.tasks.MainBuildTask; import ru.gravit.launchserver.binary.tasks.ProGuardBuildTask; -import ru.gravit.launchserver.binary.tasks.StripLineNumbersTask; -import ru.gravit.launchserver.binary.tasks.UnpackBuildTask; +import ru.gravit.launchserver.binary.tasks.AdditionalFixesApplyTask; +import ru.gravit.launchserver.binary.tasks.PrepareBuildTask; +import ru.gravit.utils.helper.CommonHelper; import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.LogHelper; public final class JARLauncherBinary extends LauncherBinary { - public ArrayList tasks; + public final AtomicLong count; public final Path runtimeDir; public final Path guardDir; - + public final Path buildDir; + public List tasks; + public List coreLibs; + public JARLauncherBinary(LaunchServer server) throws IOException { super(server); - tasks = new ArrayList<>(); - tasks.add(new UnpackBuildTask(server)); - tasks.add(new MainBuildTask(server)); - if(server.config.enabledProGuard) tasks.add(new ProGuardBuildTask(server)); - if(server.config.stripLineNumbers) tasks.add(new StripLineNumbersTask(server)); + count = new AtomicLong(0); syncBinaryFile = server.dir.resolve(server.config.binaryName + ".jar"); runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR); guardDir = server.dir.resolve(Launcher.GUARD_DIR); + buildDir = server.dir.resolve("build"); + tasks = new ArrayList<>(); + coreLibs = new ArrayList<>(); + if (!Files.isDirectory(buildDir)) { + Files.deleteIfExists(buildDir); + Files.createDirectory(buildDir); + } } + @Override + public void init() { + tasks.add(new PrepareBuildTask(server)); + tasks.add(new MainBuildTask(server)); + tasks.add(new ProGuardBuildTask(server)); + tasks.add(new AttachJarsTask(server)); + tasks.add(new AdditionalFixesApplyTask(server)); + } + @Override public void build() throws IOException { LogHelper.info("Building launcher binary file"); + count.set(0); // set jar number Path thisPath = null; boolean isNeedDelete = false; long time_start = System.currentTimeMillis(); @@ -47,12 +67,29 @@ public void build() throws IOException { long time_task_end = System.currentTimeMillis(); long time_task = time_task_end - time_this; time_this = time_task_end; - if (isNeedDelete) Files.delete(oldPath); + if (isNeedDelete && server.config.deleteTempFiles) Files.deleteIfExists(oldPath); isNeedDelete = task.allowDelete(); LogHelper.subInfo("Task %s processed from %d millis",task.getName(), time_task); } long time_end = System.currentTimeMillis(); - IOHelper.move(thisPath, syncBinaryFile); + if (isNeedDelete && server.config.deleteTempFiles) IOHelper.move(thisPath, syncBinaryFile); + else IOHelper.copy(thisPath, syncBinaryFile); LogHelper.info("Build successful from %d millis",time_end - time_start); } + + public String nextName(String taskName) { + return String.format("Launcher-%s-%d.jar", taskName, count.getAndIncrement()); + } + + public Path nextPath(String taskName) { + return buildDir.resolve(nextName(taskName)); + } + + public Path nextPath(LauncherBuildTask task) { + return nextPath(task.getName()); + } + + public Path nextLowerPath(LauncherBuildTask task) { + return nextPath(CommonHelper.low(task.getName())); + } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/LauncherBinary.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/LauncherBinary.java index 63bb9f32..15adcfe2 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/LauncherBinary.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/LauncherBinary.java @@ -9,25 +9,20 @@ import ru.gravit.utils.helper.SecurityHelper; public abstract class LauncherBinary { - public final LaunchServer server; - public Path syncBinaryFile; private volatile DigestBytesHolder binary; private volatile byte[] sign; - protected LauncherBinary(LaunchServer server, Path binaryFile) { this.server = server; syncBinaryFile = binaryFile; } - protected LauncherBinary(LaunchServer server) { this.server = server; } - public abstract void build() throws IOException; @@ -44,6 +39,8 @@ public final byte[] getSign() { return sign; } + public void init() { + } public final boolean sync() throws IOException { boolean exists = exists(); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/ProguardConf.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/ProguardConf.java index df293074..d4cd0bea 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/ProguardConf.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/ProguardConf.java @@ -9,6 +9,7 @@ import java.nio.file.Path; import java.security.SecureRandom; import java.util.ArrayList; +import java.util.List; import ru.gravit.launchserver.LaunchServer; import ru.gravit.utils.helper.IOHelper; @@ -30,8 +31,6 @@ private static String generateString(SecureRandom rand, int il) { public final Path config; public final Path mappings; public final Path words; - public final Path outputJar; - public final ArrayList confStrs; public transient final LaunchServer srv; public ProguardConf(LaunchServer srv) { @@ -39,20 +38,22 @@ public ProguardConf(LaunchServer srv) { config = proguard.resolve("proguard.config"); mappings = proguard.resolve("mappings.pro"); words = proguard.resolve("random.pro"); - outputJar = srv.dir.resolve(srv.config.binaryName + "-obfPre.jar"); - confStrs = new ArrayList<>(); this.srv = srv; } - public void buildConfig(Path inputJar) + public String[] buildConfig(Path inputJar, Path outputJar) { - confStrs.clear(); + List confStrs = new ArrayList<>(); prepare(false); if (srv.config.genMappings) confStrs.add("-printmapping \'" + mappings.toFile().getName() + "\'"); confStrs.add("-obfuscationdictionary \'" + words.toFile().getName() + "\'"); confStrs.add("-injar \'" + inputJar.toAbsolutePath() + "\'"); confStrs.add("-outjar \'" + outputJar.toAbsolutePath() + "\'"); + srv.launcherBinary.coreLibs.stream() + .map(e -> "-libraryjars \'" + e.toAbsolutePath().toString() + "\'") + .forEach(confStrs::add); confStrs.add("-classobfuscationdictionary \'" + words.toFile().getName() + "\'"); confStrs.add(readConf()); + return confStrs.toArray(new String[0]); } private void genConfig(boolean force) throws IOException { diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/StripLineNumbersTask.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/AdditionalFixesApplyTask.java similarity index 74% rename from LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/StripLineNumbersTask.java rename to LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/AdditionalFixesApplyTask.java index d8baa571..0b334cbd 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/StripLineNumbersTask.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/AdditionalFixesApplyTask.java @@ -10,33 +10,38 @@ import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.ClassNode; import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.asm.ClassMetadataReader; import ru.gravit.launchserver.asm.SafeClassWriter; import ru.gravit.utils.helper.IOHelper; -public class StripLineNumbersTask implements LauncherBuildTask { +public class AdditionalFixesApplyTask implements LauncherBuildTask { private final LaunchServer server; - public StripLineNumbersTask(LaunchServer server) { + public AdditionalFixesApplyTask(LaunchServer server) { this.server = server; } @Override public String getName() { - return "Strip debug task"; + return "AdditionalFixesApply"; } @Override public Path process(Path inputFile) throws IOException { - Path out = server.dir.resolve(server.config.projectName + "-stripped.jar"); + Path out = server.launcherBinary.nextPath("post-fixed"); try (ClassMetadataReader reader = new ClassMetadataReader()) { reader.getCp().add(new JarFile(inputFile.toFile())); try (ZipInputStream input = IOHelper.newZipInput(inputFile); ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(out))) { ZipEntry e = input.getNextEntry(); while (e != null) { + if (e.isDirectory()) { + e = input.getNextEntry(); + continue; + } String filename = e.getName(); output.putNextEntry(IOHelper.newZipEntry(e)); if (filename.endsWith(".class")) { @@ -45,7 +50,7 @@ public Path process(Path inputFile) throws IOException { IOHelper.transfer(input, outputStream); bytes = outputStream.toByteArray(); } - output.write(classFix(bytes, reader)); + output.write(classFix(bytes, reader, server.config.stripLineNumbers)); } else IOHelper.transfer(input, output); e = input.getNextEntry(); @@ -55,10 +60,13 @@ public Path process(Path inputFile) throws IOException { return out; } - private static byte[] classFix(byte[] bytes, ClassMetadataReader reader) { + private static byte[] classFix(byte[] bytes, ClassMetadataReader reader, boolean stripNumbers) { ClassReader cr = new ClassReader(bytes); + ClassNode cn = new ClassNode(); + cr.accept(cn, stripNumbers ? (ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) : ClassReader.SKIP_FRAMES); + ClassWriter cw = new SafeClassWriter(reader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - cr.accept(cw, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + cn.accept(cw); return cw.toByteArray(); } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/AttachJarsTask.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/AttachJarsTask.java new file mode 100644 index 00000000..6301498f --- /dev/null +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/AttachJarsTask.java @@ -0,0 +1,82 @@ +package ru.gravit.launchserver.binary.tasks; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +import ru.gravit.launchserver.LaunchServer; +import ru.gravit.utils.helper.IOHelper; +import ru.gravit.utils.helper.LogHelper; + +public class AttachJarsTask implements LauncherBuildTask { + private final LaunchServer srv; + private final List jars; + private final List exclusions; + + public AttachJarsTask(LaunchServer srv) { + this.srv = srv; + jars = new ArrayList<>(); + exclusions = new ArrayList<>(); + exclusions.add("META-INF"); + } + + @Override + public String getName() { + return "AttachJars"; + } + + @Override + public Path process(Path inputFile) throws IOException { + Path outputFile = srv.launcherBinary.nextPath("attached"); + try (ZipInputStream input = IOHelper.newZipInput(inputFile); + ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputFile))) { + ZipEntry e = input.getNextEntry(); + while (e != null) { + if (e.isDirectory() || srv.buildHookManager.isContainsBlacklist(e.getName())) { + e = input.getNextEntry(); + continue; + } + output.putNextEntry(IOHelper.newZipEntry(e)); + IOHelper.transfer(input, output); + e = input.getNextEntry(); + } + attach(output, srv.launcherBinary.coreLibs); + attach(output, jars); + } + return outputFile; + } + + private void attach(ZipOutputStream output, List lst) throws IOException { + for (Path p : lst) { + LogHelper.debug("Attaching: " + p); + try (ZipInputStream input = IOHelper.newZipInput(p)) { + ZipEntry e = input.getNextEntry(); + while (e != null) { + String filename = e.getName(); + if (exclusions.stream().noneMatch(filename::startsWith) && !srv.buildHookManager.isContainsBlacklist(filename) && !e.isDirectory()) { + output.putNextEntry(IOHelper.newZipEntry(e)); + IOHelper.transfer(input, output); + } + e = input.getNextEntry(); + } + } + } + } + + @Override + public boolean allowDelete() { + return true; + } + + public List getJars() { + return jars; + } + + public List getExclusions() { + return exclusions; + } +} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/MainBuildTask.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/MainBuildTask.java index 27d7f654..88a5f602 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/MainBuildTask.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/MainBuildTask.java @@ -31,8 +31,6 @@ import ru.gravit.utils.helper.SecurityHelper; public class MainBuildTask implements LauncherBuildTask { - public final Path binaryFile; - public Path cleanJar; private final LaunchServer server; public final ClassMetadataReader reader; private final class RuntimeDirVisitor extends SimpleFileVisitor { @@ -105,7 +103,6 @@ private static ZipEntry newGuardEntry(String fileName) { public MainBuildTask(LaunchServer srv) { server = srv; - binaryFile = server.dir.resolve(server.config.binaryName + "-main.jar"); reader = new ClassMetadataReader(); } @@ -115,11 +112,19 @@ public String getName() { } @Override - public Path process(Path cleanJar) throws IOException { - this.cleanJar = cleanJar; - try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(binaryFile)); + public Path process(Path inputJar) throws IOException { + Path outputJar = server.launcherBinary.nextPath("main"); + try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar)); JAConfigurator jaConfigurator = new JAConfigurator(AutogenConfig.class.getName(), this)) { - jaConfigurator.pool.insertClassPath(cleanJar.toFile().getAbsolutePath()); + jaConfigurator.pool.insertClassPath(inputJar.toFile().getAbsolutePath()); + server.launcherBinary.coreLibs.stream().map(e -> e.toFile().getAbsolutePath()) + .forEach(t -> { + try { + jaConfigurator.pool.appendClassPath(t); + } catch (NotFoundException e2) { + LogHelper.error(e2); + } + }); BuildContext context = new BuildContext(output, jaConfigurator, this); server.buildHookManager.hook(context); jaConfigurator.setAddress(server.config.getAddress()); @@ -131,12 +136,19 @@ public Path process(Path cleanJar) throws IOException { jaConfigurator.setDownloadJava(server.config.isDownloadJava); jaConfigurator.setEnv(server.config.env); server.buildHookManager.registerAllClientModuleClass(jaConfigurator); - reader.getCp().add(new JarFile(cleanJar.toFile())); - try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(cleanJar))) { + reader.getCp().add(new JarFile(inputJar.toFile())); + server.launcherBinary.coreLibs.forEach(e -> { + try { + reader.getCp().add(new JarFile(e.toFile())); + } catch (IOException e1) { + LogHelper.error(e1); + } + }); + try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(inputJar))) { ZipEntry e = input.getNextEntry(); while (e != null) { String filename = e.getName(); - if (server.buildHookManager.isContainsBlacklist(filename)) { + if (server.buildHookManager.isContainsBlacklist(filename) || e.isDirectory()) { e = input.getNextEntry(); continue; } @@ -196,7 +208,7 @@ public Path process(Path cleanJar) throws IOException { LogHelper.error(e); } reader.close(); - return binaryFile; + return outputJar; } @Override diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/UnpackBuildTask.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/PrepareBuildTask.java similarity index 50% rename from LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/UnpackBuildTask.java rename to LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/PrepareBuildTask.java index b4919b1a..61ec274c 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/UnpackBuildTask.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/PrepareBuildTask.java @@ -6,15 +6,20 @@ import ru.gravit.utils.helper.UnpackHelper; import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.List; -public class UnpackBuildTask implements LauncherBuildTask { +public class PrepareBuildTask implements LauncherBuildTask { private final LaunchServer server; private final Path result; - public UnpackBuildTask(LaunchServer server) { + public PrepareBuildTask(LaunchServer server) { this.server = server; - result = server.dir.resolve(server.config.binaryName + "-clean.jar"); + result = server.launcherBinary.buildDir.resolve(server.config.binaryName + "-clean.jar"); } @Override @@ -24,6 +29,8 @@ public String getName() { @Override public Path process(Path inputFile) throws IOException { + server.launcherBinary.coreLibs.clear(); + IOHelper.walk(server.launcherLibraries, new ListFileVisitor(server.launcherBinary.coreLibs), true); UnpackHelper.unpack(IOHelper.getResourceURL("Launcher.jar"), result); tryUnpack(); return result; @@ -39,4 +46,19 @@ public void tryUnpack() throws IOException { UnpackHelper.unpackZipNoCheck("guard.zip", server.launcherBinary.guardDir); UnpackHelper.unpackZipNoCheck("runtime.zip", server.launcherBinary.runtimeDir); } + + private static final class ListFileVisitor extends SimpleFileVisitor { + private final List lst; + + private ListFileVisitor(List lst) { + this.lst = lst; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (!Files.isDirectory(file) && file.toFile().getName().endsWith(".jar")) + lst.add(file); + return super.visitFile(file, attrs); + } + } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/ProGuardBuildTask.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/ProGuardBuildTask.java index 72366ea2..9be2393d 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/ProGuardBuildTask.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/ProGuardBuildTask.java @@ -8,6 +8,8 @@ import proguard.ParseException; import proguard.ProGuard; import ru.gravit.launchserver.LaunchServer; +import ru.gravit.utils.helper.IOHelper; +import ru.gravit.utils.helper.LogHelper; public class ProGuardBuildTask implements LauncherBuildTask { private final LaunchServer server; @@ -23,18 +25,24 @@ public String getName() { @Override public Path process(Path inputFile) throws IOException { - Configuration proguard_cfg = new Configuration(); - server.proguardConf.buildConfig(inputFile); - ConfigurationParser parser = new ConfigurationParser(server.proguardConf.confStrs.toArray(new String[0]), - server.proguardConf.proguard.toFile(), System.getProperties()); - try { - parser.parse(proguard_cfg); - ProGuard proGuard = new ProGuard(proguard_cfg); - proGuard.execute(); - } catch (ParseException e1) { - e1.printStackTrace(); - } - return server.proguardConf.outputJar; + if (server.config.enabledProGuard) { + Path outputJar = server.launcherBinary.nextLowerPath(this); + Configuration proguard_cfg = new Configuration(); + ConfigurationParser parser = new ConfigurationParser(server.proguardConf.buildConfig(inputFile, outputJar), + server.proguardConf.proguard.toFile(), System.getProperties()); + try { + parser.parse(proguard_cfg); + ProGuard proGuard = new ProGuard(proguard_cfg); + proGuard.execute(); + } catch (ParseException e) { + LogHelper.error(e); + } + return outputJar; + } else { + Path outputJar = server.launcherBinary.nextPath("non-obf"); + IOHelper.copy(inputFile, outputJar); + return outputJar; + } } @Override diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/TaskUtil.java b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/TaskUtil.java new file mode 100644 index 00000000..8175b7e1 --- /dev/null +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/binary/tasks/TaskUtil.java @@ -0,0 +1,59 @@ +package ru.gravit.launchserver.binary.tasks; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public final class TaskUtil { + public static void addCounted(List tasks, int count, Predicate pred, LauncherBuildTask taskAdd) { + List indexes = new ArrayList<>(); + tasks.stream().filter(pred).forEach(e -> { + indexes.add(e); + }); + indexes.forEach(e -> { + tasks.add(tasks.indexOf(e)+count, taskAdd); + }); + } + + public static void replaceCounted(List tasks, int count, Predicate pred, LauncherBuildTask taskRep) { + List indexes = new ArrayList<>(); + tasks.stream().filter(pred).forEach(e -> { + indexes.add(e); + }); + indexes.forEach(e -> { + tasks.set(tasks.indexOf(e)+count, taskRep); + }); + } + + public static void addPre(List tasks, Predicate pred, LauncherBuildTask taskAdd) { + addCounted(tasks, -1, pred, taskAdd); + } + + public static void add(List tasks, Predicate pred, LauncherBuildTask taskAdd) { + addCounted(tasks, 0, pred, taskAdd); + } + + public static void addAfter(List tasks, Predicate pred, LauncherBuildTask taskAdd) { + addCounted(tasks, 1, pred, taskAdd); + } + + public static void replacePre(List tasks, Predicate pred, LauncherBuildTask taskRep) { + replaceCounted(tasks, -1, pred, taskRep); + } + + public static void replace(List tasks, Predicate pred, LauncherBuildTask taskRep) { + replaceCounted(tasks, 0, pred, taskRep); + } + + public static void replaceAfter(List tasks, Predicate pred, LauncherBuildTask taskRep) { + replaceCounted(tasks, 1, pred, taskRep); + } + + public static List getTaskByClass(List tasks, Class taskClass) { + return tasks.stream().filter(taskClass::isInstance).map(taskClass::cast).collect(Collectors.toList()); + } + + private TaskUtil() { + } +} diff --git a/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/proguard.cfg b/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/proguard.cfg index c08bbda3..3c081430 100644 --- a/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/proguard.cfg +++ b/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/proguard.cfg @@ -1,6 +1,7 @@ -libraryjars '/lib/rt.jar' -libraryjars '/lib/jce.jar' -libraryjars '/lib/ext/nashorn.jar' +-libraryjars '/lib/ext/jfxrt.jar' -keepattributes SourceFile,LineNumberTable -renamesourcefileattribute Source diff --git a/Launcher/build.gradle b/Launcher/build.gradle index b41df9a2..79220380 100644 --- a/Launcher/build.gradle +++ b/Launcher/build.gradle @@ -1,19 +1,24 @@ String mainClassName = "ru.gravit.launcher.ClientLauncherWrapper" String mainAgentName = "ru.gravit.launcher.LauncherAgent" - repositories { - maven { - url "http://repo.spring.io/plugins-release/" - } + maven { + url "http://repo.spring.io/plugins-release/" + } } sourceCompatibility = '1.8' targetCompatibility = '1.8' +configurations { + bundle + pack + compile.extendsFrom bundle, pack +} + jar { - from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } } - manifest.attributes("Main-Class": mainClassName, + from { configurations.pack.collect { it.isDirectory() ? it : zipTree(it) } } + manifest.attributes("Main-Class": mainClassName, "Premain-Class": mainAgentName, "Can-Redefine-Classes": "true", "Can-Retransform-Classes": "true", @@ -21,14 +26,20 @@ } dependencies { - compile project(':LauncherAPI') - compile 'com.github.oshi:oshi-core:3.11.0' + pack project(':LauncherAPI') // Not error on obf. + bundle 'com.github.oshi:oshi-core:3.11.0' } task genRuntimeJS(type: Zip) { - archiveName = "runtime.zip" - destinationDir = file("${buildDir}/tmp") - from "runtime/" + archiveName = "runtime.zip" + destinationDir = file("${buildDir}/tmp") + from "runtime/" } -build.dependsOn tasks.genRuntimeJS +task dumpLibs(type: Copy) { + into "$buildDir/libs/libraries" + from configurations.bundle +} + + +build.dependsOn tasks.genRuntimeJS, tasks.dumpLibs diff --git a/Launcher/runtime/dialog/dialog.js b/Launcher/runtime/dialog/dialog.js index 883792e5..b193e69f 100644 --- a/Launcher/runtime/dialog/dialog.js +++ b/Launcher/runtime/dialog/dialog.js @@ -149,7 +149,7 @@ function goAuth(event) { var rsaPassword = null; if (!passwordField.isDisable()) { var password = passwordField.getText(); - if (!password.isEmpty()) { + if (password !== null && !password.isEmpty()) { rsaPassword = settings.setPassword(password); } else if (settings.rsaPassword !== null) { rsaPassword = settings.rsaPassword; @@ -213,6 +213,7 @@ function verifyLauncher(e) { function doAuth(login, rsaPassword) { processing.resetOverlay(); overlay.show(processing.overlay, function (event) { + FunctionalBridge.getHWID.join(); makeAuthRequest(login, rsaPassword, function (result) { loginData = { pp: result.pp , accessToken: result.accessToken, permissions: result.permissions}; diff --git a/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java index efa612fd..9061e389 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java @@ -67,7 +67,8 @@ public void start(String... args) throws Throwable { runtimeProvider.preLoad(); FunctionalBridge.worker = new RequestWorker(); CommonHelper.newThread("FX Task Worker", true, FunctionalBridge.worker).start(); - CommonHelper.newThread("GetHWID Thread",true, FunctionalBridge::getHWID).start(); + FunctionalBridge.getHWID = CommonHelper.newThread("GetHWID Thread",true, FunctionalBridge::getHWID); + FunctionalBridge.getHWID.start(); LogHelper.debug("Dir: %s", DirBridge.dir); runtimeProvider.run(args); } diff --git a/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java b/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java index 6d9cf772..8b94f5fe 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java +++ b/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java @@ -29,6 +29,8 @@ public class FunctionalBridge { public static OshiHWIDProvider hwidProvider = new OshiHWIDProvider(); @LauncherAPI public static AtomicReference hwid = new AtomicReference<>(); + @LauncherAPI + public static Thread getHWID = null; @LauncherAPI public static HashedDirRunnable offlineUpdateRequest(String dirName, Path dir, SignedObjectHolder hdir, FileNameMatcher matcher, boolean digest) throws Exception { diff --git a/LauncherAPI/build.gradle b/LauncherAPI/build.gradle index e7f413a1..102de532 100644 --- a/LauncherAPI/build.gradle +++ b/LauncherAPI/build.gradle @@ -2,8 +2,8 @@ targetCompatibility = '1.8' dependencies { - compile project(':libLauncher') - compile 'javax.websocket:javax.websocket-client-api:1.1' - compileOnly 'com.google.guava:guava:26.0-jre' - compile files('../compat/authlib/authlib-clean.jar') + compile project(':libLauncher') + compile 'javax.websocket:javax.websocket-client-api:1.1' + compileOnly 'com.google.guava:guava:26.0-jre' + compile files('../compat/authlib/authlib-clean.jar') } diff --git a/ServerWrapper/build.gradle b/ServerWrapper/build.gradle index ad5d0e30..d8996fa0 100644 --- a/ServerWrapper/build.gradle +++ b/ServerWrapper/build.gradle @@ -22,5 +22,4 @@ dependencies { compile project(':LauncherAPI') - compile 'org.javassist:javassist:3.23.1-GA' } diff --git a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java index 8fa85a88..f742962e 100644 --- a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java @@ -1,6 +1,5 @@ package ru.gravit.launcher.server; - import com.google.gson.Gson; import com.google.gson.GsonBuilder; import ru.gravit.launcher.ClientPermissions; diff --git a/build.gradle b/build.gradle index 871960d4..6c9468a2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,18 @@ allprojects { apply plugin: 'eclipse' apply plugin: 'idea' - +} + +subprojects { + apply plugin: 'java' + repositories { mavenCentral() maven { url "http://clojars.org/repo/" } } -} -subprojects { - apply plugin: 'java' - configurations { apt aptCompileOnly diff --git a/libLauncher/build.gradle b/libLauncher/build.gradle index 2d77906e..0e527171 100644 --- a/libLauncher/build.gradle +++ b/libLauncher/build.gradle @@ -3,5 +3,5 @@ dependencies { compileOnly 'org.fusesource.jansi:jansi:1.17.1' - compile 'com.google.code.gson:gson:2.8.5' + compile 'com.google.code.gson:gson:2.8.5' } diff --git a/libLauncher/src/main/java/ru/gravit/utils/HTTPRequest.java b/libLauncher/src/main/java/ru/gravit/utils/HTTPRequest.java index 868de75c..20eb5292 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/HTTPRequest.java +++ b/libLauncher/src/main/java/ru/gravit/utils/HTTPRequest.java @@ -13,7 +13,7 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -public class HTTPRequest { +public final class HTTPRequest { private static final int TIMEOUT = 10000; private static final JsonParser parser = new JsonParser(); @@ -61,4 +61,7 @@ public static JsonElement jsonRequest(JsonElement request, URL url) throws IOExc JsonElement content = parser.parse(reader); return content; } + + private HTTPRequest() { + } } diff --git a/libLauncher/src/main/java/ru/gravit/utils/HttpDownloader.java b/libLauncher/src/main/java/ru/gravit/utils/HttpDownloader.java index a73bca13..504f8f3f 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/HttpDownloader.java +++ b/libLauncher/src/main/java/ru/gravit/utils/HttpDownloader.java @@ -13,7 +13,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -public class HttpDownloader extends Observable { +public final class HttpDownloader extends Observable { public static final int BUFER_SIZE = 8192; public static final int INTERVAL = 300; public AtomicInteger writed = new AtomicInteger(0); diff --git a/libLauncher/src/main/java/ru/gravit/utils/NativeJVMHalt.java b/libLauncher/src/main/java/ru/gravit/utils/NativeJVMHalt.java index 9d067daf..728e82be 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/NativeJVMHalt.java +++ b/libLauncher/src/main/java/ru/gravit/utils/NativeJVMHalt.java @@ -2,7 +2,7 @@ import ru.gravit.utils.helper.LogHelper; -public class NativeJVMHalt { +public final class NativeJVMHalt { public NativeJVMHalt(int haltCode) { this.haltCode = haltCode; LogHelper.error("JVM exit code %d", haltCode); diff --git a/libLauncher/src/main/java/ru/gravit/utils/Version.java b/libLauncher/src/main/java/ru/gravit/utils/Version.java index 2d189c7e..5795a7a8 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/Version.java +++ b/libLauncher/src/main/java/ru/gravit/utils/Version.java @@ -4,7 +4,7 @@ import java.util.Objects; -public class Version { +public final class Version { @LauncherAPI public final int major; @LauncherAPI diff --git a/libLauncher/src/main/java/ru/gravit/utils/helper/EnvHelper.java b/libLauncher/src/main/java/ru/gravit/utils/helper/EnvHelper.java index 175cae96..dfe0b35f 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/helper/EnvHelper.java +++ b/libLauncher/src/main/java/ru/gravit/utils/helper/EnvHelper.java @@ -3,7 +3,7 @@ import java.util.Locale; import java.util.Map; -public class EnvHelper { +public final class EnvHelper { public static final String[] toTest = {"_JAVA_OPTIONS", "_JAVA_OPTS", "JAVA_OPTS", "JAVA_OPTIONS"}; public static void addEnv(ProcessBuilder builder) { diff --git a/libLauncher/src/main/java/ru/gravit/utils/helper/UnpackHelper.java b/libLauncher/src/main/java/ru/gravit/utils/helper/UnpackHelper.java index 40dc0212..75709a15 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/helper/UnpackHelper.java +++ b/libLauncher/src/main/java/ru/gravit/utils/helper/UnpackHelper.java @@ -10,13 +10,13 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -public class UnpackHelper { +public final class UnpackHelper { public static boolean unpack(URL resource, Path target) throws IOException { if (IOHelper.isFile(target)) { if (matches(target, resource)) return false; } Files.deleteIfExists(target); - Files.createFile(target); + IOHelper.createParentDirs(target); try (InputStream in = IOHelper.newInput(resource)) { IOHelper.transfer(in, target); } diff --git a/modules b/modules index f87bdf0e..5e37ef4d 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit f87bdf0e1eeed4ca097e4ab90b99b0639aa4b52a +Subproject commit 5e37ef4d9a6d001e70b4ea5c3cd837e30b692d51