mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-23 22:30:47 +08:00
Http api fix conflict
This commit is contained in:
commit
1660e5b938
@ -103,6 +103,7 @@ suspend fun MessagePacket<*, *>.toDTO() = when (this) {
|
|||||||
suspend fun MessageChainDTO.toMessageChain(contact: Contact) =
|
suspend fun MessageChainDTO.toMessageChain(contact: Contact) =
|
||||||
buildMessageChain { this@toMessageChain.forEach { it.toMessage(contact)?.let(::add) } }
|
buildMessageChain { this@toMessageChain.forEach { it.toMessage(contact)?.let(::add) } }
|
||||||
|
|
||||||
|
|
||||||
@UseExperimental(ExperimentalUnsignedTypes::class)
|
@UseExperimental(ExperimentalUnsignedTypes::class)
|
||||||
suspend fun MessagePacket<*, *>.messageDTO(message: Message) = when (message) {
|
suspend fun MessagePacket<*, *>.messageDTO(message: Message) = when (message) {
|
||||||
is MessageSource -> MessageSourceDTO(message.id)
|
is MessageSource -> MessageSourceDTO(message.id)
|
||||||
|
@ -17,8 +17,11 @@ import com.moandjiezana.toml.Toml
|
|||||||
import com.moandjiezana.toml.TomlWriter
|
import com.moandjiezana.toml.TomlWriter
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UnstableDefault
|
import kotlinx.serialization.UnstableDefault
|
||||||
|
import net.mamoe.mirai.utils.io.encodeToString
|
||||||
import org.yaml.snakeyaml.Yaml
|
import org.yaml.snakeyaml.Yaml
|
||||||
|
import tornadofx.c
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.InputStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import kotlin.collections.LinkedHashMap
|
import kotlin.collections.LinkedHashMap
|
||||||
@ -69,6 +72,9 @@ interface Config {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a read-write config
|
||||||
|
* */
|
||||||
fun load(file: File): Config {
|
fun load(file: File): Config {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
file.createNewFile()
|
file.createNewFile()
|
||||||
@ -86,6 +92,32 @@ interface Config {
|
|||||||
else -> error("Unsupported file config type ${file.extension.toLowerCase()}")
|
else -> error("Unsupported file config type ${file.extension.toLowerCase()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a read-only config
|
||||||
|
*/
|
||||||
|
fun load(content: String, type: String): Config {
|
||||||
|
return when (type.toLowerCase()) {
|
||||||
|
"json" -> JsonConfig(content)
|
||||||
|
"yml" -> YamlConfig(content)
|
||||||
|
"yaml" -> YamlConfig(content)
|
||||||
|
"mirai" -> YamlConfig(content)
|
||||||
|
"ini" -> TomlConfig(content)
|
||||||
|
"toml" -> TomlConfig(content)
|
||||||
|
"properties" -> TomlConfig(content)
|
||||||
|
"property" -> TomlConfig(content)
|
||||||
|
"data" -> TomlConfig(content)
|
||||||
|
else -> error("Unsupported file config type $content")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a read-only config
|
||||||
|
*/
|
||||||
|
fun load(inputStream: InputStream, type: String): Config {
|
||||||
|
return load(inputStream.readBytes().encodeToString(), type)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,14 +395,23 @@ interface FileConfig : Config {
|
|||||||
|
|
||||||
|
|
||||||
abstract class FileConfigImpl internal constructor(
|
abstract class FileConfigImpl internal constructor(
|
||||||
private val file: File
|
private val rawContent: String
|
||||||
) : FileConfig,
|
) : FileConfig,
|
||||||
ConfigSection {
|
ConfigSection {
|
||||||
|
|
||||||
private val content by lazy {
|
internal var file: File? = null
|
||||||
deserialize(file.readText())
|
|
||||||
|
|
||||||
|
constructor(file: File) : this(file.readText()) {
|
||||||
|
this.file = file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val content by lazy {
|
||||||
|
deserialize(rawContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override val size: Int get() = content.size
|
override val size: Int get() = content.size
|
||||||
override val entries: MutableSet<MutableMap.MutableEntry<String, Any>> get() = content.entries
|
override val entries: MutableSet<MutableMap.MutableEntry<String, Any>> get() = content.entries
|
||||||
override val keys: MutableSet<String> get() = content.keys
|
override val keys: MutableSet<String> get() = content.keys
|
||||||
@ -384,12 +425,17 @@ abstract class FileConfigImpl internal constructor(
|
|||||||
override fun remove(key: String): Any? = content.remove(key)
|
override fun remove(key: String): Any? = content.remove(key)
|
||||||
|
|
||||||
override fun save() {
|
override fun save() {
|
||||||
if (!file.exists()) {
|
if (isReadOnly()) {
|
||||||
file.createNewFile()
|
error("Config is readonly")
|
||||||
}
|
}
|
||||||
file.writeText(serialize(content))
|
if (!((file?.exists())!!)) {
|
||||||
|
file?.createNewFile()
|
||||||
|
}
|
||||||
|
file?.writeText(serialize(content))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isReadOnly() = file == null
|
||||||
|
|
||||||
override fun contains(key: String): Boolean {
|
override fun contains(key: String): Boolean {
|
||||||
return content.contains(key)
|
return content.contains(key)
|
||||||
}
|
}
|
||||||
@ -409,8 +455,12 @@ abstract class FileConfigImpl internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JsonConfig internal constructor(
|
class JsonConfig internal constructor(
|
||||||
file: File
|
content: String
|
||||||
) : FileConfigImpl(file) {
|
) : FileConfigImpl(content) {
|
||||||
|
constructor(file: File) : this(file.readText()) {
|
||||||
|
this.file = file
|
||||||
|
}
|
||||||
|
|
||||||
@UnstableDefault
|
@UnstableDefault
|
||||||
override fun deserialize(content: String): ConfigSection {
|
override fun deserialize(content: String): ConfigSection {
|
||||||
if (content.isEmpty() || content.isBlank() || content == "{}") {
|
if (content.isEmpty() || content.isBlank() || content == "{}") {
|
||||||
@ -429,7 +479,11 @@ class JsonConfig internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class YamlConfig internal constructor(file: File) : FileConfigImpl(file) {
|
class YamlConfig internal constructor(content: String) : FileConfigImpl(content) {
|
||||||
|
constructor(file: File) : this(file.readText()) {
|
||||||
|
this.file = file
|
||||||
|
}
|
||||||
|
|
||||||
override fun deserialize(content: String): ConfigSection {
|
override fun deserialize(content: String): ConfigSection {
|
||||||
if (content.isEmpty() || content.isBlank()) {
|
if (content.isEmpty() || content.isBlank()) {
|
||||||
return ConfigSectionImpl()
|
return ConfigSectionImpl()
|
||||||
@ -447,7 +501,11 @@ class YamlConfig internal constructor(file: File) : FileConfigImpl(file) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TomlConfig internal constructor(file: File) : FileConfigImpl(file) {
|
class TomlConfig internal constructor(content: String) : FileConfigImpl(content) {
|
||||||
|
constructor(file: File) : this(file.readText()) {
|
||||||
|
this.file = file
|
||||||
|
}
|
||||||
|
|
||||||
override fun deserialize(content: String): ConfigSection {
|
override fun deserialize(content: String): ConfigSection {
|
||||||
if (content.isEmpty() || content.isBlank()) {
|
if (content.isEmpty() || content.isBlank()) {
|
||||||
return ConfigSectionImpl()
|
return ConfigSectionImpl()
|
||||||
|
@ -17,6 +17,7 @@ import net.mamoe.mirai.utils.MiraiLogger
|
|||||||
import net.mamoe.mirai.utils.SimpleLogger
|
import net.mamoe.mirai.utils.SimpleLogger
|
||||||
import net.mamoe.mirai.utils.io.encodeToString
|
import net.mamoe.mirai.utils.io.encodeToString
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.InputStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
@ -91,6 +92,13 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope {
|
|||||||
val logger: MiraiLogger by lazy {
|
val logger: MiraiLogger by lazy {
|
||||||
DefaultLogger(pluginDescription.name)
|
DefaultLogger(pluginDescription.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getResources(fileName: String): InputStream? {
|
||||||
|
return PluginManager.getFileInJarByName(
|
||||||
|
this.pluginDescription.name,
|
||||||
|
fileName
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PluginDescription(
|
class PluginDescription(
|
||||||
@ -325,6 +333,47 @@ object PluginManager {
|
|||||||
it.disable(throwable)
|
it.disable(throwable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据插件名字找Jar的文件
|
||||||
|
* null => 没找到
|
||||||
|
*/
|
||||||
|
fun getJarPath(pluginName: String): File? {
|
||||||
|
File(pluginsPath).listFiles()?.forEach { file ->
|
||||||
|
if (file != null && file.extension == "jar") {
|
||||||
|
val jar = JarFile(file)
|
||||||
|
val pluginYml =
|
||||||
|
jar.entries().asSequence().filter { it.name.toLowerCase().contains("plugin.yml") }.firstOrNull()
|
||||||
|
if (pluginYml != null) {
|
||||||
|
val description =
|
||||||
|
PluginDescription.readFromContent(
|
||||||
|
URL("jar:file:" + file.absoluteFile + "!/" + pluginYml.name).openConnection().inputStream.use {
|
||||||
|
it.readBytes().encodeToString()
|
||||||
|
})
|
||||||
|
if (description.name.toLowerCase() == pluginName.toLowerCase()) {
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据插件名字找Jar resources中的文件
|
||||||
|
* null => 没找到
|
||||||
|
*/
|
||||||
|
fun getFileInJarByName(pluginName: String, toFind: String): InputStream? {
|
||||||
|
val jarFile = getJarPath(pluginName)
|
||||||
|
if (jarFile == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val jar = JarFile(jarFile)
|
||||||
|
val toFindFile =
|
||||||
|
jar.entries().asSequence().filter { it.name == toFind }.firstOrNull() ?: return null
|
||||||
|
return URL("jar:file:" + jarFile.absoluteFile + "!/" + toFindFile.name).openConnection().inputStream
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ internal class NotOnlineImageFromServer(
|
|||||||
internal fun MsgComm.Msg.toMessageChain(): MessageChain {
|
internal fun MsgComm.Msg.toMessageChain(): MessageChain {
|
||||||
val elements = this.msgBody.richText.elems
|
val elements = this.msgBody.richText.elems
|
||||||
|
|
||||||
val message = ArrayList<Message>(elements.size + 1)
|
val message = MessageChainBuilder(elements.size + 1)
|
||||||
message.add(MessageSourceFromMsg(delegate = this))
|
message.add(MessageSourceFromMsg(delegate = this))
|
||||||
elements.joinToMessageChain(message)
|
elements.joinToMessageChain(message)
|
||||||
return message.asMessageChain()
|
return message.asMessageChain()
|
||||||
@ -338,7 +338,7 @@ internal fun MsgComm.Msg.toMessageChain(): MessageChain {
|
|||||||
internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
|
internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
|
||||||
val elements = this.elems!!
|
val elements = this.elems!!
|
||||||
|
|
||||||
val message = ArrayList<Message>(elements.size + 1)
|
val message = MessageChainBuilder(elements.size + 1)
|
||||||
message.add(MessageSourceFromServer(delegate = this))
|
message.add(MessageSourceFromServer(delegate = this))
|
||||||
elements.joinToMessageChain(message)
|
elements.joinToMessageChain(message)
|
||||||
return message.asMessageChain()
|
return message.asMessageChain()
|
||||||
@ -346,7 +346,7 @@ internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
|
|||||||
|
|
||||||
|
|
||||||
@UseExperimental(MiraiInternalAPI::class, ExperimentalUnsignedTypes::class, MiraiDebugAPI::class)
|
@UseExperimental(MiraiInternalAPI::class, ExperimentalUnsignedTypes::class, MiraiDebugAPI::class)
|
||||||
internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MutableList<Message>) {
|
internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChainBuilder) {
|
||||||
this.forEach {
|
this.forEach {
|
||||||
when {
|
when {
|
||||||
it.srcMsg != null -> message.add(QuoteReply(MessageSourceFromServer(it.srcMsg)))
|
it.srcMsg != null -> message.add(QuoteReply(MessageSourceFromServer(it.srcMsg)))
|
||||||
|
@ -285,7 +285,7 @@ internal class MessageSvc {
|
|||||||
|
|
||||||
@UseExperimental(MiraiExperimentalAPI::class)
|
@UseExperimental(MiraiExperimentalAPI::class)
|
||||||
fun startWaitingSequenceId(contact: Contact) {
|
fun startWaitingSequenceId(contact: Contact) {
|
||||||
sequenceIdDeferred = contact.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int> {
|
sequenceIdDeferred = contact.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int>(timeoutMillis = 3000) {
|
||||||
if (it.messageRandom == this@MessageSourceFromSend.messageRandom) {
|
if (it.messageRandom == this@MessageSourceFromSend.messageRandom) {
|
||||||
it.sequenceId
|
it.sequenceId
|
||||||
} else null
|
} else null
|
||||||
|
@ -138,9 +138,5 @@ suspend inline fun <C : Contact> C.sendMessage(message: Message): MessageReceipt
|
|||||||
/**
|
/**
|
||||||
* @see Contact.sendMessage
|
* @see Contact.sendMessage
|
||||||
*/
|
*/
|
||||||
suspend inline fun <C : Contact> C.sendMessage(plain: String): MessageReceipt<C> = sendMessage(plain.toMessage())
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
suspend inline fun <C : Contact> C.sendMessage(plain: String): MessageReceipt<C> = sendMessage(plain.toMessage())
|
||||||
/**
|
|
||||||
* @see Contact.sendMessage
|
|
||||||
*/
|
|
||||||
suspend inline fun <C : Contact> C.sendMessage(plain: CombinedMessage): MessageReceipt<C> = sendMessage(MessageChain(plain as Message)) as MessageReceipt<C>
|
|
@ -26,7 +26,8 @@ import kotlin.jvm.JvmName
|
|||||||
*
|
*
|
||||||
* @see AtAll 全体成员
|
* @see AtAll 全体成员
|
||||||
*/
|
*/
|
||||||
class At @MiraiInternalAPI constructor(val target: Long, val display: String) : Message {
|
class At
|
||||||
|
@MiraiInternalAPI constructor(val target: Long, val display: String) : Message, MessageContent {
|
||||||
@UseExperimental(MiraiInternalAPI::class)
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
constructor(member: Member) : this(member.id, "@${member.nameCardOrNick}")
|
constructor(member: Member) : this(member.id, "@${member.nameCardOrNick}")
|
||||||
|
|
||||||
@ -38,9 +39,9 @@ class At @MiraiInternalAPI constructor(val target: Long, val display: String) :
|
|||||||
|
|
||||||
override fun followedBy(tail: Message): CombinedMessage {
|
override fun followedBy(tail: Message): CombinedMessage {
|
||||||
if (tail is PlainText && tail.stringValue.startsWith(' ')) {
|
if (tail is PlainText && tail.stringValue.startsWith(' ')) {
|
||||||
return super.followedBy(tail)
|
return super<MessageContent>.followedBy(tail)
|
||||||
}
|
}
|
||||||
return super.followedBy(PlainText(" ")) + tail
|
return super<MessageContent>.followedBy(PlainText(" ")) + tail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,15 +22,15 @@ import kotlin.jvm.JvmName
|
|||||||
*
|
*
|
||||||
* @see At at 单个群成员
|
* @see At at 单个群成员
|
||||||
*/
|
*/
|
||||||
object AtAll : Message, Message.Key<AtAll> {
|
object AtAll : Message, Message.Key<AtAll>, MessageContent {
|
||||||
override fun toString(): String = "@全体成员"
|
override fun toString(): String = "@全体成员"
|
||||||
|
|
||||||
// 自动为消息补充 " "
|
// 自动为消息补充 " "
|
||||||
|
|
||||||
override fun followedBy(tail: Message): CombinedMessage {
|
override fun followedBy(tail: Message): CombinedMessage {
|
||||||
if (tail is PlainText && tail.stringValue.startsWith(' ')) {
|
if (tail is PlainText && tail.stringValue.startsWith(' ')) {
|
||||||
return super.followedBy(tail)
|
return super<MessageContent>.followedBy(tail)
|
||||||
}
|
}
|
||||||
return super.followedBy(PlainText(" ")) + tail
|
return super<MessageContent>.followedBy(PlainText(" ")) + tail
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,8 +7,14 @@
|
|||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:JvmMultifileClass
|
||||||
|
@file:JvmName("MessageUtils")
|
||||||
|
|
||||||
package net.mamoe.mirai.message.data
|
package net.mamoe.mirai.message.data
|
||||||
|
|
||||||
|
import kotlin.jvm.JvmMultifileClass
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Left-biased list
|
* Left-biased list
|
||||||
*/
|
*/
|
||||||
@ -16,6 +22,8 @@ class CombinedMessage(
|
|||||||
val left: Message,
|
val left: Message,
|
||||||
val element: Message
|
val element: Message
|
||||||
) : Iterable<Message>, Message {
|
) : Iterable<Message>, Message {
|
||||||
|
|
||||||
|
// 不要把它用作 local function, 会编译错误
|
||||||
private suspend fun SequenceScope<Message>.yieldCombinedOrElements(message: Message) {
|
private suspend fun SequenceScope<Message>.yieldCombinedOrElements(message: Message) {
|
||||||
when (message) {
|
when (message) {
|
||||||
is CombinedMessage -> {
|
is CombinedMessage -> {
|
||||||
@ -36,6 +44,6 @@ class CombinedMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return left.toString() + element.toString()
|
return element.toString() + left.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ import kotlin.jvm.JvmName
|
|||||||
/**
|
/**
|
||||||
* QQ 自带表情
|
* QQ 自带表情
|
||||||
*/
|
*/
|
||||||
class Face(val id: Int) : Message {
|
class Face(val id: Int) : Message, MessageContent {
|
||||||
override fun toString(): String = "[mirai:face$id]"
|
override fun toString(): String = "[mirai:face$id]"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,7 @@ import kotlin.jvm.JvmStatic
|
|||||||
/**
|
/**
|
||||||
* 自定义表情 (收藏的表情), 图片
|
* 自定义表情 (收藏的表情), 图片
|
||||||
*/
|
*/
|
||||||
sealed class Image : Message {
|
sealed class Image : Message, MessageContent {
|
||||||
companion object Key : Message.Key<Image> {
|
companion object Key : Message.Key<Image> {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JsName("fromId")
|
@JsName("fromId")
|
||||||
|
@ -20,6 +20,12 @@ import kotlin.jvm.JvmSynthetic
|
|||||||
* 可发送的或从服务器接收的消息.
|
* 可发送的或从服务器接收的消息.
|
||||||
* 采用这样的消息模式是因为 QQ 的消息多元化, 一条消息中可包含 [纯文本][PlainText], [图片][Image] 等.
|
* 采用这样的消息模式是因为 QQ 的消息多元化, 一条消息中可包含 [纯文本][PlainText], [图片][Image] 等.
|
||||||
*
|
*
|
||||||
|
* [消息][Message] 分为
|
||||||
|
* - [MessageMetadata] 消息元数据, 包括: [消息来源][MessageSource]
|
||||||
|
* - [MessageContent] 单个消息, 包括: [纯文本][PlainText], [@群员][At], [@全体成员][AtAll] 等.
|
||||||
|
* - [CombinedMessage] 通过 [plus] 连接的两个消息. 可通过 [asMessageChain] 转换为 [MessageChain]
|
||||||
|
* - [MessageChain] 不可变消息链, 即 [List] 形式链接的多个 [Message] 实例.
|
||||||
|
*
|
||||||
* **在 Kotlin 使用 [Message]**
|
* **在 Kotlin 使用 [Message]**
|
||||||
* 这与使用 [String] 的使用非常类似.
|
* 这与使用 [String] 的使用非常类似.
|
||||||
*
|
*
|
||||||
@ -44,7 +50,12 @@ import kotlin.jvm.JvmSynthetic
|
|||||||
* @see PlainText 纯文本
|
* @see PlainText 纯文本
|
||||||
* @see Image 图片
|
* @see Image 图片
|
||||||
* @see Face 表情
|
* @see Face 表情
|
||||||
|
* @see At 引用一个群成员
|
||||||
|
* @see AtAll 引用全体成员
|
||||||
|
* @see QuoteReply 引用一条消息
|
||||||
|
*
|
||||||
* @see MessageChain 消息链(即 `List<Message>`)
|
* @see MessageChain 消息链(即 `List<Message>`)
|
||||||
|
* @see buildMessageChain 构造一个 [MessageChain]
|
||||||
*
|
*
|
||||||
* @see Contact.sendMessage 发送消息
|
* @see Contact.sendMessage 发送消息
|
||||||
*/
|
*/
|
||||||
@ -86,8 +97,6 @@ interface Message {
|
|||||||
*/
|
*/
|
||||||
@JvmSynthetic // in java they should use `plus` instead
|
@JvmSynthetic // in java they should use `plus` instead
|
||||||
fun followedBy(tail: Message): CombinedMessage {
|
fun followedBy(tail: Message): CombinedMessage {
|
||||||
require(tail !is SingleOnly) { "SingleOnly Message cannot follow another message" }
|
|
||||||
require(this !is SingleOnly) { "SingleOnly Message cannot be followed" }
|
|
||||||
return CombinedMessage(tail, this)
|
return CombinedMessage(tail, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,12 +109,37 @@ interface Message {
|
|||||||
operator fun plus(another: CharSequence): CombinedMessage = this.followedBy(another.toString().toMessage())
|
operator fun plus(another: CharSequence): CombinedMessage = this.followedBy(another.toString().toMessage())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun <C : Contact> Message.sendTo(contact: C): MessageReceipt<C> {
|
||||||
|
return contact.sendMessage(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SingleMessage : Message
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表示这个 [Message] 仅能单个存在, 无法被连接.
|
* 消息元数据, 即不含内容的元素.
|
||||||
|
* 包括: [MessageSource]
|
||||||
*/
|
*/
|
||||||
interface SingleOnly : Message
|
interface MessageMetadata : SingleMessage {
|
||||||
|
/*
|
||||||
|
fun iterator(): Iterator<Message> {
|
||||||
|
return object : Iterator<Message> {
|
||||||
|
var visited: Boolean = false
|
||||||
|
override fun hasNext(): Boolean = !visited
|
||||||
|
override fun next(): Message {
|
||||||
|
if (visited) throw NoSuchElementException()
|
||||||
|
return this@MessageMetadata.also { visited = true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息内容
|
||||||
|
*/
|
||||||
|
interface MessageContent : SingleMessage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 [this] 发送给指定联系人
|
* 将 [this] 发送给指定联系人
|
||||||
*/
|
*/
|
||||||
suspend inline fun <C : Contact> Message.sendTo(contact: C): MessageReceipt<C> = contact.sendMessage(this)
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
suspend inline fun <C : Contact> MessageChain.sendTo(contact: C): MessageReceipt<C> = contact.sendMessage(this) as MessageReceipt<C>
|
@ -16,27 +16,19 @@ import net.mamoe.mirai.message.data.NullMessageChain.toString
|
|||||||
import kotlin.js.JsName
|
import kotlin.js.JsName
|
||||||
import kotlin.jvm.JvmMultifileClass
|
import kotlin.jvm.JvmMultifileClass
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
|
import kotlin.jvm.JvmSynthetic
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息链. 即 MutableList<Message>.
|
* 消息链.
|
||||||
* 它的一般实现为 [MessageChainImpl], `null` 实现为 [NullMessageChain]
|
* 它的一般实现为 [MessageChainImpl], `null` 实现为 [NullMessageChain]
|
||||||
*
|
*
|
||||||
* 有关 [MessageChain] 的创建和连接:
|
|
||||||
* - 当任意两个不是 [MessageChain] 的 [Message] 相连接后, 将会产生一个 [MessageChain].
|
|
||||||
* - 若两个 [MessageChain] 连接, 后一个将会被合并到第一个内.
|
|
||||||
* - 若一个 [MessageChain] 与一个其他 [Message] 连接, [Message] 将会被添加入 [MessageChain].
|
|
||||||
* - 若一个 [Message] 与一个 [MessageChain] 连接, [Message] 将会被添加入 [MessageChain].
|
|
||||||
*
|
|
||||||
* 要获取更多信息, 请查看 [Message]
|
* 要获取更多信息, 请查看 [Message]
|
||||||
*
|
*
|
||||||
* @see buildMessageChain
|
* @see buildMessageChain 构造一个 [MessageChain]
|
||||||
*/
|
*/
|
||||||
interface MessageChain : Message, List<Message> {
|
interface MessageChain : Message, Iterable<SingleMessage> {
|
||||||
// region Message override
|
|
||||||
override operator fun contains(sub: String): Boolean
|
override operator fun contains(sub: String): Boolean
|
||||||
// endregion
|
|
||||||
|
|
||||||
override fun toString(): String
|
override fun toString(): String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,29 +43,16 @@ interface MessageChain : Message, List<Message> {
|
|||||||
* 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]
|
* 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]
|
||||||
*/
|
*/
|
||||||
inline fun MessageChain.foreachContent(block: (Message) -> Unit) {
|
inline fun MessageChain.foreachContent(block: (Message) -> Unit) {
|
||||||
this.forEachIndexed { index: Int, message: Message ->
|
var last: Message? = null
|
||||||
|
this.forEach { message: Message ->
|
||||||
if (message is At) {
|
if (message is At) {
|
||||||
if (index == 0 || this[index - 1] !is QuoteReply) {
|
if (last != null || last !is QuoteReply) {
|
||||||
block(message)
|
block(message)
|
||||||
}
|
}
|
||||||
} else if (message.hasContent()) {
|
} else if (message is MessageContent) {
|
||||||
block(message)
|
block(message)
|
||||||
}
|
}
|
||||||
}
|
last = message
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断这个 [Message] 是否含有内容, 即是否为 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]
|
|
||||||
*/
|
|
||||||
fun Message.hasContent(): Boolean {
|
|
||||||
return when (this) {
|
|
||||||
is At,
|
|
||||||
is AtAll,
|
|
||||||
is PlainText,
|
|
||||||
is Image,
|
|
||||||
is Face,
|
|
||||||
is XMLMessage -> true
|
|
||||||
else -> false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +78,7 @@ fun MessageChain(): MessageChain = EmptyMessageChain
|
|||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
fun MessageChain(vararg messages: Message): MessageChain =
|
fun MessageChain(vararg messages: Message): MessageChain =
|
||||||
if (messages.isEmpty()) EmptyMessageChain
|
if (messages.isEmpty()) EmptyMessageChain
|
||||||
else MessageChainImpl(messages.toMutableList())
|
else MessageChainImpl(messages.asSequence().flatten())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造 [MessageChain] 的快速途径 (无 [Array] 创建)
|
* 构造 [MessageChain] 的快速途径 (无 [Array] 创建)
|
||||||
@ -109,7 +88,10 @@ fun MessageChain(vararg messages: Message): MessageChain =
|
|||||||
@JsName("newChain")
|
@JsName("newChain")
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
fun MessageChain(message: Message): MessageChain =
|
fun MessageChain(message: Message): MessageChain =
|
||||||
MessageChainImpl(listOf(message))
|
when (message) {
|
||||||
|
is SingleMessage -> SingleMessageChainImpl(message)
|
||||||
|
else -> MessageChainImpl(message.flatten().asIterable())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造 [MessageChain]
|
* 构造 [MessageChain]
|
||||||
@ -118,7 +100,7 @@ fun MessageChain(message: Message): MessageChain =
|
|||||||
@JsName("newChain")
|
@JsName("newChain")
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
fun MessageChain(messages: Iterable<Message>): MessageChain =
|
fun MessageChain(messages: Iterable<Message>): MessageChain =
|
||||||
MessageChainImpl(messages.toList())
|
MessageChainImpl(messages.flatten().asIterable())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造 [MessageChain]
|
* 构造 [MessageChain]
|
||||||
@ -127,7 +109,7 @@ fun MessageChain(messages: Iterable<Message>): MessageChain =
|
|||||||
@JsName("newChain")
|
@JsName("newChain")
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
fun MessageChain(messages: List<Message>): MessageChain =
|
fun MessageChain(messages: List<Message>): MessageChain =
|
||||||
MessageChainImpl(messages)
|
MessageChainImpl(messages.flatten().asIterable())
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,14 +117,34 @@ fun MessageChain(messages: List<Message>): MessageChain =
|
|||||||
* 若 [this] 为 [MessageChain] 将直接返回 this
|
* 若 [this] 为 [MessageChain] 将直接返回 this
|
||||||
* 否则将调用 [MessageChain] 构造一个 [MessageChainImpl]
|
* 否则将调用 [MessageChain] 构造一个 [MessageChainImpl]
|
||||||
*/
|
*/
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE", "UNCHECKED_CAST")
|
||||||
inline fun Message.toChain(): MessageChain = if (this is MessageChain) this else MessageChain(this)
|
@JvmSynthetic
|
||||||
|
fun Message.toChain(): MessageChain = when (this) {
|
||||||
|
is MessageChain -> this
|
||||||
|
is CombinedMessage -> MessageChainImpl((this as Iterable<Message>).flatten().asIterable())
|
||||||
|
else -> SingleMessageChainImpl(this as SingleMessage)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
@JvmName("asMessageChain1")
|
||||||
* 构造 [MessageChain]
|
@JvmSynthetic
|
||||||
*/
|
|
||||||
@Suppress("unused", "NOTHING_TO_INLINE")
|
@Suppress("unused", "NOTHING_TO_INLINE")
|
||||||
inline fun List<Message>.asMessageChain(): MessageChain = MessageChain(this)
|
fun Iterable<SingleMessage>.asMessageChain(): MessageChain = MessageChainImpl(this)
|
||||||
|
|
||||||
|
@JvmSynthetic
|
||||||
|
@Suppress("unused", "NOTHING_TO_INLINE")
|
||||||
|
fun Iterable<Message>.asMessageChain(): MessageChain = MessageChainImpl(this.flatten())
|
||||||
|
|
||||||
|
fun Iterable<Message>.flatten(): Sequence<SingleMessage> = asSequence().flatten()
|
||||||
|
|
||||||
|
fun Sequence<Message>.flatten(): Sequence<SingleMessage> = flatMap { it.flatten() }
|
||||||
|
|
||||||
|
fun Message.flatten(): Sequence<SingleMessage> {
|
||||||
|
return when (this) {
|
||||||
|
is MessageChain -> this.asSequence()
|
||||||
|
is CombinedMessage -> this.asSequence().flatten()
|
||||||
|
else -> sequenceOf(this as SingleMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取第一个 [M] 类型的 [Message] 实例
|
* 获取第一个 [M] 类型的 [Message] 实例
|
||||||
@ -189,9 +191,7 @@ fun <M : Message> MessageChain.first(key: Message.Key<M>): M = firstOrNull(key)
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <M : Message> MessageChain.any(key: Message.Key<M>): Boolean = firstOrNull(key) != null
|
fun <M : Message> MessageChain.any(key: Message.Key<M>): Boolean = firstOrNull(key) != null
|
||||||
|
|
||||||
object EmptyMessageChain : MessageChain by {
|
object EmptyMessageChain : MessageChain by MessageChainImpl(emptyList())
|
||||||
MessageChainImpl(emptyList())
|
|
||||||
}()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Null 的 [MessageChain].
|
* Null 的 [MessageChain].
|
||||||
@ -200,45 +200,27 @@ object EmptyMessageChain : MessageChain by {
|
|||||||
* 除 [toString] 外, 其他方法均 [error]
|
* 除 [toString] 外, 其他方法均 [error]
|
||||||
*/
|
*/
|
||||||
object NullMessageChain : MessageChain {
|
object NullMessageChain : MessageChain {
|
||||||
override fun subList(fromIndex: Int, toIndex: Int): MutableList<Message> = error("accessing NullMessageChain")
|
|
||||||
|
|
||||||
override fun toString(): String = "null"
|
override fun toString(): String = "null"
|
||||||
|
|
||||||
override fun contains(sub: String): Boolean = error("accessing NullMessageChain")
|
override fun contains(sub: String): Boolean = error("accessing NullMessageChain")
|
||||||
override fun contains(element: Message): Boolean = error("accessing NullMessageChain")
|
|
||||||
override fun followedBy(tail: Message): CombinedMessage = CombinedMessage(left = EmptyMessageChain, element = tail)
|
override fun followedBy(tail: Message): CombinedMessage = CombinedMessage(left = EmptyMessageChain, element = tail)
|
||||||
|
override fun iterator(): MutableIterator<SingleMessage> = error("accessing NullMessageChain")
|
||||||
override val size: Int get() = error("accessing NullMessageChain")
|
|
||||||
override fun containsAll(elements: Collection<Message>): Boolean = error("accessing NullMessageChain")
|
|
||||||
override fun get(index: Int): Message = error("accessing NullMessageChain")
|
|
||||||
override fun indexOf(element: Message): Int = error("accessing NullMessageChain")
|
|
||||||
override fun isEmpty(): Boolean = error("accessing NullMessageChain")
|
|
||||||
override fun iterator(): MutableIterator<Message> = error("accessing NullMessageChain")
|
|
||||||
|
|
||||||
override fun lastIndexOf(element: Message): Int = error("accessing NullMessageChain")
|
|
||||||
override fun listIterator(): MutableListIterator<Message> = error("accessing NullMessageChain")
|
|
||||||
|
|
||||||
override fun listIterator(index: Int): MutableListIterator<Message> = error("accessing NullMessageChain")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@PublishedApi
|
||||||
* [MessageChain] 实现
|
|
||||||
* 它是一个特殊的 [Message], 实现 [MutableList] 接口, 但将所有的接口调用都转到内部维护的另一个 [MutableList].
|
|
||||||
*/
|
|
||||||
internal class MessageChainImpl constructor(
|
internal class MessageChainImpl constructor(
|
||||||
/**
|
private val delegate: Iterable<SingleMessage>
|
||||||
* Elements will not be instances of [MessageChain]
|
) : Message, Iterable<SingleMessage> by delegate, MessageChain {
|
||||||
*/
|
constructor(delegate: Sequence<SingleMessage>) : this(delegate.asIterable())
|
||||||
private val delegate: List<Message>
|
|
||||||
) : Message, List<Message> by delegate, MessageChain {
|
|
||||||
override fun toString(): String = this.delegate.joinToString("") { it.toString() }
|
|
||||||
|
|
||||||
|
override fun toString(): String = this.delegate.joinToString("") { it.toString() }
|
||||||
override operator fun contains(sub: String): Boolean = delegate.any { it.contains(sub) }
|
override operator fun contains(sub: String): Boolean = delegate.any { it.contains(sub) }
|
||||||
override fun followedBy(tail: Message): CombinedMessage {
|
|
||||||
require(tail !is SingleOnly) { "SingleOnly Message cannot follow another message" }
|
|
||||||
// if (tail is MessageChain) tail.forEach { child -> this.followedBy(child) }
|
|
||||||
// else this.delegate.add(tail)
|
|
||||||
return CombinedMessage(tail, this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PublishedApi
|
||||||
|
internal class SingleMessageChainImpl constructor(
|
||||||
|
private val delegate: SingleMessage
|
||||||
|
) : Message, Iterable<SingleMessage> by listOf(delegate), MessageChain {
|
||||||
|
override fun toString(): String = this.delegate.toString()
|
||||||
|
|
||||||
|
override operator fun contains(sub: String): Boolean = sub in delegate
|
||||||
|
}
|
@ -23,7 +23,7 @@ import kotlin.jvm.JvmName
|
|||||||
*
|
*
|
||||||
* @see MessageSource.quote 引用这条消息, 创建 [MessageChain]
|
* @see MessageSource.quote 引用这条消息, 创建 [MessageChain]
|
||||||
*/
|
*/
|
||||||
interface MessageSource : Message {
|
interface MessageSource : Message, MessageMetadata {
|
||||||
companion object Key : Message.Key<MessageSource>
|
companion object Key : Message.Key<MessageSource>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,7 +21,7 @@ import kotlin.jvm.JvmStatic
|
|||||||
*
|
*
|
||||||
* 一般不需要主动构造 [PlainText], [Message] 可直接与 [String] 相加. Java 用户请使用 [MessageChain.plus]
|
* 一般不需要主动构造 [PlainText], [Message] 可直接与 [String] 相加. Java 用户请使用 [MessageChain.plus]
|
||||||
*/
|
*/
|
||||||
inline class PlainText(val stringValue: String) : Message {
|
inline class PlainText(val stringValue: String) : Message, MessageContent {
|
||||||
constructor(charSequence: CharSequence) : this(charSequence.toString())
|
constructor(charSequence: CharSequence) : this(charSequence.toString())
|
||||||
|
|
||||||
override operator fun contains(sub: String): Boolean = sub in stringValue
|
override operator fun contains(sub: String): Boolean = sub in stringValue
|
||||||
|
@ -21,25 +21,27 @@ import kotlin.jvm.JvmName
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 群内的或好友的引用回复.
|
* 从服务器接收的或客户端构造用来发送的群内的或好友的引用回复.
|
||||||
*
|
*
|
||||||
* 可以引用一条群消息并发送给一个好友, 或是引用好友消息发送给群.
|
* 可以引用一条群消息并发送给一个好友, 或是引用好友消息发送给群.
|
||||||
* 可以引用自己发出的消息. 详见 [MessageReceipt.quote]
|
* 可以引用自己发出的消息. 详见 [MessageReceipt.quote]
|
||||||
*
|
*
|
||||||
* 总是使用 [quote] 来构造这个实例.
|
* 总是使用 [quote] 来构造这个实例.
|
||||||
*/
|
*/
|
||||||
open class QuoteReply @MiraiInternalAPI constructor(val source: MessageSource) : Message {
|
open class QuoteReply
|
||||||
|
@MiraiInternalAPI constructor(val source: MessageSource) : Message, MessageContent {
|
||||||
companion object Key : Message.Key<QuoteReply>
|
companion object Key : Message.Key<QuoteReply>
|
||||||
|
|
||||||
override fun toString(): String = ""
|
override fun toString(): String = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 群内的引用回复.
|
* 用于发送的引用回复.
|
||||||
* 总是使用 [quote] 来构造实例.
|
* 总是使用 [quote] 来构造实例.
|
||||||
*/
|
*/
|
||||||
@UseExperimental(MiraiInternalAPI::class)
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
class QuoteReplyToSend @MiraiInternalAPI constructor(source: MessageSource, val sender: QQ) : QuoteReply(source) {
|
class QuoteReplyToSend
|
||||||
|
@MiraiInternalAPI constructor(source: MessageSource, val sender: QQ) : QuoteReply(source) {
|
||||||
fun createAt(): At = At(sender as Member)
|
fun createAt(): At = At(sender as Member)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ import kotlin.jvm.JvmName
|
|||||||
*
|
*
|
||||||
* @see buildXMLMessage
|
* @see buildXMLMessage
|
||||||
*/
|
*/
|
||||||
inline class XMLMessage(val stringValue: String) : Message,
|
@MiraiExperimentalAPI
|
||||||
SingleOnly {
|
inline class XMLMessage(val stringValue: String) : Message, MessageContent {
|
||||||
override fun followedBy(tail: Message): Nothing = error("XMLMessage Message cannot be followed")
|
override fun followedBy(tail: Message): Nothing = error("XMLMessage Message cannot be followed")
|
||||||
override fun toString(): String = stringValue
|
override fun toString(): String = stringValue
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,10 @@ inline fun buildMessageChain(block: MessageChainBuilder.() -> Unit): MessageChai
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MessageChainBuilder @JvmOverloads constructor(
|
class MessageChainBuilder @JvmOverloads constructor(
|
||||||
private val container: MutableList<Message> = mutableListOf()
|
private val container: MutableCollection<Message> = mutableListOf()
|
||||||
) : MutableList<Message> by container, Appendable {
|
) : MutableCollection<Message> by container, Appendable {
|
||||||
|
constructor(initialSize: Int) : this(ArrayList<Message>(initialSize))
|
||||||
|
|
||||||
operator fun Message.unaryPlus() {
|
operator fun Message.unaryPlus() {
|
||||||
add(this)
|
add(this)
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ internal class LockFreeLinkedListTest {
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNREACHABLE_CODE", "DeferredResultUnused")
|
||||||
@Test
|
@Test
|
||||||
fun `so many concurrent add remove and foreach`() = runBlocking {
|
fun `so many concurrent add remove and foreach`() = runBlocking {
|
||||||
return@runBlocking // 测试通过了, 加快速度. 因为 kotlin 一些其他 bug
|
return@runBlocking // 测试通过了, 加快速度. 因为 kotlin 一些其他 bug
|
||||||
|
@ -12,17 +12,17 @@ package net.mamoe.mirai.imageplugin
|
|||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import net.mamoe.mirai.console.plugins.Config
|
import net.mamoe.mirai.console.plugins.Config
|
||||||
import net.mamoe.mirai.console.plugins.ConfigSection
|
import net.mamoe.mirai.console.plugins.ConfigSection
|
||||||
|
import net.mamoe.mirai.console.plugins.PluginBase
|
||||||
|
import net.mamoe.mirai.contact.Contact
|
||||||
import net.mamoe.mirai.event.events.BotOnlineEvent
|
import net.mamoe.mirai.event.events.BotOnlineEvent
|
||||||
import net.mamoe.mirai.event.subscribeAlways
|
import net.mamoe.mirai.event.subscribeAlways
|
||||||
import net.mamoe.mirai.event.subscribeMessages
|
import net.mamoe.mirai.event.subscribeMessages
|
||||||
import net.mamoe.mirai.console.plugins.PluginBase
|
|
||||||
import net.mamoe.mirai.contact.Contact
|
|
||||||
import net.mamoe.mirai.message.data.Image
|
import net.mamoe.mirai.message.data.Image
|
||||||
import net.mamoe.mirai.message.uploadAsImage
|
import net.mamoe.mirai.message.uploadAsImage
|
||||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.random.Random
|
import java.net.URL
|
||||||
|
|
||||||
class ImageSenderMain : PluginBase() {
|
class ImageSenderMain : PluginBase() {
|
||||||
|
|
||||||
@ -60,7 +60,6 @@ class ImageSenderMain : PluginBase() {
|
|||||||
reply(e.message ?: "unknown error")
|
reply(e.message ?: "unknown error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,16 +83,21 @@ class ImageSenderMain : PluginBase() {
|
|||||||
|
|
||||||
override fun onLoad() {
|
override fun onLoad() {
|
||||||
logger.info("loading local image data")
|
logger.info("loading local image data")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
images = Config.load(this.javaClass.classLoader.getResource("data.yml")!!.path!!)
|
images = Config.load(getResources(fileName = "data.yml")!!, "yml")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
logger.info("无法加载本地图片")
|
logger.info("无法加载本地图片")
|
||||||
}
|
}
|
||||||
logger.info("本地图片版本" + images.getString("version"))
|
logger.info("本地图片版本" + images.getString("version"))
|
||||||
logger.info("Normal * " + images.getList("normal").size)
|
r18 = images.getConfigSectionList("R18")
|
||||||
logger.info("R18 * " + images.getList("R18").size)
|
normal = images.getConfigSectionList("normal")
|
||||||
|
logger.info("Normal * " + normal.size)
|
||||||
|
logger.info("R18 * " + r18.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onDisable() {
|
override fun onDisable() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user