refactor(使用配置加载模块而非硬编码在主类中): 配置加载模块

This commit is contained in:
叁玖领域 2026-02-07 19:29:07 +08:00
parent 37eeaf143c
commit 988ed191ec
27 changed files with 690 additions and 415 deletions

View File

@ -3,5 +3,5 @@ org.gradle.downloadSources=false
org.gradle.parallel=true
org.gradle.degree_of_parallelism=16
project_group=top.r3944realms.ltdmanager
project_version=1.14-SNAPSHOT
project_version=1.15-SNAPSHOT
dg_lab_version=4.4.14.18

View File

@ -22,7 +22,7 @@ object GlobalManager {
}
fun initApplication() {
moduleManager.loadConfig()
}
// NapCat 客户端

View File

@ -38,7 +38,7 @@ data class BlessingSkinServerConfig(
try {
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"blessing-skin-server.invitation-api.encrypted-token",
encryptedToken!!
)

View File

@ -37,7 +37,7 @@ data class DatabaseConfig(
try {
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"database.encrypted-password",
this.encryptedPassword!!
)

View File

@ -38,7 +38,7 @@ data class DgLabConfig(
try {
encryptedLocalServerSslPassword = "ENC(${CryptoUtil.encrypt(encryptedLocalServerSslPassword!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"dg-lab.ws-server.encrypted-local-server-ssl-password",
encryptedLocalServerSslPassword!!
)

View File

@ -36,7 +36,7 @@ data class HttpConfig(
try {
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"http.encrypted-token",
this.encryptedToken!!
)

View File

@ -36,7 +36,7 @@ data class ImgTuConfig(
try {
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"img-tu.encrypted-password",
this.encryptedPassword!!
)

View File

@ -34,7 +34,7 @@ data class MailConfig(
try {
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"mail.encrypted-password",
this.encryptedPassword!!
)

View File

@ -30,7 +30,7 @@ data class McsmConfig(
try {
encryptedApiKey = "ENC(${CryptoUtil.encrypt(encryptedApiKey!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"mcsm.encrypted-api-key",
this.encryptedApiKey!!
)

View File

@ -0,0 +1,246 @@
package top.r3944realms.ltdmanager.core.config
import top.r3944realms.ltdmanager.module.Modules
import top.r3944realms.ltdmanager.module.exception.ConfigError
data class ModuleConfig(
var modules: List<Module>? = emptyList()
) {
data class Module(
var name: String = "default",
var type: ModuleType = ModuleType.HELP_MODULE,
var enabled: Boolean = true,
var dependencies: List<Dependency> = emptyList(),
var config: Map<String, Any> = emptyMap()
) {
data class Dependency(
var name: String,
var type: ModuleType
) {
private val dependencyName: String = "${type.modName}-$name"
fun getDepName() :String = dependencyName
}
fun findDependency(type: ModuleType): Dependency? {
return dependencies.find { it.type == type }
}
inline fun <reified T> typedList(paramName: String): List<T> {
val list = anyList(paramName)
return list.map { element ->
when (T::class) {
String::class -> element.toString() as T
Int::class -> convertToInt(element, "$paramName.list.element") as T
Long::class -> convertToLong(element, "$paramName.list.element") as T
Boolean::class -> convertToBoolean(element, "$paramName.list.element") as T
else -> {
if (element is T) element
else throw ConfigError(
ConfigError.Type.NOT_EXPECTED_VALUE,
name,
"$paramName.list",
T::class.simpleName ?: T::class.java.simpleName,
element::class.simpleName ?: element::class.java.simpleName
)
}
}
}
}
// 特定类型的 List 方法
fun <T> list(paramName: String): List<T> = get<List<T>>(paramName)
// 特定类型的 Map 方法
fun <K, V> map(paramName: String): Map<K, V> = get<Map<K, V>>(paramName)
// 泛型 List 获取(返回 List<Any>
fun anyList(paramName: String): List<Any> = get<List<Any>>(paramName)
// 泛型 Map 获取(返回 Map<String, Any>
fun anyMap(paramName: String): Map<String, Any> = get<Map<String, Any>>(paramName)
// String List 的便捷方法
fun stringList(paramName: String): List<String> {
val list = anyList(paramName)
return list.map { it.toString() }
}
// Int List 的便捷方法
fun intList(paramName: String): List<Int> {
val list = anyList(paramName)
return list.map { value ->
when (value) {
is Int -> value
is Number -> value.toInt()
is String -> value.toIntOrNull()
?: throw ConfigError(
ConfigError.Type.NOT_EXPECTED_VALUE,
name,
paramName,
"List<Int>",
"元素类型: ${value::class.simpleName}"
)
else -> throw ConfigError(
ConfigError.Type.NOT_EXPECTED_VALUE,
name,
paramName,
"List<Int>",
"元素类型: ${value::class.simpleName}"
)
}
}
}
// 获取特定类型的 Map
inline fun <reified V> typedMap(paramName: String): Map<String, V> {
val map = anyMap(paramName)
return map.mapValues { (key, value) ->
when (V::class) {
String::class -> value.toString() as V
Int::class -> convertToInt(value, "$paramName.$key") as V
Long::class -> convertToLong(value, "$paramName.$key") as V
Boolean::class -> convertToBoolean(value, "$paramName.$key") as V
else -> {
if (value is V) value
else throw ConfigError(
ConfigError.Type.NOT_EXPECTED_VALUE,
name,
"$paramName.$key",
V::class.simpleName ?: V::class.java.simpleName,
value::class.simpleName ?: value::class.java.simpleName
)
}
}
}
}
enum class ModuleType(val modName: String) {
GROUP_MESSAGE_POLLING_MODULE(Modules.GROUP_MESSAGE_POLLING),
GROUP_REQUEST_HANDLER_MODULE(Modules.GROUP_REQUEST_HANDLER),
MAIL_MODULE(Modules.MAIL),
BAN_MODULE(Modules.BAN),
DG_LAB_MODULE(Modules.DG_LAB),
INVITE_MODULE(Modules.INVITATION_CODE),
MC_SERVER_STATUS_MODULE(Modules.MC_SERVER_STATUS),
MOD_GROUP_HANDLER_MODULE(Modules.MOD_GROUP_HANDLER),
RCON_PLAYER_LIST_MODULE(Modules.RCON_PLAYER_LIST),
STATE_MODULE(Modules.STATE),
HELP_MODULE(Modules.HELP),;
}
// 基础获取方法
fun value(paramName: String): Any =
config[paramName] ?: throw ConfigError(
ConfigError.Type.MISSING_PARAMETER,
name,
paramName
)
// 泛型获取方法
private inline fun <reified T> get(paramName: String): T {
val value = value(paramName)
return when (T::class) {
Long::class -> convertToLong(value, paramName) as T
Int::class -> convertToInt(value, paramName) as T
String::class -> value.toString() as T
Boolean::class -> convertToBoolean(value, paramName) as T
Double::class -> convertToDouble(value, paramName) as T
Float::class -> convertToFloat(value, paramName) as T
else -> {
if (value is T) value
else throw typeMismatchError<T>(value, paramName)
}
}
}
// 特定类型方法(向后兼容)
fun long(paramName: String): Long = get<Long>(paramName)
fun int(paramName: String): Int = get<Int>(paramName)
fun string(paramName: String): String = get<String>(paramName)
fun boolean(paramName: String): Boolean = get<Boolean>(paramName)
fun double(paramName: String): Double = get<Double>(paramName)
fun float(paramName: String): Float = get<Float>(paramName)
// 可选值方法
inline fun <reified T> getOrNull(paramName: String): T? =
config[paramName] as? T ?: run {
val value = config[paramName]
if (value == null) null
else if (value is T) value
else null
}
inline fun <reified T> getOrDefault(paramName: String, defaultValue: T): T =
getOrNull<T>(paramName) ?: defaultValue
// 类型转换辅助方法
fun convertToLong(value: Any, paramName: String): Long = when (value) {
is Long -> value
is Number -> value.toLong()
is String -> try {
value.toLong()
} catch (e: NumberFormatException) {
throw typeMismatchError<Long>(value, paramName)
}
else -> throw typeMismatchError<Long>(value, paramName)
}
fun convertToInt(value: Any, paramName: String): Int = when (value) {
is Int -> value
is Number -> value.toInt()
is String -> try {
value.toInt()
} catch (e: NumberFormatException) {
throw typeMismatchError<Int>(value, paramName)
}
else -> throw typeMismatchError<Int>(value, paramName)
}
fun convertToBoolean(value: Any, paramName: String): Boolean = when (value) {
is Boolean -> value
is String -> when (value.lowercase()) {
"true", "yes", "1" -> true
"false", "no", "0" -> false
else -> throw typeMismatchError<Boolean>(value, paramName)
}
is Number -> value.toInt() != 0
else -> throw typeMismatchError<Boolean>(value, paramName)
}
private fun convertToDouble(value: Any, paramName: String): Double = when (value) {
is Double -> value
is Number -> value.toDouble()
is String -> try {
value.toDouble()
} catch (e: NumberFormatException) {
throw typeMismatchError<Double>(value, paramName)
}
else -> throw typeMismatchError<Double>(value, paramName)
}
private fun convertToFloat(value: Any, paramName: String): Float = when (value) {
is Float -> value
is Number -> value.toFloat()
is String -> try {
value.toFloat()
} catch (e: NumberFormatException) {
throw typeMismatchError<Float>(value, paramName)
}
else -> throw typeMismatchError<Float>(value, paramName)
}
// 错误处理辅助方法
private inline fun <reified T> typeMismatchError(
actualValue: Any,
paramName: String
): Nothing {
throw ConfigError(
ConfigError.Type.NOT_EXPECTED_VALUE,
paramName,
T::class.simpleName ?: T::class.java.simpleName,
actualValue::class.simpleName ?: actualValue::class.java.simpleName
)
}
}
}

View File

@ -38,7 +38,7 @@ data class ToolConfig(
try {
rconPassword = "ENC(${CryptoUtil.encrypt(rconPassword!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"tools.rcon.rcon-password",
rconPassword!!
)

View File

@ -36,7 +36,7 @@ data class WebsocketConfig(
try {
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
YamlUpdater.updateYaml(
YamlConfigLoader.configFilePath.toString(),
YamlConfigLoader.appConfigFilePath.toString(),
"websocket.encrypted-token",
this.encryptedToken!!
)

View File

@ -8,26 +8,30 @@ import org.yaml.snakeyaml.introspector.PropertyUtils
import top.r3944realms.ltdmanager.utils.ConfigInitializer
import top.r3944realms.ltdmanager.utils.NamingConventionUtil
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
object YamlConfigLoader {
val configFilePath = Paths.get("config/application.yaml") // 配置文件路径
private val _config by lazy { loadConfig() } // 延迟初始化
val config: ConfigWrapper get() = _config
val appConfigFilePath: Path = Paths.get("config/application.yaml") // 配置文件路径
val moduleConfigFilePath: Path = Paths.get("config/module.yaml") // 配置文件路径
private val _app_config by lazy { loadAppConfigWrapper() } // 延迟初始化
val appConfig: AppConfigWrapper get() = _app_config
private val _module_config by lazy { loadModuleConfigWrapper() } // 延迟初始化
val moduleConfig: ModuleConfigWrapper get() = _module_config
init {
// 第一次启动确保配置文件存在
ConfigInitializer.initConfig("module.yaml", "config", false)
ConfigInitializer.initConfig("application.yaml", "config")
// 初始化后加密(确保只执行一次)
runCatching {
ensureConfigEncrypted(_config)
ensureConfigEncrypted(_app_config)
}.onFailure { e ->
println("初始化加密失败: ${e.message}")
e.printStackTrace()
}
}
private fun ensureConfigEncrypted(config: ConfigWrapper?) {
private fun ensureConfigEncrypted(config: AppConfigWrapper?) {
config?.database?.encryptPassword()
config?.websocket?.encryptToken()
config?.http?.encryptToken()
@ -38,15 +42,15 @@ object YamlConfigLoader {
config?.dgLab?.wsServer?.encryptPassword()
config?.imgTu?.encryptPassword()
}
private fun loadConfig(): ConfigWrapper {
if (!Files.exists(configFilePath)) {
throw RuntimeException("配置文件未找到: $configFilePath")
private fun loadAppConfigWrapper(): AppConfigWrapper {
if (!Files.exists(appConfigFilePath)) {
throw RuntimeException("应用配置文件未找到: $appConfigFilePath")
}
try {
val yamlContent = Files.readString(configFilePath)
val yamlContent = Files.readString(appConfigFilePath)
return Yaml(getConstructor()).load(yamlContent)
return Yaml(getConstructor(AppConfigWrapper::class.java)).load(yamlContent)
?: throw RuntimeException("YAML解析返回null")
} catch (e: Exception) {
@ -54,7 +58,23 @@ object YamlConfigLoader {
}
}
private fun getConstructor(): Constructor {
private fun loadModuleConfigWrapper(): ModuleConfigWrapper {
if (!Files.exists(moduleConfigFilePath)) {
throw RuntimeException("模块配置文件未找到: $moduleConfigFilePath")
}
try {
val yamlContent = Files.readString(moduleConfigFilePath)
return Yaml(getConstructor(ModuleConfigWrapper::class.java)).load(yamlContent)
?: throw RuntimeException("YAML解析返回null")
} catch (e: Exception) {
throw RuntimeException("YAML解析失败: ${e.message}", e)
}
}
private fun getConstructor(clazz: Class<*>): Constructor {
val propertyUtils = object : PropertyUtils() {
override fun getProperty(type: Class<*>, name: String): Property {
val processedName = if (name.contains("-")) {
@ -66,23 +86,24 @@ object YamlConfigLoader {
}
}
return Constructor(ConfigWrapper::class.java, LoaderOptions()).apply {
return Constructor(clazz, LoaderOptions()).apply {
setPropertyUtils(propertyUtils)
}
}
fun loadDatabaseConfig(): DatabaseConfig = config.database
fun loadCryptoConfig(): CryptoConfig = config.crypto
fun loadMcsmConfig(): McsmConfig = config.mcsm
fun loadWebsocketConfig(): WebsocketConfig = config.websocket
fun loadHttpConfig(): HttpConfig = config.http
fun loadModeConfig(): ModeConfig = config.mode
fun loadToolConfig(): ToolConfig = config.tools
fun loadMailConfig(): MailConfig = config.mail
fun loadBlessingSkinServerConfig(): BlessingSkinServerConfig = config.blessingSkinServer
fun loadDgLabConfig(): DgLabConfig = config.dgLab
fun loadTuImgConfig(): ImgTuConfig = config.imgTu
data class ConfigWrapper(
fun loadDatabaseConfig(): DatabaseConfig = appConfig.database
fun loadCryptoConfig(): CryptoConfig = appConfig.crypto
fun loadMcsmConfig(): McsmConfig = appConfig.mcsm
fun loadWebsocketConfig(): WebsocketConfig = appConfig.websocket
fun loadHttpConfig(): HttpConfig = appConfig.http
fun loadModeConfig(): ModeConfig = appConfig.mode
fun loadToolConfig(): ToolConfig = appConfig.tools
fun loadMailConfig(): MailConfig = appConfig.mail
fun loadBlessingSkinServerConfig(): BlessingSkinServerConfig = appConfig.blessingSkinServer
fun loadDgLabConfig(): DgLabConfig = appConfig.dgLab
fun loadTuImgConfig(): ImgTuConfig = appConfig.imgTu
fun loadModuleConfig(): ModuleConfig = moduleConfig.module
data class AppConfigWrapper(
var database: DatabaseConfig = DatabaseConfig(),
var crypto: CryptoConfig = CryptoConfig(),
var mode: ModeConfig = ModeConfig(),
@ -94,6 +115,9 @@ object YamlConfigLoader {
var blessingSkinServer: BlessingSkinServerConfig = BlessingSkinServerConfig(),
var dgLab: DgLabConfig = DgLabConfig(),
var imgTu: ImgTuConfig = ImgTuConfig(),
)
data class ModuleConfigWrapper(
var module: ModuleConfig = ModuleConfig(),
)
}

View File

@ -1,4 +0,0 @@
package top.r3944realms.ltdmanager.core.init
class DependencyResolver() {
}

View File

@ -1,149 +0,0 @@
package top.r3944realms.ltdmanager.core.init
import top.r3944realms.ltdmanager.module.Modules
import top.r3944realms.ltdmanager.module.exception.ConfigError
data class ModuleConfig(
val name: String,
val type: ModuleType,
val enabled: Boolean,
val dependencies: List<Dependency> = emptyList(),
val config: Map<String, Any> = emptyMap()
) {
data class Dependency(
private val name: String,
val type: ModuleType,
val required: Boolean = true
) {
private val dependencyName: String = "${type.modName}-$name"
fun getDepName() :String = dependencyName
}
enum class ModuleType(val modName: String) {
GROUP_MESSAGE_POLLING_MODULE(Modules.GROUP_MESSAGE_POLLING),
GROUP_REQUEST_HANDLER_MODULE(Modules.GROUP_REQUEST_HANDLER),
MAIL_MODULE(Modules.MAIL),
BAN_MODULE(Modules.BAN),
DG_LAB_MODULE(Modules.DG_LAB),
INVITE_MODULE(Modules.INVITATION_CODE),
MC_SERVER_STATUS_MODULE(Modules.MC_SERVER_STATUS),
MOD_GROUP_HANDLER_MODULE(Modules.MOD_GROUP_HANDLER),
RCON_PLAYER_LIST_MODULE(Modules.RCON_PLAYER_LIST),
STATE_MODULE(Modules.STATE),
HELP_MODULE(Modules.HELP),;
}
// 基础获取方法
fun value(paramName: String): Any =
config[paramName] ?: throw ConfigError(
ConfigError.Type.MISSING_PARAMETER,
name,
paramName
)
// 泛型获取方法
private inline fun <reified T> get(paramName: String): T {
val value = value(paramName)
return when (T::class) {
Long::class -> convertToLong(value, paramName) as T
Int::class -> convertToInt(value, paramName) as T
String::class -> value.toString() as T
Boolean::class -> convertToBoolean(value, paramName) as T
Double::class -> convertToDouble(value, paramName) as T
Float::class -> convertToFloat(value, paramName) as T
else -> {
if (value is T) value
else throw typeMismatchError<T>(value, paramName)
}
}
}
// 特定类型方法(向后兼容)
fun long(paramName: String): Long = get<Long>(paramName)
fun int(paramName: String): Int = get<Int>(paramName)
fun string(paramName: String): String = get<String>(paramName)
fun boolean(paramName: String): Boolean = get<Boolean>(paramName)
fun double(paramName: String): Double = get<Double>(paramName)
fun float(paramName: String): Float = get<Float>(paramName)
// 可选值方法
inline fun <reified T> getOrNull(paramName: String): T? =
config[paramName] as? T ?: run {
val value = config[paramName]
if (value == null) null
else if (value is T) value
else null
}
inline fun <reified T> getOrDefault(paramName: String, defaultValue: T): T =
getOrNull<T>(paramName) ?: defaultValue
// 类型转换辅助方法
private fun convertToLong(value: Any, paramName: String): Long = when (value) {
is Long -> value
is Number -> value.toLong()
is String -> try {
value.toLong()
} catch (e: NumberFormatException) {
throw typeMismatchError<Long>(value, paramName)
}
else -> throw typeMismatchError<Long>(value, paramName)
}
private fun convertToInt(value: Any, paramName: String): Int = when (value) {
is Int -> value
is Number -> value.toInt()
is String -> try {
value.toInt()
} catch (e: NumberFormatException) {
throw typeMismatchError<Int>(value, paramName)
}
else -> throw typeMismatchError<Int>(value, paramName)
}
private fun convertToBoolean(value: Any, paramName: String): Boolean = when (value) {
is Boolean -> value
is String -> when (value.lowercase()) {
"true", "yes", "1" -> true
"false", "no", "0" -> false
else -> throw typeMismatchError<Boolean>(value, paramName)
}
is Number -> value.toInt() != 0
else -> throw typeMismatchError<Boolean>(value, paramName)
}
private fun convertToDouble(value: Any, paramName: String): Double = when (value) {
is Double -> value
is Number -> value.toDouble()
is String -> try {
value.toDouble()
} catch (e: NumberFormatException) {
throw typeMismatchError<Double>(value, paramName)
}
else -> throw typeMismatchError<Double>(value, paramName)
}
private fun convertToFloat(value: Any, paramName: String): Float = when (value) {
is Float -> value
is Number -> value.toFloat()
is String -> try {
value.toFloat()
} catch (e: NumberFormatException) {
throw typeMismatchError<Float>(value, paramName)
}
else -> throw typeMismatchError<Float>(value, paramName)
}
// 错误处理辅助方法
private inline fun <reified T> typeMismatchError(
actualValue: Any,
paramName: String
): Nothing {
throw ConfigError(
ConfigError.Type.NOT_EXPECTED_VALUE,
name,
T::class.simpleName ?: T::class.java.simpleName,
actualValue::class.simpleName ?: actualValue::class.java.simpleName
)
}
}

View File

@ -1,32 +0,0 @@
package top.r3944realms.ltdmanager.core.init
import top.r3944realms.ltdmanager.GlobalManager
import top.r3944realms.ltdmanager.core.init.ModuleConfig.ModuleType.*
import top.r3944realms.ltdmanager.module.BaseModule
import top.r3944realms.ltdmanager.module.GroupRequestHandlerModule
object ModuleFactory {
fun createModule(config: ModuleConfig): BaseModule {
return when(config.type) {
GROUP_MESSAGE_POLLING_MODULE -> TODO()
GROUP_REQUEST_HANDLER_MODULE -> createGroupRequestHandler(config)
MAIL_MODULE -> TODO()
BAN_MODULE -> TODO()
DG_LAB_MODULE -> TODO()
INVITE_MODULE -> TODO()
MC_SERVER_STATUS_MODULE -> TODO()
RCON_PLAYER_LIST_MODULE -> TODO()
STATE_MODULE -> TODO()
MOD_GROUP_HANDLER_MODULE -> TODO()
HELP_MODULE -> TODO()
}
}
private fun createGroupRequestHandler(config: ModuleConfig): GroupRequestHandlerModule {
val targetGroupId = config.long("targetGroupId")
val pollIntervalMillis = config.getOrDefault("pollIntervalMillis", 30_000L)
return GroupRequestHandlerModule(
config.name, GlobalManager.napCatClient,
targetGroupId, pollIntervalMillis
)
}
}

View File

@ -1,10 +0,0 @@
package top.r3944realms.ltdmanager.core.init
import java.nio.file.Paths
object ModuleLoader {
val configFilePath = Paths.get("config/modules.yaml")
init {
}
}

View File

@ -1,15 +0,0 @@
package top.r3944realms.ltdmanager.core.init
import top.r3944realms.ltdmanager.module.BaseModule
object ModuleRegistry {
private val registry: MutableMap<String, BaseModule> = mutableMapOf()
fun register(baseModule: BaseModule) {
registry.putIfAbsent(baseModule.name, baseModule)
}
fun get(moduleName: String): BaseModule? {
return registry[moduleName]
}
}

View File

@ -5,160 +5,161 @@ import top.r3944realms.ltdmanager.module.*
// DSL
fun main() = GlobalManager.runBlockingMain {
val commonGroupId:Long = 538751386
val whitelistGroupId:Long = 920719236
val selfQQId = 3327379836
val selfNickName = "闲趣老土豆"
// 创建模块实例
val groupModule = GroupRequestHandlerModule(
moduleName = "WhiteListGroup",
client = GlobalManager.napCatClient,
targetGroupId = whitelistGroupId
)
val commonGroupMsgPollingModule = GroupMessagePollingModule(
moduleName = "CommonGroupMsgPolling",
targetGroupId = commonGroupId,
pollIntervalMillis = 5_000L,
msgHistoryCheck = 15
)
val whiteListGroupMsgPollingModule = GroupMessagePollingModule(
moduleName = "WhiteListGroup",
targetGroupId = whitelistGroupId,
pollIntervalMillis = 5_000L,
msgHistoryCheck = 15
)
val commonHelpModule = HelpModule(
moduleName = "CommonGroup",
keywords = listOf("help", "帮助"),
groupMessagePollingModule = commonGroupMsgPollingModule,
selfId = selfQQId,
selfNickName = selfNickName,
)
val whitelistHelpModule = HelpModule(
moduleName = "WhiteListGroup",
keywords = listOf("help", "帮助"),
groupMessagePollingModule = whiteListGroupMsgPollingModule,
selfId = selfQQId,
selfNickName = selfNickName,
)
val toolConfig = YamlConfigLoader.loadToolConfig()
val corconModule = RconPlayerListModule(
moduleName = "CommonGroup",
groupMessagePollingModule = commonGroupMsgPollingModule,
rconTimeOut = 2_000L,
cooldownMillis = 10_000L,
selfId = selfQQId,
selfNickName = selfNickName,
rconPath = toolConfig.rcon.mcRconToolPath.toString(),
rconConfigPath = toolConfig.rcon.mcRconToolConfigPath.toString(),
keywords = setOf(
//形容
"土豆", "马铃薯", "Potato", "potato", "POTATO",
"Potatoes", "potatoes", "POTATOES", "🥔",
//正经
"列表","服务器状态", "TPS", "tps", "list", "List"
)
)
val rconModule = RconPlayerListModule(
moduleName = "WhiteListGroup",
groupMessagePollingModule = whiteListGroupMsgPollingModule,
rconTimeOut = 2_000L,
cooldownMillis = 10_000L,
selfId = selfQQId,
selfNickName = selfNickName,
rconPath = toolConfig.rcon.mcRconToolPath.toString(),
rconConfigPath = toolConfig.rcon.mcRconToolConfigPath.toString(),
keywords = setOf(
//形容
"土豆", "马铃薯", "Potato", "potato", "POTATO",
"Potatoes", "potatoes", "POTATOES", "🥔",
//正经
"列表","服务器状态", "TPS", "tps", "list", "List"
)
)
// val mailConfig = YamlConfigLoader.loadMailConfig()
// val mailModule = MailModule(
GlobalManager.initApplication()
// val commonGroupId:Long = 538751386
// val whitelistGroupId:Long = 920719236
// val selfQQId = 3327379836
// val selfNickName = "闲趣老土豆"
// // 创建模块实例
// val groupModule = GroupRequestHandlerModule(
// moduleName = "WhiteListGroup",
// host = mailConfig.host.toString(),
// authToken = mailConfig.decryptedPassword.toString(),
// port = mailConfig.port!!,
// senderEmailAddress = mailConfig.mailAddress!!,
// client = GlobalManager.napCatClient,
// targetGroupId = whitelistGroupId
// )
// val blessingSkinConfig = YamlConfigLoader.loadBlessingSkinServerConfig()
// val invitationCodesModule = InvitationCodesModule(
// val commonGroupMsgPollingModule = GroupMessagePollingModule(
// moduleName = "CommonGroupMsgPolling",
// targetGroupId = commonGroupId,
// pollIntervalMillis = 5_000L,
// msgHistoryCheck = 15
// )
// val whiteListGroupMsgPollingModule = GroupMessagePollingModule(
// moduleName = "WhiteListGroup",
// groupMessagePollingModule = commonGroupMsgPollingModule,
// mailModule = mailModule,
// apiToken = blessingSkinConfig.invitationApi?.decryptedToken!!,
// selfId = selfQQId,
// keywords = setOf(
// "申请皮肤站注册邀请码",
// "申请土豆服务器注册邀请码",
// "申请LTD邀请码",
// "Apply for an invitation code"
// )
// targetGroupId = whitelistGroupId,
// pollIntervalMillis = 5_000L,
// msgHistoryCheck = 15
// )
// val commonMcServerStatusModule = McServerStatusModule(
// val commonHelpModule = HelpModule(
// moduleName = "CommonGroup",
// keywords = listOf("help", "帮助"),
// groupMessagePollingModule = commonGroupMsgPollingModule,
// selfId = selfQQId,
// cooldownMillis = 20_000L,
// selfNickName = selfNickName,
// commands = listOf("/m", "/mcs", "seek", "s", "test"),
// presetServer = mapOf(
// setOf("老土豆", "七周目", "7" ,"ZZ", "zz", "Zz", "seven") to "main.mmccdd.top:11106",
// setOf("土豆", "八周目", "8" ,"39", "eight") to "ac.r3944realms.top"
// )
// )
// val whitelistMcServerStatusModule = McServerStatusModule(
// val whitelistHelpModule = HelpModule(
// moduleName = "WhiteListGroup",
// keywords = listOf("help", "帮助"),
// groupMessagePollingModule = whiteListGroupMsgPollingModule,
// selfId = selfQQId,
// cooldownMillis = 20_000L,
// selfNickName = selfNickName,
// commands = listOf("/m", "/mcs", "seek", "s", "test"),
// presetServer = mapOf(
// setOf("老土豆", "七周目", "7" ,"ZZ", "zz", "Zz", "seven") to "main.mmccdd.top:11106",
// setOf("土豆", "八周目", "8" ,"39", "eight") to "ac.r3944realms.top"
// )
// val toolConfig = YamlConfigLoader.loadToolConfig()
// val corconModule = RconPlayerListModule(
// moduleName = "CommonGroup",
// groupMessagePollingModule = commonGroupMsgPollingModule,
// rconTimeOut = 2_000L,
// cooldownMillis = 10_000L,
// selfId = selfQQId,
// selfNickName = selfNickName,
// rconPath = toolConfig.rcon.mcRconToolPath.toString(),
// rconConfigPath = toolConfig.rcon.mcRconToolConfigPath.toString(),
// keywords = setOf(
// //形容
// "土豆", "马铃薯", "Potato", "potato", "POTATO",
// "Potatoes", "potatoes", "POTATOES", "🥔",
// //正经
// "列表","服务器状态", "TPS", "tps", "list", "List"
// )
// )
val dgLabModule = DGLabModule(
moduleName = "DG",
groupMessagePollingModule = commonGroupMsgPollingModule,
selfId = selfQQId,
adminIds = listOf(2561098830L),
commandHead = listOf("dglab")
)
// 注册模块到全局模块管理器
GlobalManager.moduleManager.registerModule(groupModule)
GlobalManager.moduleManager.registerModule(commonGroupMsgPollingModule)
GlobalManager.moduleManager.registerModule(whiteListGroupMsgPollingModule)
// GlobalManager.moduleManager.registerModule(commonMcServerStatusModule)
GlobalManager.moduleManager.registerModule(rconModule)
GlobalManager.moduleManager.registerModule(corconModule)
// GlobalManager.moduleManager.registerModule(whitelistMcServerStatusModule)
// GlobalManager.moduleManager.registerModule(mailModule)
// GlobalManager.moduleManager.registerModule(invitationCodesModule)
GlobalManager.moduleManager.registerModule(whitelistHelpModule)
GlobalManager.moduleManager.registerModule(commonHelpModule)
GlobalManager.moduleManager.registerModule(dgLabModule)
// GlobalManager.moduleManager.registerModule(banModule)
// GlobalManager.moduleManager.registerModule(modGroupHandlerModule)
// 加载模块
GlobalManager.moduleManager.loadModule(groupModule.name)
GlobalManager.moduleManager.loadModule(commonGroupMsgPollingModule.name)
GlobalManager.moduleManager.loadModule(whiteListGroupMsgPollingModule.name)
// GlobalManager.moduleManager.loadModule(commonMcServerStatusModule.name)
GlobalManager.moduleManager.loadModule(corconModule.name)
GlobalManager.moduleManager.loadModule(rconModule.name)
// GlobalManager.moduleManager.loadModule(mailModule.name)
// GlobalManager.moduleManager.loadModule(invitationCodesModule.name)
GlobalManager.moduleManager.loadModule(commonHelpModule.name)
// GlobalManager.moduleManager.loadModule(whitelistMcServerStatusModule.name)
GlobalManager.moduleManager.loadModule(whitelistHelpModule.name)
GlobalManager.moduleManager.loadModule(dgLabModule.name)
// GlobalManager.moduleManager.loadModule(banModule.name)
// GlobalManager.moduleManager.loadModule(modGroupHandlerModule.name)
// val rconModule = RconPlayerListModule(
// moduleName = "WhiteListGroup",
// groupMessagePollingModule = whiteListGroupMsgPollingModule,
// rconTimeOut = 2_000L,
// cooldownMillis = 10_000L,
// selfId = selfQQId,
// selfNickName = selfNickName,
// rconPath = toolConfig.rcon.mcRconToolPath.toString(),
// rconConfigPath = toolConfig.rcon.mcRconToolConfigPath.toString(),
// keywords = setOf(
// //形容
// "土豆", "马铃薯", "Potato", "potato", "POTATO",
// "Potatoes", "potatoes", "POTATOES", "🥔",
// //正经
// "列表","服务器状态", "TPS", "tps", "list", "List"
// )
// )
//// val mailConfig = YamlConfigLoader.loadMailConfig()
//// val mailModule = MailModule(
//// moduleName = "WhiteListGroup",
//// host = mailConfig.host.toString(),
//// authToken = mailConfig.decryptedPassword.toString(),
//// port = mailConfig.port!!,
//// senderEmailAddress = mailConfig.mailAddress!!,
//// )
//// val blessingSkinConfig = YamlConfigLoader.loadBlessingSkinServerConfig()
//// val invitationCodesModule = InvitationCodesModule(
//// moduleName = "WhiteListGroup",
//// groupMessagePollingModule = commonGroupMsgPollingModule,
//// mailModule = mailModule,
//// apiToken = blessingSkinConfig.invitationApi?.decryptedToken!!,
//// selfId = selfQQId,
//// keywords = setOf(
//// "申请皮肤站注册邀请码",
//// "申请土豆服务器注册邀请码",
//// "申请LTD邀请码",
//// "Apply for an invitation code"
//// )
//// )
//// val commonMcServerStatusModule = McServerStatusModule(
//// moduleName = "CommonGroup",
//// groupMessagePollingModule = commonGroupMsgPollingModule,
//// selfId = selfQQId,
//// cooldownMillis = 20_000L,
//// selfNickName = selfNickName,
//// commands = listOf("/m", "/mcs", "seek", "s", "test"),
//// presetServer = mapOf(
//// setOf("老土豆", "七周目", "7" ,"ZZ", "zz", "Zz", "seven") to "main.mmccdd.top:11106",
//// setOf("土豆", "八周目", "8" ,"39", "eight") to "ac.r3944realms.top"
//// )
//// )
//// val whitelistMcServerStatusModule = McServerStatusModule(
//// moduleName = "WhiteListGroup",
//// groupMessagePollingModule = whiteListGroupMsgPollingModule,
//// selfId = selfQQId,
//// cooldownMillis = 20_000L,
//// selfNickName = selfNickName,
//// commands = listOf("/m", "/mcs", "seek", "s", "test"),
//// presetServer = mapOf(
//// setOf("老土豆", "七周目", "7" ,"ZZ", "zz", "Zz", "seven") to "main.mmccdd.top:11106",
//// setOf("土豆", "八周目", "8" ,"39", "eight") to "ac.r3944realms.top"
//// )
//// )
// val dgLabModule = DGLabModule(
// moduleName = "DG",
// groupMessagePollingModule = commonGroupMsgPollingModule,
// selfId = selfQQId,
// adminIds = listOf(2561098830L),
// commandHead = listOf("dglab")
// )
//
// // 注册模块到全局模块管理器
// GlobalManager.moduleManager.register(groupModule)
// GlobalManager.moduleManager.register(commonGroupMsgPollingModule)
// GlobalManager.moduleManager.register(whiteListGroupMsgPollingModule)
//// GlobalManager.moduleManager.registerModule(commonMcServerStatusModule)
// GlobalManager.moduleManager.register(rconModule)
// GlobalManager.moduleManager.register(corconModule)
//// GlobalManager.moduleManager.registerModule(whitelistMcServerStatusModule)
//// GlobalManager.moduleManager.registerModule(mailModule)
//// GlobalManager.moduleManager.registerModule(invitationCodesModule)
// GlobalManager.moduleManager.register(whitelistHelpModule)
// GlobalManager.moduleManager.register(commonHelpModule)
// GlobalManager.moduleManager.register(dgLabModule)
//// GlobalManager.moduleManager.registerModule(banModule)
//// GlobalManager.moduleManager.registerModule(modGroupHandlerModule)
//
// // 加载模块
// GlobalManager.moduleManager.load(groupModule.name)
// GlobalManager.moduleManager.load(commonGroupMsgPollingModule.name)
// GlobalManager.moduleManager.load(whiteListGroupMsgPollingModule.name)
//// GlobalManager.moduleManager.loadModule(commonMcServerStatusModule.name)
// GlobalManager.moduleManager.load(corconModule.name)
// GlobalManager.moduleManager.load(rconModule.name)
//// GlobalManager.moduleManager.loadModule(mailModule.name)
//// GlobalManager.moduleManager.loadModule(invitationCodesModule.name)
// GlobalManager.moduleManager.load(commonHelpModule.name)
//// GlobalManager.moduleManager.loadModule(whitelistMcServerStatusModule.name)
// GlobalManager.moduleManager.load(whitelistHelpModule.name)
// GlobalManager.moduleManager.load(dgLabModule.name)
//// GlobalManager.moduleManager.loadModule(banModule.name)
//// GlobalManager.moduleManager.loadModule(modGroupHandlerModule.name)
}

View File

@ -137,7 +137,7 @@ class GroupRequestHandlerModule(
try {
getConnection().use { conn ->
val stmt = conn.prepareStatement(
"SELECT status FROM minecraft_manager_ltd_8.players WHERE qq=?"
"SELECT status FROM minecraft_manager_ltd_9.players WHERE qq=?"
)
stmt.setLong(1, actor)
val rs = stmt.executeQuery()

View File

@ -0,0 +1,193 @@
package top.r3944realms.ltdmanager.module
import top.r3944realms.ltdmanager.GlobalManager
import top.r3944realms.ltdmanager.core.config.ModuleConfig
import top.r3944realms.ltdmanager.core.config.ModuleConfig.Module.ModuleType.*
import top.r3944realms.ltdmanager.core.config.YamlConfigLoader
import top.r3944realms.ltdmanager.module.exception.ConfigError
object ModuleFactory {
fun createModule(config: ModuleConfig.Module): BaseModule {
return when(config.type) {
GROUP_MESSAGE_POLLING_MODULE -> createGroupMessagePolling(config)
GROUP_REQUEST_HANDLER_MODULE -> createGroupRequestHandler(config)
MAIL_MODULE -> createMail(config)
BAN_MODULE -> createBan(config)
DG_LAB_MODULE -> createDgLab(config)
INVITE_MODULE -> createInvite(config)
MC_SERVER_STATUS_MODULE -> createMcServerStatus(config)
RCON_PLAYER_LIST_MODULE -> createRconPlayerList(config)
STATE_MODULE -> createState(config)
MOD_GROUP_HANDLER_MODULE -> createModGroupHandler(config)
HELP_MODULE -> createHelpModule(config)
}
}
private fun resolveDependency(dep: ModuleConfig.Module.Dependency?, name: String): BaseModule? {
if (dep != null) {
return GlobalManager.moduleManager.getModule(dep.getDepName())
} else throw ConfigError (ConfigError.Type.MISSING_PARAMETER, "dependency", name)
}
private fun createGroupMessagePolling(config: ModuleConfig.Module): GroupMessagePollingModule {
val targetGroupId = config.long("target-group-id")
val pollIntervalMillis = config.getOrDefault("poll-interval-millis", 5_000L)
val msgHistoryCheck = config.getOrDefault("msg-history-check", 15)
return GroupMessagePollingModule(
config.name, targetGroupId,
pollIntervalMillis, msgHistoryCheck,
)
}
private fun createGroupRequestHandler(config: ModuleConfig.Module): GroupRequestHandlerModule {
val targetGroupId = config.long("target-group-id")
val pollIntervalMillis = config.getOrDefault("poll-interval-millis", 30_000L)
return GroupRequestHandlerModule(
config.name, GlobalManager.napCatClient,
targetGroupId, pollIntervalMillis
)
}
private fun createMail(config: ModuleConfig.Module): MailModule {
val mailConfig = YamlConfigLoader.loadMailConfig()
return MailModule(
moduleName = config.name,
host = mailConfig.host.toString(),
authToken = mailConfig.decryptedPassword.toString(),
port = mailConfig.port!!,
senderEmailAddress = mailConfig.mailAddress!!
)
}
private fun createBan(config: ModuleConfig.Module): BanModule {
val selfId = config.long("self-id")
val adminIds = config.list<Long>("admin-ids")
val muteCommandPrefixList = config.stringList("mute-command-prefix-list")
val unmuteCommandPrefixList = config.stringList("unmute-command-prefix-list")
val groupMessagePollingModule = resolveDependency(config.findDependency(GROUP_MESSAGE_POLLING_MODULE), "groupMessagePolling") as GroupMessagePollingModule
val minBanMinutes = config.int("min-ban-minutes")
val maxBanMinutes = config.int("max-ban-minutes")
val factorX: Int = config.int("factor-x")
return BanModule(
config.name,
groupMessagePollingModule,
selfId,
adminIds,
muteCommandPrefixList,
unmuteCommandPrefixList,
minBanMinutes,
maxBanMinutes,
factorX
)
}
private fun createDgLab(config: ModuleConfig.Module): DGLabModule {
val selfId = config.long("self-id")
val adminIds = config.list<Long>("admin-ids")
val maxClientNumber = config.int("max-client-number")
val commandHead = config.stringList("command-head")
val groupMessagePollingModule = resolveDependency(config.findDependency(GROUP_MESSAGE_POLLING_MODULE), "groupMessagePolling") as GroupMessagePollingModule
return DGLabModule(
config.name,
groupMessagePollingModule,
selfId,
adminIds,
maxClientNumber,
commandHead
)
}
private fun createInvite(config: ModuleConfig.Module): InvitationCodesModule {
val selfId = config.long("self-id")
val groupMessagePollingModule = resolveDependency(config.findDependency(GROUP_MESSAGE_POLLING_MODULE), "groupMessagePolling") as GroupMessagePollingModule
val mailModule = resolveDependency(config.findDependency(MAIL_MODULE), "mailModule") as MailModule
val blessingSkinConfig = YamlConfigLoader.loadBlessingSkinServerConfig()
val cooldownMillis = config.getOrDefault("cooldown-millis", 120_000L)
val keywords = config.stringList("keywords")
return InvitationCodesModule(
config.name,
groupMessagePollingModule,
mailModule,
blessingSkinConfig.invitationApi?.decryptedToken!!,
selfId,
cooldownMillis,
keywords.toSet()
)
}
private fun createMcServerStatus(config: ModuleConfig.Module): McServerStatusModule {
val selfId = config.long("self-id")
val cooldownMillis = config.getOrDefault("cooldown-millis", 60_000L)
val groupMessagePollingModule = resolveDependency(config.findDependency(GROUP_MESSAGE_POLLING_MODULE), "groupMessagePolling") as GroupMessagePollingModule
val commands = config.stringList("commands")
val selfNickName = config.string("self-nick-name")
val preset = config.map<Set<String>, String>("preset-server")
return McServerStatusModule(
config.name,
groupMessagePollingModule,
selfId,
selfNickName,
cooldownMillis,
commands,
preset
)
}
private fun createRconPlayerList(config: ModuleConfig.Module): RconPlayerListModule {
val toolConfig = YamlConfigLoader.loadToolConfig()
val selfId = config.long("self-id")
val cooldownMillis = config.getOrDefault("cooldown-millis", 10_000L)
val rconTimeout = config.getOrDefault("rcon-timeout-millis", 2_000L)
val groupMessagePollingModule = resolveDependency(config.findDependency(GROUP_MESSAGE_POLLING_MODULE), "groupMessagePolling") as GroupMessagePollingModule
val selfNickName = config.string("self-nick-name")
val keywords = config.stringList("keywords")
return RconPlayerListModule(
config.name,
groupMessagePollingModule,
rconTimeout,
cooldownMillis,
selfId,
selfNickName,
toolConfig.rcon.mcRconToolPath.toString(),
toolConfig.rcon.mcRconToolConfigPath.toString(),
keywords.toSet()
)
}
private fun createState(config: ModuleConfig.Module): StateModule {
val onlineName = config.string("online-name")
val offlineName = config.string("offline-name")
return StateModule(
config.name,
onlineName,
offlineName
)
}
private fun createModGroupHandler(config: ModuleConfig.Module): ModGroupHandlerModule {
val targetGroupId = config.long("target-group-id")
val answers = config.stringList("answers")
val pollingMillis = config.getOrDefault("poll-interval-millis", 30_000L)
return ModGroupHandlerModule(
config.name,
targetGroupId,
answers,
pollingMillis
)
}
private fun createHelpModule(config: ModuleConfig.Module): HelpModule {
val selfId = config.long("self-id")
val cooldownMillis = config.getOrDefault("cooldown-millis", 10_000L)
config.getOrDefault("rcon-timeout-millis", 2_000L)
val groupMessagePollingModule = resolveDependency(config.findDependency(GROUP_MESSAGE_POLLING_MODULE), "groupMessagePolling") as GroupMessagePollingModule
val selfNickName = config.string("self-nick-name")
val keywords = config.stringList("keywords")
return HelpModule(
config.name,
groupMessagePollingModule,
selfId,
selfNickName,
keywords,
cooldownMillis
)
}
}

View File

@ -1,18 +1,43 @@
package top.r3944realms.ltdmanager.module
import top.r3944realms.ltdmanager.core.config.YamlConfigLoader
import top.r3944realms.ltdmanager.utils.LoggerUtil
import java.util.*
class ModuleManager {
private val modules = mutableMapOf<String, BaseModule>()
private var hasLoaded = false
fun getModules(): Map<String, BaseModule> {
return (modules).toMap()
}
fun getModule(name: String): BaseModule? {
return modules[name]
}
fun loadConfig() {
if (!hasLoaded) {
hasLoaded = true
val moduleConfig = YamlConfigLoader.loadModuleConfig()
moduleConfig.modules.let {
val enableBaseModules = LinkedList<BaseModule>()
if (it != null) {
for (mod in it) {
val module = ModuleFactory.createModule(mod)
register(module)
if (mod.enabled) {
enableBaseModules.add(module)
}
}
}
for (module in enableBaseModules) {
load(module.name)
}
}
}
}
/**
* 注册模块到管理器
*/
fun registerModule(module: BaseModule) {
fun register(module: BaseModule) {
if (modules.containsKey(module.name)) {
LoggerUtil.logger.warn("模块已注册: ${module.name}")
return
@ -23,16 +48,16 @@ class ModuleManager {
/**
* 注册多模块到管理器
*/
fun registerModules(moduleList: List<BaseModule>) {
fun register(moduleList: List<BaseModule>) {
for (module in moduleList) {
registerModule(module)
register(module)
}
}
/**
* 加载指定模块
*/
fun loadModule(name: String) {
fun load(name: String) {
val module = modules[name]
if (module == null) {
LoggerUtil.logger.warn("尝试加载不存在的模块: $name")
@ -52,7 +77,7 @@ class ModuleManager {
/**
* 卸载指定模块
*/
suspend fun unloadModule(name: String) {
suspend fun unload(name: String) {
val module = modules[name]
if (module == null) {
LoggerUtil.logger.warn("尝试卸载不存在的模块: $name")
@ -107,14 +132,14 @@ class ModuleManager {
* 扩展方法批量加载模块
*/
fun ModuleManager.loadModules(vararg names: String) {
names.forEach { loadModule(it) }
names.forEach { load(it) }
}
/**
* 扩展方法批量卸载模块
*/
suspend fun ModuleManager.unloadModules(vararg names: String) {
names.forEach { unloadModule(it) }
names.forEach { unload(it) }
}
/**
* 关闭所有模块

View File

@ -0,0 +1,2 @@
module:
modules:

View File

@ -29,11 +29,11 @@ fun main() = GlobalManager.runBlockingMain {
adminIds = listOf(2561098830L),
commandHead = listOf("dglab")
)
GlobalManager.moduleManager.registerModule(groupMsgPollingModule)
GlobalManager.moduleManager.registerModule(helpModule)
GlobalManager.moduleManager.registerModule(dgLabModule)
GlobalManager.moduleManager.register(groupMsgPollingModule)
GlobalManager.moduleManager.register(helpModule)
GlobalManager.moduleManager.register(dgLabModule)
GlobalManager.moduleManager.loadModule(groupMsgPollingModule.name)
GlobalManager.moduleManager.loadModule(helpModule.name)
GlobalManager.moduleManager.loadModule(dgLabModule.name)
GlobalManager.moduleManager.load(groupMsgPollingModule.name)
GlobalManager.moduleManager.load(helpModule.name)
GlobalManager.moduleManager.load(dgLabModule.name)
}

View File

@ -22,9 +22,9 @@ fun main() = GlobalManager.runBlockingMain {
}
}
if (mailModule == null) throw IllegalStateException("Lost Required Argument")
GlobalManager.moduleManager.registerModule(mailModule)
GlobalManager.moduleManager.register(mailModule)
GlobalManager.moduleManager.loadModule(mailModule.name)
GlobalManager.moduleManager.load(mailModule.name)
val template = object {}.javaClass.classLoader
.getResource("mail-body.html")?: throw IllegalArgumentException("模板文件未找到")
val expireHours = 24 // 有效期 24 小时

View File

@ -1,12 +1,7 @@
package top.r394realms.ltdmanagertest.mod
import kotlinx.coroutines.delay
import top.r3944realms.ltdmanager.GlobalManager
import top.r3944realms.ltdmanager.GlobalManager.napCatClient
import top.r3944realms.ltdmanager.module.ModGroupHandlerModule
import top.r3944realms.ltdmanager.napcat.data.ID
import top.r3944realms.ltdmanager.napcat.data.MessageType
import top.r3944realms.ltdmanager.napcat.request.message.SendForwardMsgRequest
fun main() = GlobalManager.runBlockingMain {
@ -23,8 +18,8 @@ fun main() = GlobalManager.runBlockingMain {
// 注册模块到全局模块管理器
GlobalManager.moduleManager.registerModule(modGroupHandlerModule)
GlobalManager.moduleManager.register(modGroupHandlerModule)
// 加载模块
GlobalManager.moduleManager.loadModule(modGroupHandlerModule.name)
GlobalManager.moduleManager.load(modGroupHandlerModule.name)
}

View File

@ -1,7 +1,6 @@
package top.r394realms.ltdmanagertest
import top.r3944realms.ltdmanager.GlobalManager
import top.r3944realms.ltdmanager.module.GroupRequestHandlerModule
import top.r3944realms.ltdmanager.module.StateModule
@ -15,8 +14,8 @@ fun main() = GlobalManager.runBlockingMain {
// 注册模块到全局模块管理器
GlobalManager.moduleManager.registerModule(stateModule)
GlobalManager.moduleManager.register(stateModule)
// 加载模块
GlobalManager.moduleManager.loadModule(stateModule.name)
GlobalManager.moduleManager.load(stateModule.name)
}