mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-15 08:00:12 +08:00
[core] feat: RockPaperScissors (#2220)
* [core] feat: RockPaperScissors Co-authored-by: Karlatemp <kar@kasukusakura.com> * docs update * rename `eliminate` to `eliminates` Co-authored-by: Karlatemp <kar@kasukusakura.com>
This commit is contained in:
parent
eea2ef509d
commit
2cffb7a4a4
@ -89,6 +89,7 @@ Mirai 支持多种消息类型。
|
||||
[`MusicShare`]: ../mirai-core-api/src/commonMain/kotlin/message/data/MusicShare.kt
|
||||
[`Dice`]: ../mirai-core-api/src/commonMain/kotlin/message/data/Dice.kt
|
||||
[`FileMessage`]: ../mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt
|
||||
[`RockPaperScissors`]: ../mirai-core-api/src/commonMain/kotlin/message/data/RockPaperScissors.kt
|
||||
|
||||
[`MessageSource`]: ../mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt
|
||||
[`QuoteReply`]: ../mirai-core-api/src/commonMain/kotlin/message/data/QuoteReply.kt
|
||||
@ -119,6 +120,7 @@ Mirai 支持多种消息类型。
|
||||
| [`SimpleServiceMessage`] | (不稳定)服务消息 | `$content` | 2.0 |
|
||||
| [`MusicShare`] | 音乐分享 | `[分享]曲名` | 2.1 |
|
||||
| [`Dice`] | 魔法表情骰子 | `[骰子:$value]` | 2.5 |
|
||||
| [`RockPaperScissors`] | 魔法表情猜拳 | `[石头]`/`[剪刀]`/`[布]` | 2.14 |
|
||||
| [`FileMessage`] | 文件消息 | `[文件]文件名称` | 2.5 |
|
||||
| [`Audio`] | 语音 | `[语音消息]` | 2.7 |
|
||||
|
||||
@ -572,6 +574,7 @@ at.serializeToMiraiCode() // 结果为 `[mirai:at:123]`
|
||||
| [`Dice`] | `[mirai:dice:$value]` |
|
||||
| [`MusicShare`] | `[mirai:musicshare:$args]` |
|
||||
| [`FileMessage`] | `[mirai:file:$id,$internalId,$name,$size]` |
|
||||
| [`RockPaperScissors`] | `[mirai:rps:$name]` |
|
||||
|
||||
### 由 mirai 码字符串取得 `MessageChain` 实例
|
||||
|
||||
|
@ -5112,6 +5112,32 @@ public final class net/mamoe/mirai/message/data/RichMessageOrigin$Key : net/mamo
|
||||
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/message/data/RockPaperScissors : java/lang/Enum, net/mamoe/mirai/message/code/CodableMessage, net/mamoe/mirai/message/data/MarketFace {
|
||||
public static final field Key Lnet/mamoe/mirai/message/data/RockPaperScissors$Key;
|
||||
public static final field PAPER Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static final field ROCK Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static final field SCISSORS Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static final field SERIAL_NAME Ljava/lang/String;
|
||||
public fun contentToString ()Ljava/lang/String;
|
||||
public final fun eliminates (Lnet/mamoe/mirai/message/data/RockPaperScissors;)Ljava/lang/Boolean;
|
||||
public final fun getContent ()Ljava/lang/String;
|
||||
public fun getId ()I
|
||||
public final fun getInternalId ()B
|
||||
public synthetic fun getName ()Ljava/lang/String;
|
||||
public static final fun random ()Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static final fun random (Lkotlin/random/Random;)Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public static fun valueOf (Ljava/lang/String;)Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static fun values ()[Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/message/data/RockPaperScissors$Key : net/mamoe/mirai/message/data/AbstractPolymorphicMessageKey {
|
||||
public final fun random ()Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public final fun random (Lkotlin/random/Random;)Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static synthetic fun random$default (Lnet/mamoe/mirai/message/data/RockPaperScissors$Key;Lkotlin/random/Random;ILjava/lang/Object;)Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||
}
|
||||
|
||||
public abstract interface class net/mamoe/mirai/message/data/ServiceMessage : net/mamoe/mirai/message/code/CodableMessage, net/mamoe/mirai/message/data/RichMessage {
|
||||
public static final field Key Lnet/mamoe/mirai/message/data/ServiceMessage$Key;
|
||||
public abstract fun getServiceId ()I
|
||||
|
@ -5112,6 +5112,32 @@ public final class net/mamoe/mirai/message/data/RichMessageOrigin$Key : net/mamo
|
||||
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/message/data/RockPaperScissors : java/lang/Enum, net/mamoe/mirai/message/code/CodableMessage, net/mamoe/mirai/message/data/MarketFace {
|
||||
public static final field Key Lnet/mamoe/mirai/message/data/RockPaperScissors$Key;
|
||||
public static final field PAPER Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static final field ROCK Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static final field SCISSORS Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static final field SERIAL_NAME Ljava/lang/String;
|
||||
public fun contentToString ()Ljava/lang/String;
|
||||
public final fun eliminates (Lnet/mamoe/mirai/message/data/RockPaperScissors;)Ljava/lang/Boolean;
|
||||
public final fun getContent ()Ljava/lang/String;
|
||||
public fun getId ()I
|
||||
public final fun getInternalId ()B
|
||||
public synthetic fun getName ()Ljava/lang/String;
|
||||
public static final fun random ()Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static final fun random (Lkotlin/random/Random;)Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public fun toString ()Ljava/lang/String;
|
||||
public static fun valueOf (Ljava/lang/String;)Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static fun values ()[Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/message/data/RockPaperScissors$Key : net/mamoe/mirai/message/data/AbstractPolymorphicMessageKey {
|
||||
public final fun random ()Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public final fun random (Lkotlin/random/Random;)Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public static synthetic fun random$default (Lnet/mamoe/mirai/message/data/RockPaperScissors$Key;Lkotlin/random/Random;ILjava/lang/Object;)Lnet/mamoe/mirai/message/data/RockPaperScissors;
|
||||
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||
}
|
||||
|
||||
public abstract interface class net/mamoe/mirai/message/data/ServiceMessage : net/mamoe/mirai/message/code/CodableMessage, net/mamoe/mirai/message/data/RichMessage {
|
||||
public static final field Key Lnet/mamoe/mirai/message/data/ServiceMessage$Key;
|
||||
public abstract fun getServiceId ()I
|
||||
|
@ -123,6 +123,9 @@ private object MiraiCodeParsers : AbstractMap<String, MiraiCodeParser>(), Map<St
|
||||
"dice" to MiraiCodeParser(Regex("""([1-6])""")) { (value) ->
|
||||
Dice(value.toInt())
|
||||
},
|
||||
"rps" to MiraiCodeParser(Regex("""(\w+)""")) { (value) ->
|
||||
RockPaperScissors.valueOf(value.uppercase())
|
||||
},
|
||||
"musicshare" to MiraiCodeParser.DynamicParser(7) { args ->
|
||||
val (kind, title, summary, jumpUrl, pictureUrl) = args
|
||||
val musicUrl = args[5]
|
||||
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2019-2022 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MessageUtils")
|
||||
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.message.code.CodableMessage
|
||||
import net.mamoe.mirai.message.data.RockPaperScissors.*
|
||||
import net.mamoe.mirai.message.data.visitor.MessageVisitor
|
||||
import net.mamoe.mirai.utils.*
|
||||
import kotlin.jvm.*
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* 石头剪刀布.
|
||||
*
|
||||
* 可以通过 [RockPaperScissors.random] 获得一个随机手势的实例.
|
||||
*
|
||||
* @property ROCK 石头 `[mirai:rps:rock]`
|
||||
* @property SCISSORS 剪刀 `[mirai:rps:scissors]`
|
||||
* @property PAPER 布(纸)`[mirai:rps:paper]`
|
||||
*
|
||||
* @since 2.14
|
||||
*/
|
||||
@kotlin.Suppress("RemoveRedundantQualifierName")
|
||||
@Serializable(RockPaperScissors.Serializer::class)
|
||||
@SerialName(RockPaperScissors.SERIAL_NAME)
|
||||
public enum class RockPaperScissors(
|
||||
public val content: String,
|
||||
|
||||
internalId: Int,
|
||||
) : MarketFace, CodableMessage {
|
||||
ROCK("[石头]", 48),
|
||||
SCISSORS("[剪刀]", 49),
|
||||
PAPER("[布]", 50)
|
||||
;
|
||||
|
||||
@MiraiExperimentalApi
|
||||
override val id: Int
|
||||
get() = 11415
|
||||
|
||||
@MiraiInternalApi
|
||||
@JvmSynthetic
|
||||
public val internalId: Byte = internalId.toByte()
|
||||
|
||||
@MiraiExperimentalApi
|
||||
override fun appendMiraiCodeTo(builder: StringBuilder) {
|
||||
builder.append("[mirai:rps:").append(name.lowercase()).append(']')
|
||||
}
|
||||
|
||||
override fun toString(): String = serializeToMiraiCode()
|
||||
|
||||
|
||||
override fun contentToString(): String = content
|
||||
|
||||
@MiraiInternalApi
|
||||
override fun <D, R> accept(visitor: MessageVisitor<D, R>, data: D): R {
|
||||
return visitor.visitRockPaperScissors(this, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 当前手势 (`this`) 能否淘汰对手 ([other])
|
||||
*
|
||||
* @return 赢返回 `true`,输返回 `false`,平局时返回 `null`
|
||||
*/
|
||||
public infix fun eliminates(other: RockPaperScissors): Boolean? {
|
||||
return when {
|
||||
this == other -> null
|
||||
this == ROCK && other == SCISSORS -> true
|
||||
this == SCISSORS && other == PAPER -> true
|
||||
this == PAPER && other == ROCK -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
public companion object Key :
|
||||
AbstractPolymorphicMessageKey<MarketFace, RockPaperScissors>(MarketFace, { it.safeCast() }) {
|
||||
public const val SERIAL_NAME: String = "RockPaperScissors"
|
||||
|
||||
private val values = values()
|
||||
|
||||
/**
|
||||
* 获取随机手势的 [石头剪刀布][RockPaperScissors]
|
||||
*
|
||||
* Java 可通过 `kotlin.random.PlatformRandomKt.asKotlinRandom()` 来传入一个 random
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
public fun random(random: Random = Random): RockPaperScissors = RockPaperScissors.values.random(random)
|
||||
|
||||
}
|
||||
|
||||
internal object Serializer : KSerializer<RockPaperScissors> by Surrogate.serializer().map(
|
||||
resultantDescriptor = Surrogate.serializer().descriptor.copy(SERIAL_NAME),
|
||||
deserialize = { valueOf(it.name) },
|
||||
serialize = { Surrogate(name) },
|
||||
) {
|
||||
|
||||
@Serializable
|
||||
@SerialName(RockPaperScissors.SERIAL_NAME)
|
||||
private class Surrogate(
|
||||
val name: String,
|
||||
)
|
||||
}
|
||||
}
|
@ -48,6 +48,7 @@ public interface MessageVisitor<in D, out R> {
|
||||
// region MarketFace
|
||||
public fun visitMarketFace(message: MarketFace, data: D): R
|
||||
public fun visitDice(message: Dice, data: D): R
|
||||
public fun visitRockPaperScissors(message: RockPaperScissors, data: D): R
|
||||
|
||||
// endregion
|
||||
// endregion
|
||||
@ -184,6 +185,10 @@ public abstract class AbstractMessageVisitor<in D, out R> : MessageVisitor<D, R>
|
||||
return visitMarketFace(message, data)
|
||||
}
|
||||
|
||||
public override fun visitRockPaperScissors(message: RockPaperScissors, data: D): R {
|
||||
return visitMarketFace(message, data)
|
||||
}
|
||||
|
||||
public override fun visitFace(message: Face, data: D): R {
|
||||
return visitMessageContent(message, data)
|
||||
}
|
||||
|
@ -107,6 +107,10 @@ internal class MessageVisitorTest {
|
||||
return arrayOf("visitDice") + super.visitDice(message, data)
|
||||
}
|
||||
|
||||
override fun visitRockPaperScissors(message: RockPaperScissors, data: Unit): Array<String> {
|
||||
return arrayOf("visitRockPaperScissors") + super.visitRockPaperScissors(message, data)
|
||||
}
|
||||
|
||||
override fun visitFace(message: Face, data: Unit): Array<String> {
|
||||
return arrayOf("visitFace") + super.visitFace(message, data)
|
||||
}
|
||||
@ -335,6 +339,18 @@ internal class MessageVisitorTest {
|
||||
Dice(1).accept(GetCalledMethodNames)
|
||||
)
|
||||
|
||||
assertContentEquals(
|
||||
arrayOf(
|
||||
"visitRockPaperScissors",
|
||||
"visitMarketFace",
|
||||
"visitHummerMessage",
|
||||
"visitMessageContent",
|
||||
"visitSingleMessage",
|
||||
"visitMessage",
|
||||
),
|
||||
RockPaperScissors.PAPER.accept(GetCalledMethodNames)
|
||||
)
|
||||
|
||||
|
||||
assertContentEquals(
|
||||
arrayOf(
|
||||
|
@ -28,6 +28,7 @@ import net.mamoe.mirai.utils.map
|
||||
internal class MarketFaceProtocol : MessageProtocol() {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
add(DiceEncoder())
|
||||
add(RockPaperScissorsEncoder())
|
||||
add(MarketFaceImplEncoder())
|
||||
|
||||
add(MarketFaceDecoder())
|
||||
@ -46,11 +47,12 @@ internal class MarketFaceProtocol : MessageProtocol() {
|
||||
MarketFace::class, MarketFaceImpl.serializer().map(
|
||||
resultantDescriptor = MarketFaceImpl.serializer().descriptor.copy(MarketFace.SERIAL_NAME),
|
||||
deserialize = {
|
||||
it.delegate.toDiceOrNull() ?: it
|
||||
it.delegate.toDiceOrNull() ?: it.delegate.toRockPaperScissorsOrNull() ?: it
|
||||
},
|
||||
serialize = {
|
||||
when (it) {
|
||||
is Dice -> MarketFaceImpl(it.toJceStruct())
|
||||
is RockPaperScissors -> MarketFaceImpl(it.toJceStruct())
|
||||
is MarketFaceImpl -> it
|
||||
else -> {
|
||||
error("Unsupported MarketFace type ${it::class.qualifiedName}")
|
||||
@ -64,6 +66,7 @@ internal class MarketFaceProtocol : MessageProtocol() {
|
||||
MessageSerializer.superclassesScope(MarketFace::class, MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(MarketFaceImpl::class, MarketFaceImpl.serializer()))
|
||||
add(MessageSerializer(Dice::class, Dice.serializer()))
|
||||
add(MessageSerializer(RockPaperScissors::class, RockPaperScissors.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,6 +93,13 @@ internal class MarketFaceProtocol : MessageProtocol() {
|
||||
}
|
||||
}
|
||||
|
||||
private class RockPaperScissorsEncoder : MessageEncoder<RockPaperScissors> {
|
||||
override suspend fun MessageEncoderContext.process(data: RockPaperScissors) {
|
||||
markAsConsumed()
|
||||
processAlso(MarketFaceImpl(data.toJceStruct()))
|
||||
}
|
||||
}
|
||||
|
||||
private class MarketFaceDecoder : MessageDecoder {
|
||||
override suspend fun MessageDecoderContext.process(data: ImMsgBody.Elem) {
|
||||
val proto = data.marketFace ?: return
|
||||
@ -99,6 +109,11 @@ internal class MarketFaceProtocol : MessageProtocol() {
|
||||
return
|
||||
}
|
||||
|
||||
proto.toRockPaperScissorsOrNull()?.let {
|
||||
collect(it)
|
||||
return
|
||||
}
|
||||
|
||||
collect(MarketFaceImpl(proto))
|
||||
}
|
||||
}
|
||||
@ -118,6 +133,12 @@ internal class MarketFaceProtocol : MessageProtocol() {
|
||||
6 to "7A2303AD80755FCB6BBFAC38327E0C01".hexToBytes(),
|
||||
)
|
||||
|
||||
private val RPS_PC_FACE_IDS = mapOf(
|
||||
48 to "E5D889F1DF79B2B45183F625584465D3".hexToBytes(),
|
||||
49 to "628FA4AB7B6C2BCCFCDCD0C2DAF7A60C".hexToBytes(),
|
||||
50 to "457CDE420F598EB424CED2E905D38D8B".hexToBytes(),
|
||||
)
|
||||
|
||||
private fun ImMsgBody.MarketFace.toDiceOrNull(): Dice? {
|
||||
if (this.tabId != 11464) return null
|
||||
val value = when {
|
||||
@ -130,6 +151,26 @@ internal class MarketFaceProtocol : MessageProtocol() {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun ImMsgBody.MarketFace.toRockPaperScissorsOrNull(): RockPaperScissors? {
|
||||
if (tabId != 11415) return null
|
||||
|
||||
val value = when {
|
||||
mobileParam.isNotEmpty() -> {
|
||||
val theLast = mobileParam.lastOrNull() ?: return null
|
||||
theLast.toInt().and(0xff)
|
||||
}
|
||||
else -> RPS_PC_FACE_IDS.entries.find { it.value.contentEquals(faceId) }?.key ?: return null
|
||||
}
|
||||
|
||||
return when (value) {
|
||||
48 -> RockPaperScissors.ROCK
|
||||
49 -> RockPaperScissors.SCISSORS
|
||||
50 -> RockPaperScissors.PAPER
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
// From https://github.com/mamoe/mirai/issues/1012
|
||||
private fun Dice.toJceStruct(): ImMsgBody.MarketFace {
|
||||
return ImMsgBody.MarketFace(
|
||||
@ -161,5 +202,31 @@ internal class MarketFaceProtocol : MessageProtocol() {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun RockPaperScissors.toJceStruct(): ImMsgBody.MarketFace {
|
||||
return ImMsgBody.MarketFace(
|
||||
faceName = byteArrayOf(91, -25, -116, -100, -26, -117, -77, 93),
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = byteArrayOf(
|
||||
-125, -56, -94, -109, -82,
|
||||
101, -54, 20, 15, 52,
|
||||
-127, 32, -89, 116, 72, -18
|
||||
),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = byteArrayOf(55, 100, 101, 51, 57, 102, 101, 98, 99, 102, 52, 53, 101, 54, 100, 98),
|
||||
mediaType = 0,
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = byteArrayOf(
|
||||
114, 115, 99, 84, 121, 112, 101,
|
||||
63, 49, 59, 118, 97, 108, 117,
|
||||
101, 61,
|
||||
internalId
|
||||
),
|
||||
pbReserve = byteArrayOf(10, 6, 8, -56, 1, 16, -56, 1, 64, 1)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,5 +82,18 @@ internal class TestMiraiCode : AbstractTest() {
|
||||
brief = "",
|
||||
)
|
||||
assertEquals(musicShare.toMessageChain(), musicShare.serializeToMiraiCode().deserializeMiraiCode())
|
||||
|
||||
assertEquals(
|
||||
messageChainOf(RockPaperScissors.ROCK),
|
||||
"[mirai:rps:rock]".deserializeMiraiCode()
|
||||
)
|
||||
assertEquals(
|
||||
messageChainOf(RockPaperScissors.SCISSORS),
|
||||
"[mirai:rps:scissors]".deserializeMiraiCode()
|
||||
)
|
||||
assertEquals(
|
||||
messageChainOf(RockPaperScissors.PAPER),
|
||||
"[mirai:rps:paper]".deserializeMiraiCode()
|
||||
)
|
||||
}
|
||||
}
|
@ -71,6 +71,7 @@ internal class MessageSerializationTest : AbstractTest() {
|
||||
AtAll,
|
||||
image,
|
||||
Face(Face.AI_NI),
|
||||
RockPaperScissors.PAPER,
|
||||
UnsupportedMessageImpl(ImMsgBody.Elem())
|
||||
)
|
||||
|
||||
|
@ -21,6 +21,7 @@ import net.mamoe.mirai.internal.testFramework.dynamicTest
|
||||
import net.mamoe.mirai.internal.testFramework.runDynamicTests
|
||||
import net.mamoe.mirai.message.data.Dice
|
||||
import net.mamoe.mirai.message.data.MarketFace
|
||||
import net.mamoe.mirai.message.data.RockPaperScissors
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
@ -104,6 +105,354 @@ internal class MarketFaceProtocolTest : AbstractMessageProtocolTest() {
|
||||
}.doEncoderChecks()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `decode RockPaperScissors`() {
|
||||
// region WinQQ PC
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "E5 D8 89 F1 DF 79 B2 B4 51 83 F6 25 58 44 65 D3".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 100,
|
||||
imageHeight = 100,
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
attr7Buf = "01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
message(RockPaperScissors.ROCK)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "62 8F A4 AB 7B 6C 2B CC FC DC D0 C2 DA F7 A6 0C".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 100,
|
||||
imageHeight = 100,
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
attr7Buf = "01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
message(RockPaperScissors.SCISSORS)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "45 7C DE 42 0F 59 8E B4 24 CE D2 E9 05 D3 8D 8B".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 100,
|
||||
imageHeight = 100,
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
attr7Buf = "01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
message(RockPaperScissors.PAPER)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
// endregion
|
||||
|
||||
// region AndroidQQ 8.4.18.49145
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=2".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 32 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
),
|
||||
)
|
||||
message(RockPaperScissors.PAPER)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=0".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 30 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
),
|
||||
)
|
||||
message(RockPaperScissors.ROCK)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=1".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 31 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
),
|
||||
)
|
||||
message(RockPaperScissors.SCISSORS)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
// endregion
|
||||
|
||||
// region MacOS
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=0".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 30 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
message(RockPaperScissors.ROCK)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
// endregion
|
||||
|
||||
// region iOS
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
// ROCK
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=0".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 30 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
),
|
||||
)
|
||||
message(RockPaperScissors.ROCK)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
buildCodingChecks { // paper
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=2".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 32 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
),
|
||||
)
|
||||
message(RockPaperScissors.PAPER)
|
||||
useOrdinaryEquality()
|
||||
}.doDecoderChecks()
|
||||
// endregion
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `encode RockPaperScissors`() {
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=0".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 30 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
extraInfo = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.ExtraInfo(
|
||||
flags = 8,
|
||||
groupMask = 1,
|
||||
),
|
||||
),
|
||||
)
|
||||
message(RockPaperScissors.ROCK)
|
||||
}.doBothChecks()
|
||||
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=1".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 31 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
),
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
extraInfo = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.ExtraInfo(
|
||||
flags = 8,
|
||||
groupMask = 1,
|
||||
),
|
||||
),
|
||||
)
|
||||
message(RockPaperScissors.SCISSORS)
|
||||
}.doBothChecks()
|
||||
|
||||
buildCodingChecks {
|
||||
elem(
|
||||
net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
marketFace = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.MarketFace(
|
||||
faceName = "[猜拳]".toByteArray(), /* 5B E7 8C 9C E6 8B B3 5D */
|
||||
itemType = 6,
|
||||
faceInfo = 1,
|
||||
faceId = "83 C8 A2 93 AE 65 CA 14 0F 34 81 20 A7 74 48 EE".hexToBytes(),
|
||||
tabId = 11415,
|
||||
subType = 3,
|
||||
key = "7de39febcf45e6db".toByteArray(), /* 37 64 65 33 39 66 65 62 63 66 34 35 65 36 64 62 */
|
||||
imageWidth = 200,
|
||||
imageHeight = 200,
|
||||
mobileParam = "rscType?1;value=2".toByteArray(), /* 72 73 63 54 79 70 65 3F 31 3B 76 61 6C 75 65 3D 32 */
|
||||
pbReserve = "0A 06 08 C8 01 10 C8 01 40 01".hexToBytes(),
|
||||
),
|
||||
), net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
text = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Text(
|
||||
str = "[猜拳]",
|
||||
),
|
||||
), net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.Elem(
|
||||
extraInfo = net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody.ExtraInfo(
|
||||
flags = 8,
|
||||
groupMask = 1,
|
||||
),
|
||||
)
|
||||
)
|
||||
message(RockPaperScissors.PAPER)
|
||||
}.doBothChecks()
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `encode decode MarketFace from Android`() {
|
||||
|
Loading…
Reference in New Issue
Block a user