Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lua-mirai-adapter-luakt/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ dependencies {
implementation "org.xerial:sqlite-jdbc:3.7.2"
implementation "org.jsoup:jsoup:1.7.3"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2"
implementation "com.github.only52607.luakt:luakt:2.5.6"
implementation "com.github.only52607.luakt:luakt:2.5.7"
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import kotlin.coroutines.ContinuationInterceptor
import kotlin.coroutines.CoroutineContext

class LuaMiraiScript(
override var source: BotScriptSource,
override val source: BotScriptSource,
override val header: BotScriptHeader,
mainInputStream: InputStream
) : AbstractBotScript(), CoroutineScope {
Expand Down Expand Up @@ -80,7 +80,11 @@ class LuaMiraiScript(
if (coroutineContext[ContinuationInterceptor] == null) {
coroutineContext += taskLib.asCoroutineDispatcher()
}
mainFunc.invoke()
try {
mainFunc.invoke()
} catch (e: Exception) {
e.printStackTrace(PrintStream(stderr ?: System.err))
}
}

override suspend fun onStop() {
Expand Down Expand Up @@ -127,7 +131,7 @@ class LuaMiraiScript(
private val parentFinder: ResourceFinder,
private val botScriptResourceFinder: BotScriptResourceFinder?
) : ResourceFinder {
override fun findResource(filename: String): InputStream {
override fun findResource(filename: String): InputStream? {
val resource = botScriptResourceFinder?.findResource(filename)
if (resource != null) return resource
return parentFinder.findResource(filename)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import com.github.only52607.luamirai.core.BotScriptBuilder
import com.github.only52607.luamirai.core.script.BotScript
import com.github.only52607.luamirai.core.script.BotScriptHeader
import com.github.only52607.luamirai.core.script.BotScriptSource
import com.github.only52607.luamirai.core.script.mutableBotScriptHeaderOf
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import java.io.BufferedInputStream

/**
Expand Down Expand Up @@ -44,16 +49,35 @@ class LuaMiraiScriptBuilder(

private suspend fun prepareHeader() {
if (headerInitialized) return
prepareMainInputStream()
val manifestInputStream = source.resourceFinder?.findResource("manifest.json")
header = if (manifestInputStream != null) {
readHeaderFromJsonManifest(String(manifestInputStream.readBytes()))
} else {
prepareMainInputStream()
readHeaderFromCodeInputStream()
}
headerInitialized = true
}

private suspend fun readHeaderFromCodeInputStream(): BotScriptHeader {
mainInputStream.mark(MAX_SCRIPT_HEADER)
withContext(Dispatchers.IO) {
return withContext(Dispatchers.IO) {
try {
header = LuaHeaderReader.readHeader(mainInputStream)
LuaHeaderReader.readHeader(mainInputStream)
} finally {
mainInputStream.reset()
}
}
headerInitialized = true
}

private fun readHeaderFromJsonManifest(jsonString: String): BotScriptHeader {
val json = Json
val manifest: JsonObject = json.parseToJsonElement(jsonString).jsonObject
return mutableBotScriptHeaderOf {
manifest["header"]?.jsonObject?.forEach { key, value ->
this@mutableBotScriptHeaderOf[key] = value.jsonPrimitive.content
}
}
}

override suspend fun buildInstance(): BotScript {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.github.only52607.luamirai.configuration

import com.github.only52607.luamirai.core.script.BotScriptSource
import kotlinx.serialization.Serializable
import java.io.InputStream

/**
* ClassName: ConfigurableScriptSource
Expand All @@ -13,19 +12,7 @@ import java.io.InputStream
*/
@Serializable(ConfigurableScriptSourceSerializer::class)
class ConfigurableScriptSource(
val source: BotScriptSource,
source: BotScriptSource,
var alias: String? = null,
var autoStart: Boolean = false
) : BotScriptSource(
lang = source.lang,
name = source.name,
size = source.size,
charset = source.charset,
) {
override val mainInputStream: InputStream
get() = source.mainInputStream

override fun toString(): String {
return source.toString()
}
}
) : BotScriptSource.Wrapper(source)
3 changes: 3 additions & 0 deletions lua-mirai-core/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2"
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package com.github.only52607.luamirai.core.script

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import java.io.ByteArrayInputStream
import java.io.File
import java.io.FileNotFoundException
import java.io.InputStream
import java.net.URL
import java.nio.charset.Charset
import java.util.zip.ZipFile

/**
* ClassName: BotScriptSource
Expand All @@ -19,24 +25,138 @@ abstract class BotScriptSource(
var name: String,
open var size: Long?,
open val charset: Charset?,
val resourceFinder: BotScriptResourceFinder? = null
) {
abstract val mainInputStream: InputStream

open val resourceFinder: BotScriptResourceFinder? = null

class FileSource(
val file: File,
scriptLang: String,
name: String = "@${file.name}",
charset: Charset = Charsets.UTF_8
) : BotScriptSource(scriptLang, name, file.length(), charset) {

private val scriptSource: BotScriptSource = when {
file.isDirectory -> DirectorySource(file, scriptLang, name, charset)
isPackage() -> ZipSource(file, scriptLang, name, charset)
else -> TextFileSource(file, scriptLang, name, charset)
}

private fun isPackage(): Boolean {
return file.name.endsWith(".zip") || file.name.endsWith(".lmpk")
}

override val mainInputStream: InputStream
get() = file.inputStream()
get() = scriptSource.mainInputStream

override val resourceFinder: BotScriptResourceFinder?
get() = scriptSource.resourceFinder

override fun toString(): String {
return "FileSource(name=$name, file=$file, lang=$lang)"
}
}

class TextFileSource(
val file: File,
scriptLang: String,
name: String = "@${file.name}",
charset: Charset = Charsets.UTF_8
) : BotScriptSource(scriptLang, name, file.length(), charset) {
override val resourceFinder: BotScriptResourceFinder = object : BotScriptResourceFinder {
val directory = file.parentFile
override fun findResource(filename: String): InputStream? {
val file = File(directory, filename)
if (!file.exists()) return null
return file.inputStream()
}
}

override val mainInputStream: InputStream
get() = file.inputStream()

override fun toString(): String {
return "TextFileSource(name=$name, file=$file, lang=$lang)"
}
}

class DirectorySource(
val directory: File,
scriptLang: String,
name: String = "@${directory.name}",
charset: Charset = Charsets.UTF_8
) : BotScriptSource(scriptLang, name, directory.length(), charset) {

override val resourceFinder: BotScriptResourceFinder = object : BotScriptResourceFinder {
override fun findResource(filename: String): InputStream? {
val file = File(directory, filename)
if (!file.exists()) return null
return file.inputStream()
}
}

private val json = Json

override val mainInputStream: InputStream
get() = resourceFinder.findResource(mainFileName)
?: throw FileNotFoundException("File $mainFileName not found in ${directory.absolutePath}")

private val manifest: JsonObject = resourceFinder.findResource("manifest.json")?.let {
json.parseToJsonElement(String(it.readBytes())).jsonObject
} ?: throw FileNotFoundException("manifest.json not found in ${directory.absolutePath}")

private val mainFileName: String = manifest["main"]?.jsonPrimitive?.content
?: throw Exception("You must specify the main field as the script entry")

init {
super.name = mainFileName
}

override fun toString(): String {
return "DirectorySource(name=$name, directory=$directory, lang=$lang)"
}
}

class ZipSource(
val file: File,
scriptLang: String,
name: String = "@${file.name}",
charset: Charset = Charsets.UTF_8
) : BotScriptSource(scriptLang, name, file.length(), charset) {

override val resourceFinder: BotScriptResourceFinder = object : BotScriptResourceFinder {
override fun findResource(filename: String): InputStream? {
val zipEntryName = filename.replace("\\", "/")
val zipEntry = zipFile.getEntry(zipEntryName) ?: return null
return zipFile.getInputStream(zipEntry)
}
}

private val zipFile = ZipFile(file)

private val json = Json

private val manifest: JsonObject = resourceFinder.findResource("manifest.json")?.let {
json.parseToJsonElement(String(it.readBytes())).jsonObject
} ?: throw FileNotFoundException("manifest.json not found in ${file.absolutePath}")

private val mainFileName: String = manifest["main"]?.jsonPrimitive?.content
?: throw Exception("You must specify the main field as the script entry")

init {
super.name = mainFileName
}

override val mainInputStream: InputStream
get() = resourceFinder.findResource(mainFileName)
?: throw FileNotFoundException("File $mainFileName not found in ${file.absolutePath}")

override fun toString(): String {
return "ZipSource(name=$name, file=$file, lang=$lang)"
}
}

class StringSource(
val content: String,
lang: String,
Expand Down Expand Up @@ -64,4 +184,23 @@ abstract class BotScriptSource(
return "URLSource(name=$name, url=$url, lang=$lang)"
}
}

open class Wrapper(
val source: BotScriptSource
) : BotScriptSource(
lang = source.lang,
name = source.name,
size = source.size,
charset = source.charset,
) {
override val mainInputStream: InputStream
get() = source.mainInputStream

override val resourceFinder: BotScriptResourceFinder?
get() = source.resourceFinder

override fun toString(): String {
return source.toString()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ class LuaMiraiCommand(
}
val builder = BotScriptBuilder.fromSource(ConfigurableScriptSource(source))
builders.add(builder)
logger.info("添加脚本源[${builders.size - 1}] $fileName 成功,脚本信息:")
logger.info(builder.readHeader().simpleInfo)
logger.info("添加脚本源[${builders.size - 1}] $fileName 成功")
logger.info("脚本信息:\n" + builder.readHeader().simpleInfo)
updateConfig()
}

Expand Down