refactor(使用配置加载模块而非硬编码在主类中): 配置加载模块
This commit is contained in:
parent
37eeaf143c
commit
988ed191ec
|
|
@ -3,5 +3,5 @@ org.gradle.downloadSources=false
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.degree_of_parallelism=16
|
org.gradle.degree_of_parallelism=16
|
||||||
project_group=top.r3944realms.ltdmanager
|
project_group=top.r3944realms.ltdmanager
|
||||||
project_version=1.14-SNAPSHOT
|
project_version=1.15-SNAPSHOT
|
||||||
dg_lab_version=4.4.14.18
|
dg_lab_version=4.4.14.18
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ object GlobalManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initApplication() {
|
fun initApplication() {
|
||||||
|
moduleManager.loadConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NapCat 客户端
|
// NapCat 客户端
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ data class BlessingSkinServerConfig(
|
||||||
try {
|
try {
|
||||||
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
|
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"blessing-skin-server.invitation-api.encrypted-token",
|
"blessing-skin-server.invitation-api.encrypted-token",
|
||||||
encryptedToken!!
|
encryptedToken!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ data class DatabaseConfig(
|
||||||
try {
|
try {
|
||||||
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
|
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"database.encrypted-password",
|
"database.encrypted-password",
|
||||||
this.encryptedPassword!!
|
this.encryptedPassword!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ data class DgLabConfig(
|
||||||
try {
|
try {
|
||||||
encryptedLocalServerSslPassword = "ENC(${CryptoUtil.encrypt(encryptedLocalServerSslPassword!!)})"
|
encryptedLocalServerSslPassword = "ENC(${CryptoUtil.encrypt(encryptedLocalServerSslPassword!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"dg-lab.ws-server.encrypted-local-server-ssl-password",
|
"dg-lab.ws-server.encrypted-local-server-ssl-password",
|
||||||
encryptedLocalServerSslPassword!!
|
encryptedLocalServerSslPassword!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ data class HttpConfig(
|
||||||
try {
|
try {
|
||||||
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
|
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"http.encrypted-token",
|
"http.encrypted-token",
|
||||||
this.encryptedToken!!
|
this.encryptedToken!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ data class ImgTuConfig(
|
||||||
try {
|
try {
|
||||||
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
|
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"img-tu.encrypted-password",
|
"img-tu.encrypted-password",
|
||||||
this.encryptedPassword!!
|
this.encryptedPassword!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ data class MailConfig(
|
||||||
try {
|
try {
|
||||||
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
|
encryptedPassword = "ENC(${CryptoUtil.encrypt(encryptedPassword!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"mail.encrypted-password",
|
"mail.encrypted-password",
|
||||||
this.encryptedPassword!!
|
this.encryptedPassword!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ data class McsmConfig(
|
||||||
try {
|
try {
|
||||||
encryptedApiKey = "ENC(${CryptoUtil.encrypt(encryptedApiKey!!)})"
|
encryptedApiKey = "ENC(${CryptoUtil.encrypt(encryptedApiKey!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"mcsm.encrypted-api-key",
|
"mcsm.encrypted-api-key",
|
||||||
this.encryptedApiKey!!
|
this.encryptedApiKey!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ data class ToolConfig(
|
||||||
try {
|
try {
|
||||||
rconPassword = "ENC(${CryptoUtil.encrypt(rconPassword!!)})"
|
rconPassword = "ENC(${CryptoUtil.encrypt(rconPassword!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"tools.rcon.rcon-password",
|
"tools.rcon.rcon-password",
|
||||||
rconPassword!!
|
rconPassword!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ data class WebsocketConfig(
|
||||||
try {
|
try {
|
||||||
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
|
encryptedToken = "ENC(${CryptoUtil.encrypt(encryptedToken!!)})"
|
||||||
YamlUpdater.updateYaml(
|
YamlUpdater.updateYaml(
|
||||||
YamlConfigLoader.configFilePath.toString(),
|
YamlConfigLoader.appConfigFilePath.toString(),
|
||||||
"websocket.encrypted-token",
|
"websocket.encrypted-token",
|
||||||
this.encryptedToken!!
|
this.encryptedToken!!
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,30 @@ import org.yaml.snakeyaml.introspector.PropertyUtils
|
||||||
import top.r3944realms.ltdmanager.utils.ConfigInitializer
|
import top.r3944realms.ltdmanager.utils.ConfigInitializer
|
||||||
import top.r3944realms.ltdmanager.utils.NamingConventionUtil
|
import top.r3944realms.ltdmanager.utils.NamingConventionUtil
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
object YamlConfigLoader {
|
object YamlConfigLoader {
|
||||||
val configFilePath = Paths.get("config/application.yaml") // 配置文件路径
|
val appConfigFilePath: Path = Paths.get("config/application.yaml") // 配置文件路径
|
||||||
private val _config by lazy { loadConfig() } // 延迟初始化
|
val moduleConfigFilePath: Path = Paths.get("config/module.yaml") // 配置文件路径
|
||||||
val config: ConfigWrapper get() = _config
|
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 {
|
init {
|
||||||
// 第一次启动确保配置文件存在
|
// 第一次启动确保配置文件存在
|
||||||
|
ConfigInitializer.initConfig("module.yaml", "config", false)
|
||||||
ConfigInitializer.initConfig("application.yaml", "config")
|
ConfigInitializer.initConfig("application.yaml", "config")
|
||||||
|
|
||||||
// 初始化后加密(确保只执行一次)
|
// 初始化后加密(确保只执行一次)
|
||||||
runCatching {
|
runCatching {
|
||||||
ensureConfigEncrypted(_config)
|
ensureConfigEncrypted(_app_config)
|
||||||
}.onFailure { e ->
|
}.onFailure { e ->
|
||||||
println("初始化加密失败: ${e.message}")
|
println("初始化加密失败: ${e.message}")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun ensureConfigEncrypted(config: ConfigWrapper?) {
|
private fun ensureConfigEncrypted(config: AppConfigWrapper?) {
|
||||||
config?.database?.encryptPassword()
|
config?.database?.encryptPassword()
|
||||||
config?.websocket?.encryptToken()
|
config?.websocket?.encryptToken()
|
||||||
config?.http?.encryptToken()
|
config?.http?.encryptToken()
|
||||||
|
|
@ -38,15 +42,15 @@ object YamlConfigLoader {
|
||||||
config?.dgLab?.wsServer?.encryptPassword()
|
config?.dgLab?.wsServer?.encryptPassword()
|
||||||
config?.imgTu?.encryptPassword()
|
config?.imgTu?.encryptPassword()
|
||||||
}
|
}
|
||||||
private fun loadConfig(): ConfigWrapper {
|
private fun loadAppConfigWrapper(): AppConfigWrapper {
|
||||||
if (!Files.exists(configFilePath)) {
|
if (!Files.exists(appConfigFilePath)) {
|
||||||
throw RuntimeException("配置文件未找到: $configFilePath")
|
throw RuntimeException("应用配置文件未找到: $appConfigFilePath")
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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")
|
?: throw RuntimeException("YAML解析返回null")
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} 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() {
|
val propertyUtils = object : PropertyUtils() {
|
||||||
override fun getProperty(type: Class<*>, name: String): Property {
|
override fun getProperty(type: Class<*>, name: String): Property {
|
||||||
val processedName = if (name.contains("-")) {
|
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)
|
setPropertyUtils(propertyUtils)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadDatabaseConfig(): DatabaseConfig = config.database
|
fun loadDatabaseConfig(): DatabaseConfig = appConfig.database
|
||||||
fun loadCryptoConfig(): CryptoConfig = config.crypto
|
fun loadCryptoConfig(): CryptoConfig = appConfig.crypto
|
||||||
fun loadMcsmConfig(): McsmConfig = config.mcsm
|
fun loadMcsmConfig(): McsmConfig = appConfig.mcsm
|
||||||
fun loadWebsocketConfig(): WebsocketConfig = config.websocket
|
fun loadWebsocketConfig(): WebsocketConfig = appConfig.websocket
|
||||||
fun loadHttpConfig(): HttpConfig = config.http
|
fun loadHttpConfig(): HttpConfig = appConfig.http
|
||||||
fun loadModeConfig(): ModeConfig = config.mode
|
fun loadModeConfig(): ModeConfig = appConfig.mode
|
||||||
fun loadToolConfig(): ToolConfig = config.tools
|
fun loadToolConfig(): ToolConfig = appConfig.tools
|
||||||
fun loadMailConfig(): MailConfig = config.mail
|
fun loadMailConfig(): MailConfig = appConfig.mail
|
||||||
fun loadBlessingSkinServerConfig(): BlessingSkinServerConfig = config.blessingSkinServer
|
fun loadBlessingSkinServerConfig(): BlessingSkinServerConfig = appConfig.blessingSkinServer
|
||||||
fun loadDgLabConfig(): DgLabConfig = config.dgLab
|
fun loadDgLabConfig(): DgLabConfig = appConfig.dgLab
|
||||||
fun loadTuImgConfig(): ImgTuConfig = config.imgTu
|
fun loadTuImgConfig(): ImgTuConfig = appConfig.imgTu
|
||||||
data class ConfigWrapper(
|
fun loadModuleConfig(): ModuleConfig = moduleConfig.module
|
||||||
|
data class AppConfigWrapper(
|
||||||
var database: DatabaseConfig = DatabaseConfig(),
|
var database: DatabaseConfig = DatabaseConfig(),
|
||||||
var crypto: CryptoConfig = CryptoConfig(),
|
var crypto: CryptoConfig = CryptoConfig(),
|
||||||
var mode: ModeConfig = ModeConfig(),
|
var mode: ModeConfig = ModeConfig(),
|
||||||
|
|
@ -94,6 +115,9 @@ object YamlConfigLoader {
|
||||||
var blessingSkinServer: BlessingSkinServerConfig = BlessingSkinServerConfig(),
|
var blessingSkinServer: BlessingSkinServerConfig = BlessingSkinServerConfig(),
|
||||||
var dgLab: DgLabConfig = DgLabConfig(),
|
var dgLab: DgLabConfig = DgLabConfig(),
|
||||||
var imgTu: ImgTuConfig = ImgTuConfig(),
|
var imgTu: ImgTuConfig = ImgTuConfig(),
|
||||||
|
)
|
||||||
|
|
||||||
|
data class ModuleConfigWrapper(
|
||||||
|
var module: ModuleConfig = ModuleConfig(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
package top.r3944realms.ltdmanager.core.init
|
|
||||||
|
|
||||||
class DependencyResolver() {
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,160 +5,161 @@ import top.r3944realms.ltdmanager.module.*
|
||||||
|
|
||||||
// DSL
|
// DSL
|
||||||
fun main() = GlobalManager.runBlockingMain {
|
fun main() = GlobalManager.runBlockingMain {
|
||||||
val commonGroupId:Long = 538751386
|
GlobalManager.initApplication()
|
||||||
val whitelistGroupId:Long = 920719236
|
// val commonGroupId:Long = 538751386
|
||||||
val selfQQId = 3327379836
|
// val whitelistGroupId:Long = 920719236
|
||||||
val selfNickName = "闲趣老土豆"
|
// val selfQQId = 3327379836
|
||||||
// 创建模块实例
|
// val selfNickName = "闲趣老土豆"
|
||||||
val groupModule = GroupRequestHandlerModule(
|
// // 创建模块实例
|
||||||
moduleName = "WhiteListGroup",
|
// val groupModule = GroupRequestHandlerModule(
|
||||||
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(
|
|
||||||
// moduleName = "WhiteListGroup",
|
// moduleName = "WhiteListGroup",
|
||||||
// host = mailConfig.host.toString(),
|
// client = GlobalManager.napCatClient,
|
||||||
// authToken = mailConfig.decryptedPassword.toString(),
|
// targetGroupId = whitelistGroupId
|
||||||
// port = mailConfig.port!!,
|
|
||||||
// senderEmailAddress = mailConfig.mailAddress!!,
|
|
||||||
// )
|
// )
|
||||||
// val blessingSkinConfig = YamlConfigLoader.loadBlessingSkinServerConfig()
|
// val commonGroupMsgPollingModule = GroupMessagePollingModule(
|
||||||
// val invitationCodesModule = InvitationCodesModule(
|
// moduleName = "CommonGroupMsgPolling",
|
||||||
|
// targetGroupId = commonGroupId,
|
||||||
|
// pollIntervalMillis = 5_000L,
|
||||||
|
// msgHistoryCheck = 15
|
||||||
|
// )
|
||||||
|
// val whiteListGroupMsgPollingModule = GroupMessagePollingModule(
|
||||||
// moduleName = "WhiteListGroup",
|
// moduleName = "WhiteListGroup",
|
||||||
// groupMessagePollingModule = commonGroupMsgPollingModule,
|
// targetGroupId = whitelistGroupId,
|
||||||
// mailModule = mailModule,
|
// pollIntervalMillis = 5_000L,
|
||||||
// apiToken = blessingSkinConfig.invitationApi?.decryptedToken!!,
|
// msgHistoryCheck = 15
|
||||||
// selfId = selfQQId,
|
|
||||||
// keywords = setOf(
|
|
||||||
// "申请皮肤站注册邀请码",
|
|
||||||
// "申请土豆服务器注册邀请码",
|
|
||||||
// "申请LTD邀请码",
|
|
||||||
// "Apply for an invitation code"
|
|
||||||
// )
|
|
||||||
// )
|
// )
|
||||||
// val commonMcServerStatusModule = McServerStatusModule(
|
// val commonHelpModule = HelpModule(
|
||||||
// moduleName = "CommonGroup",
|
// moduleName = "CommonGroup",
|
||||||
|
// keywords = listOf("help", "帮助"),
|
||||||
// groupMessagePollingModule = commonGroupMsgPollingModule,
|
// groupMessagePollingModule = commonGroupMsgPollingModule,
|
||||||
// selfId = selfQQId,
|
// selfId = selfQQId,
|
||||||
// cooldownMillis = 20_000L,
|
|
||||||
// selfNickName = selfNickName,
|
// 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",
|
// moduleName = "WhiteListGroup",
|
||||||
|
// keywords = listOf("help", "帮助"),
|
||||||
// groupMessagePollingModule = whiteListGroupMsgPollingModule,
|
// groupMessagePollingModule = whiteListGroupMsgPollingModule,
|
||||||
// selfId = selfQQId,
|
// selfId = selfQQId,
|
||||||
// cooldownMillis = 20_000L,
|
|
||||||
// selfNickName = selfNickName,
|
// selfNickName = selfNickName,
|
||||||
// commands = listOf("/m", "/mcs", "seek", "s", "test"),
|
// )
|
||||||
// presetServer = mapOf(
|
// val toolConfig = YamlConfigLoader.loadToolConfig()
|
||||||
// setOf("老土豆", "七周目", "7" ,"ZZ", "zz", "Zz", "seven") to "main.mmccdd.top:11106",
|
// val corconModule = RconPlayerListModule(
|
||||||
// setOf("土豆", "八周目", "8" ,"39", "eight") to "ac.r3944realms.top"
|
// 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(
|
// val rconModule = RconPlayerListModule(
|
||||||
moduleName = "DG",
|
// moduleName = "WhiteListGroup",
|
||||||
groupMessagePollingModule = commonGroupMsgPollingModule,
|
// groupMessagePollingModule = whiteListGroupMsgPollingModule,
|
||||||
selfId = selfQQId,
|
// rconTimeOut = 2_000L,
|
||||||
adminIds = listOf(2561098830L),
|
// cooldownMillis = 10_000L,
|
||||||
commandHead = listOf("dglab")
|
// selfId = selfQQId,
|
||||||
)
|
// selfNickName = selfNickName,
|
||||||
|
// rconPath = toolConfig.rcon.mcRconToolPath.toString(),
|
||||||
// 注册模块到全局模块管理器
|
// rconConfigPath = toolConfig.rcon.mcRconToolConfigPath.toString(),
|
||||||
GlobalManager.moduleManager.registerModule(groupModule)
|
// keywords = setOf(
|
||||||
GlobalManager.moduleManager.registerModule(commonGroupMsgPollingModule)
|
// //形容
|
||||||
GlobalManager.moduleManager.registerModule(whiteListGroupMsgPollingModule)
|
// "土豆", "马铃薯", "Potato", "potato", "POTATO",
|
||||||
// GlobalManager.moduleManager.registerModule(commonMcServerStatusModule)
|
// "Potatoes", "potatoes", "POTATOES", "🥔",
|
||||||
GlobalManager.moduleManager.registerModule(rconModule)
|
// //正经
|
||||||
GlobalManager.moduleManager.registerModule(corconModule)
|
// "列表","服务器状态", "TPS", "tps", "list", "List"
|
||||||
// GlobalManager.moduleManager.registerModule(whitelistMcServerStatusModule)
|
// )
|
||||||
// GlobalManager.moduleManager.registerModule(mailModule)
|
// )
|
||||||
// GlobalManager.moduleManager.registerModule(invitationCodesModule)
|
//// val mailConfig = YamlConfigLoader.loadMailConfig()
|
||||||
GlobalManager.moduleManager.registerModule(whitelistHelpModule)
|
//// val mailModule = MailModule(
|
||||||
GlobalManager.moduleManager.registerModule(commonHelpModule)
|
//// moduleName = "WhiteListGroup",
|
||||||
GlobalManager.moduleManager.registerModule(dgLabModule)
|
//// host = mailConfig.host.toString(),
|
||||||
// GlobalManager.moduleManager.registerModule(banModule)
|
//// authToken = mailConfig.decryptedPassword.toString(),
|
||||||
// GlobalManager.moduleManager.registerModule(modGroupHandlerModule)
|
//// port = mailConfig.port!!,
|
||||||
|
//// senderEmailAddress = mailConfig.mailAddress!!,
|
||||||
// 加载模块
|
//// )
|
||||||
GlobalManager.moduleManager.loadModule(groupModule.name)
|
//// val blessingSkinConfig = YamlConfigLoader.loadBlessingSkinServerConfig()
|
||||||
GlobalManager.moduleManager.loadModule(commonGroupMsgPollingModule.name)
|
//// val invitationCodesModule = InvitationCodesModule(
|
||||||
GlobalManager.moduleManager.loadModule(whiteListGroupMsgPollingModule.name)
|
//// moduleName = "WhiteListGroup",
|
||||||
// GlobalManager.moduleManager.loadModule(commonMcServerStatusModule.name)
|
//// groupMessagePollingModule = commonGroupMsgPollingModule,
|
||||||
GlobalManager.moduleManager.loadModule(corconModule.name)
|
//// mailModule = mailModule,
|
||||||
GlobalManager.moduleManager.loadModule(rconModule.name)
|
//// apiToken = blessingSkinConfig.invitationApi?.decryptedToken!!,
|
||||||
// GlobalManager.moduleManager.loadModule(mailModule.name)
|
//// selfId = selfQQId,
|
||||||
// GlobalManager.moduleManager.loadModule(invitationCodesModule.name)
|
//// keywords = setOf(
|
||||||
GlobalManager.moduleManager.loadModule(commonHelpModule.name)
|
//// "申请皮肤站注册邀请码",
|
||||||
// GlobalManager.moduleManager.loadModule(whitelistMcServerStatusModule.name)
|
//// "申请土豆服务器注册邀请码",
|
||||||
GlobalManager.moduleManager.loadModule(whitelistHelpModule.name)
|
//// "申请LTD邀请码",
|
||||||
GlobalManager.moduleManager.loadModule(dgLabModule.name)
|
//// "Apply for an invitation code"
|
||||||
// GlobalManager.moduleManager.loadModule(banModule.name)
|
//// )
|
||||||
// GlobalManager.moduleManager.loadModule(modGroupHandlerModule.name)
|
//// )
|
||||||
|
//// 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)
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +137,7 @@ class GroupRequestHandlerModule(
|
||||||
try {
|
try {
|
||||||
getConnection().use { conn ->
|
getConnection().use { conn ->
|
||||||
val stmt = conn.prepareStatement(
|
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)
|
stmt.setLong(1, actor)
|
||||||
val rs = stmt.executeQuery()
|
val rs = stmt.executeQuery()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,18 +1,43 @@
|
||||||
package top.r3944realms.ltdmanager.module
|
package top.r3944realms.ltdmanager.module
|
||||||
|
|
||||||
|
import top.r3944realms.ltdmanager.core.config.YamlConfigLoader
|
||||||
import top.r3944realms.ltdmanager.utils.LoggerUtil
|
import top.r3944realms.ltdmanager.utils.LoggerUtil
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class ModuleManager {
|
class ModuleManager {
|
||||||
|
|
||||||
private val modules = mutableMapOf<String, BaseModule>()
|
private val modules = mutableMapOf<String, BaseModule>()
|
||||||
|
private var hasLoaded = false
|
||||||
fun getModules(): Map<String, BaseModule> {
|
fun getModules(): Map<String, BaseModule> {
|
||||||
return (modules).toMap()
|
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)) {
|
if (modules.containsKey(module.name)) {
|
||||||
LoggerUtil.logger.warn("模块已注册: ${module.name}")
|
LoggerUtil.logger.warn("模块已注册: ${module.name}")
|
||||||
return
|
return
|
||||||
|
|
@ -23,16 +48,16 @@ class ModuleManager {
|
||||||
/**
|
/**
|
||||||
* 注册多模块到管理器
|
* 注册多模块到管理器
|
||||||
*/
|
*/
|
||||||
fun registerModules(moduleList: List<BaseModule>) {
|
fun register(moduleList: List<BaseModule>) {
|
||||||
for (module in moduleList) {
|
for (module in moduleList) {
|
||||||
registerModule(module)
|
register(module)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载指定模块
|
* 加载指定模块
|
||||||
*/
|
*/
|
||||||
fun loadModule(name: String) {
|
fun load(name: String) {
|
||||||
val module = modules[name]
|
val module = modules[name]
|
||||||
if (module == null) {
|
if (module == null) {
|
||||||
LoggerUtil.logger.warn("尝试加载不存在的模块: $name")
|
LoggerUtil.logger.warn("尝试加载不存在的模块: $name")
|
||||||
|
|
@ -52,7 +77,7 @@ class ModuleManager {
|
||||||
/**
|
/**
|
||||||
* 卸载指定模块
|
* 卸载指定模块
|
||||||
*/
|
*/
|
||||||
suspend fun unloadModule(name: String) {
|
suspend fun unload(name: String) {
|
||||||
val module = modules[name]
|
val module = modules[name]
|
||||||
if (module == null) {
|
if (module == null) {
|
||||||
LoggerUtil.logger.warn("尝试卸载不存在的模块: $name")
|
LoggerUtil.logger.warn("尝试卸载不存在的模块: $name")
|
||||||
|
|
@ -107,14 +132,14 @@ class ModuleManager {
|
||||||
* 扩展方法:批量加载模块
|
* 扩展方法:批量加载模块
|
||||||
*/
|
*/
|
||||||
fun ModuleManager.loadModules(vararg names: String) {
|
fun ModuleManager.loadModules(vararg names: String) {
|
||||||
names.forEach { loadModule(it) }
|
names.forEach { load(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扩展方法:批量卸载模块
|
* 扩展方法:批量卸载模块
|
||||||
*/
|
*/
|
||||||
suspend fun ModuleManager.unloadModules(vararg names: String) {
|
suspend fun ModuleManager.unloadModules(vararg names: String) {
|
||||||
names.forEach { unloadModule(it) }
|
names.forEach { unload(it) }
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 关闭所有模块
|
* 关闭所有模块
|
||||||
|
|
|
||||||
2
src/main/resources/module.yaml
Normal file
2
src/main/resources/module.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
module:
|
||||||
|
modules:
|
||||||
|
|
@ -29,11 +29,11 @@ fun main() = GlobalManager.runBlockingMain {
|
||||||
adminIds = listOf(2561098830L),
|
adminIds = listOf(2561098830L),
|
||||||
commandHead = listOf("dglab")
|
commandHead = listOf("dglab")
|
||||||
)
|
)
|
||||||
GlobalManager.moduleManager.registerModule(groupMsgPollingModule)
|
GlobalManager.moduleManager.register(groupMsgPollingModule)
|
||||||
GlobalManager.moduleManager.registerModule(helpModule)
|
GlobalManager.moduleManager.register(helpModule)
|
||||||
GlobalManager.moduleManager.registerModule(dgLabModule)
|
GlobalManager.moduleManager.register(dgLabModule)
|
||||||
|
|
||||||
GlobalManager.moduleManager.loadModule(groupMsgPollingModule.name)
|
GlobalManager.moduleManager.load(groupMsgPollingModule.name)
|
||||||
GlobalManager.moduleManager.loadModule(helpModule.name)
|
GlobalManager.moduleManager.load(helpModule.name)
|
||||||
GlobalManager.moduleManager.loadModule(dgLabModule.name)
|
GlobalManager.moduleManager.load(dgLabModule.name)
|
||||||
}
|
}
|
||||||
|
|
@ -22,9 +22,9 @@ fun main() = GlobalManager.runBlockingMain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mailModule == null) throw IllegalStateException("Lost Required Argument")
|
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
|
val template = object {}.javaClass.classLoader
|
||||||
.getResource("mail-body.html")?: throw IllegalArgumentException("模板文件未找到")
|
.getResource("mail-body.html")?: throw IllegalArgumentException("模板文件未找到")
|
||||||
val expireHours = 24 // 有效期 24 小时
|
val expireHours = 24 // 有效期 24 小时
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,7 @@
|
||||||
package top.r394realms.ltdmanagertest.mod
|
package top.r394realms.ltdmanagertest.mod
|
||||||
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import top.r3944realms.ltdmanager.GlobalManager
|
import top.r3944realms.ltdmanager.GlobalManager
|
||||||
import top.r3944realms.ltdmanager.GlobalManager.napCatClient
|
|
||||||
import top.r3944realms.ltdmanager.module.ModGroupHandlerModule
|
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 {
|
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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package top.r394realms.ltdmanagertest
|
package top.r394realms.ltdmanagertest
|
||||||
|
|
||||||
import top.r3944realms.ltdmanager.GlobalManager
|
import top.r3944realms.ltdmanager.GlobalManager
|
||||||
import top.r3944realms.ltdmanager.module.GroupRequestHandlerModule
|
|
||||||
import top.r3944realms.ltdmanager.module.StateModule
|
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)
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user