Merge pull request #132 from GravitLauncher/addTasks

Building tasks improvements.
This commit is contained in:
Gravit 2019-01-09 21:30:55 +07:00 committed by GitHub
commit 8653de90d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 361 additions and 103 deletions

View file

@ -23,7 +23,7 @@
} }
jar { 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 { configurations.pack.collect { it.isDirectory() ? it : zipTree(it) } }
from(parent.childProjects.Launcher.tasks.jar.archivePath, parent.childProjects.Launcher.tasks.genRuntimeJS.archivePath) from(parent.childProjects.Launcher.tasks.jar.archivePath, parent.childProjects.Launcher.tasks.genRuntimeJS.archivePath)
manifest.attributes("Main-Class": mainClassName, manifest.attributes("Main-Class": mainClassName,
@ -35,7 +35,7 @@
} }
dependencies { dependencies {
pack project(':libLauncher') // pack bundle project(':libLauncher')
bundle 'org.ow2.asm:asm-commons:7.0' bundle 'org.ow2.asm:asm-commons:7.0'
bundle 'org.ow2.asm:asm-util:7.0' bundle 'org.ow2.asm:asm-util:7.0'
bundle 'mysql:mysql-connector-java:8.0.13' 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 compileOnly('net.sf.launch4j:launch4j:3.12') { // need user
exclude group: '*' exclude group: '*'
} }
//compile 'org.mozilla:rhino:1.7.10' will be module
} }
task hikari(type: Copy) { task hikari(type: Copy) {
@ -75,4 +73,10 @@ task dumpLibs(type: Copy) {
from configurations.bundleOnly 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

View file

@ -140,6 +140,7 @@ public static final class Config {
public boolean isWarningMissArchJava; public boolean isWarningMissArchJava;
public boolean enabledProGuard; public boolean enabledProGuard;
public boolean stripLineNumbers; public boolean stripLineNumbers;
public boolean deleteTempFiles;
public String startScript; public String startScript;
@ -259,6 +260,8 @@ public static void main(String... args) throws Throwable {
public final Path dir; public final Path dir;
public final Path launcherLibraries;
public final List<String> args; public final List<String> args;
public final Path configFile; 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 { public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecException {
this.dir = dir; this.dir = dir;
launcherLibraries = dir.resolve("launcher-libraries");
if (!Files.isDirectory(launcherLibraries)) {
Files.deleteIfExists(launcherLibraries);
Files.createDirectory(launcherLibraries);
}
this.args = Arrays.asList(args); this.args = Arrays.asList(args);
configFile = dir.resolve("LaunchServer.conf"); configFile = dir.resolve("LaunchServer.conf");
publicKeyFile = dir.resolve("public.key"); publicKeyFile = dir.resolve("public.key");
@ -459,6 +467,9 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
// Set launcher EXE binary // Set launcher EXE binary
launcherBinary = new JARLauncherBinary(this); launcherBinary = new JARLauncherBinary(this);
launcherEXEBinary = binary(); launcherEXEBinary = binary();
launcherBinary.init();
launcherEXEBinary.init();
syncLauncherBinaries(); syncLauncherBinaries();
// Sync updates dir // Sync updates dir
@ -576,9 +587,11 @@ private void generateConfigIfNotExists() throws IOException {
newConfig.whitelistRejectString = "Вас нет в белом списке"; newConfig.whitelistRejectString = "Вас нет в белом списке";
newConfig.threadCoreCount = 0; // on your own 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.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 // Set server address
LogHelper.println("LaunchServer address: "); LogHelper.println("LaunchServer address: ");
newConfig.setAddress(commandHandler.readLine()); newConfig.setAddress(commandHandler.readLine());

View file

@ -12,12 +12,12 @@
import java.util.Collections; import java.util.Collections;
import java.util.jar.JarFile; import java.util.jar.JarFile;
public class StarterAgent { public final class StarterAgent {
public static final class StarterVisitor extends SimpleFileVisitor<Path> { private static final class StarterVisitor extends SimpleFileVisitor<Path> {
private Instrumentation inst; private final Instrumentation inst;
public StarterVisitor(Instrumentation inst) { private StarterVisitor(Instrumentation inst) {
this.inst = inst; this.inst = inst;
} }

View file

@ -41,7 +41,6 @@ public void clear() {
public EXEL4JLauncherBinary(LaunchServer server) { public EXEL4JLauncherBinary(LaunchServer server) {
super(server, server.dir.resolve(server.config.binaryName + ".exe")); super(server, server.dir.resolve(server.config.binaryName + ".exe"));
faviconFile = server.dir.resolve("favicon.ico"); faviconFile = server.dir.resolve("favicon.ico");
//setConfig();
} }
@Override @Override

View file

@ -23,7 +23,6 @@ public class JAConfigurator implements AutoCloseable {
public JAConfigurator(String configclass, MainBuildTask jarLauncherBinary) throws NotFoundException { public JAConfigurator(String configclass, MainBuildTask jarLauncherBinary) throws NotFoundException {
pool = new ClassPool(false); pool = new ClassPool(false);
pool.insertClassPath(jarLauncherBinary.cleanJar.toFile().getAbsolutePath());
pool.appendSystemPath(); pool.appendSystemPath();
classname = configclass; classname = configclass;
ctClass = pool.get(classname); ctClass = pool.get(classname);

View file

@ -4,37 +4,57 @@
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import ru.gravit.launcher.Launcher; import ru.gravit.launcher.Launcher;
import ru.gravit.launchserver.LaunchServer; 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.LauncherBuildTask;
import ru.gravit.launchserver.binary.tasks.MainBuildTask; import ru.gravit.launchserver.binary.tasks.MainBuildTask;
import ru.gravit.launchserver.binary.tasks.ProGuardBuildTask; import ru.gravit.launchserver.binary.tasks.ProGuardBuildTask;
import ru.gravit.launchserver.binary.tasks.StripLineNumbersTask; import ru.gravit.launchserver.binary.tasks.AdditionalFixesApplyTask;
import ru.gravit.launchserver.binary.tasks.UnpackBuildTask; import ru.gravit.launchserver.binary.tasks.PrepareBuildTask;
import ru.gravit.utils.helper.CommonHelper;
import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
public final class JARLauncherBinary extends LauncherBinary { public final class JARLauncherBinary extends LauncherBinary {
public ArrayList<LauncherBuildTask> tasks; public final AtomicLong count;
public final Path runtimeDir; public final Path runtimeDir;
public final Path guardDir; public final Path guardDir;
public final Path buildDir;
public List<LauncherBuildTask> tasks;
public List<Path> coreLibs;
public JARLauncherBinary(LaunchServer server) throws IOException { public JARLauncherBinary(LaunchServer server) throws IOException {
super(server); super(server);
tasks = new ArrayList<>(); count = new AtomicLong(0);
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));
syncBinaryFile = server.dir.resolve(server.config.binaryName + ".jar"); syncBinaryFile = server.dir.resolve(server.config.binaryName + ".jar");
runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR); runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR);
guardDir = server.dir.resolve(Launcher.GUARD_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 @Override
public void build() throws IOException { public void build() throws IOException {
LogHelper.info("Building launcher binary file"); LogHelper.info("Building launcher binary file");
count.set(0); // set jar number
Path thisPath = null; Path thisPath = null;
boolean isNeedDelete = false; boolean isNeedDelete = false;
long time_start = System.currentTimeMillis(); long time_start = System.currentTimeMillis();
@ -47,12 +67,29 @@ public void build() throws IOException {
long time_task_end = System.currentTimeMillis(); long time_task_end = System.currentTimeMillis();
long time_task = time_task_end - time_this; long time_task = time_task_end - time_this;
time_this = time_task_end; time_this = time_task_end;
if (isNeedDelete) Files.delete(oldPath); if (isNeedDelete && server.config.deleteTempFiles) Files.deleteIfExists(oldPath);
isNeedDelete = task.allowDelete(); isNeedDelete = task.allowDelete();
LogHelper.subInfo("Task %s processed from %d millis",task.getName(), time_task); LogHelper.subInfo("Task %s processed from %d millis",task.getName(), time_task);
} }
long time_end = System.currentTimeMillis(); 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); 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()));
}
} }

View file

@ -9,25 +9,20 @@
import ru.gravit.utils.helper.SecurityHelper; import ru.gravit.utils.helper.SecurityHelper;
public abstract class LauncherBinary { public abstract class LauncherBinary {
public final LaunchServer server; public final LaunchServer server;
public Path syncBinaryFile; public Path syncBinaryFile;
private volatile DigestBytesHolder binary; private volatile DigestBytesHolder binary;
private volatile byte[] sign; private volatile byte[] sign;
protected LauncherBinary(LaunchServer server, Path binaryFile) { protected LauncherBinary(LaunchServer server, Path binaryFile) {
this.server = server; this.server = server;
syncBinaryFile = binaryFile; syncBinaryFile = binaryFile;
} }
protected LauncherBinary(LaunchServer server) { protected LauncherBinary(LaunchServer server) {
this.server = server; this.server = server;
} }
public abstract void build() throws IOException; public abstract void build() throws IOException;
@ -44,6 +39,8 @@ public final byte[] getSign() {
return sign; return sign;
} }
public void init() {
}
public final boolean sync() throws IOException { public final boolean sync() throws IOException {
boolean exists = exists(); boolean exists = exists();

View file

@ -9,6 +9,7 @@
import java.nio.file.Path; import java.nio.file.Path;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.LaunchServer;
import ru.gravit.utils.helper.IOHelper; 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 config;
public final Path mappings; public final Path mappings;
public final Path words; public final Path words;
public final Path outputJar;
public final ArrayList<String> confStrs;
public transient final LaunchServer srv; public transient final LaunchServer srv;
public ProguardConf(LaunchServer srv) { public ProguardConf(LaunchServer srv) {
@ -39,20 +38,22 @@ public ProguardConf(LaunchServer srv) {
config = proguard.resolve("proguard.config"); config = proguard.resolve("proguard.config");
mappings = proguard.resolve("mappings.pro"); mappings = proguard.resolve("mappings.pro");
words = proguard.resolve("random.pro"); words = proguard.resolve("random.pro");
outputJar = srv.dir.resolve(srv.config.binaryName + "-obfPre.jar");
confStrs = new ArrayList<>();
this.srv = srv; this.srv = srv;
} }
public void buildConfig(Path inputJar) public String[] buildConfig(Path inputJar, Path outputJar)
{ {
confStrs.clear(); List<String> confStrs = new ArrayList<>();
prepare(false); prepare(false);
if (srv.config.genMappings) confStrs.add("-printmapping \'" + mappings.toFile().getName() + "\'"); if (srv.config.genMappings) confStrs.add("-printmapping \'" + mappings.toFile().getName() + "\'");
confStrs.add("-obfuscationdictionary \'" + words.toFile().getName() + "\'"); confStrs.add("-obfuscationdictionary \'" + words.toFile().getName() + "\'");
confStrs.add("-injar \'" + inputJar.toAbsolutePath() + "\'"); confStrs.add("-injar \'" + inputJar.toAbsolutePath() + "\'");
confStrs.add("-outjar \'" + outputJar.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("-classobfuscationdictionary \'" + words.toFile().getName() + "\'");
confStrs.add(readConf()); confStrs.add(readConf());
return confStrs.toArray(new String[0]);
} }
private void genConfig(boolean force) throws IOException { private void genConfig(boolean force) throws IOException {

View file

@ -10,33 +10,38 @@
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.asm.ClassMetadataReader; import ru.gravit.launchserver.asm.ClassMetadataReader;
import ru.gravit.launchserver.asm.SafeClassWriter; import ru.gravit.launchserver.asm.SafeClassWriter;
import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.IOHelper;
public class StripLineNumbersTask implements LauncherBuildTask { public class AdditionalFixesApplyTask implements LauncherBuildTask {
private final LaunchServer server; private final LaunchServer server;
public StripLineNumbersTask(LaunchServer server) { public AdditionalFixesApplyTask(LaunchServer server) {
this.server = server; this.server = server;
} }
@Override @Override
public String getName() { public String getName() {
return "Strip debug task"; return "AdditionalFixesApply";
} }
@Override @Override
public Path process(Path inputFile) throws IOException { 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()) { try (ClassMetadataReader reader = new ClassMetadataReader()) {
reader.getCp().add(new JarFile(inputFile.toFile())); reader.getCp().add(new JarFile(inputFile.toFile()));
try (ZipInputStream input = IOHelper.newZipInput(inputFile); try (ZipInputStream input = IOHelper.newZipInput(inputFile);
ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(out))) { ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(out))) {
ZipEntry e = input.getNextEntry(); ZipEntry e = input.getNextEntry();
while (e != null) { while (e != null) {
if (e.isDirectory()) {
e = input.getNextEntry();
continue;
}
String filename = e.getName(); String filename = e.getName();
output.putNextEntry(IOHelper.newZipEntry(e)); output.putNextEntry(IOHelper.newZipEntry(e));
if (filename.endsWith(".class")) { if (filename.endsWith(".class")) {
@ -45,7 +50,7 @@ public Path process(Path inputFile) throws IOException {
IOHelper.transfer(input, outputStream); IOHelper.transfer(input, outputStream);
bytes = outputStream.toByteArray(); bytes = outputStream.toByteArray();
} }
output.write(classFix(bytes, reader)); output.write(classFix(bytes, reader, server.config.stripLineNumbers));
} else } else
IOHelper.transfer(input, output); IOHelper.transfer(input, output);
e = input.getNextEntry(); e = input.getNextEntry();
@ -55,10 +60,13 @@ public Path process(Path inputFile) throws IOException {
return out; 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); 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); 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(); return cw.toByteArray();
} }

View file

@ -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<Path> jars;
private final List<String> 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<Path> 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<Path> getJars() {
return jars;
}
public List<String> getExclusions() {
return exclusions;
}
}

View file

@ -31,8 +31,6 @@
import ru.gravit.utils.helper.SecurityHelper; import ru.gravit.utils.helper.SecurityHelper;
public class MainBuildTask implements LauncherBuildTask { public class MainBuildTask implements LauncherBuildTask {
public final Path binaryFile;
public Path cleanJar;
private final LaunchServer server; private final LaunchServer server;
public final ClassMetadataReader reader; public final ClassMetadataReader reader;
private final class RuntimeDirVisitor extends SimpleFileVisitor<Path> { private final class RuntimeDirVisitor extends SimpleFileVisitor<Path> {
@ -105,7 +103,6 @@ private static ZipEntry newGuardEntry(String fileName) {
public MainBuildTask(LaunchServer srv) { public MainBuildTask(LaunchServer srv) {
server = srv; server = srv;
binaryFile = server.dir.resolve(server.config.binaryName + "-main.jar");
reader = new ClassMetadataReader(); reader = new ClassMetadataReader();
} }
@ -115,11 +112,19 @@ public String getName() {
} }
@Override @Override
public Path process(Path cleanJar) throws IOException { public Path process(Path inputJar) throws IOException {
this.cleanJar = cleanJar; Path outputJar = server.launcherBinary.nextPath("main");
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(binaryFile)); try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar));
JAConfigurator jaConfigurator = new JAConfigurator(AutogenConfig.class.getName(), this)) { 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); BuildContext context = new BuildContext(output, jaConfigurator, this);
server.buildHookManager.hook(context); server.buildHookManager.hook(context);
jaConfigurator.setAddress(server.config.getAddress()); jaConfigurator.setAddress(server.config.getAddress());
@ -131,12 +136,19 @@ public Path process(Path cleanJar) throws IOException {
jaConfigurator.setDownloadJava(server.config.isDownloadJava); jaConfigurator.setDownloadJava(server.config.isDownloadJava);
jaConfigurator.setEnv(server.config.env); jaConfigurator.setEnv(server.config.env);
server.buildHookManager.registerAllClientModuleClass(jaConfigurator); server.buildHookManager.registerAllClientModuleClass(jaConfigurator);
reader.getCp().add(new JarFile(cleanJar.toFile())); reader.getCp().add(new JarFile(inputJar.toFile()));
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(cleanJar))) { 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(); ZipEntry e = input.getNextEntry();
while (e != null) { while (e != null) {
String filename = e.getName(); String filename = e.getName();
if (server.buildHookManager.isContainsBlacklist(filename)) { if (server.buildHookManager.isContainsBlacklist(filename) || e.isDirectory()) {
e = input.getNextEntry(); e = input.getNextEntry();
continue; continue;
} }
@ -196,7 +208,7 @@ public Path process(Path cleanJar) throws IOException {
LogHelper.error(e); LogHelper.error(e);
} }
reader.close(); reader.close();
return binaryFile; return outputJar;
} }
@Override @Override

View file

@ -6,15 +6,20 @@
import ru.gravit.utils.helper.UnpackHelper; import ru.gravit.utils.helper.UnpackHelper;
import java.io.IOException; import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path; 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 LaunchServer server;
private final Path result; private final Path result;
public UnpackBuildTask(LaunchServer server) { public PrepareBuildTask(LaunchServer server) {
this.server = server; this.server = server;
result = server.dir.resolve(server.config.binaryName + "-clean.jar"); result = server.launcherBinary.buildDir.resolve(server.config.binaryName + "-clean.jar");
} }
@Override @Override
@ -24,6 +29,8 @@ public String getName() {
@Override @Override
public Path process(Path inputFile) throws IOException { 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); UnpackHelper.unpack(IOHelper.getResourceURL("Launcher.jar"), result);
tryUnpack(); tryUnpack();
return result; return result;
@ -39,4 +46,19 @@ public void tryUnpack() throws IOException {
UnpackHelper.unpackZipNoCheck("guard.zip", server.launcherBinary.guardDir); UnpackHelper.unpackZipNoCheck("guard.zip", server.launcherBinary.guardDir);
UnpackHelper.unpackZipNoCheck("runtime.zip", server.launcherBinary.runtimeDir); UnpackHelper.unpackZipNoCheck("runtime.zip", server.launcherBinary.runtimeDir);
} }
private static final class ListFileVisitor extends SimpleFileVisitor<Path> {
private final List<Path> lst;
private ListFileVisitor(List<Path> 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);
}
}
} }

View file

@ -8,6 +8,8 @@
import proguard.ParseException; import proguard.ParseException;
import proguard.ProGuard; import proguard.ProGuard;
import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.LaunchServer;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
public class ProGuardBuildTask implements LauncherBuildTask { public class ProGuardBuildTask implements LauncherBuildTask {
private final LaunchServer server; private final LaunchServer server;
@ -23,18 +25,24 @@ public String getName() {
@Override @Override
public Path process(Path inputFile) throws IOException { public Path process(Path inputFile) throws IOException {
Configuration proguard_cfg = new Configuration(); if (server.config.enabledProGuard) {
server.proguardConf.buildConfig(inputFile); Path outputJar = server.launcherBinary.nextLowerPath(this);
ConfigurationParser parser = new ConfigurationParser(server.proguardConf.confStrs.toArray(new String[0]), Configuration proguard_cfg = new Configuration();
server.proguardConf.proguard.toFile(), System.getProperties()); ConfigurationParser parser = new ConfigurationParser(server.proguardConf.buildConfig(inputFile, outputJar),
try { server.proguardConf.proguard.toFile(), System.getProperties());
parser.parse(proguard_cfg); try {
ProGuard proGuard = new ProGuard(proguard_cfg); parser.parse(proguard_cfg);
proGuard.execute(); ProGuard proGuard = new ProGuard(proguard_cfg);
} catch (ParseException e1) { proGuard.execute();
e1.printStackTrace(); } catch (ParseException e) {
} LogHelper.error(e);
return server.proguardConf.outputJar; }
return outputJar;
} else {
Path outputJar = server.launcherBinary.nextPath("non-obf");
IOHelper.copy(inputFile, outputJar);
return outputJar;
}
} }
@Override @Override

View file

@ -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<LauncherBuildTask> tasks, int count, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskAdd) {
List<LauncherBuildTask> 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<LauncherBuildTask> tasks, int count, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskRep) {
List<LauncherBuildTask> 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<LauncherBuildTask> tasks, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskAdd) {
addCounted(tasks, -1, pred, taskAdd);
}
public static void add(List<LauncherBuildTask> tasks, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskAdd) {
addCounted(tasks, 0, pred, taskAdd);
}
public static void addAfter(List<LauncherBuildTask> tasks, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskAdd) {
addCounted(tasks, 1, pred, taskAdd);
}
public static void replacePre(List<LauncherBuildTask> tasks, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskRep) {
replaceCounted(tasks, -1, pred, taskRep);
}
public static void replace(List<LauncherBuildTask> tasks, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskRep) {
replaceCounted(tasks, 0, pred, taskRep);
}
public static void replaceAfter(List<LauncherBuildTask> tasks, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskRep) {
replaceCounted(tasks, 1, pred, taskRep);
}
public static <T extends LauncherBuildTask> List<T> getTaskByClass(List<LauncherBuildTask> tasks, Class<T> taskClass) {
return tasks.stream().filter(taskClass::isInstance).map(taskClass::cast).collect(Collectors.toList());
}
private TaskUtil() {
}
}

View file

@ -1,6 +1,7 @@
-libraryjars '<java.home>/lib/rt.jar' -libraryjars '<java.home>/lib/rt.jar'
-libraryjars '<java.home>/lib/jce.jar' -libraryjars '<java.home>/lib/jce.jar'
-libraryjars '<java.home>/lib/ext/nashorn.jar' -libraryjars '<java.home>/lib/ext/nashorn.jar'
-libraryjars '<java.home>/lib/ext/jfxrt.jar'
-keepattributes SourceFile,LineNumberTable -keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute Source -renamesourcefileattribute Source

View file

@ -1,19 +1,24 @@
String mainClassName = "ru.gravit.launcher.ClientLauncherWrapper" String mainClassName = "ru.gravit.launcher.ClientLauncherWrapper"
String mainAgentName = "ru.gravit.launcher.LauncherAgent" String mainAgentName = "ru.gravit.launcher.LauncherAgent"
repositories { repositories {
maven { maven {
url "http://repo.spring.io/plugins-release/" url "http://repo.spring.io/plugins-release/"
} }
} }
sourceCompatibility = '1.8' sourceCompatibility = '1.8'
targetCompatibility = '1.8' targetCompatibility = '1.8'
configurations {
bundle
pack
compile.extendsFrom bundle, pack
}
jar { jar {
from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } } from { configurations.pack.collect { it.isDirectory() ? it : zipTree(it) } }
manifest.attributes("Main-Class": mainClassName, manifest.attributes("Main-Class": mainClassName,
"Premain-Class": mainAgentName, "Premain-Class": mainAgentName,
"Can-Redefine-Classes": "true", "Can-Redefine-Classes": "true",
"Can-Retransform-Classes": "true", "Can-Retransform-Classes": "true",
@ -21,14 +26,20 @@
} }
dependencies { dependencies {
compile project(':LauncherAPI') pack project(':LauncherAPI') // Not error on obf.
compile 'com.github.oshi:oshi-core:3.11.0' bundle 'com.github.oshi:oshi-core:3.11.0'
} }
task genRuntimeJS(type: Zip) { task genRuntimeJS(type: Zip) {
archiveName = "runtime.zip" archiveName = "runtime.zip"
destinationDir = file("${buildDir}/tmp") destinationDir = file("${buildDir}/tmp")
from "runtime/" from "runtime/"
} }
build.dependsOn tasks.genRuntimeJS task dumpLibs(type: Copy) {
into "$buildDir/libs/libraries"
from configurations.bundle
}
build.dependsOn tasks.genRuntimeJS, tasks.dumpLibs

View file

@ -149,7 +149,7 @@ function goAuth(event) {
var rsaPassword = null; var rsaPassword = null;
if (!passwordField.isDisable()) { if (!passwordField.isDisable()) {
var password = passwordField.getText(); var password = passwordField.getText();
if (!password.isEmpty()) { if (password !== null && !password.isEmpty()) {
rsaPassword = settings.setPassword(password); rsaPassword = settings.setPassword(password);
} else if (settings.rsaPassword !== null) { } else if (settings.rsaPassword !== null) {
rsaPassword = settings.rsaPassword; rsaPassword = settings.rsaPassword;
@ -213,6 +213,7 @@ function verifyLauncher(e) {
function doAuth(login, rsaPassword) { function doAuth(login, rsaPassword) {
processing.resetOverlay(); processing.resetOverlay();
overlay.show(processing.overlay, function (event) { overlay.show(processing.overlay, function (event) {
FunctionalBridge.getHWID.join();
makeAuthRequest(login, rsaPassword, function (result) { makeAuthRequest(login, rsaPassword, function (result) {
loginData = { pp: result.pp , accessToken: result.accessToken, permissions: result.permissions}; loginData = { pp: result.pp , accessToken: result.accessToken, permissions: result.permissions};

View file

@ -67,7 +67,8 @@ public void start(String... args) throws Throwable {
runtimeProvider.preLoad(); runtimeProvider.preLoad();
FunctionalBridge.worker = new RequestWorker(); FunctionalBridge.worker = new RequestWorker();
CommonHelper.newThread("FX Task Worker", true, FunctionalBridge.worker).start(); 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); LogHelper.debug("Dir: %s", DirBridge.dir);
runtimeProvider.run(args); runtimeProvider.run(args);
} }

View file

@ -29,6 +29,8 @@ public class FunctionalBridge {
public static OshiHWIDProvider hwidProvider = new OshiHWIDProvider(); public static OshiHWIDProvider hwidProvider = new OshiHWIDProvider();
@LauncherAPI @LauncherAPI
public static AtomicReference<HWID> hwid = new AtomicReference<>(); public static AtomicReference<HWID> hwid = new AtomicReference<>();
@LauncherAPI
public static Thread getHWID = null;
@LauncherAPI @LauncherAPI
public static HashedDirRunnable offlineUpdateRequest(String dirName, Path dir, SignedObjectHolder<HashedDir> hdir, FileNameMatcher matcher, boolean digest) throws Exception { public static HashedDirRunnable offlineUpdateRequest(String dirName, Path dir, SignedObjectHolder<HashedDir> hdir, FileNameMatcher matcher, boolean digest) throws Exception {

View file

@ -2,8 +2,8 @@
targetCompatibility = '1.8' targetCompatibility = '1.8'
dependencies { dependencies {
compile project(':libLauncher') compile project(':libLauncher')
compile 'javax.websocket:javax.websocket-client-api:1.1' compile 'javax.websocket:javax.websocket-client-api:1.1'
compileOnly 'com.google.guava:guava:26.0-jre' compileOnly 'com.google.guava:guava:26.0-jre'
compile files('../compat/authlib/authlib-clean.jar') compile files('../compat/authlib/authlib-clean.jar')
} }

View file

@ -22,5 +22,4 @@
dependencies { dependencies {
compile project(':LauncherAPI') compile project(':LauncherAPI')
compile 'org.javassist:javassist:3.23.1-GA'
} }

View file

@ -1,6 +1,5 @@
package ru.gravit.launcher.server; package ru.gravit.launcher.server;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import ru.gravit.launcher.ClientPermissions; import ru.gravit.launcher.ClientPermissions;

View file

@ -1,6 +1,10 @@
allprojects { allprojects {
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'idea' apply plugin: 'idea'
}
subprojects {
apply plugin: 'java'
repositories { repositories {
mavenCentral() mavenCentral()
@ -8,10 +12,6 @@
url "http://clojars.org/repo/" url "http://clojars.org/repo/"
} }
} }
}
subprojects {
apply plugin: 'java'
configurations { configurations {
apt apt

View file

@ -3,5 +3,5 @@
dependencies { dependencies {
compileOnly 'org.fusesource.jansi:jansi:1.17.1' 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'
} }

View file

@ -13,7 +13,7 @@
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
public class HTTPRequest { public final class HTTPRequest {
private static final int TIMEOUT = 10000; private static final int TIMEOUT = 10000;
private static final JsonParser parser = new JsonParser(); 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); JsonElement content = parser.parse(reader);
return content; return content;
} }
private HTTPRequest() {
}
} }

View file

@ -13,7 +13,7 @@
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; 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 BUFER_SIZE = 8192;
public static final int INTERVAL = 300; public static final int INTERVAL = 300;
public AtomicInteger writed = new AtomicInteger(0); public AtomicInteger writed = new AtomicInteger(0);

View file

@ -2,7 +2,7 @@
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
public class NativeJVMHalt { public final class NativeJVMHalt {
public NativeJVMHalt(int haltCode) { public NativeJVMHalt(int haltCode) {
this.haltCode = haltCode; this.haltCode = haltCode;
LogHelper.error("JVM exit code %d", haltCode); LogHelper.error("JVM exit code %d", haltCode);

View file

@ -4,7 +4,7 @@
import java.util.Objects; import java.util.Objects;
public class Version { public final class Version {
@LauncherAPI @LauncherAPI
public final int major; public final int major;
@LauncherAPI @LauncherAPI

View file

@ -3,7 +3,7 @@
import java.util.Locale; import java.util.Locale;
import java.util.Map; 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 final String[] toTest = {"_JAVA_OPTIONS", "_JAVA_OPTS", "JAVA_OPTS", "JAVA_OPTIONS"};
public static void addEnv(ProcessBuilder builder) { public static void addEnv(ProcessBuilder builder) {

View file

@ -10,13 +10,13 @@
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
public class UnpackHelper { public final class UnpackHelper {
public static boolean unpack(URL resource, Path target) throws IOException { public static boolean unpack(URL resource, Path target) throws IOException {
if (IOHelper.isFile(target)) { if (IOHelper.isFile(target)) {
if (matches(target, resource)) return false; if (matches(target, resource)) return false;
} }
Files.deleteIfExists(target); Files.deleteIfExists(target);
Files.createFile(target); IOHelper.createParentDirs(target);
try (InputStream in = IOHelper.newInput(resource)) { try (InputStream in = IOHelper.newInput(resource)) {
IOHelper.transfer(in, target); IOHelper.transfer(in, target);
} }

@ -1 +1 @@
Subproject commit f87bdf0e1eeed4ca097e4ab90b99b0639aa4b52a Subproject commit 5e37ef4d9a6d001e70b4ea5c3cd837e30b692d51