feat(scripting): module exports

- add currentSide global
- add script name rule
- add displayName
This commit is contained in:
rhunk
2023-12-25 02:02:27 +01:00
parent 4a4aa28ccf
commit 3edd6ed723
7 changed files with 40 additions and 13 deletions

View File

@ -64,6 +64,7 @@ class ModDatabase(
"scripts" to listOf( "scripts" to listOf(
"name VARCHAR PRIMARY KEY", "name VARCHAR PRIMARY KEY",
"version VARCHAR NOT NULL", "version VARCHAR NOT NULL",
"displayName VARCHAR",
"description VARCHAR", "description VARCHAR",
"author VARCHAR NOT NULL", "author VARCHAR NOT NULL",
"enabled BOOLEAN" "enabled BOOLEAN"
@ -266,6 +267,7 @@ class ModDatabase(
ModuleInfo( ModuleInfo(
name = cursor.getStringOrNull("name")!!, name = cursor.getStringOrNull("name")!!,
version = cursor.getStringOrNull("version")!!, version = cursor.getStringOrNull("version")!!,
displayName = cursor.getStringOrNull("displayName"),
description = cursor.getStringOrNull("description"), description = cursor.getStringOrNull("description"),
author = cursor.getStringOrNull("author"), author = cursor.getStringOrNull("author"),
grantedPermissions = emptyList() grantedPermissions = emptyList()
@ -305,14 +307,18 @@ class ModDatabase(
} }
availableScripts.forEach { script -> availableScripts.forEach { script ->
if (!enabledScriptPaths.contains(script.name)) { if (!enabledScriptPaths.contains(script.name) || script != enabledScripts.find { it.name == script.name }) {
database.execSQL("INSERT OR REPLACE INTO scripts (name, version, description, author, enabled) VALUES (?, ?, ?, ?, ?)", arrayOf( database.execSQL(
script.name, "INSERT OR REPLACE INTO scripts (name, version, displayName, description, author, enabled) VALUES (?, ?, ?, ?, ?, ?)",
script.version, arrayOf(
script.description, script.name,
script.author, script.version,
0 script.displayName,
)) script.description,
script.author,
0
)
)
} }
} }
} }

View File

@ -7,6 +7,7 @@ import me.rhunk.snapenhance.bridge.scripting.AutoReloadListener
import me.rhunk.snapenhance.bridge.scripting.IPCListener import me.rhunk.snapenhance.bridge.scripting.IPCListener
import me.rhunk.snapenhance.bridge.scripting.IScripting import me.rhunk.snapenhance.bridge.scripting.IScripting
import me.rhunk.snapenhance.common.scripting.ScriptRuntime import me.rhunk.snapenhance.common.scripting.ScriptRuntime
import me.rhunk.snapenhance.common.scripting.bindings.BindingSide
import me.rhunk.snapenhance.common.scripting.impl.ConfigInterface import me.rhunk.snapenhance.common.scripting.impl.ConfigInterface
import me.rhunk.snapenhance.common.scripting.impl.ConfigTransactionType import me.rhunk.snapenhance.common.scripting.impl.ConfigTransactionType
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
@ -63,6 +64,7 @@ class RemoteScriptManager(
fun init() { fun init() {
runtime.buildModuleObject = { module -> runtime.buildModuleObject = { module ->
putConst("currentSide", this, BindingSide.MANAGER.key)
module.registerBindings( module.registerBindings(
ManagerIPC(ipcListeners), ManagerIPC(ipcListeners),
InterfaceManager(), InterfaceManager(),

View File

@ -64,7 +64,7 @@ class ScriptsSection : Section() {
.weight(1f) .weight(1f)
.padding(end = 8.dp) .padding(end = 8.dp)
) { ) {
Text(text = script.name, fontSize = 20.sp,) Text(text = script.displayName ?: script.name, fontSize = 20.sp,)
Text(text = script.description ?: "No description", fontSize = 14.sp,) Text(text = script.description ?: "No description", fontSize = 14.sp,)
} }
IconButton(onClick = { openSettings = !openSettings }) { IconButton(onClick = { openSettings = !openSettings }) {

View File

@ -6,6 +6,7 @@ import me.rhunk.snapenhance.common.scripting.bindings.AbstractBinding
import me.rhunk.snapenhance.common.scripting.bindings.BindingsContext import me.rhunk.snapenhance.common.scripting.bindings.BindingsContext
import me.rhunk.snapenhance.common.scripting.ktx.contextScope import me.rhunk.snapenhance.common.scripting.ktx.contextScope
import me.rhunk.snapenhance.common.scripting.ktx.putFunction import me.rhunk.snapenhance.common.scripting.ktx.putFunction
import me.rhunk.snapenhance.common.scripting.ktx.scriptable
import me.rhunk.snapenhance.common.scripting.ktx.scriptableObject import me.rhunk.snapenhance.common.scripting.ktx.scriptableObject
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
import org.mozilla.javascript.Function import org.mozilla.javascript.Function
@ -39,6 +40,7 @@ class JSModule(
putConst("info", this, scriptableObject { putConst("info", this, scriptableObject {
putConst("name", this, moduleInfo.name) putConst("name", this, moduleInfo.name)
putConst("version", this, moduleInfo.version) putConst("version", this, moduleInfo.version)
putConst("displayName", this, moduleInfo.displayName)
putConst("description", this, moduleInfo.description) putConst("description", this, moduleInfo.description)
putConst("author", this, moduleInfo.author) putConst("author", this, moduleInfo.author)
putConst("minSnapchatVersion", this, moduleInfo.minSnapchatVersion) putConst("minSnapchatVersion", this, moduleInfo.minSnapchatVersion)
@ -145,7 +147,16 @@ class JSModule(
moduleObject.putFunction("require") { args -> moduleObject.putFunction("require") { args ->
val bindingName = args?.get(0).toString() val bindingName = args?.get(0).toString()
moduleBindings[bindingName]?.getObject() val (namespace, path) = bindingName.takeIf {
it.startsWith("@") && it.contains("/")
}?.let {
it.substring(1).substringBefore("/") to it.substringAfter("/")
} ?: (null to "")
when (namespace) {
"modules" -> scriptRuntime.getModuleByName(path)?.moduleObject?.scriptable("module")?.scriptable("exports")
else -> moduleBindings[bindingName]?.getObject()
}
} }
evaluateString(moduleObject, content, moduleInfo.name, 1, null) evaluateString(moduleObject, content, moduleInfo.name, 1, null)

View File

@ -54,12 +54,17 @@ open class ScriptRuntime(
} }
return ModuleInfo( return ModuleInfo(
name = properties["name"] ?: throw Exception("Missing module name"), name = properties["name"]?.also {
if (!it.matches(Regex("[a-z_]+"))) {
throw Exception("Invalid module name : Only lowercase letters and underscores are allowed")
}
} ?: throw Exception("Missing module name"),
version = properties["version"] ?: throw Exception("Missing module version"), version = properties["version"] ?: throw Exception("Missing module version"),
displayName = properties["displayName"],
description = properties["description"], description = properties["description"],
author = properties["author"], author = properties["author"],
minSnapchatVersion = properties["minSnapchatVersion"]?.toLong(), minSnapchatVersion = properties["minSnapchatVersion"]?.toLongOrNull(),
minSEVersion = properties["minSEVersion"]?.toLong(), minSEVersion = properties["minSEVersion"]?.toLongOrNull(),
grantedPermissions = properties["permissions"]?.split(",")?.map { it.trim() } ?: emptyList(), grantedPermissions = properties["permissions"]?.split(",")?.map { it.trim() } ?: emptyList(),
) )
} }

View File

@ -3,6 +3,7 @@ package me.rhunk.snapenhance.common.scripting.type
data class ModuleInfo( data class ModuleInfo(
val name: String, val name: String,
val version: String, val version: String,
val displayName: String? = null,
val description: String? = null, val description: String? = null,
val author: String? = null, val author: String? = null,
val minSnapchatVersion: Long? = null, val minSnapchatVersion: Long? = null,

View File

@ -4,6 +4,7 @@ import me.rhunk.snapenhance.bridge.scripting.AutoReloadListener
import me.rhunk.snapenhance.bridge.scripting.IScripting import me.rhunk.snapenhance.bridge.scripting.IScripting
import me.rhunk.snapenhance.common.logger.AbstractLogger import me.rhunk.snapenhance.common.logger.AbstractLogger
import me.rhunk.snapenhance.common.scripting.ScriptRuntime import me.rhunk.snapenhance.common.scripting.ScriptRuntime
import me.rhunk.snapenhance.common.scripting.bindings.BindingSide
import me.rhunk.snapenhance.core.ModContext import me.rhunk.snapenhance.core.ModContext
import me.rhunk.snapenhance.core.scripting.impl.CoreIPC import me.rhunk.snapenhance.core.scripting.impl.CoreIPC
import me.rhunk.snapenhance.core.scripting.impl.CoreScriptConfig import me.rhunk.snapenhance.core.scripting.impl.CoreScriptConfig
@ -17,6 +18,7 @@ class CoreScriptRuntime(
scripting = scriptingInterface scripting = scriptingInterface
scriptingInterface.apply { scriptingInterface.apply {
buildModuleObject = { module -> buildModuleObject = { module ->
putConst("currentSide", this, BindingSide.CORE.key)
module.registerBindings( module.registerBindings(
CoreScriptConfig(), CoreScriptConfig(),
CoreIPC(), CoreIPC(),