mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-03-28 20:18:21 +03:00
LauncherBuildTask введение новой системы сборки лаунчера
Часть 1
This commit is contained in:
parent
2590c97061
commit
4e1f268d4f
13 changed files with 360 additions and 223 deletions
|
@ -8,16 +8,17 @@
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import ru.gravit.launchserver.binary.tasks.MainBuildTask;
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
|
|
||||||
public class BuildContext {
|
public class BuildContext {
|
||||||
public final ZipOutputStream output;
|
public final ZipOutputStream output;
|
||||||
public final JAConfigurator config;
|
public final JAConfigurator config;
|
||||||
public final JARLauncherBinary data;
|
public final MainBuildTask data;
|
||||||
public final HashSet<String> fileList;
|
public final HashSet<String> fileList;
|
||||||
|
|
||||||
|
|
||||||
public BuildContext(ZipOutputStream output, JAConfigurator config, JARLauncherBinary data) {
|
public BuildContext(ZipOutputStream output, JAConfigurator config, MainBuildTask data) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
|
|
@ -41,12 +41,13 @@ 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();
|
//setConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build() throws IOException {
|
public void build() throws IOException {
|
||||||
LogHelper.info("Building launcher EXE binary file (Using Launch4J)");
|
LogHelper.info("Building launcher EXE binary file (Using Launch4J)");
|
||||||
|
setConfig();
|
||||||
|
|
||||||
// Set favicon path
|
// Set favicon path
|
||||||
Config config = ConfigPersister.getInstance().getConfig();
|
Config config = ConfigPersister.getInstance().getConfig();
|
||||||
|
@ -99,14 +100,14 @@ private void setConfig() {
|
||||||
info.setTxtFileVersion(formatVars(server.config.launch4j.txtFileVersion));
|
info.setTxtFileVersion(formatVars(server.config.launch4j.txtFileVersion));
|
||||||
info.setTxtProductVersion(formatVars(server.config.launch4j.txtProductVersion));
|
info.setTxtProductVersion(formatVars(server.config.launch4j.txtProductVersion));
|
||||||
// Prepare version info (misc)
|
// Prepare version info (misc)
|
||||||
info.setOriginalFilename(binaryFile.getFileName().toString());
|
info.setOriginalFilename(syncBinaryFile.getFileName().toString());
|
||||||
info.setLanguage(LanguageID.RUSSIAN);
|
info.setLanguage(LanguageID.RUSSIAN);
|
||||||
config.setVersionInfo(info);
|
config.setVersionInfo(info);
|
||||||
|
|
||||||
// Set JAR wrapping options
|
// Set JAR wrapping options
|
||||||
config.setDontWrapJar(false);
|
config.setDontWrapJar(false);
|
||||||
config.setJar(server.launcherBinary.syncBinaryFile.toFile());
|
config.setJar(server.launcherBinary.syncBinaryFile.toFile());
|
||||||
config.setOutfile(binaryFile.toFile());
|
config.setOutfile(syncBinaryFile.toFile());
|
||||||
|
|
||||||
// Return prepared config
|
// Return prepared config
|
||||||
ConfigPersister.getInstance().setAntConfig(config, null);
|
ConfigPersister.getInstance().setAntConfig(config, null);
|
||||||
|
|
|
@ -15,9 +15,9 @@ public EXELauncherBinary(LaunchServer server) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build() throws IOException {
|
public void build() throws IOException {
|
||||||
if (IOHelper.isFile(binaryFile)) {
|
if (IOHelper.isFile(syncBinaryFile)) {
|
||||||
LogHelper.subWarning("Deleting obsolete launcher EXE binary file");
|
LogHelper.subWarning("Deleting obsolete launcher EXE binary file");
|
||||||
Files.delete(binaryFile);
|
Files.delete(syncBinaryFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
import javassist.NotFoundException;
|
import javassist.NotFoundException;
|
||||||
import ru.gravit.launcher.LauncherConfig;
|
import ru.gravit.launcher.LauncherConfig;
|
||||||
|
import ru.gravit.launchserver.binary.tasks.MainBuildTask;
|
||||||
|
|
||||||
public class JAConfigurator implements AutoCloseable {
|
public class JAConfigurator implements AutoCloseable {
|
||||||
public ClassPool pool;
|
public ClassPool pool;
|
||||||
|
@ -20,7 +21,7 @@ public class JAConfigurator implements AutoCloseable {
|
||||||
StringBuilder moduleBody;
|
StringBuilder moduleBody;
|
||||||
int autoincrement;
|
int autoincrement;
|
||||||
|
|
||||||
public JAConfigurator(String configclass, JARLauncherBinary 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.insertClassPath(jarLauncherBinary.cleanJar.toFile().getAbsolutePath());
|
||||||
pool.appendSystemPath();
|
pool.appendSystemPath();
|
||||||
|
|
|
@ -32,6 +32,10 @@
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
import ru.gravit.launcher.serialize.HOutput;
|
||||||
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.binary.tasks.LauncherBuildTask;
|
||||||
|
import ru.gravit.launchserver.binary.tasks.MainBuildTask;
|
||||||
|
import ru.gravit.launchserver.binary.tasks.ProGuardBuildTask;
|
||||||
|
import ru.gravit.launchserver.binary.tasks.UnpackBuildTask;
|
||||||
import ru.gravit.launchserver.manangers.hook.BuildHookManager.ZipBuildHook;
|
import ru.gravit.launchserver.manangers.hook.BuildHookManager.ZipBuildHook;
|
||||||
import ru.gravit.utils.helper.CommonHelper;
|
import ru.gravit.utils.helper.CommonHelper;
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
|
@ -41,89 +45,15 @@
|
||||||
import ru.gravit.utils.helper.UnpackHelper;
|
import ru.gravit.utils.helper.UnpackHelper;
|
||||||
|
|
||||||
public final class JARLauncherBinary extends LauncherBinary {
|
public final class JARLauncherBinary extends LauncherBinary {
|
||||||
|
//public ClassMetadataReader reader;
|
||||||
private final class RuntimeDirVisitor extends SimpleFileVisitor<Path> {
|
public ArrayList<LauncherBuildTask> tasks;
|
||||||
private final ZipOutputStream output;
|
|
||||||
private final Map<String, byte[]> runtime;
|
|
||||||
|
|
||||||
private RuntimeDirVisitor(ZipOutputStream output, Map<String, byte[]> runtime) {
|
|
||||||
this.output = output;
|
|
||||||
this.runtime = runtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
|
||||||
String dirName = IOHelper.toString(runtimeDir.relativize(dir));
|
|
||||||
output.putNextEntry(newEntry(dirName + '/'));
|
|
||||||
return super.preVisitDirectory(dir, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
|
||||||
String fileName = IOHelper.toString(runtimeDir.relativize(file));
|
|
||||||
runtime.put(fileName, SecurityHelper.digest(DigestAlgorithm.MD5, file));
|
|
||||||
|
|
||||||
// Create zip entry and transfer contents
|
|
||||||
output.putNextEntry(newEntry(fileName));
|
|
||||||
IOHelper.transfer(file, output);
|
|
||||||
|
|
||||||
// Return result
|
|
||||||
return super.visitFile(file, attrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: new native security wrapper and library...
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final class GuardDirVisitor extends SimpleFileVisitor<Path> {
|
|
||||||
private final ZipOutputStream output;
|
|
||||||
private final Map<String, byte[]> guard;
|
|
||||||
|
|
||||||
private GuardDirVisitor(ZipOutputStream output, Map<String, byte[]> guard) {
|
|
||||||
this.output = output;
|
|
||||||
this.guard = guard;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
|
||||||
String dirName = IOHelper.toString(guardDir.relativize(dir));
|
|
||||||
output.putNextEntry(newGuardEntry(dirName + '/'));
|
|
||||||
return super.preVisitDirectory(dir, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
|
||||||
String fileName = IOHelper.toString(guardDir.relativize(file));
|
|
||||||
guard.put(fileName, SecurityHelper.digest(DigestAlgorithm.MD5, file));
|
|
||||||
|
|
||||||
// Create zip entry and transfer contents
|
|
||||||
output.putNextEntry(newGuardEntry(fileName));
|
|
||||||
IOHelper.transfer(file, output);
|
|
||||||
|
|
||||||
// Return result
|
|
||||||
return super.visitFile(file, attrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ZipEntry newEntry(String fileName) {
|
|
||||||
return newZipEntry(Launcher.RUNTIME_DIR + IOHelper.CROSS_SEPARATOR + fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ZipEntry newGuardEntry(String fileName) {
|
|
||||||
return newZipEntry(Launcher.GUARD_DIR + IOHelper.CROSS_SEPARATOR + fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Path cleanJar;
|
|
||||||
public final Path runtimeDir;
|
|
||||||
public final Path guardDir;
|
|
||||||
public final Path initScriptFile;
|
|
||||||
public final Path obfJar;
|
|
||||||
public final Path obfOutJar;
|
|
||||||
public ClassMetadataReader reader;
|
|
||||||
|
|
||||||
public JARLauncherBinary(LaunchServer server) throws IOException {
|
public JARLauncherBinary(LaunchServer server) throws IOException {
|
||||||
super(server, server.dir.resolve(server.config.binaryName + "-nonObf.jar"),
|
super(server);
|
||||||
server.dir.resolve(server.config.binaryName + ".jar"));
|
tasks = new ArrayList<>();
|
||||||
runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR);
|
tasks.add(new UnpackBuildTask());
|
||||||
|
tasks.add(new MainBuildTask());
|
||||||
|
tasks.add(new ProGuardBuildTask());
|
||||||
|
/*runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR);
|
||||||
guardDir = server.dir.resolve(Launcher.GUARD_DIR);
|
guardDir = server.dir.resolve(Launcher.GUARD_DIR);
|
||||||
initScriptFile = runtimeDir.resolve(Launcher.INIT_SCRIPT_FILE);
|
initScriptFile = runtimeDir.resolve(Launcher.INIT_SCRIPT_FILE);
|
||||||
obfJar = server.dir.resolve(server.config.binaryName + "-obfPre.jar");
|
obfJar = server.dir.resolve(server.config.binaryName + "-obfPre.jar");
|
||||||
|
@ -132,30 +62,26 @@ public JARLauncherBinary(LaunchServer server) throws IOException {
|
||||||
cleanJar = server.dir.resolve(server.config.binaryName + "-clean.jar");
|
cleanJar = server.dir.resolve(server.config.binaryName + "-clean.jar");
|
||||||
reader = new ClassMetadataReader();
|
reader = new ClassMetadataReader();
|
||||||
UnpackHelper.unpack(IOHelper.getResourceURL("Launcher.jar"), cleanJar);
|
UnpackHelper.unpack(IOHelper.getResourceURL("Launcher.jar"), cleanJar);
|
||||||
reader.getCp().add(new JarFile(cleanJar.toFile()));
|
reader.getCp().add(new JarFile(cleanJar.toFile()));*/
|
||||||
tryUnpack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void build() throws IOException {
|
public void build() throws IOException {
|
||||||
tryUnpack();
|
|
||||||
|
|
||||||
// Build launcher binary
|
// Build launcher binary
|
||||||
LogHelper.info("Building launcher binary file");
|
LogHelper.info("Building launcher binary file");
|
||||||
stdBuild();
|
Path thisPath = null;
|
||||||
|
for(LauncherBuildTask task : tasks)
|
||||||
|
{
|
||||||
|
LogHelper.subInfo("Task %s",task.getName());
|
||||||
|
thisPath = task.process(thisPath);
|
||||||
|
LogHelper.subInfo("Task %s processed",task.getName());
|
||||||
|
}
|
||||||
|
syncBinaryFile = thisPath;
|
||||||
|
LogHelper.info("Build successful");
|
||||||
|
|
||||||
// ProGuard
|
// ProGuard
|
||||||
Configuration proguard_cfg = new Configuration();
|
|
||||||
ConfigurationParser parser = new ConfigurationParser(server.proguardConf.confStrs.toArray(new String[0]),
|
/*for (Runnable r : server.buildHookManager.getPostProguardRunHooks())
|
||||||
server.proguardConf.proguard.toFile(), System.getProperties());
|
|
||||||
try {
|
|
||||||
parser.parse(proguard_cfg);
|
|
||||||
ProGuard proGuard = new ProGuard(proguard_cfg);
|
|
||||||
proGuard.execute();
|
|
||||||
} catch (ParseException e1) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
for (Runnable r : server.buildHookManager.getPostProguardRunHooks())
|
|
||||||
r.run();
|
r.run();
|
||||||
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(obfJar));
|
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(obfJar));
|
||||||
ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(obfOutJar))) {
|
ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(obfOutJar))) {
|
||||||
|
@ -170,7 +96,7 @@ public void build() throws IOException {
|
||||||
IOHelper.transfer(input, outputStream);
|
IOHelper.transfer(input, outputStream);
|
||||||
bytes = outputStream.toByteArray();
|
bytes = outputStream.toByteArray();
|
||||||
}
|
}
|
||||||
bytes = server.buildHookManager.proGuardClassTransform(bytes, classname, this);
|
//bytes = server.buildHookManager.proGuardClassTransform(bytes, classname, this);
|
||||||
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
|
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
|
||||||
IOHelper.transfer(inputStream, output);
|
IOHelper.transfer(inputStream, output);
|
||||||
}
|
}
|
||||||
|
@ -182,11 +108,11 @@ public void build() throws IOException {
|
||||||
h.build(output);
|
h.build(output);
|
||||||
}
|
}
|
||||||
if (server.config.buildPostTransform.enabled)
|
if (server.config.buildPostTransform.enabled)
|
||||||
transformedBuild();
|
transformedBuild();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transformedBuild() throws IOException {
|
private void transformedBuild() throws IOException {
|
||||||
List<String> cmd = new ArrayList<>(1);
|
/*List<String> cmd = new ArrayList<>(1);
|
||||||
for (String v : server.config.buildPostTransform.script)
|
for (String v : server.config.buildPostTransform.script)
|
||||||
cmd.add(CommonHelper.replace(v, "launcher-output", IOHelper.toAbsPathString(syncBinaryFile), "launcher-obf",
|
cmd.add(CommonHelper.replace(v, "launcher-output", IOHelper.toAbsPathString(syncBinaryFile), "launcher-obf",
|
||||||
IOHelper.toAbsPathString(obfJar), "launcher-nonObf", IOHelper.toAbsPathString(binaryFile)));
|
IOHelper.toAbsPathString(obfJar), "launcher-nonObf", IOHelper.toAbsPathString(binaryFile)));
|
||||||
|
@ -199,98 +125,6 @@ private void transformedBuild() throws IOException {
|
||||||
LogHelper.debug("Transformer process return code: " + proc.waitFor());
|
LogHelper.debug("Transformer process return code: " + proc.waitFor());
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}*/
|
||||||
}
|
|
||||||
|
|
||||||
private void stdBuild() throws IOException {
|
|
||||||
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(binaryFile));
|
|
||||||
JAConfigurator jaConfigurator = new JAConfigurator(AutogenConfig.class.getName(), this)) {
|
|
||||||
jaConfigurator.pool.insertClassPath(cleanJar.toFile().getAbsolutePath());
|
|
||||||
BuildContext context = new BuildContext(output, jaConfigurator, this);
|
|
||||||
server.buildHookManager.preHook(context);
|
|
||||||
jaConfigurator.setAddress(server.config.getAddress());
|
|
||||||
jaConfigurator.setPort(server.config.port);
|
|
||||||
jaConfigurator.setProjectName(server.config.projectName);
|
|
||||||
jaConfigurator.setSecretKey(SecurityHelper.randomStringAESKey());
|
|
||||||
jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512));
|
|
||||||
jaConfigurator.setUsingWrapper(server.config.isUsingWrapper);
|
|
||||||
jaConfigurator.setDownloadJava(server.config.isDownloadJava);
|
|
||||||
jaConfigurator.setEnv(server.config.env);
|
|
||||||
server.buildHookManager.registerAllClientModuleClass(jaConfigurator);
|
|
||||||
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(cleanJar))) {
|
|
||||||
ZipEntry e = input.getNextEntry();
|
|
||||||
while (e != null) {
|
|
||||||
String filename = e.getName();
|
|
||||||
if (server.buildHookManager.isContainsBlacklist(filename)) {
|
|
||||||
e = input.getNextEntry();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
output.putNextEntry(IOHelper.newZipEntry(e));
|
|
||||||
} catch (ZipException ex) {
|
|
||||||
LogHelper.error(ex);
|
|
||||||
e = input.getNextEntry();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (filename.endsWith(".class")) {
|
|
||||||
String classname = filename.replace('/', '.').substring(0,
|
|
||||||
filename.length() - ".class".length());
|
|
||||||
byte[] bytes;
|
|
||||||
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048)) {
|
|
||||||
IOHelper.transfer(input, outputStream);
|
|
||||||
bytes = outputStream.toByteArray();
|
|
||||||
}
|
|
||||||
bytes = server.buildHookManager.classTransform(bytes, classname, this);
|
|
||||||
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
|
|
||||||
IOHelper.transfer(inputStream, output);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
IOHelper.transfer(input, output);
|
|
||||||
context.fileList.add(filename);
|
|
||||||
e = input.getNextEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// write additional classes
|
|
||||||
for (Entry<String, byte[]> ent : server.buildHookManager.getIncludeClass().entrySet()) {
|
|
||||||
output.putNextEntry(newZipEntry(ent.getKey().replace('.', '/').concat(".class")));
|
|
||||||
output.write(server.buildHookManager.classTransform(ent.getValue(), ent.getKey(), this));
|
|
||||||
}
|
|
||||||
// map for guard
|
|
||||||
Map<String, byte[]> runtime = new HashMap<>(256);
|
|
||||||
if (server.buildHookManager.buildRuntime()) {
|
|
||||||
// Verify has init script file
|
|
||||||
if (!IOHelper.isFile(initScriptFile))
|
|
||||||
throw new IOException(String.format("Missing init script file ('%s')", Launcher.INIT_SCRIPT_FILE));
|
|
||||||
// Write launcher guard dir
|
|
||||||
IOHelper.walk(runtimeDir, new RuntimeDirVisitor(output, runtime), false);
|
|
||||||
// IOHelper.walk(guardDir, new GuardDirVisitor(output, runtime), false);
|
|
||||||
}
|
|
||||||
// Create launcher config file
|
|
||||||
byte[] launcherConfigBytes;
|
|
||||||
try (ByteArrayOutputStream configArray = IOHelper.newByteArrayOutput()) {
|
|
||||||
try (HOutput configOutput = new HOutput(configArray)) {
|
|
||||||
new LauncherConfig(server.config.getAddress(), server.config.port, server.publicKey, runtime)
|
|
||||||
.write(configOutput);
|
|
||||||
}
|
|
||||||
launcherConfigBytes = configArray.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write launcher config file
|
|
||||||
output.putNextEntry(newZipEntry(Launcher.CONFIG_FILE));
|
|
||||||
output.write(launcherConfigBytes);
|
|
||||||
ZipEntry e = newZipEntry(jaConfigurator.getZipEntryPath());
|
|
||||||
output.putNextEntry(e);
|
|
||||||
jaConfigurator.compile();
|
|
||||||
output.write(jaConfigurator.getBytecode());
|
|
||||||
server.buildHookManager.postHook(context);
|
|
||||||
} catch (CannotCompileException | NotFoundException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tryUnpack() throws IOException {
|
|
||||||
LogHelper.info("Unpacking launcher native guard files and runtime");
|
|
||||||
UnpackHelper.unpackZipNoCheck("guard.zip", guardDir);
|
|
||||||
UnpackHelper.unpackZipNoCheck("runtime.zip", runtimeDir);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,23 +12,19 @@ public abstract class LauncherBinary {
|
||||||
|
|
||||||
public final LaunchServer server;
|
public final LaunchServer server;
|
||||||
|
|
||||||
public final Path binaryFile;
|
public Path syncBinaryFile;
|
||||||
public final 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;
|
||||||
this.binaryFile = binaryFile;
|
|
||||||
syncBinaryFile = binaryFile;
|
syncBinaryFile = binaryFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected LauncherBinary(LaunchServer server, Path binaryFile, Path syncBinaryFile) {
|
protected LauncherBinary(LaunchServer server) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.binaryFile = binaryFile;
|
|
||||||
this.syncBinaryFile = syncBinaryFile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +32,7 @@ protected LauncherBinary(LaunchServer server, Path binaryFile, Path syncBinaryFi
|
||||||
|
|
||||||
|
|
||||||
public final boolean exists() {
|
public final boolean exists() {
|
||||||
return IOHelper.isFile(syncBinaryFile);
|
return syncBinaryFile != null && IOHelper.isFile(syncBinaryFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,22 +30,29 @@ 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 final ArrayList<String> confStrs;
|
||||||
|
public transient final LaunchServer srv;
|
||||||
|
|
||||||
public ProguardConf(LaunchServer srv) {
|
public ProguardConf(LaunchServer srv) {
|
||||||
proguard = srv.dir.resolve("proguard");
|
proguard = srv.dir.resolve("proguard");
|
||||||
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<>();
|
confStrs = new ArrayList<>();
|
||||||
|
this.srv = srv;
|
||||||
|
}
|
||||||
|
public void buildConfig(Path inputJar)
|
||||||
|
{
|
||||||
|
confStrs.clear();
|
||||||
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 \'" + srv.dir.toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + "-nonObf.jar\'");
|
confStrs.add("-injar \'" + inputJar.toAbsolutePath() + "\'");
|
||||||
confStrs.add("-outjar \'" + srv.dir.toAbsolutePath() + IOHelper.PLATFORM_SEPARATOR + srv.config.binaryName + "-obfPre.jar\'");
|
confStrs.add("-outjar \'" + outputJar.toAbsolutePath() + "\'");
|
||||||
confStrs.add("-classobfuscationdictionary \'" + words.toFile().getName() + "\'");
|
confStrs.add("-classobfuscationdictionary \'" + words.toFile().getName() + "\'");
|
||||||
confStrs.add(readConf());
|
confStrs.add(readConf());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void genConfig(boolean force) throws IOException {
|
private void genConfig(boolean force) throws IOException {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.gravit.launchserver.binary.tasks;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public interface LauncherBuildTask {
|
||||||
|
String getName();
|
||||||
|
int priority();
|
||||||
|
Path process(Path inputFile) throws IOException;
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
package ru.gravit.launchserver.binary.tasks;
|
||||||
|
|
||||||
|
import javassist.CannotCompileException;
|
||||||
|
import javassist.NotFoundException;
|
||||||
|
import ru.gravit.launcher.AutogenConfig;
|
||||||
|
import ru.gravit.launcher.Launcher;
|
||||||
|
import ru.gravit.launcher.LauncherConfig;
|
||||||
|
import ru.gravit.launcher.serialize.HOutput;
|
||||||
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
|
import ru.gravit.launchserver.binary.BuildContext;
|
||||||
|
import ru.gravit.launchserver.binary.JAConfigurator;
|
||||||
|
import ru.gravit.launchserver.binary.JARLauncherBinary;
|
||||||
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
import ru.gravit.utils.helper.SecurityHelper;
|
||||||
|
import ru.gravit.utils.helper.UnpackHelper;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileVisitResult;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.SimpleFileVisitor;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipException;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import static ru.gravit.utils.helper.IOHelper.newZipEntry;
|
||||||
|
|
||||||
|
public class MainBuildTask implements LauncherBuildTask {
|
||||||
|
public static LaunchServer server = LaunchServer.server;
|
||||||
|
public final Path runtimeDir;
|
||||||
|
public final Path guardDir;
|
||||||
|
public final Path binaryFile;
|
||||||
|
public Path cleanJar;
|
||||||
|
private final class RuntimeDirVisitor extends SimpleFileVisitor<Path> {
|
||||||
|
private final ZipOutputStream output;
|
||||||
|
private final Map<String, byte[]> runtime;
|
||||||
|
|
||||||
|
private RuntimeDirVisitor(ZipOutputStream output, Map<String, byte[]> runtime) {
|
||||||
|
this.output = output;
|
||||||
|
this.runtime = runtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||||
|
String dirName = IOHelper.toString(runtimeDir.relativize(dir));
|
||||||
|
output.putNextEntry(newEntry(dirName + '/'));
|
||||||
|
return super.preVisitDirectory(dir, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
|
String fileName = IOHelper.toString(runtimeDir.relativize(file));
|
||||||
|
runtime.put(fileName, SecurityHelper.digest(SecurityHelper.DigestAlgorithm.MD5, file));
|
||||||
|
|
||||||
|
// Create zip entry and transfer contents
|
||||||
|
output.putNextEntry(newEntry(fileName));
|
||||||
|
IOHelper.transfer(file, output);
|
||||||
|
|
||||||
|
// Return result
|
||||||
|
return super.visitFile(file, attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: new native security wrapper and library...
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final class GuardDirVisitor extends SimpleFileVisitor<Path> {
|
||||||
|
private final ZipOutputStream output;
|
||||||
|
private final Map<String, byte[]> guard;
|
||||||
|
|
||||||
|
private GuardDirVisitor(ZipOutputStream output, Map<String, byte[]> guard) {
|
||||||
|
this.output = output;
|
||||||
|
this.guard = guard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||||
|
String dirName = IOHelper.toString(guardDir.relativize(dir));
|
||||||
|
output.putNextEntry(newGuardEntry(dirName + '/'));
|
||||||
|
return super.preVisitDirectory(dir, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
|
String fileName = IOHelper.toString(guardDir.relativize(file));
|
||||||
|
guard.put(fileName, SecurityHelper.digest(SecurityHelper.DigestAlgorithm.MD5, file));
|
||||||
|
|
||||||
|
// Create zip entry and transfer contents
|
||||||
|
output.putNextEntry(newGuardEntry(fileName));
|
||||||
|
IOHelper.transfer(file, output);
|
||||||
|
|
||||||
|
// Return result
|
||||||
|
return super.visitFile(file, attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ZipEntry newEntry(String fileName) {
|
||||||
|
return newZipEntry(Launcher.RUNTIME_DIR + IOHelper.CROSS_SEPARATOR + fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ZipEntry newGuardEntry(String fileName) {
|
||||||
|
return newZipEntry(Launcher.GUARD_DIR + IOHelper.CROSS_SEPARATOR + fileName);
|
||||||
|
}
|
||||||
|
public MainBuildTask() {
|
||||||
|
runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR);
|
||||||
|
guardDir = server.dir.resolve(Launcher.GUARD_DIR);
|
||||||
|
binaryFile = server.dir.resolve(server.config.binaryName + "-main_task.jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "main";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path process(Path cleanJar) throws IOException {
|
||||||
|
this.cleanJar = cleanJar;
|
||||||
|
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(binaryFile));
|
||||||
|
JAConfigurator jaConfigurator = new JAConfigurator(AutogenConfig.class.getName(), this)) {
|
||||||
|
jaConfigurator.pool.insertClassPath(cleanJar.toFile().getAbsolutePath());
|
||||||
|
BuildContext context = new BuildContext(output, jaConfigurator, this);
|
||||||
|
server.buildHookManager.preHook(context);
|
||||||
|
jaConfigurator.setAddress(server.config.getAddress());
|
||||||
|
jaConfigurator.setPort(server.config.port);
|
||||||
|
jaConfigurator.setProjectName(server.config.projectName);
|
||||||
|
jaConfigurator.setSecretKey(SecurityHelper.randomStringAESKey());
|
||||||
|
jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512));
|
||||||
|
jaConfigurator.setUsingWrapper(server.config.isUsingWrapper);
|
||||||
|
jaConfigurator.setDownloadJava(server.config.isDownloadJava);
|
||||||
|
jaConfigurator.setEnv(server.config.env);
|
||||||
|
server.buildHookManager.registerAllClientModuleClass(jaConfigurator);
|
||||||
|
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(cleanJar))) {
|
||||||
|
ZipEntry e = input.getNextEntry();
|
||||||
|
while (e != null) {
|
||||||
|
String filename = e.getName();
|
||||||
|
if (server.buildHookManager.isContainsBlacklist(filename)) {
|
||||||
|
e = input.getNextEntry();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
output.putNextEntry(IOHelper.newZipEntry(e));
|
||||||
|
} catch (ZipException ex) {
|
||||||
|
LogHelper.error(ex);
|
||||||
|
e = input.getNextEntry();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*if (filename.endsWith(".class")) {
|
||||||
|
String classname = filename.replace('/', '.').substring(0,
|
||||||
|
filename.length() - ".class".length());
|
||||||
|
byte[] bytes;
|
||||||
|
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048)) {
|
||||||
|
IOHelper.transfer(input, outputStream);
|
||||||
|
bytes = outputStream.toByteArray();
|
||||||
|
}
|
||||||
|
bytes = server.buildHookManager.classTransform(bytes, classname, this);
|
||||||
|
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
|
||||||
|
IOHelper.transfer(inputStream, output);
|
||||||
|
}
|
||||||
|
} else */
|
||||||
|
IOHelper.transfer(input, output);
|
||||||
|
context.fileList.add(filename);
|
||||||
|
e = input.getNextEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// write additional classes
|
||||||
|
for (Map.Entry<String, byte[]> ent : server.buildHookManager.getIncludeClass().entrySet()) {
|
||||||
|
output.putNextEntry(newZipEntry(ent.getKey().replace('.', '/').concat(".class")));
|
||||||
|
output.write(server.buildHookManager.classTransform(ent.getValue(), ent.getKey(), this));
|
||||||
|
}
|
||||||
|
// map for guard
|
||||||
|
Map<String, byte[]> runtime = new HashMap<>(256);
|
||||||
|
if (server.buildHookManager.buildRuntime()) {
|
||||||
|
// Write launcher guard dir
|
||||||
|
IOHelper.walk(runtimeDir, new RuntimeDirVisitor(output, runtime), false);
|
||||||
|
// IOHelper.walk(guardDir, new GuardDirVisitor(output, runtime), false);
|
||||||
|
}
|
||||||
|
// Create launcher config file
|
||||||
|
byte[] launcherConfigBytes;
|
||||||
|
try (ByteArrayOutputStream configArray = IOHelper.newByteArrayOutput()) {
|
||||||
|
try (HOutput configOutput = new HOutput(configArray)) {
|
||||||
|
new LauncherConfig(server.config.getAddress(), server.config.port, server.publicKey, runtime)
|
||||||
|
.write(configOutput);
|
||||||
|
}
|
||||||
|
launcherConfigBytes = configArray.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write launcher config file
|
||||||
|
output.putNextEntry(newZipEntry(Launcher.CONFIG_FILE));
|
||||||
|
output.write(launcherConfigBytes);
|
||||||
|
ZipEntry e = newZipEntry(jaConfigurator.getZipEntryPath());
|
||||||
|
output.putNextEntry(e);
|
||||||
|
jaConfigurator.compile();
|
||||||
|
output.write(jaConfigurator.getBytecode());
|
||||||
|
server.buildHookManager.postHook(context);
|
||||||
|
} catch (CannotCompileException | NotFoundException e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
|
return binaryFile;
|
||||||
|
}
|
||||||
|
public void tryUnpack() throws IOException {
|
||||||
|
LogHelper.info("Unpacking launcher native guard files and runtime");
|
||||||
|
UnpackHelper.unpackZipNoCheck("guard.zip", guardDir);
|
||||||
|
UnpackHelper.unpackZipNoCheck("runtime.zip", runtimeDir);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package ru.gravit.launchserver.binary.tasks;
|
||||||
|
|
||||||
|
import proguard.Configuration;
|
||||||
|
import proguard.ConfigurationParser;
|
||||||
|
import proguard.ParseException;
|
||||||
|
import proguard.ProGuard;
|
||||||
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class ProGuardBuildTask implements LauncherBuildTask {
|
||||||
|
public static LaunchServer server = LaunchServer.server;
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "proguard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package ru.gravit.launchserver.binary.tasks;
|
||||||
|
|
||||||
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
|
import ru.gravit.utils.helper.UnpackHelper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class UnpackBuildTask implements LauncherBuildTask {
|
||||||
|
public static LaunchServer server = LaunchServer.server;
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "unpack clean";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path process(Path inputFile) throws IOException {
|
||||||
|
Path result = server.dir.resolve(server.config.binaryName + "-clean.jar");
|
||||||
|
URL url = IOHelper.getResourceURL("Launcher.jar");
|
||||||
|
UnpackHelper.unpack(url, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
import ru.gravit.launcher.LauncherConfig;
|
import ru.gravit.launcher.LauncherConfig;
|
||||||
import ru.gravit.launchserver.asm.SafeClassWriter;
|
import ru.gravit.launchserver.asm.SafeClassWriter;
|
||||||
import ru.gravit.launchserver.binary.JARLauncherBinary;
|
import ru.gravit.launchserver.binary.JARLauncherBinary;
|
||||||
|
import ru.gravit.launchserver.binary.tasks.MainBuildTask;
|
||||||
import ru.gravit.launchserver.manangers.hook.BuildHookManager.Transformer;
|
import ru.gravit.launchserver.manangers.hook.BuildHookManager.Transformer;
|
||||||
|
|
||||||
public class NodeTransformer implements Transformer {
|
public class NodeTransformer implements Transformer {
|
||||||
|
@ -29,13 +30,14 @@ public NodeTransformer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] transform(byte[] input, String classname, JARLauncherBinary data) {
|
public byte[] transform(byte[] input, String classname, MainBuildTask data) {
|
||||||
ClassReader cr = new ClassReader(input);
|
//ClassReader cr = new ClassReader(input);
|
||||||
ClassNode cn = new ClassNode();
|
//ClassNode cn = new ClassNode();
|
||||||
cr.accept(cn, data.server.config.env.equals(LauncherConfig.LauncherEnvironment.PROD) || data.server.config.env.equals(LauncherConfig.LauncherEnvironment.STD) ? ClassReader.SKIP_DEBUG : 0);
|
//cr.accept(cn, data.server.config.env.equals(LauncherConfig.LauncherEnvironment.PROD) || data.server.config.env.equals(LauncherConfig.LauncherEnvironment.STD) ? ClassReader.SKIP_DEBUG : 0);
|
||||||
for (ClassNodeTransformer tr : transLst) tr.transform(cn, classname, data);
|
//for (ClassNodeTransformer tr : transLst) tr.transform(cn, classname, data);
|
||||||
ClassWriter cw = new SafeClassWriter(data.reader, ClassWriter.COMPUTE_MAXS);
|
//ClassWriter cw = new SafeClassWriter(data.reader, ClassWriter.COMPUTE_MAXS);
|
||||||
cn.accept(cw);
|
//cn.accept(cw);
|
||||||
return cw.toByteArray();
|
//return cw.toByteArray();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
import ru.gravit.launchserver.binary.BuildContext;
|
import ru.gravit.launchserver.binary.BuildContext;
|
||||||
import ru.gravit.launchserver.binary.JAConfigurator;
|
import ru.gravit.launchserver.binary.JAConfigurator;
|
||||||
import ru.gravit.launchserver.binary.JARLauncherBinary;
|
import ru.gravit.launchserver.binary.JARLauncherBinary;
|
||||||
|
import ru.gravit.launchserver.binary.tasks.MainBuildTask;
|
||||||
import ru.gravit.launchserver.manangers.NodeTransformer;
|
import ru.gravit.launchserver.manangers.NodeTransformer;
|
||||||
|
|
||||||
public class BuildHookManager {
|
public class BuildHookManager {
|
||||||
|
@ -26,7 +27,7 @@ public interface BuildHook {
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface Transformer {
|
public interface Transformer {
|
||||||
byte[] transform(byte[] input, String classname, JARLauncherBinary data);
|
byte[] transform(byte[] input, String classname, MainBuildTask data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean BUILDRUNTIME;
|
private boolean BUILDRUNTIME;
|
||||||
|
@ -96,13 +97,13 @@ public boolean buildRuntime() {
|
||||||
return BUILDRUNTIME;
|
return BUILDRUNTIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] classTransform(byte[] clazz, String classname, JARLauncherBinary reader) {
|
public byte[] classTransform(byte[] clazz, String classname, MainBuildTask reader) {
|
||||||
byte[] result = clazz;
|
byte[] result = clazz;
|
||||||
for (Transformer transformer : CLASS_TRANSFORMER) result = transformer.transform(result, classname, reader);
|
for (Transformer transformer : CLASS_TRANSFORMER) result = transformer.transform(result, classname, reader);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] proGuardClassTransform(byte[] clazz, String classname, JARLauncherBinary reader) {
|
public byte[] proGuardClassTransform(byte[] clazz, String classname, MainBuildTask reader) {
|
||||||
byte[] result = clazz;
|
byte[] result = clazz;
|
||||||
for (Transformer transformer : POST_PROGUARD_HOOKS) result = transformer.transform(result, classname, reader);
|
for (Transformer transformer : POST_PROGUARD_HOOKS) result = transformer.transform(result, classname, reader);
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Reference in a new issue