diff --git a/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java index 305a2f50..efa612fd 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java @@ -2,126 +2,16 @@ import com.google.gson.GsonBuilder; import ru.gravit.launcher.client.*; -import ru.gravit.launcher.gui.choosebox.CheckComboBox; -import ru.gravit.launcher.gui.choosebox.CheckComboBoxSkin; -import ru.gravit.launcher.gui.choosebox.CheckModel; -import ru.gravit.launcher.gui.choosebox.IndexedCheckModel; -import ru.gravit.launcher.gui.indicator.RingProgressIndicator; -import ru.gravit.launcher.gui.indicator.RingProgressIndicatorSkin; -import ru.gravit.launcher.hasher.FileNameMatcher; -import ru.gravit.launcher.hasher.HashedDir; -import ru.gravit.launcher.hasher.HashedEntry; -import ru.gravit.launcher.hasher.HashedFile; -import ru.gravit.launcher.profiles.ClientProfile; -import ru.gravit.launcher.profiles.PlayerProfile; -import ru.gravit.launcher.profiles.Texture; -import ru.gravit.launcher.request.*; -import ru.gravit.launcher.request.auth.AuthRequest; -import ru.gravit.launcher.request.auth.CheckServerRequest; -import ru.gravit.launcher.request.auth.JoinServerRequest; -import ru.gravit.launcher.request.auth.SetProfileRequest; -import ru.gravit.launcher.request.update.LauncherRequest; -import ru.gravit.launcher.request.update.ProfilesRequest; -import ru.gravit.launcher.request.update.UpdateRequest; -import ru.gravit.launcher.request.uuid.BatchProfileByUsernameRequest; -import ru.gravit.launcher.request.uuid.ProfileByUUIDRequest; -import ru.gravit.launcher.request.uuid.ProfileByUsernameRequest; -import ru.gravit.launcher.serialize.HInput; -import ru.gravit.launcher.serialize.HOutput; -import ru.gravit.launcher.serialize.signed.SignedBytesHolder; -import ru.gravit.launcher.serialize.signed.SignedObjectHolder; -import ru.gravit.launcher.serialize.stream.EnumSerializer; -import ru.gravit.launcher.serialize.stream.StreamObject; -import ru.gravit.utils.HTTPRequest; +import ru.gravit.launcher.gui.JSRuntimeProvider; +import ru.gravit.launcher.gui.RuntimeProvider; import ru.gravit.utils.helper.*; -import javax.script.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.net.URL; import java.time.Duration; import java.time.Instant; -import java.util.Map; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; public class LauncherEngine { - @LauncherAPI - public static void addLauncherClassBindings(Map bindings) { - bindings.put("LauncherClass", Launcher.class); - bindings.put("LauncherConfigClass", LauncherConfig.class); - bindings.put("HTTPRequestClass", HTTPRequest.class); - - // Set client class bindings - bindings.put("PlayerProfileClass", PlayerProfile.class); - bindings.put("PlayerProfileTextureClass", Texture.class); - bindings.put("ClientProfileClass", ClientProfile.class); - bindings.put("ClientProfileVersionClass", ClientProfile.Version.class); - bindings.put("ClientLauncherClass", ClientLauncher.class); - bindings.put("ClientLauncherParamsClass", ClientLauncher.Params.class); - bindings.put("ServerPingerClass", ServerPinger.class); - - // Set request class bindings - bindings.put("RequestClass", Request.class); - bindings.put("RequestTypeClass", RequestType.class); - bindings.put("RequestExceptionClass", RequestException.class); - bindings.put("CustomRequestClass", CustomRequest.class); - bindings.put("PingRequestClass", PingRequest.class); - bindings.put("AuthRequestClass", AuthRequest.class); - bindings.put("JoinServerRequestClass", JoinServerRequest.class); - bindings.put("CheckServerRequestClass", CheckServerRequest.class); - bindings.put("UpdateRequestClass", UpdateRequest.class); - bindings.put("LauncherRequestClass", LauncherRequest.class); - bindings.put("SetProfileRequestClass", SetProfileRequest.class); - bindings.put("ProfilesRequestClass", ProfilesRequest.class); - bindings.put("ProfileByUsernameRequestClass", ProfileByUsernameRequest.class); - bindings.put("ProfileByUUIDRequestClass", ProfileByUUIDRequest.class); - bindings.put("BatchProfileByUsernameRequestClass", BatchProfileByUsernameRequest.class); - - // Set hasher class bindings - bindings.put("FileNameMatcherClass", FileNameMatcher.class); - bindings.put("HashedDirClass", HashedDir.class); - bindings.put("HashedFileClass", HashedFile.class); - bindings.put("HashedEntryTypeClass", HashedEntry.Type.class); - - // Set serialization class bindings - bindings.put("HInputClass", HInput.class); - bindings.put("HOutputClass", HOutput.class); - bindings.put("StreamObjectClass", StreamObject.class); - bindings.put("StreamObjectAdapterClass", StreamObject.Adapter.class); - bindings.put("SignedBytesHolderClass", SignedBytesHolder.class); - bindings.put("SignedObjectHolderClass", SignedObjectHolder.class); - bindings.put("EnumSerializerClass", EnumSerializer.class); - - // Set helper class bindings - bindings.put("CommonHelperClass", CommonHelper.class); - bindings.put("IOHelperClass", IOHelper.class); - bindings.put("EnvHelperClass", EnvHelper.class); - bindings.put("JVMHelperClass", JVMHelper.class); - bindings.put("JVMHelperOSClass", JVMHelper.OS.class); - bindings.put("LogHelperClass", LogHelper.class); - bindings.put("LogHelperOutputClass", LogHelper.Output.class); - bindings.put("SecurityHelperClass", SecurityHelper.class); - bindings.put("DigestAlgorithmClass", SecurityHelper.DigestAlgorithm.class); - bindings.put("VerifyHelperClass", VerifyHelper.class); - bindings.put("DirBridgeClass", DirBridge.class); - bindings.put("FunctionalBridgeClass", FunctionalBridge.class); - bindings.put("LauncherSettingsClass", LauncherSettings.class); - - // Load JS API if available - try { - Class.forName("javafx.application.Application"); - bindings.put("JSApplicationClass", JSApplication.class); - bindings.put("RingProgressIndicatorClass", RingProgressIndicator.class); - bindings.put("RingProgressIndicatorSkinClass", RingProgressIndicatorSkin.class); - bindings.put("CheckComboBoxClass", CheckComboBox.class); - bindings.put("CheckModelClass", CheckModel.class); - bindings.put("IndexedCheckModelClass", IndexedCheckModel.class); - bindings.put("CheckComboBoxSkinClass", CheckComboBoxSkin.class); - } catch (ClassNotFoundException ignored) { - LogHelper.warning("JavaFX API isn't available"); - } - } public static void main(String... args) throws Throwable { JVMHelper.checkStackTrace(LauncherEngine.class); @@ -153,30 +43,13 @@ public static void initGson() // Instance private final AtomicBoolean started = new AtomicBoolean(false); - - private final ScriptEngine engine = CommonHelper.newScriptEngine(); + public RuntimeProvider runtimeProvider; private LauncherEngine() { - setScriptBindings(); + } - @LauncherAPI - public Object loadScript(String path) throws IOException, ScriptException { - URL url = Launcher.getResourceURL(path); - LogHelper.debug("Loading script: '%s'", url); - try (BufferedReader reader = IOHelper.newReader(url)) { - return engine.eval(reader, engine.getBindings(ScriptContext.ENGINE_SCOPE)); - } - } - private void setScriptBindings() { - LogHelper.info("Setting up script engine bindings"); - Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); - bindings.put("launcher", this); - - // Add launcher class bindings - addLauncherClassBindings(bindings); - } @LauncherAPI public void start(String... args) throws Throwable { @@ -184,22 +57,19 @@ public void start(String... args) throws Throwable { Launcher.modulesManager = new ClientModuleManager(this); LauncherConfig.getAutogenConfig().initModules(); //INIT Launcher.modulesManager.preInitModules(); + if(runtimeProvider == null) runtimeProvider = new JSRuntimeProvider(); + runtimeProvider.init(false); Objects.requireNonNull(args, "args"); if (started.getAndSet(true)) throw new IllegalStateException("Launcher has been already started"); Launcher.modulesManager.initModules(); // Load init.js script + runtimeProvider.preLoad(); FunctionalBridge.worker = new RequestWorker(); CommonHelper.newThread("FX Task Worker", true, FunctionalBridge.worker).start(); CommonHelper.newThread("GetHWID Thread",true, FunctionalBridge::getHWID).start(); - loadScript(Launcher.API_SCRIPT_FILE); - loadScript(Launcher.CONFIG_SCRIPT_FILE); LogHelper.debug("Dir: %s", DirBridge.dir); - loadScript(Launcher.INIT_SCRIPT_FILE); - LogHelper.info("Invoking start() function"); - Invocable invoker = (Invocable) engine; - Launcher.modulesManager.postInitModules(); - invoker.invokeFunction("start", (Object) args); + runtimeProvider.run(args); } public static LauncherEngine clientInstance() { diff --git a/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java b/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java index c795199f..e597a3e3 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java +++ b/Launcher/src/main/java/ru/gravit/launcher/client/ClientLauncher.java @@ -3,6 +3,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import ru.gravit.launcher.*; +import ru.gravit.launcher.gui.JSRuntimeProvider; import ru.gravit.launcher.hasher.DirWatcher; import ru.gravit.launcher.hasher.FileNameMatcher; import ru.gravit.launcher.hasher.HashedDir; @@ -405,18 +406,19 @@ public static Process launch( @LauncherAPI public static void main(String... args) throws Throwable { - Launcher.modulesManager = new ClientModuleManager(null); + LauncherEngine engine = LauncherEngine.clientInstance(); + Launcher.modulesManager = new ClientModuleManager(engine); LauncherConfig.getAutogenConfig().initModules(); //INIT initGson(); - LauncherEngine engine = LauncherEngine.clientInstance(); - engine.loadScript(Launcher.API_SCRIPT_FILE); - engine.loadScript(Launcher.CONFIG_SCRIPT_FILE); Launcher.modulesManager.preInitModules(); checkJVMBitsAndVersion(); JVMHelper.verifySystemProperties(ClientLauncher.class, true); EnvHelper.checkDangerousParams(); JVMHelper.checkStackTrace(ClientLauncher.class); LogHelper.printVersion("Client Launcher"); + if(engine.runtimeProvider == null) engine.runtimeProvider = new JSRuntimeProvider(); + engine.runtimeProvider.init(true); + engine.runtimeProvider.preLoad(); // Read and delete params file LogHelper.debug("Reading ClientLauncher params"); Params params; diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java b/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java new file mode 100644 index 00000000..ec550573 --- /dev/null +++ b/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java @@ -0,0 +1,163 @@ +package ru.gravit.launcher.gui; + +import ru.gravit.launcher.JSApplication; +import ru.gravit.launcher.Launcher; +import ru.gravit.launcher.LauncherAPI; +import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.client.*; +import ru.gravit.launcher.gui.choosebox.CheckComboBox; +import ru.gravit.launcher.gui.choosebox.CheckComboBoxSkin; +import ru.gravit.launcher.gui.choosebox.CheckModel; +import ru.gravit.launcher.gui.choosebox.IndexedCheckModel; +import ru.gravit.launcher.gui.indicator.RingProgressIndicator; +import ru.gravit.launcher.gui.indicator.RingProgressIndicatorSkin; +import ru.gravit.launcher.hasher.FileNameMatcher; +import ru.gravit.launcher.hasher.HashedDir; +import ru.gravit.launcher.hasher.HashedEntry; +import ru.gravit.launcher.hasher.HashedFile; +import ru.gravit.launcher.profiles.ClientProfile; +import ru.gravit.launcher.profiles.PlayerProfile; +import ru.gravit.launcher.profiles.Texture; +import ru.gravit.launcher.request.*; +import ru.gravit.launcher.request.auth.AuthRequest; +import ru.gravit.launcher.request.auth.CheckServerRequest; +import ru.gravit.launcher.request.auth.JoinServerRequest; +import ru.gravit.launcher.request.auth.SetProfileRequest; +import ru.gravit.launcher.request.update.LauncherRequest; +import ru.gravit.launcher.request.update.ProfilesRequest; +import ru.gravit.launcher.request.update.UpdateRequest; +import ru.gravit.launcher.request.uuid.BatchProfileByUsernameRequest; +import ru.gravit.launcher.request.uuid.ProfileByUUIDRequest; +import ru.gravit.launcher.request.uuid.ProfileByUsernameRequest; +import ru.gravit.launcher.serialize.HInput; +import ru.gravit.launcher.serialize.HOutput; +import ru.gravit.launcher.serialize.signed.SignedBytesHolder; +import ru.gravit.launcher.serialize.signed.SignedObjectHolder; +import ru.gravit.launcher.serialize.stream.EnumSerializer; +import ru.gravit.launcher.serialize.stream.StreamObject; +import ru.gravit.utils.HTTPRequest; +import ru.gravit.utils.helper.*; + +import javax.script.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.net.URL; +import java.util.Map; + +public class JSRuntimeProvider implements RuntimeProvider { + + private final ScriptEngine engine = CommonHelper.newScriptEngine(); + @LauncherAPI + public static void addLauncherClassBindings(Map bindings) { + bindings.put("LauncherClass", Launcher.class); + bindings.put("LauncherConfigClass", LauncherConfig.class); + bindings.put("HTTPRequestClass", HTTPRequest.class); + + // Set client class bindings + bindings.put("PlayerProfileClass", PlayerProfile.class); + bindings.put("PlayerProfileTextureClass", Texture.class); + bindings.put("ClientProfileClass", ClientProfile.class); + bindings.put("ClientProfileVersionClass", ClientProfile.Version.class); + bindings.put("ClientLauncherClass", ClientLauncher.class); + bindings.put("ClientLauncherParamsClass", ClientLauncher.Params.class); + bindings.put("ServerPingerClass", ServerPinger.class); + + // Set request class bindings + bindings.put("RequestClass", Request.class); + bindings.put("RequestTypeClass", RequestType.class); + bindings.put("RequestExceptionClass", RequestException.class); + bindings.put("CustomRequestClass", CustomRequest.class); + bindings.put("PingRequestClass", PingRequest.class); + bindings.put("AuthRequestClass", AuthRequest.class); + bindings.put("JoinServerRequestClass", JoinServerRequest.class); + bindings.put("CheckServerRequestClass", CheckServerRequest.class); + bindings.put("UpdateRequestClass", UpdateRequest.class); + bindings.put("LauncherRequestClass", LauncherRequest.class); + bindings.put("SetProfileRequestClass", SetProfileRequest.class); + bindings.put("ProfilesRequestClass", ProfilesRequest.class); + bindings.put("ProfileByUsernameRequestClass", ProfileByUsernameRequest.class); + bindings.put("ProfileByUUIDRequestClass", ProfileByUUIDRequest.class); + bindings.put("BatchProfileByUsernameRequestClass", BatchProfileByUsernameRequest.class); + + // Set hasher class bindings + bindings.put("FileNameMatcherClass", FileNameMatcher.class); + bindings.put("HashedDirClass", HashedDir.class); + bindings.put("HashedFileClass", HashedFile.class); + bindings.put("HashedEntryTypeClass", HashedEntry.Type.class); + + // Set serialization class bindings + bindings.put("HInputClass", HInput.class); + bindings.put("HOutputClass", HOutput.class); + bindings.put("StreamObjectClass", StreamObject.class); + bindings.put("StreamObjectAdapterClass", StreamObject.Adapter.class); + bindings.put("SignedBytesHolderClass", SignedBytesHolder.class); + bindings.put("SignedObjectHolderClass", SignedObjectHolder.class); + bindings.put("EnumSerializerClass", EnumSerializer.class); + + // Set helper class bindings + bindings.put("CommonHelperClass", CommonHelper.class); + bindings.put("IOHelperClass", IOHelper.class); + bindings.put("EnvHelperClass", EnvHelper.class); + bindings.put("JVMHelperClass", JVMHelper.class); + bindings.put("JVMHelperOSClass", JVMHelper.OS.class); + bindings.put("LogHelperClass", LogHelper.class); + bindings.put("LogHelperOutputClass", LogHelper.Output.class); + bindings.put("SecurityHelperClass", SecurityHelper.class); + bindings.put("DigestAlgorithmClass", SecurityHelper.DigestAlgorithm.class); + bindings.put("VerifyHelperClass", VerifyHelper.class); + bindings.put("DirBridgeClass", DirBridge.class); + bindings.put("FunctionalBridgeClass", FunctionalBridge.class); + bindings.put("LauncherSettingsClass", LauncherSettings.class); + + // Load JS API if available + try { + Class.forName("javafx.application.Application"); + bindings.put("JSApplicationClass", JSApplication.class); + bindings.put("RingProgressIndicatorClass", RingProgressIndicator.class); + bindings.put("RingProgressIndicatorSkinClass", RingProgressIndicatorSkin.class); + bindings.put("CheckComboBoxClass", CheckComboBox.class); + bindings.put("CheckModelClass", CheckModel.class); + bindings.put("IndexedCheckModelClass", IndexedCheckModel.class); + bindings.put("CheckComboBoxSkinClass", CheckComboBoxSkin.class); + } catch (ClassNotFoundException ignored) { + LogHelper.warning("JavaFX API isn't available"); + } + } + @LauncherAPI + public Object loadScript(String path) throws IOException, ScriptException { + URL url = Launcher.getResourceURL(path); + LogHelper.debug("Loading script: '%s'", url); + try (BufferedReader reader = IOHelper.newReader(url)) { + return engine.eval(reader, engine.getBindings(ScriptContext.ENGINE_SCOPE)); + } + } + + private void setScriptBindings() { + LogHelper.info("Setting up script engine bindings"); + Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); + bindings.put("launcher", this); + + // Add launcher class bindings + JSRuntimeProvider.addLauncherClassBindings(bindings); + } + + @Override + public void run(String[] args) throws ScriptException, NoSuchMethodException, IOException { + loadScript(Launcher.INIT_SCRIPT_FILE); + LogHelper.info("Invoking start() function"); + Invocable invoker = (Invocable) engine; + Launcher.modulesManager.postInitModules(); + invoker.invokeFunction("start", (Object) args); + } + + @Override + public void preLoad() throws IOException, ScriptException { + loadScript(Launcher.API_SCRIPT_FILE); + loadScript(Launcher.CONFIG_SCRIPT_FILE); + } + + @Override + public void init(boolean clientInstance) { + setScriptBindings(); + } +} diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/RuntimeProvider.java b/Launcher/src/main/java/ru/gravit/launcher/gui/RuntimeProvider.java new file mode 100644 index 00000000..ff5a33af --- /dev/null +++ b/Launcher/src/main/java/ru/gravit/launcher/gui/RuntimeProvider.java @@ -0,0 +1,7 @@ +package ru.gravit.launcher.gui; + +public interface RuntimeProvider { + void run(String[] args) throws Exception; + void preLoad() throws Exception; + void init(boolean clientInstance) throws Exception; +}