mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-09 19:50:27 +08:00
MiraiCode of MusicShare (#1044)
* Improve MiraiCode parsing * MiraiCode of MusicShare
This commit is contained in:
parent
69cceaf695
commit
9bb3ae20ef
@ -4706,12 +4706,13 @@ public final class net/mamoe/mirai/message/data/MusicKind : java/lang/Enum {
|
||||
public static fun values ()[Lnet/mamoe/mirai/message/data/MusicKind;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/message/data/MusicShare : net/mamoe/mirai/message/data/ConstrainSingle, net/mamoe/mirai/message/data/MessageContent {
|
||||
public final class net/mamoe/mirai/message/data/MusicShare : net/mamoe/mirai/message/code/CodableMessage, net/mamoe/mirai/message/data/ConstrainSingle, net/mamoe/mirai/message/data/MessageContent {
|
||||
public static final field Key Lnet/mamoe/mirai/message/data/MusicShare$Key;
|
||||
public static final field SERIAL_NAME Ljava/lang/String;
|
||||
public synthetic fun <init> (ILnet/mamoe/mirai/message/data/MusicKind;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||
public fun <init> (Lnet/mamoe/mirai/message/data/MusicKind;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||
public fun <init> (Lnet/mamoe/mirai/message/data/MusicKind;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||
public fun appendMiraiCodeTo (Ljava/lang/StringBuilder;)V
|
||||
public final fun component1 ()Lnet/mamoe/mirai/message/data/MusicKind;
|
||||
public final fun component2 ()Ljava/lang/String;
|
||||
public final fun component3 ()Ljava/lang/String;
|
||||
|
@ -25,13 +25,7 @@ internal fun String.parseMiraiCodeImpl(contact: Contact?): MessageChain = buildM
|
||||
add(PlainText(origin.decodeMiraiCode()))
|
||||
return@forEachMiraiCode
|
||||
}
|
||||
parser.argsRegex.matchEntire(args)
|
||||
?.destructured
|
||||
?.let {
|
||||
parser.runCatching {
|
||||
contact.mapper(it)
|
||||
}.getOrNull()
|
||||
}
|
||||
parser.parse(contact, args)
|
||||
?.let(::add)
|
||||
?: add(PlainText(origin.decodeMiraiCode()))
|
||||
}
|
||||
@ -128,12 +122,76 @@ private object MiraiCodeParsers : Map<String, MiraiCodeParser> by mapOf(
|
||||
"dice" to MiraiCodeParser(Regex("""([1-6])""")) { (value) ->
|
||||
Dice(value.toInt())
|
||||
},
|
||||
"musicshare" to MiraiCodeParser.DynamicParser(7) { args ->
|
||||
val (kind, title, summary, jumpUrl, pictureUrl) = args
|
||||
val musicUrl = args[5]
|
||||
val brief = args[6]
|
||||
|
||||
MusicShare(MusicKind.valueOf(kind), title, summary, jumpUrl, pictureUrl, musicUrl, brief)
|
||||
},
|
||||
)
|
||||
|
||||
private class MiraiCodeParser(
|
||||
val argsRegex: Regex,
|
||||
val mapper: Contact?.(MatchResult.Destructured) -> Message?
|
||||
)
|
||||
|
||||
// Visitable for test
|
||||
internal sealed class MiraiCodeParser {
|
||||
abstract fun parse(contact: Contact?, args: String): Message?
|
||||
class RegexParser(
|
||||
private val argsRegex: Regex,
|
||||
private val mapper: Contact?.(MatchResult.Destructured) -> Message?
|
||||
) : MiraiCodeParser() {
|
||||
override fun parse(contact: Contact?, args: String): Message? =
|
||||
argsRegex.matchEntire(args)
|
||||
?.destructured
|
||||
?.let {
|
||||
runCatching {
|
||||
contact.mapper(it)
|
||||
}.getOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
class DynamicParser(
|
||||
private val minArgs: Int,
|
||||
private val maxArgs: Int = minArgs,
|
||||
private val parser: (Contact?.(args: Array<String>) -> Message?),
|
||||
) : MiraiCodeParser() {
|
||||
override fun parse(contact: Contact?, args: String): Message? {
|
||||
val ranges = mutableListOf<IntRange>()
|
||||
if (args.isNotEmpty()) {
|
||||
var begin = 0
|
||||
var pos = 0
|
||||
val len = args.length
|
||||
while (pos < len) {
|
||||
when (args[pos]) {
|
||||
'\\' -> pos += 2
|
||||
',' -> {
|
||||
ranges.add(begin..pos)
|
||||
pos++
|
||||
begin = pos
|
||||
}
|
||||
else -> pos++
|
||||
}
|
||||
}
|
||||
ranges.add(begin..len)
|
||||
}
|
||||
if (ranges.size < minArgs) return null
|
||||
if (ranges.size > maxArgs) return null
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
val args0 = Array<String>(ranges.size) { index ->
|
||||
val range = ranges[index]
|
||||
args.substring(range.first, range.last).decodeMiraiCode()
|
||||
}
|
||||
runCatching {
|
||||
return parser(contact, args0)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MiraiCodeParser(
|
||||
argsRegex: Regex,
|
||||
mapper: Contact?.(MatchResult.Destructured) -> Message?
|
||||
): MiraiCodeParser = MiraiCodeParser.RegexParser(argsRegex, mapper)
|
||||
|
||||
internal fun StringBuilder.appendStringAsMiraiCode(value: String): StringBuilder = apply {
|
||||
value.forEach { char ->
|
||||
|
@ -13,6 +13,8 @@ package net.mamoe.mirai.message.data
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.message.code.CodableMessage
|
||||
import net.mamoe.mirai.message.code.internal.appendStringAsMiraiCode
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import net.mamoe.mirai.utils.safeCast
|
||||
@ -53,7 +55,7 @@ public data class MusicShare(
|
||||
* 在消息列表显示
|
||||
*/
|
||||
public val brief: String,
|
||||
) : MessageContent, ConstrainSingle {
|
||||
) : MessageContent, ConstrainSingle, CodableMessage {
|
||||
|
||||
public constructor(
|
||||
/**
|
||||
@ -88,6 +90,19 @@ public data class MusicShare(
|
||||
override fun contentToString(): String =
|
||||
brief.takeIf { it.isNotBlank() } ?: "[分享]$title" // empty content is not accepted by `sendMessage`
|
||||
|
||||
override fun appendMiraiCodeTo(builder: StringBuilder) {
|
||||
builder.append("[mirai:musicshare:")
|
||||
.append(kind.name)
|
||||
.append(',').appendStringAsMiraiCode(title)
|
||||
.append(',').appendStringAsMiraiCode(summary)
|
||||
.append(',').appendStringAsMiraiCode(jumpUrl)
|
||||
.append(',').appendStringAsMiraiCode(pictureUrl)
|
||||
.append(',').appendStringAsMiraiCode(musicUrl)
|
||||
.append(',').appendStringAsMiraiCode(brief)
|
||||
.append(']')
|
||||
}
|
||||
|
||||
|
||||
// MusicShare(type=NeteaseCloudMusic, title='ファッション', summary='rinahamu/Yunomi', brief='', url='http://music.163.com/song/1338728297/?userid=324076307', pictureUrl='http://p2.music.126.net/y19E5SadGUmSR8SZxkrNtw==/109951163785855539.jpg', musicUrl='http://music.163.com/song/media/outer/url?id=1338728297&userid=324076307')
|
||||
|
||||
/**
|
||||
|
@ -10,11 +10,27 @@
|
||||
package net.mamoe.mirai.message.code
|
||||
|
||||
import net.mamoe.mirai.message.code.MiraiCode.deserializeMiraiCode
|
||||
import net.mamoe.mirai.message.code.internal.MiraiCodeParser
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class TestMiraiCode {
|
||||
@Test
|
||||
fun testDynamicMiraiCodeParser() {
|
||||
fun runTest(args: Int, code: String, parse: (args: Array<String>) -> Unit) {
|
||||
val response = MiraiCodeParser.DynamicParser(args) { args0 -> parse(args0); AtAll }.parse(null, code)
|
||||
assertNotNull(response, "Parser not invoked")
|
||||
}
|
||||
runTest(3, "test,\\,test,\\,\\,test") { (arg1, arg2, arg3) ->
|
||||
assertEquals("test", arg1)
|
||||
assertEquals(",test", arg2)
|
||||
assertEquals(",,test", arg3)
|
||||
}
|
||||
runTest(2, ",") {}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCodes() {
|
||||
assertEquals(AtAll.toMessageChain(), "[mirai:atall]".deserializeMiraiCode())
|
||||
@ -46,5 +62,16 @@ class TestMiraiCode {
|
||||
assertEquals(buildMessageChain {
|
||||
+Dice(1)
|
||||
}, "[mirai:dice:1]".deserializeMiraiCode())
|
||||
|
||||
val musicShare = MusicShare(
|
||||
kind = MusicKind.NeteaseCloudMusic,
|
||||
title = "ファッション",
|
||||
summary = "rinahamu/Yunomi",
|
||||
jumpUrl = "http://music.163.com/song/1338728297/?userid=324076307",
|
||||
pictureUrl = "http://p2.music.126.net/y19E5SadGUmSR8SZxkrNtw==/109951163785855539.jpg",
|
||||
musicUrl = "http://music.163.com/song/media/outer/url?id=1338728297&userid=324076307",
|
||||
brief = "",
|
||||
)
|
||||
assertEquals(musicShare.toMessageChain(), musicShare.serializeToMiraiCode().deserializeMiraiCode())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user