mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 09:01:08 +03:00
Merge branch 'master' of github.com:GravitLauncher/Launcher
This commit is contained in:
commit
df5d3e8020
9 changed files with 24 additions and 80 deletions
|
@ -17,13 +17,14 @@
|
||||||
bundleOnly
|
bundleOnly
|
||||||
bundle
|
bundle
|
||||||
hikari
|
hikari
|
||||||
bundle.extendsFrom bundleOnly
|
pack
|
||||||
compileOnly.extendsFrom bundle, hikari
|
bundleOnly.extendsFrom bundle
|
||||||
|
compile.extendsFrom bundle, hikari, pack
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
dependsOn parent.childProjects.Launcher.tasks.build, parent.childProjects.Launcher.tasks.genRuntimeJS, parent.childProjects.Launcher.tasks.jar
|
dependsOn parent.childProjects.Launcher.tasks.build, parent.childProjects.Launcher.tasks.genRuntimeJS, parent.childProjects.Launcher.tasks.jar
|
||||||
from { configurations.runtime.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,
|
||||||
"Premain-Class": mainAgentName,
|
"Premain-Class": mainAgentName,
|
||||||
|
@ -34,7 +35,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':libLauncher') // pack
|
pack project(':libLauncher') // pack
|
||||||
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.12'
|
bundle 'mysql:mysql-connector-java:8.0.12'
|
||||||
|
@ -70,7 +71,7 @@ task hikari(type: Copy) {
|
||||||
task dumpLibs(type: Copy) {
|
task dumpLibs(type: Copy) {
|
||||||
dependsOn tasks.hikari
|
dependsOn tasks.hikari
|
||||||
into "$buildDir/libs/libraries"
|
into "$buildDir/libs/libraries"
|
||||||
from configurations.bundle
|
from configurations.bundleOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
build.dependsOn tasks.dumpLibs
|
build.dependsOn tasks.dumpLibs
|
||||||
|
|
|
@ -59,6 +59,7 @@ public void invoke(String... args) throws IOException, CommandException {
|
||||||
}
|
}
|
||||||
client.setTitle(dirName);
|
client.setTitle(dirName);
|
||||||
client.block.getEntry("dir", StringConfigEntry.class).setValue(dirName);
|
client.block.getEntry("dir", StringConfigEntry.class).setValue(dirName);
|
||||||
|
client.block.getEntry("title", StringConfigEntry.class).setValue(dirName);
|
||||||
try (BufferedWriter writer = IOHelper.newWriter(IOHelper.resolveIncremental(server.profilesDir,
|
try (BufferedWriter writer = IOHelper.newWriter(IOHelper.resolveIncremental(server.profilesDir,
|
||||||
dirName, "cfg"))) {
|
dirName, "cfg"))) {
|
||||||
TextConfigWriter.write(client.block, writer, true);
|
TextConfigWriter.write(client.block, writer, true);
|
||||||
|
|
|
@ -25,6 +25,6 @@ public String getUsageDescription() {
|
||||||
public void invoke(String... args) throws Exception {
|
public void invoke(String... args) throws Exception {
|
||||||
verifyArgs(args, 1);
|
verifyArgs(args, 1);
|
||||||
URI uri = Paths.get(args[0]).toUri();
|
URI uri = Paths.get(args[0]).toUri();
|
||||||
server.modulesManager.loadModule(uri.toURL(), false);
|
server.modulesManager.loadModuleFull(uri.toURL());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':LauncherAPI')
|
compile project(':LauncherAPI')
|
||||||
compile 'org.javassist:javassist:3.23.1-GA'
|
compile 'com.github.oshi:oshi-core:3.11.0'
|
||||||
compile group: 'com.github.oshi', name: 'oshi-core', version: '3.11.0'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task genRuntimeJS(type: Zip) {
|
task genRuntimeJS(type: Zip) {
|
||||||
|
|
|
@ -3,6 +3,5 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.fusesource.jansi:jansi:1.17.1'
|
compileOnly 'org.fusesource.jansi:jansi:1.17.1'
|
||||||
compileOnly 'org.javassist:javassist:3.23.1-GA'
|
|
||||||
compile 'com.google.code.gson:gson:2.8.5'
|
compile 'com.google.code.gson:gson:2.8.5'
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,12 @@
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.instrument.Instrumentation;
|
import java.lang.instrument.Instrumentation;
|
||||||
import java.lang.instrument.UnmodifiableClassException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
import javassist.bytecode.ClassFile;
|
|
||||||
import ru.gravit.launcher.transformers.SystemClassLoaderTransformer;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public class LauncherAgent {
|
public class LauncherAgent {
|
||||||
private static final boolean enabled = false;
|
|
||||||
private static boolean isAgentStarted = false;
|
private static boolean isAgentStarted = false;
|
||||||
public static Instrumentation inst;
|
public static Instrumentation inst;
|
||||||
|
|
||||||
|
@ -33,22 +28,6 @@ public static void premain(String agentArgument, Instrumentation instrumentation
|
||||||
System.out.println("Launcher Agent");
|
System.out.println("Launcher Agent");
|
||||||
inst = instrumentation;
|
inst = instrumentation;
|
||||||
isAgentStarted = true;
|
isAgentStarted = true;
|
||||||
|
|
||||||
if (ClassFile.MAJOR_VERSION > ClassFile.JAVA_8 || enabled) {
|
|
||||||
inst.addTransformer(new SystemClassLoaderTransformer());
|
|
||||||
Class<?>[] classes = inst.getAllLoadedClasses(); // Получаем список уже загруженных классов, которые могут быть изменены. Классы, которые ещё не загружены, будут изменены при загрузке
|
|
||||||
ArrayList<Class<?>> classList = new ArrayList<>();
|
|
||||||
for (Class<?> classe : classes)
|
|
||||||
if (inst.isModifiableClass(classe))
|
|
||||||
classList.add(classe);
|
|
||||||
// Reload classes, if possible.
|
|
||||||
Class<?>[] workaround = new Class[classList.size()];
|
|
||||||
try {
|
|
||||||
inst.retransformClasses(classList.toArray(workaround)); // Запускаем процесс трансформации
|
|
||||||
} catch (UnmodifiableClassException e) {
|
|
||||||
System.err.println("MainClass was unable to retransform early loaded classes: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isStarted() {
|
public static boolean isStarted() {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package ru.gravit.launcher;
|
package ru.gravit.launcher;
|
||||||
|
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface NeedGarbageCollection {
|
public interface NeedGarbageCollection {
|
||||||
void garbageCollection();
|
void garbageCollection();
|
||||||
|
|
|
@ -105,6 +105,21 @@ public void loadModule(URL jarpath, boolean preload) throws ClassNotFoundExcepti
|
||||||
f.close();
|
f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadModuleFull(URL jarpath) throws ClassNotFoundException, IllegalAccessException, InstantiationException, URISyntaxException, IOException {
|
||||||
|
JarFile f = new JarFile(Paths.get(jarpath.toURI()).toString());
|
||||||
|
Manifest m = f.getManifest();
|
||||||
|
String mainclass = m.getMainAttributes().getValue("Main-Class");
|
||||||
|
classloader.addURL(jarpath);
|
||||||
|
Class<?> moduleclass = Class.forName(mainclass, true, classloader);
|
||||||
|
Module module = (Module) moduleclass.newInstance();
|
||||||
|
modules.add(module);
|
||||||
|
module.preInit(context);
|
||||||
|
module.init(context);
|
||||||
|
module.postInit(context);
|
||||||
|
LogHelper.info("Module %s version: %s loaded", module.getName(), module.getVersion());
|
||||||
|
f.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
public void loadModule(URL jarpath, String classname, boolean preload) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
|
public void loadModule(URL jarpath, String classname, boolean preload) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
package ru.gravit.launcher.transformers;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
|
||||||
import java.security.ProtectionDomain;
|
|
||||||
|
|
||||||
import javassist.ClassPool;
|
|
||||||
import javassist.CodeConverter;
|
|
||||||
import javassist.CtClass;
|
|
||||||
import javassist.CtConstructor;
|
|
||||||
import javassist.CtMethod;
|
|
||||||
import javassist.LoaderClassPath;
|
|
||||||
import ru.gravit.utils.PublicURLClassLoader;
|
|
||||||
|
|
||||||
public class SystemClassLoaderTransformer implements ClassFileTransformer {
|
|
||||||
@Override
|
|
||||||
public byte[] transform(ClassLoader classLoader, String classname, Class<?> aClass, ProtectionDomain protectionDomain, byte[] bytes) {
|
|
||||||
if (classname.startsWith("ru/gravit/launcher/")) return bytes;
|
|
||||||
if (classname.startsWith("java/")) return bytes;
|
|
||||||
if (classname.startsWith("sun/")) return bytes;
|
|
||||||
if (classname.startsWith("com/sun/")) return bytes;
|
|
||||||
if (classname.startsWith("javax/")) return bytes;
|
|
||||||
if (classname.startsWith("jdk/")) return bytes;
|
|
||||||
try {
|
|
||||||
ClassPool pool = ClassPool.getDefault();
|
|
||||||
pool.appendClassPath(new LoaderClassPath(PublicURLClassLoader.systemclassloader));
|
|
||||||
pool.appendClassPath(new LoaderClassPath(classLoader));
|
|
||||||
CtClass s1 = pool.get("java.lang.ClassLoader");
|
|
||||||
CtMethod m11 = s1.getDeclaredMethod("getSystemClassLoader"); // Находим метод, который нам нужно заменить
|
|
||||||
CtClass s2 = pool.get(PublicURLClassLoader.class.getName());
|
|
||||||
CtMethod m21 = s2.getDeclaredMethod("getSystemClassLoader"); // Находим метод, на который мы будем заменять
|
|
||||||
CodeConverter cc = new CodeConverter();
|
|
||||||
cc.redirectMethodCall(m11, m21); // Указываем что на что нам нужно заменить
|
|
||||||
|
|
||||||
CtClass cl = pool.makeClass(new ByteArrayInputStream(bytes), false); // Загружаем класс, переданный для трансформации
|
|
||||||
if (cl.isFrozen()) return null;
|
|
||||||
CtConstructor[] constructors = cl.getConstructors(); // Находим все конструкторы класса
|
|
||||||
for (CtConstructor constructor : constructors)
|
|
||||||
constructor.instrument(cc); // Заменяем вызовы
|
|
||||||
CtMethod[] methods = cl.getDeclaredMethods(); // Находим все методы класса
|
|
||||||
for (CtMethod method : methods)
|
|
||||||
method.instrument(cc); // Заменяем вызовы
|
|
||||||
return cl.toBytecode();
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue