diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java index 53118da0..0e547f35 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java @@ -15,6 +15,7 @@ import ru.gravit.launchserver.auth.handler.MemoryAuthHandler; import ru.gravit.launchserver.auth.hwid.AcceptHWIDHandler; import ru.gravit.launchserver.auth.hwid.HWIDHandler; +import ru.gravit.launchserver.auth.permissions.DefaultPermissionsHandler; import ru.gravit.launchserver.auth.permissions.JsonFilePermissionsHandler; import ru.gravit.launchserver.auth.permissions.PermissionsHandler; import ru.gravit.launchserver.auth.protect.NoProtectHandler; @@ -45,6 +46,7 @@ import java.io.File; import java.io.IOException; import java.lang.ProcessBuilder.Redirect; +import java.lang.reflect.InvocationTargetException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.file.*; @@ -308,7 +310,7 @@ public static void main(String... args) throws Throwable { long startTime = System.currentTimeMillis(); try { @SuppressWarnings("resource") - LaunchServer launchserver = new LaunchServer(IOHelper.WORKING_DIR, args); + LaunchServer launchserver = new LaunchServer(IOHelper.WORKING_DIR, false, args); if (args.length == 0) launchserver.run(); else { //Обработка команды launchserver.commandHandler.eval(args, false); @@ -325,6 +327,8 @@ public static void main(String... args) throws Throwable { public final Path dir; + public final boolean testEnv; + public final Path launcherLibraries; public final Path launcherLibrariesCompile; @@ -354,6 +358,8 @@ public static void main(String... args) throws Throwable { public final JARLauncherBinary launcherBinary; + public Class launcherEXEBinaryClass; + public final LauncherBinary launcherEXEBinary; // HWID ban + anti-brutforce @@ -397,8 +403,11 @@ public static void main(String... args) throws Throwable { public static Gson gson; public static GsonBuilder gsonBuilder; - public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecException { + public static Class defaultLauncherEXEBinaryClass = null; + + public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException, InvalidKeySpecException { this.dir = dir; + this.testEnv = testEnv; taskPool = new Timer("Timered task worker thread", true); launcherLibraries = dir.resolve("launcher-libraries"); launcherLibrariesCompile = dir.resolve("launcher-libraries-compile"); @@ -422,16 +431,19 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE // Set command handler CommandHandler localCommandHandler; - try { - Class.forName("jline.Terminal"); + if (testEnv) + localCommandHandler = new StdCommandHandler(false); + else + try { + Class.forName("jline.Terminal"); - // JLine2 available - localCommandHandler = new JLineCommandHandler(); - LogHelper.info("JLine2 terminal enabled"); - } catch (ClassNotFoundException ignored) { - localCommandHandler = new StdCommandHandler(true); - LogHelper.warning("JLine2 isn't in classpath, using std"); - } + // JLine2 available + localCommandHandler = new JLineCommandHandler(); + LogHelper.info("JLine2 terminal enabled"); + } catch (ClassNotFoundException ignored) { + localCommandHandler = new StdCommandHandler(true); + LogHelper.warning("JLine2 isn't in classpath, using std"); + } ru.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler); commandHandler = localCommandHandler; @@ -459,6 +471,9 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE crc.update(publicKey.getModulus().toByteArray()); // IDEA говорит, что это Java 9 API. WTF? LogHelper.subInfo("Modulus CRC32: 0x%08x", crc.getValue()); + // Load class bindings. + launcherEXEBinaryClass = defaultLauncherEXEBinaryClass; + // pre init modules modulesManager = new ModulesManager(this); modulesManager.autoload(dir.resolve("modules")); @@ -466,7 +481,7 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE initGson(); // Read LaunchServer config - generateConfigIfNotExists(); + generateConfigIfNotExists(testEnv); LogHelper.info("Reading LaunchServer config file"); try (BufferedReader reader = IOHelper.newReader(configFile)) { config = Launcher.gson.fromJson(reader, Config.class); @@ -589,6 +604,14 @@ public static void initGson() { } private LauncherBinary binary() { + if (launcherEXEBinaryClass != null) { + try { + return (LauncherBinary)launcherEXEBinaryClass.getConstructor(LaunchServer.class).newInstance(this); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException | SecurityException e) { + LogHelper.error(e); + } + } try { Class.forName("net.sf.launch4j.Builder"); if (config.launch4j.enabled) return new EXEL4JLauncherBinary(this); @@ -614,7 +637,7 @@ public void close() { LogHelper.info("LaunchServer stopped"); } - private void generateConfigIfNotExists() throws IOException { + private void generateConfigIfNotExists(boolean testEnv) throws IOException { if (IOHelper.isFile(configFile)) return; @@ -640,7 +663,8 @@ private void generateConfigIfNotExists() throws IOException { new RequestTextureProvider("http://example.com/skins/%username%.png", "http://example.com/cloaks/%username%.png") , "std")}; newConfig.protectHandler = new NoProtectHandler(); - newConfig.permissionsHandler = new JsonFilePermissionsHandler(); + if (testEnv) newConfig.permissionsHandler = new DefaultPermissionsHandler(); + else newConfig.permissionsHandler = new JsonFilePermissionsHandler(); newConfig.legacyPort = 7240; newConfig.legacyBindAddress = "0.0.0.0"; newConfig.binaryName = "Launcher"; @@ -674,10 +698,15 @@ private void generateConfigIfNotExists() throws IOException { newConfig.components.put("authLimiter", authLimiterComponent); // Set server address - System.out.println("LaunchServer address: "); - newConfig.setLegacyAddress(commandHandler.readLine()); - System.out.println("LaunchServer projectName: "); - newConfig.setProjectName(commandHandler.readLine()); + if (testEnv) { + newConfig.setLegacyAddress("localhost"); + newConfig.setProjectName("test"); + } else { + System.out.println("LaunchServer address: "); + newConfig.setLegacyAddress(commandHandler.readLine()); + System.out.println("LaunchServer projectName: "); + newConfig.setProjectName(commandHandler.readLine()); + } // Write LaunchServer config LogHelper.info("Writing LaunchServer config file"); @@ -686,10 +715,13 @@ private void generateConfigIfNotExists() throws IOException { } } - public Collection getProfiles() { + public List getProfiles() { return profilesList; } + public void setProfiles(List profilesList) { + this.profilesList = Collections.unmodifiableList(profilesList); + } public SignedObjectHolder getUpdateDir(String name) { return updatesDirMap.get(name); @@ -717,8 +749,10 @@ public void run() { throw new IllegalStateException("LaunchServer has been already started"); // Add shutdown hook, then start LaunchServer - JVMHelper.RUNTIME.addShutdownHook(CommonHelper.newThread(null, false, this::close)); - CommonHelper.newThread("Command Thread", true, commandHandler).start(); + if (!this.testEnv) { + JVMHelper.RUNTIME.addShutdownHook(CommonHelper.newThread(null, false, this::close)); + CommonHelper.newThread("Command Thread", true, commandHandler).start(); + } rebindServerSocket(); if (config.netty != null) rebindNettyServerSocket(); diff --git a/Launcher/build.gradle b/Launcher/build.gradle index a5f72937..f15b639d 100644 --- a/Launcher/build.gradle +++ b/Launcher/build.gradle @@ -28,6 +28,7 @@ dependencies { pack project(':LauncherAPI') // Not error on obf. bundle 'com.github.oshi:oshi-core:3.13.0' + bundle 'org.ow2.asm:asm-tree:7.1' } task genRuntimeJS(type: Zip) { diff --git a/Launcher/src/main/java/ru/gravit/launcher/ClientLauncherWrapper.java b/Launcher/src/main/java/ru/gravit/launcher/ClientLauncherWrapper.java index aede9407..f8c6c03d 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/ClientLauncherWrapper.java +++ b/Launcher/src/main/java/ru/gravit/launcher/ClientLauncherWrapper.java @@ -40,7 +40,7 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_OPTDIR_PROPERTY); Collections.addAll(args, MAGIC_ARG); Collections.addAll(args, "-XX:+DisableAttachMechanism"); - Collections.addAll(args, "-javaagent:".concat(pathLauncher)); + Collections.addAll(args, "-javaagent:".concat(pathLauncher).concat("=pr")); Collections.addAll(args, "-cp"); Collections.addAll(args, pathLauncher); Collections.addAll(args, LauncherEngine.class.getName()); diff --git a/Launcher/src/main/java/ru/gravit/launcher/LauncherAgent.java b/Launcher/src/main/java/ru/gravit/launcher/LauncherAgent.java new file mode 100644 index 00000000..3a589a16 --- /dev/null +++ b/Launcher/src/main/java/ru/gravit/launcher/LauncherAgent.java @@ -0,0 +1,159 @@ +package ru.gravit.launcher; + +import ru.gravit.utils.helper.LogHelper; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.instrument.Instrumentation; +import java.util.jar.JarFile; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.MethodNode; + +import static org.objectweb.asm.Opcodes.*; + +@LauncherAPI +public final class LauncherAgent { + private static boolean isAgentStarted = false; + public static Instrumentation inst; + + public static void addJVMClassPath(String path) throws IOException { + LogHelper.debug("Launcher Agent addJVMClassPath"); + inst.appendToSystemClassLoaderSearch(new JarFile(path)); + } + + public boolean isAgentStarted() { + return isAgentStarted; + } + + public static void premain(String agentArgument, Instrumentation instrumentation) { + System.out.println("Launcher Agent"); + inst = instrumentation; + isAgentStarted = true; + boolean pb = true; + boolean rt = true; + if (agentArgument != null) { + String trimmedArg = agentArgument.trim(); + if (!trimmedArg.isEmpty()) { + if (trimmedArg.contains("p")) pb = false; + if (trimmedArg.contains("r")) rt = false; + } + } + replaceClasses(pb, rt); + } + + public static boolean isStarted() { + return isAgentStarted; + } + + /** + * @author https://github.com/Konloch/JVM-Sandbox + * Replaces the Runtime class via instrumentation, transforms the class via ASM + */ + public static void replaceClasses(boolean pb, boolean rt) { + for(Class c : inst.getAllLoadedClasses()) { + if(rt && c.getName().equals("java.lang.Runtime")) { + try { + inst.redefineClasses(new java.lang.instrument.ClassDefinition(java.lang.Runtime.class, transformClass(c.getName(), getClassFile(c)))); + } catch(Exception e) { + e.printStackTrace(); + } + } + if(pb && c.getName().equals("java.lang.ProcessBuilder")) { + try { + inst.redefineClasses(new java.lang.instrument.ClassDefinition(java.lang.ProcessBuilder.class, transformClass(c.getName(), getClassFile(c)))); + } catch(Exception e) { + e.printStackTrace(); + } + } + if(c.getName().equals("java.awt.Robot")) { + try { + inst.redefineClasses(new java.lang.instrument.ClassDefinition(java.lang.ProcessBuilder.class, transformClass(c.getName(), getClassFile(c)))); + } catch(Exception e) { + e.printStackTrace(); + } + } + } + } + + /** + * @author https://github.com/Konloch/JVM-Sandbox + * Use ASM to modify the byte array + */ + public static byte[] transformClass(String className, byte[] classBytes) { + if (className.equals("java.lang.Runtime")) { + ClassReader cr=new ClassReader(classBytes); + ClassNode cn=new ClassNode(); + cr.accept(cn,ClassReader.EXPAND_FRAMES); + + for (Object o : cn.methods.toArray()) { + MethodNode m = (MethodNode) o; + if(m.name.equals("exec")) { + m.instructions.insert(new InsnNode(ARETURN)); + m.instructions.insert(new InsnNode(ACONST_NULL)); + } + } + ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + cn.accept(cw); + return cw.toByteArray(); + } else if (className.equals("java.lang.ProcessBuilder")) { + ClassReader cr=new ClassReader(classBytes); + ClassNode cn=new ClassNode(); + cr.accept(cn,ClassReader.EXPAND_FRAMES); + + for (Object o : cn.methods.toArray()) { + MethodNode m = (MethodNode) o; + if(m.name.equals("start")) { + m.instructions.insert(new InsnNode(ARETURN)); + m.instructions.insert(new InsnNode(ACONST_NULL)); + } + } + ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + cn.accept(cw); + return cw.toByteArray(); + } else if (className.equals("java.awt.Robot")) { + ClassReader cr=new ClassReader(classBytes); + ClassNode cn=new ClassNode(); + cr.accept(cn,ClassReader.EXPAND_FRAMES); + + for (Object o : cn.methods.toArray()) { + MethodNode m = (MethodNode) o; + if( m.name.equals("createScreenCapture") || m.name.equals("getPixelColor") || + m.name.equals("keyPress") || m.name.equals("keyRelease") || + m.name.equals("mouseMove") || m.name.equals("mousePress") || + m.name.equals("mouseWheel")) + { + m.instructions.insert(new InsnNode(ARETURN)); + m.instructions.insert(new InsnNode(ACONST_NULL)); + } + } + ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + cn.accept(cw); + return cw.toByteArray(); + } + return classBytes; + } + + /** + * @author https://github.com/Konloch/JVM-Sandbox + * Do not remove this method. Do not to cause classloading! + * Grab the byte array from the loaded Class object + * @param clazz + * @return array, respending this class in bytecode. + * @throws IOException + */ + public static byte[] getClassFile(Class clazz) throws IOException { + InputStream is = clazz.getResourceAsStream( "/" + clazz.getName().replace('.', '/') + ".class"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int r = 0; + byte[] buffer = new byte[8192]; + while((r=is.read(buffer))>=0) { + baos.write(buffer, 0, r); + } + return baos.toByteArray(); + } +} diff --git a/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java b/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java index d6e1ee5b..6c2e1ba9 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java +++ b/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java @@ -14,7 +14,6 @@ import ru.gravit.launcher.request.websockets.RequestInterface; import ru.gravit.launcher.serialize.signed.SignedObjectHolder; -import java.io.IOException; import java.nio.file.Path; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/SetProfileRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/SetProfileRequest.java index c749edfa..8c391fe6 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/SetProfileRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/SetProfileRequest.java @@ -8,12 +8,10 @@ import ru.gravit.launcher.request.websockets.RequestInterface; public class SetProfileRequest extends Request implements RequestInterface { - private transient ClientProfile profile; @LauncherNetworkAPI public String client; public SetProfileRequest(ClientProfile profile) { - this.profile = profile; this.client = profile.getTitle(); } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java index 25258cf9..68401d5b 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java @@ -10,7 +10,6 @@ import ru.gravit.launcher.hasher.HashedEntry; import ru.gravit.launcher.hasher.HashedFile; import ru.gravit.launcher.request.Request; -import ru.gravit.launcher.request.UpdateAction; import ru.gravit.launcher.request.update.UpdateRequest.State.Callback; import ru.gravit.launcher.request.websockets.LegacyRequestBridge; import ru.gravit.launcher.request.websockets.RequestInterface; @@ -26,7 +25,6 @@ import java.util.List; import java.util.Map.Entry; import java.util.Objects; -import java.util.Queue; public final class UpdateRequest extends Request implements RequestInterface { @@ -168,26 +166,6 @@ public double getTotalSizeMiB() { } } - private static void fillActionsQueue(Queue queue, HashedDir mismatch) { - for (Entry mapEntry : mismatch.map().entrySet()) { - String name = mapEntry.getKey(); - HashedEntry entry = mapEntry.getValue(); - HashedEntry.Type entryType = entry.getType(); - switch (entryType) { - case DIR: // cd - get - cd .. - queue.add(new UpdateAction(UpdateAction.Type.CD, name, entry)); - fillActionsQueue(queue, (HashedDir) entry); - queue.add(UpdateAction.CD_BACK); - break; - case FILE: // get - queue.add(new UpdateAction(UpdateAction.Type.GET, name, entry)); - break; - default: - throw new AssertionError("Unsupported hashed entry type: " + entryType.name()); - } - } - } - @Override public UpdateRequestEvent requestDo() throws Exception { LogHelper.debug("Start update request"); diff --git a/LauncherTest/src/main/java/Empty.java b/LauncherTest/src/main/java/Empty.java deleted file mode 100644 index e69de29b..00000000 diff --git a/LauncherTest/src/main/java/ru/gravit/launcher/test/utils/EXENonWarningLauncherBinary.java b/LauncherTest/src/main/java/ru/gravit/launcher/test/utils/EXENonWarningLauncherBinary.java new file mode 100644 index 00000000..3d8b409c --- /dev/null +++ b/LauncherTest/src/main/java/ru/gravit/launcher/test/utils/EXENonWarningLauncherBinary.java @@ -0,0 +1,23 @@ +package ru.gravit.launcher.test.utils; + +import ru.gravit.launchserver.LaunchServer; +import ru.gravit.launchserver.binary.LauncherBinary; +import ru.gravit.utils.helper.IOHelper; + +import java.io.IOException; +import java.nio.file.Files; + +public class EXENonWarningLauncherBinary extends LauncherBinary { + + public EXENonWarningLauncherBinary(LaunchServer server) { + super(server, server.dir.resolve(server.config.binaryName + ".exe")); + } + + @Override + public void build() throws IOException { + if (IOHelper.isFile(syncBinaryFile)) { + Files.delete(syncBinaryFile); + } + } + +} diff --git a/LauncherTest/src/test/java/Empty.java b/LauncherTest/src/test/java/Empty.java deleted file mode 100644 index e69de29b..00000000 diff --git a/LauncherTest/src/test/java/ru/gravit/launcher/StartTest.java b/LauncherTest/src/test/java/ru/gravit/launcher/StartTest.java new file mode 100644 index 00000000..8b546a8c --- /dev/null +++ b/LauncherTest/src/test/java/ru/gravit/launcher/StartTest.java @@ -0,0 +1,36 @@ +package ru.gravit.launcher; + +import java.io.IOException; +import java.nio.file.Path; +import java.security.spec.InvalidKeySpecException; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import ru.gravit.launcher.test.utils.EXENonWarningLauncherBinary; +import ru.gravit.launchserver.LaunchServer; +import ru.gravit.utils.helper.LogHelper; + +public class StartTest { + @TempDir + public Path dir; + + @BeforeAll + public static void prepare() { + LogHelper.removeStdOutput(); + LaunchServer.defaultLauncherEXEBinaryClass = EXENonWarningLauncherBinary.class; + } + + @Test + public void checkLaunchServerStarts() { + try { + LaunchServer srv = new LaunchServer(dir, true, new String[] { "checkInstall" }); + srv.run(); + srv.commandHandler.eval(new String[] { "checkInstall" }, false); + srv.close(); + } catch (InvalidKeySpecException | IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/Radon b/Radon index e1f7548f..e6974532 160000 --- a/Radon +++ b/Radon @@ -1 +1 @@ -Subproject commit e1f7548f97132fa29b01f68bd57ffab32de7b6e7 +Subproject commit e6974532efc7228a8b826a8cd9e1f1f7b609659f diff --git a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java index 115f978b..ec2974cc 100644 --- a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java @@ -37,7 +37,7 @@ public class ServerWrapper extends JsonConfigurable { public ClassLoader loader; public ClientPermissions permissions; public static ServerWrapper wrapper; - private static Gson gson; + public static Gson gson; private static GsonBuilder gsonBuiler; public static Path modulesDir = Paths.get(System.getProperty("serverwrapper.modulesDir", "modules")); diff --git a/ServerWrapper/src/main/java/ru/gravit/launcher/server/setup/ServerWrapperSetup.java b/ServerWrapper/src/main/java/ru/gravit/launcher/server/setup/ServerWrapperSetup.java index d583d160..b7d192ec 100644 --- a/ServerWrapper/src/main/java/ru/gravit/launcher/server/setup/ServerWrapperSetup.java +++ b/ServerWrapper/src/main/java/ru/gravit/launcher/server/setup/ServerWrapperSetup.java @@ -1,6 +1,5 @@ package ru.gravit.launcher.server.setup; -import ru.gravit.launcher.LauncherConfig; import ru.gravit.launcher.server.ServerWrapper; import ru.gravit.utils.PublicURLClassLoader; import ru.gravit.utils.helper.IOHelper; @@ -24,20 +23,22 @@ public void run() throws IOException { System.out.println("Print jar filename:"); String jarName = commands.commandHandler.readLine(); Path jarPath = Paths.get(jarName); - JarFile file = new JarFile(jarPath.toFile()); - URL jarURL = jarPath.toUri().toURL(); - urlClassLoader = new PublicURLClassLoader(new URL[]{jarURL}); - LogHelper.info("Check jar MainClass"); - String mainClassName = file.getManifest().getMainAttributes().getValue("Main-Class"); - if (mainClassName == null) { - LogHelper.error("Main-Class not found in MANIFEST"); - return; - } - try { - Class mainClass = Class.forName(mainClassName, false, urlClassLoader); - } catch (ClassNotFoundException e) { - LogHelper.error(e); - return; + String mainClassName = null; + try (JarFile file = new JarFile(jarPath.toFile())) { + URL jarURL = jarPath.toUri().toURL(); + urlClassLoader = new PublicURLClassLoader(new URL[]{jarURL}); + LogHelper.info("Check jar MainClass"); + mainClassName = file.getManifest().getMainAttributes().getValue("Main-Class"); + if (mainClassName == null) { + LogHelper.error("Main-Class not found in MANIFEST"); + return; + } + try { + Class.forName(mainClassName, false, urlClassLoader); + } catch (ClassNotFoundException e) { + LogHelper.error(e); + return; + } } LogHelper.info("Found MainClass %s", mainClassName); System.out.println("Print launchserver websocket host:"); @@ -66,7 +67,6 @@ public void run() throws IOException { wrapper.config.password = password; wrapper.config.title = title; wrapper.config.stopOnError = false; - LauncherConfig cfg = null; if (wrapper.auth()) { break; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/LauncherAgent.java b/libLauncher/src/main/java/ru/gravit/launcher/LauncherAgent.java deleted file mode 100644 index 8c94c604..00000000 --- a/libLauncher/src/main/java/ru/gravit/launcher/LauncherAgent.java +++ /dev/null @@ -1,32 +0,0 @@ -package ru.gravit.launcher; - -import ru.gravit.utils.helper.LogHelper; - -import java.io.IOException; -import java.lang.instrument.Instrumentation; -import java.util.jar.JarFile; - -@LauncherAPI -public final class LauncherAgent { - private static boolean isAgentStarted = false; - public static Instrumentation inst; - - public static void addJVMClassPath(String path) throws IOException { - LogHelper.debug("Launcher Agent addJVMClassPath"); - inst.appendToSystemClassLoaderSearch(new JarFile(path)); - } - - public boolean isAgentStarted() { - return isAgentStarted; - } - - public static void premain(String agentArgument, Instrumentation instrumentation) { - System.out.println("Launcher Agent"); - inst = instrumentation; - isAgentStarted = true; - } - - public static boolean isStarted() { - return isAgentStarted; - } -} diff --git a/libLauncher/src/main/java/ru/gravit/launcher/managers/ConfigManager.java b/libLauncher/src/main/java/ru/gravit/launcher/managers/ConfigManager.java index 7723de55..d2269162 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/managers/ConfigManager.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/managers/ConfigManager.java @@ -9,8 +9,9 @@ import java.util.HashMap; import java.util.Objects; +@SuppressWarnings("rawtypes") public class ConfigManager { - private final HashMap CONFIGURABLE = new HashMap<>(); + private final HashMap CONFIGURABLE = new HashMap<>(); public void registerConfigurable(String name, JsonConfigurable reconfigurable) { VerifyHelper.putIfAbsent(CONFIGURABLE, name.toLowerCase(), Objects.requireNonNull(reconfigurable, "adapter"), diff --git a/settings.gradle b/settings.gradle index 234a8355..d10b250c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,6 +7,7 @@ include 'ServerWrapper' include 'LaunchServer' include 'LaunchServerConsole' +include 'LauncherTest' include 'modules' file('modules').eachDir { sub -> if (sub.name.endsWith('_module')) include 'modules:' + sub.name