Merge branch 'master' of github.com:GravitLauncher/Launcher

This commit is contained in:
Gravit 2018-12-20 16:38:01 +07:00
commit df5d3e8020
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
9 changed files with 24 additions and 80 deletions

View file

@ -17,13 +17,14 @@
bundleOnly
bundle
hikari
bundle.extendsFrom bundleOnly
compileOnly.extendsFrom bundle, hikari
pack
bundleOnly.extendsFrom bundle
compile.extendsFrom bundle, hikari, pack
}
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)
manifest.attributes("Main-Class": mainClassName,
"Premain-Class": mainAgentName,
@ -34,7 +35,7 @@
}
dependencies {
compile project(':libLauncher') // pack
pack project(':libLauncher') // pack
bundle 'org.ow2.asm:asm-commons:7.0'
bundle 'org.ow2.asm:asm-util:7.0'
bundle 'mysql:mysql-connector-java:8.0.12'
@ -70,7 +71,7 @@ task hikari(type: Copy) {
task dumpLibs(type: Copy) {
dependsOn tasks.hikari
into "$buildDir/libs/libraries"
from configurations.bundle
from configurations.bundleOnly
}
build.dependsOn tasks.dumpLibs

View file

@ -59,6 +59,7 @@ public void invoke(String... args) throws IOException, CommandException {
}
client.setTitle(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,
dirName, "cfg"))) {
TextConfigWriter.write(client.block, writer, true);

View file

@ -25,6 +25,6 @@ public String getUsageDescription() {
public void invoke(String... args) throws Exception {
verifyArgs(args, 1);
URI uri = Paths.get(args[0]).toUri();
server.modulesManager.loadModule(uri.toURL(), false);
server.modulesManager.loadModuleFull(uri.toURL());
}
}

View file

@ -22,8 +22,7 @@
dependencies {
compile project(':LauncherAPI')
compile 'org.javassist:javassist:3.23.1-GA'
compile group: 'com.github.oshi', name: 'oshi-core', version: '3.11.0'
compile 'com.github.oshi:oshi-core:3.11.0'
}
task genRuntimeJS(type: Zip) {

View file

@ -3,6 +3,5 @@
dependencies {
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'
}

View file

@ -2,17 +2,12 @@
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.ArrayList;
import java.util.jar.JarFile;
import javassist.bytecode.ClassFile;
import ru.gravit.launcher.transformers.SystemClassLoaderTransformer;
import ru.gravit.utils.helper.LogHelper;
@LauncherAPI
public class LauncherAgent {
private static final boolean enabled = false;
private static boolean isAgentStarted = false;
public static Instrumentation inst;
@ -33,22 +28,6 @@ public static void premain(String agentArgument, Instrumentation instrumentation
System.out.println("Launcher Agent");
inst = instrumentation;
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() {

View file

@ -1,6 +1,5 @@
package ru.gravit.launcher;
@FunctionalInterface
public interface NeedGarbageCollection {
void garbageCollection();

View file

@ -105,6 +105,21 @@ public void loadModule(URL jarpath, boolean preload) throws ClassNotFoundExcepti
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
public void loadModule(URL jarpath, String classname, boolean preload) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

View file

@ -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;
}
}