All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xyz.cssxsh.mirai.admin.data.AdminSetting.kt Maven / Gradle / Ivy

The newest version!
package xyz.cssxsh.mirai.admin.data

import kotlinx.coroutines.*
import net.mamoe.mirai.console.data.*
import net.mamoe.mirai.console.plugin.jvm.*
import net.mamoe.mirai.console.util.*
import xyz.cssxsh.mirai.admin.*
import java.io.IOException
import java.nio.file.*
import java.util.WeakHashMap
import kotlin.io.path.*

@PublishedApi
internal object AdminSetting : ReadOnlyPluginConfig("AdminSetting"), MiraiContentCensorConfig {

    internal const val OWNER_DEFAULT = 12345L

    private val dict: MutableMap> = HashMap()

    private val cache: MutableMap = WeakHashMap()

    override val censorRegex: Sequence = sequence {
        for ((_, patterns) in dict) {
            for (pattern in patterns) {
                if (pattern.isEmpty()) continue
                val regex = try {
                    cache.getOrPut(pattern) { pattern.toRegex() }
                } catch (_: IllegalArgumentException) {
                    continue
                }

                yield(regex)
            }
        }
    }

    @ConsoleExperimentalApi
    override fun onInit(owner: PluginDataHolder, storage: PluginDataStorage) {
        val plugin = owner as? JvmPlugin ?: return
        val folder = plugin.resolveConfigPath("censor")
        folder.toFile().mkdirs()

        for (path in folder.listDirectoryEntries()) {
            if (!path.name.endsWith(".txt")) continue
            plugin.logger.info("读取审核库 ${path.fileName}")

            try {
                dict[path.name] = path.readLines()
            } catch (cause: IOException) {
                plugin.logger.warning("读取失败 $path", cause)
            }
        }

        plugin.launch(CoroutineName(name = "CENSOR_WATCH")) {
            val watcher = try {
                runInterruptible(Dispatchers.IO) {
                    folder.fileSystem.newWatchService()
                }
            } catch (cause: IOException) {
                plugin.logger.warning("正则词库文件监视器创建失败", cause)
                return@launch
            }
            val kinds = arrayOf(
                StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE,
                StandardWatchEventKinds.ENTRY_MODIFY
            )
            runInterruptible(Dispatchers.IO) {
                folder.register(watcher, kinds, com.sun.nio.file.SensitivityWatchEventModifier.LOW)
            }
            while (isActive) {
                val key = runInterruptible(Dispatchers.IO, watcher::take)
                for (event in key.pollEvents()) {
                    val path = event.context() as? Path ?: continue
                    if (!path.toString().endsWith(".txt")) continue

                    when (val kind = event.kind()) {
                        StandardWatchEventKinds.ENTRY_CREATE,
                        StandardWatchEventKinds.ENTRY_MODIFY -> {
                            val file = folder.resolve(path)
                            if (!file.exists()) {
                                plugin.logger.info("移除审核库 $path , ${kind.name()}")
                                dict.remove(file.name)
                                continue
                            }
                            plugin.logger.info("更新审核库 $path , ${kind.name()}")
                            try {
                                dict[file.name] = file.readLines()
                            } catch (cause: IOException) {
                                plugin.logger.warning("更新审核库 ${file.toUri()} 失败, ${kind.name()}", cause)
                            }
                        }
                        StandardWatchEventKinds.ENTRY_DELETE -> {
                            plugin.logger.info("移除审核库 $path , ${kind.name()}")
                            dict.remove(path.name)
                        }
                        else -> Unit
                    }
                }
                key.reset()
            }
        }
    }

    @ValueName("owner")
    @ValueDescription("机器人所有者")
    val owner: Long by value(OWNER_DEFAULT)

    @ValueName("censor_regex")
    @ValueDescription("配置项废除, 改为加载 censor 文件夹中的 txt 文件")
    @Suppress("unused")
    private val censorRegexOld: String by value("")

    @ValueName("censor_types")
    @ValueDescription("消息审查,类型, IMAGE, FLASH, SERVICE, APP, AUDIO, FORWARD, VIP, MARKET, MUSIC, POKE")
    override val censorTypes: Set by value()

    @ValueName("censor_mute")
    @ValueDescription("消息审查,禁言时间 单位秒")
    override val censorMute: Int by value(0)

    @ValueName("record_limit")
    @ValueDescription("联系人(群/好友/...)聊天记录上限,(用于消息撤销等操作)")
    val recordLimit: Int by value(100)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy