commit 86cc8238efd26c1d08703ce077162075e63b9763
parent 19a0ab8398c9c8fd2ddb6dce8afcc3bc24375d11
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Mon, 18 Sep 2023 00:03:12 +0200

feat(scripting): static class type

Diffstat:
Mapp/src/main/kotlin/me/rhunk/snapenhance/scripting/RemoteScriptManager.kt | 2+-
Mcore/src/main/kotlin/me/rhunk/snapenhance/scripting/JSModule.kt | 36++++++++++++++++++++++++++++++++++--
Mcore/src/main/kotlin/me/rhunk/snapenhance/scripting/ScriptRuntime.kt | 5+++--
Mcore/src/main/kotlin/me/rhunk/snapenhance/scripting/core/CoreScriptRuntime.kt | 13++-----------
4 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/scripting/RemoteScriptManager.kt b/app/src/main/kotlin/me/rhunk/snapenhance/scripting/RemoteScriptManager.kt @@ -12,7 +12,7 @@ import java.io.InputStream class RemoteScriptManager( private val context: RemoteSideContext, ) : IScripting.Stub() { - val runtime = ScriptRuntime(context.log) + val runtime = ScriptRuntime(context.log, context.androidContext.classLoader) private val reloadListeners = mutableListOf<ReloadListener>() private val cachedModuleInfo = mutableMapOf<String, ModuleInfo>() diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/scripting/JSModule.kt b/core/src/main/kotlin/me/rhunk/snapenhance/scripting/JSModule.kt @@ -9,12 +9,13 @@ import org.mozilla.javascript.Function import org.mozilla.javascript.NativeJavaObject import org.mozilla.javascript.ScriptableObject import org.mozilla.javascript.Undefined +import java.lang.reflect.Modifier class JSModule( + val scriptRuntime: ScriptRuntime, val moduleInfo: ModuleInfo, val content: String, ) { - lateinit var logger: AbstractLogger private lateinit var moduleObject: ScriptableObject fun load(block: ScriptableObject.() -> Unit) { @@ -50,8 +51,39 @@ class JSModule( field.get(obj.unwrap()) } + moduleObject.putFunction("findClass") { + val className = it?.get(0).toString() + scriptRuntime.classLoader.loadClass(className) + } + + moduleObject.putFunction("type") { args -> + val className = args?.get(0).toString() + val clazz = scriptRuntime.classLoader.loadClass(className) + + scriptableObject("JavaClassWrapper") { + putFunction("newInstance") newInstance@{ args -> + val constructor = clazz.declaredConstructors.find { + it.parameterCount == (args?.size ?: 0) + } ?: return@newInstance Undefined.instance + constructor.newInstance(*args ?: emptyArray()) + } + + clazz.declaredMethods.forEach { method -> + method.isAccessible = true + putFunction(method.name) { args -> + args?.also { method.invoke(null, *it) } ?: method.invoke(null) + } + } + + clazz.declaredFields.filter { Modifier.isStatic(it.modifiers) }.forEach { field -> + field.isAccessible = true + defineProperty(field.name, { field.get(null)}, { value -> field.set(null, value) }, 0) + } + } + } + moduleObject.putFunction("logInfo") { args -> - logger.info(args?.joinToString(" ") ?: "") + scriptRuntime.logger.info(args?.joinToString(" ") ?: "") Undefined.instance } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/scripting/ScriptRuntime.kt b/core/src/main/kotlin/me/rhunk/snapenhance/scripting/ScriptRuntime.kt @@ -8,7 +8,8 @@ import java.io.ByteArrayInputStream import java.io.InputStream open class ScriptRuntime( - protected val logger: AbstractLogger, + val logger: AbstractLogger, + val classLoader: ClassLoader, ) { var buildModuleObject: ScriptableObject.(JSModule) -> Unit = {} private val modules = mutableMapOf<String, JSModule>() @@ -72,10 +73,10 @@ open class ScriptRuntime( logger.info("Loading module $path") return runCatching { JSModule( + scriptRuntime = this, moduleInfo = readModuleInfo(ByteArrayInputStream(content.toByteArray(Charsets.UTF_8)).bufferedReader()), content = content, ).apply { - logger = this@ScriptRuntime.logger load { buildModuleObject(this, this@apply) } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/scripting/core/CoreScriptRuntime.kt b/core/src/main/kotlin/me/rhunk/snapenhance/scripting/core/CoreScriptRuntime.kt @@ -8,14 +8,11 @@ import me.rhunk.snapenhance.scripting.IPCInterface import me.rhunk.snapenhance.scripting.Listener import me.rhunk.snapenhance.scripting.ScriptRuntime import me.rhunk.snapenhance.scripting.core.impl.ScriptHooker -import me.rhunk.snapenhance.scripting.ktx.putFunction class CoreScriptRuntime( logger: AbstractLogger, - private val classLoader: ClassLoader -): ScriptRuntime(logger) { - private lateinit var ipcInterface: IPCInterface - + classLoader: ClassLoader, +): ScriptRuntime(logger, classLoader) { private val scriptHookers = mutableListOf<ScriptHooker>() fun connect(scriptingInterface: IScripting) { @@ -48,18 +45,12 @@ class CoreScriptRuntime( sendIPCMessage(channel, eventName, args) } }) - putFunction("findClass") { - val className = it?.get(0).toString() - classLoader.loadClass(className) - } putConst("hooker", this, ScriptHooker(module.moduleInfo, logger, classLoader).also { scriptHookers.add(it) }) } } - - scriptingInterface.enabledScripts.forEach { path -> runCatching { load(path, scriptingInterface.getScriptContent(path))