1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-05-06 05:45:19 +08:00

Redesign nudge

This commit is contained in:
Him188 2020-09-15 22:42:28 +08:00
parent c21b28e160
commit 8a7f56f90b
13 changed files with 274 additions and 179 deletions
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid
mirai-core/src/commonMain/kotlin/net.mamoe.mirai

View File

@ -32,6 +32,7 @@ import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.event.internal.MiraiAtomicBoolean
import net.mamoe.mirai.getGroupOrNull
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.action.Nudge
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.network.LoginFailedException
import net.mamoe.mirai.qqandroid.contact.FriendImpl
@ -45,10 +46,7 @@ import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopNum
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.LongMsg
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.MultiMsg
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NewContact
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.PbMessageSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.calculateValidationDataForGroup
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.*
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.voice.PttStore
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
@ -230,6 +228,30 @@ internal class QQAndroidBot constructor(
accept = accept
)
}
@Suppress("CANNOT_OVERRIDE_INVISIBLE_MEMBER")
override suspend fun sendNudge(nudge: Nudge, receiver: Contact): Boolean {
if (configuration.protocol != BotConfiguration.MiraiProtocol.ANDROID_PHONE) {
throw UnsupportedOperationException("nudge is supported only with protocol ANDROID_PHONE")
}
network.run {
return if (receiver is Group) {
receiver.checkIsGroupImpl()
NudgePacket.troopInvoke(
client = client,
messageReceiverGroupCode = receiver.id,
nudgeTargetId = nudge.target.id,
).sendAndExpect<NudgePacket.Response>().success
} else {
NudgePacket.friendInvoke(
client = client,
messageReceiverUin = receiver.id,
nudgeTargetId = nudge.target.id,
).sendAndExpect<NudgePacket.Response>().success
}
}
}
}

View File

@ -38,11 +38,13 @@ import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.network.highway.postImage
import net.mamoe.mirai.qqandroid.network.highway.sizeToString
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NudgePacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
import net.mamoe.mirai.qqandroid.utils.toUHexString
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.getValue
import net.mamoe.mirai.utils.unsafeWeakRef
import net.mamoe.mirai.utils.verbose
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext
@ -83,9 +85,6 @@ internal class FriendImpl(
override val nick: String
get() = friendInfo.nick
@Suppress("PropertyName")
var _nudgeTimestamp: Long = 0L
@JvmSynthetic
@Suppress("DuplicatedCode")
override suspend fun sendMessage(message: Message): MessageReceipt<Friend> {
@ -99,35 +98,6 @@ internal class FriendImpl(
}
}
override suspend fun nudge(): Boolean {
return nudge(this@FriendImpl)
}
override suspend fun nudgeBot(): Boolean {
return bot.selfQQ.checkIsFriendImpl().nudge(this@FriendImpl)
}
private suspend fun nudge(chatTarget: Friend): Boolean {
if (bot.configuration.protocol != BotConfiguration.MiraiProtocol.ANDROID_PHONE) {
throw UnsupportedOperationException("nudge is supported only with protocol ANDROID_PHONE")
}
val coolDown = currentTimeMillis - _nudgeTimestamp;
check(coolDown > 10000L) {
"Cooling, Please wait $coolDown ms and try again"
}
bot.network.run {
return NudgePacket.friendInvoke(
client = bot.client,
targetUin = this@FriendImpl.id,
chatTargetUin = chatTarget.id
).sendAndExpect<NudgePacket.Response>().success.also { success ->
if (success) {
_nudgeTimestamp = currentTimeMillis
}
}
}
}
@JvmSynthetic
override suspend fun uploadImage(image: ExternalImage): Image = try {
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")

View File

@ -26,11 +26,13 @@ import net.mamoe.mirai.qqandroid.message.MessageSourceToTempImpl
import net.mamoe.mirai.qqandroid.message.ensureSequenceIdAvailable
import net.mamoe.mirai.qqandroid.message.firstIsInstanceOrNull
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopMemberInfo
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NudgePacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToTemp
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.currentTimeSeconds
import net.mamoe.mirai.utils.getValue
import net.mamoe.mirai.utils.unsafeWeakRef
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext
@ -220,28 +222,6 @@ internal class MemberImpl constructor(
net.mamoe.mirai.event.events.MemberUnmuteEvent(this@MemberImpl, null).broadcast()
}
override suspend fun nudge(): Boolean {
if (bot.configuration.protocol != BotConfiguration.MiraiProtocol.ANDROID_PHONE) {
throw UnsupportedOperationException("nudge is supported only with protocol ANDROID_PHONE")
}
val coolDown = currentTimeMillis - _nudgeTimestamp;
check(coolDown > 10000L) {
"Cooling, Please wait $coolDown ms and try again"
}
bot.network.run {
return NudgePacket.troopInvoke(
client = bot.client,
groupCode = group.id,
targetUin = this@MemberImpl.id,
).sendAndExpect<NudgePacket.Response>().success.also { success ->
if (success) {
_nudgeTimestamp = currentTimeMillis
}
}
}
}
@JvmSynthetic
override suspend fun kick(message: String) {
checkBotPermissionHigherThanThis("kick")

View File

@ -26,7 +26,7 @@ import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
internal object NudgePacket : OutgoingPacketFactory<NudgePacket.Response>("OidbSvc.0xed3") {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
with(readBytes().loadAs(OidbSso.OIDBSSOPkg.serializer())) {
return Response(result == 0, result);
return Response(result == 0, result)
}
}
@ -36,8 +36,8 @@ internal object NudgePacket : OutgoingPacketFactory<NudgePacket.Response>("OidbS
fun friendInvoke(
client: QQAndroidClient,
targetUin: Long,
chatTargetUin: Long,
nudgeTargetId: Long,
messageReceiverUin: Long,
): OutgoingPacket {
return buildOutgoingUniPacket(client) {
writeProtoBuf(
@ -47,8 +47,8 @@ internal object NudgePacket : OutgoingPacketFactory<NudgePacket.Response>("OidbS
serviceType = 1,
result = 0,
bodybuffer = Cmd0xed3.ReqBody(
toUin = targetUin,
aioUin = chatTargetUin
toUin = nudgeTargetId,
aioUin = messageReceiverUin
).toByteArray(Cmd0xed3.ReqBody.serializer())
)
)
@ -57,8 +57,8 @@ internal object NudgePacket : OutgoingPacketFactory<NudgePacket.Response>("OidbS
fun troopInvoke(
client: QQAndroidClient,
groupCode: Long,
targetUin: Long,
messageReceiverGroupCode: Long,
nudgeTargetId: Long,
): OutgoingPacket {
return buildOutgoingUniPacket(client) {
writeProtoBuf(
@ -68,8 +68,8 @@ internal object NudgePacket : OutgoingPacketFactory<NudgePacket.Response>("OidbS
serviceType = 1,
result = 0,
bodybuffer = Cmd0xed3.ReqBody(
toUin = targetUin,
groupCode = groupCode
toUin = nudgeTargetId,
groupCode = messageReceiverGroupCode
).toByteArray(Cmd0xed3.ReqBody.serializer())
)
)

View File

@ -259,7 +259,10 @@ private object Transformers732 : Map<Int, Lambda732> by mapOf(
}
}
}
return@lambda732 sequenceOf(MemberNudgeEvent(from, action, target, suffix))
if (target.id == bot.id) {
return@lambda732 sequenceOf(BotNudgedEvent(from, action, suffix))
}
return@lambda732 sequenceOf(MemberNudgedEvent(from, target, action, suffix))
}
else -> {
bot.logger.debug {
@ -402,7 +405,7 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
0x8AL to lambda528 { bot ->
@Serializable
data class Sub8AMsgInfo(
class Sub8AMsgInfo(
@ProtoNumber(1) val fromUin: Long,
@ProtoNumber(2) val botUin: Long,
@ProtoNumber(3) val srcId: Int,
@ -416,7 +419,7 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
) : ProtoBuf
@Serializable
data class Sub8A(
class Sub8A(
@ProtoNumber(1) val msgInfo: List<Sub8AMsgInfo>,
@ProtoNumber(2) val appId: Int, // 1
@ProtoNumber(3) val instId: Int, // 1
@ -491,30 +494,27 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
} else emptySequence()
},
//戳一戳信息等
0x122L to lambda528 { bot, msgInfo ->
0x122L to lambda528 { bot, _ ->
val body = vProtobuf.loadAs(Submsgtype0x122.Submsgtype0x122.MsgBody.serializer())
when (body.templId) {
//戳一戳
1134L, 1135L, 1136L, 10043L -> {
//预置数据,服务器将不会提供己方已知消息
val chatTarget: Friend = bot.getFriend(msgInfo.lFromUin)
var from: Friend = bot.selfQQ
var action = ""
var target: Friend = bot.selfQQ
var suffix = ""
body.msgTemplParam?.map {
Pair(it.name.decodeToString(), it.value.decodeToString())
}?.asSequence()?.forEach { (key, value) ->
run {
when (key) {
"action_str" -> action = value
"uin_str1" -> from = bot.getFriend(value.toLong())
"uin_str2" -> target = bot.getFriend(value.toLong())
"suffix_str" -> suffix = value
}
body.msgTemplParam?.asSequence()?.map {
it.name.decodeToString() to it.value.decodeToString()
}?.forEach { (key, value) ->
when (key) {
"action_str" -> action = value
"uin_str1" -> from = bot.getFriend(value.toLong())
"uin_str2" -> target = bot.getFriend(value.toLong())
"suffix_str" -> suffix = value
}
}
return@lambda528 sequenceOf(FriendNudgeEvent(chatTarget, from, action, target, suffix))
return@lambda528 sequenceOf(BotNudgedEvent(from, action, suffix))
}
else -> {

View File

@ -20,6 +20,9 @@ import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
import net.mamoe.mirai.event.events.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.action.BotNudge
import net.mamoe.mirai.message.action.MemberNudge
import net.mamoe.mirai.message.action.Nudge
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.network.LoginFailedException
import net.mamoe.mirai.utils.*
@ -216,6 +219,15 @@ public abstract class Bot internal constructor(
@JvmSynthetic
public abstract suspend fun recall(source: MessageSource)
/**
* 创建一个 "戳一戳" 消息
*
* @see MemberNudge.sendTo 发送这个戳一戳消息
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public fun nudge(): BotNudge = BotNudge(this)
/**
* 获取图片下载链接
*
@ -339,6 +351,9 @@ public abstract class Bot internal constructor(
@JvmSynthetic
public abstract suspend fun ignoreInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
@SinceMirai("1.3.0")
internal abstract suspend fun sendNudge(nudge: Nudge, receiver: Contact): Boolean
// endregion
/**

View File

@ -12,19 +12,19 @@
package net.mamoe.mirai.contact
import kotlinx.coroutines.CoroutineScope
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.EventCancelledException
import net.mamoe.mirai.event.events.FriendMessagePostSendEvent
import net.mamoe.mirai.event.events.FriendMessagePreSendEvent
import net.mamoe.mirai.event.events.FriendNudgeEvent
import net.mamoe.mirai.message.FriendMessageEvent
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.action.FriendNudge
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.message.data.isContentEmpty
import net.mamoe.mirai.message.recall
import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.SinceMirai
import kotlin.jvm.JvmSynthetic
/**
@ -73,6 +73,15 @@ public abstract class Friend : User(), CoroutineScope {
@JvmSynthetic
abstract override suspend fun sendMessage(message: Message): MessageReceipt<Friend>
/**
* 创建一个 "戳一戳" 消息
*
* @see FriendNudge.sendTo 发送这个戳一戳消息
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public final override fun nudge(): FriendNudge = FriendNudge(this)
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "VIRTUAL_MEMBER_HIDDEN", "OVERRIDE_BY_INLINE")
@kotlin.internal.InlineOnly
@JvmSynthetic
@ -80,39 +89,5 @@ public abstract class Friend : User(), CoroutineScope {
return sendMessage(PlainText(message))
}
/**
* 发送戳一戳好友的消息冷却时间为 10
* 如对方已禁用该功能发送将会失败且不会抛出异常
* 调用需要使用协议 [MiraiProtocol.ANDROID_PHONE]
*
*
* @see nudgeBot 戳一戳自己
* @see FriendNudgeEvent 好友戳一戳事件
*
* @throws IllegalStateException 当仍处于冷却状态时
* @throws UnsupportedOperationException 当未使用安卓协议时 ([MiraiProtocol.ANDROID_PHONE])
*
* @return 是否成功发送
*/
@JvmBlockingBridge
public abstract suspend fun nudge(): Boolean
/**
* 发送戳一戳自己的消息冷却时间为 10
* 如Bot已禁用该功能发送将会失败且不会抛出异常
* 调用需要使用协议 [MiraiProtocol.ANDROID_PHONE]
*
*
* @see nudge 戳一戳好友
* @see FriendNudgeEvent 好友戳一戳事件
*
* @throws IllegalStateException 当仍处于冷却状态时
* @throws UnsupportedOperationException 当未使用安卓协议时 ([MiraiProtocol.ANDROID_PHONE])
*
* @return 是否成功发送
*/
@JvmBlockingBridge
public abstract suspend fun nudgeBot(): Boolean
final override fun toString(): String = "Friend($id)"
}

View File

@ -11,17 +11,19 @@
package net.mamoe.mirai.contact
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.Bot
import net.mamoe.mirai.JavaFriendlyAPI
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.getFriendOrNull
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.action.MemberNudge
import net.mamoe.mirai.message.action.Nudge
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.message.data.isContentEmpty
import net.mamoe.mirai.message.recall
import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.SinceMirai
import net.mamoe.mirai.utils.WeakRefProperty
import kotlin.jvm.JvmSynthetic
import kotlin.time.Duration
@ -126,21 +128,6 @@ public abstract class Member : MemberJavaFriendlyAPI, User() {
@JvmSynthetic
public abstract suspend fun unmute()
/**
* 发送戳一戳该成员的消息冷却时间为 10
* 如对方已禁用该功能发送将会失败且不会抛出异常
* 调用需要使用协议 [MiraiProtocol.ANDROID_PHONE]
*
* @see MemberNudgeEvent 成员戳一戳事件
*
* @throws IllegalStateException 当仍处于冷却状态时
* @throws UnsupportedOperationException 当未使用安卓协议时 ([MiraiProtocol.ANDROID_PHONE])
*
* @return 是否成功发送
*/
@JvmBlockingBridge
public abstract suspend fun nudge(): Boolean
/**
* 踢出该成员.
*
@ -174,6 +161,15 @@ public abstract class Member : MemberJavaFriendlyAPI, User() {
@JvmSynthetic
public abstract override suspend fun sendMessage(message: Message): MessageReceipt<Member>
/**
* 创建一个 "戳一戳" 消息
*
* @see MemberNudge.sendTo 发送这个戳一戳消息
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public final override fun nudge(): Nudge = MemberNudge(this)
/**
* @see sendMessage
*/

View File

@ -15,11 +15,17 @@ import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.action.FriendNudge
import net.mamoe.mirai.message.action.Nudge
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.message.data.isContentEmpty
import net.mamoe.mirai.message.recall
import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.OverFileSizeMaxException
import net.mamoe.mirai.utils.SinceMirai
import kotlin.jvm.JvmSynthetic
/**
@ -67,6 +73,15 @@ public abstract class User : Contact(), CoroutineScope {
@JvmSynthetic
public abstract override suspend fun sendMessage(message: Message): MessageReceipt<User>
/**
* 创建一个 "戳一戳" 消息
*
* @see FriendNudge.sendTo 发送这个戳一戳消息
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public abstract fun nudge(): Nudge
/**
* @see sendMessage
*/

View File

@ -14,7 +14,9 @@
package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.User
import net.mamoe.mirai.event.AbstractEvent
import net.mamoe.mirai.message.action.Nudge
import net.mamoe.mirai.qqandroid.network.Packet
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiInternalAPI
@ -124,6 +126,31 @@ public data class BotNickChangedEvent(
public val to: String
) : BotEvent, Packet, AbstractEvent()
/**
* [Bot] [][Nudge] 的事件.
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public data class BotNudgedEvent internal constructor(
/**
* 戳一戳的发起人 [Bot] 的某一好友, 或某一群员
*/
public val from: User,
/**
* 戳一戳的动作名称
*/
public val action: String,
/**
* 戳一戳中设置的自定义后缀
*/
public val suffix: String,
) : BotEvent, Packet, AbstractEvent() {
/**
* 戳一戳的目标
*/
public override val bot: Bot get() = from.bot
}
// region 图片
// endregion

View File

@ -112,33 +112,6 @@ public data class FriendAvatarChangedEvent internal constructor(
public override val friend: Friend
) : FriendEvent, Packet, AbstractEvent()
/**
* [Friend] 的戳一戳事件.
*/
@SinceMirai("1.3.0")
public data class FriendNudgeEvent internal constructor(
/**
* 发起戳一戳的好友会话此处使用 [Friend] 指定
*/
public override val friend: Friend,
/**
* 戳一戳的发起者可为 [Bot] 自身或好友
*/
public val from: Friend,
/**
* 戳一戳的动作
*/
public val action: String,
/**
* 戳一戳的目标可为 [Bot] 自身或好友
*/
public val target: Friend,
/**
* 戳一戳中设置的自定义后缀
*/
public val suffix: String
) : FriendEvent, Packet, AbstractEvent()
/**
* [Friend] 昵称改变事件, 在此事件广播时好友已经完成改名
* @see BotNickChangedEvent
@ -149,7 +122,7 @@ public data class FriendNickChangedEvent internal constructor(
public val from: String,
public val to: String
) : FriendEvent, Packet, AbstractEvent()
/**
* 好友输入状态改变的事件当开始输入文字退出聊天窗口或清空输入框时会触发此事件
*/

View File

@ -22,6 +22,7 @@ import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.AbstractEvent
import net.mamoe.mirai.event.BroadcastControllable
import net.mamoe.mirai.event.internal.MiraiAtomicBoolean
import net.mamoe.mirai.message.action.Nudge
import net.mamoe.mirai.qqandroid.network.Packet
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.SinceMirai
@ -131,6 +132,7 @@ public sealed class BotJoinGroupEvent : GroupEvent, BotPassiveEvent, Packet, Abs
return "BotJoinGroupEvent.Invite(invitor=$invitor)"
}
}
/**
* 原群主通过 https://huifu.qq.com/ 恢复原来群主身份并入群,
* [Bot] 是原群主
@ -511,27 +513,30 @@ public data class MemberUnmuteEvent internal constructor(
// endregion
// region 戳一戳
/**
* 群成员戳一戳事件.
*
* [Member] [][Nudge] 的事件.
*/
public data class MemberNudgeEvent internal constructor(
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public data class MemberNudgedEvent internal constructor(
/**
* 戳一戳的发起者如果对象是 [Bot] 则为 [Bot] [Member] 对象
* 戳一戳的发起人, 不可能是 bot
*/
public val from: Member,
/**
* 戳一戳的目标 (被戳的群员), 不可能是 bot
*/
public override val member: Member,
/**
* 戳一戳的动作
* 戳一戳的动作名称
*/
public val action: String,
/**
* 戳一戳的目标如果对象是 [Bot] 则为 [Bot] [Member] 对象
*/
public val target: Member,
/**
* 戳一戳中设置的自定义后缀
*/
public val suffix: String
public val suffix: String,
) : GroupMemberEvent, BotPassiveEvent, Packet, AbstractEvent()
// endregion

View File

@ -0,0 +1,117 @@
/*
*
* * Copyright 2020 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/master/LICENSE
*
*/
package net.mamoe.mirai.message.action
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.event.events.BotNudgedEvent
import net.mamoe.mirai.event.events.MemberNudgedEvent
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.SinceMirai
/**
* 一个 "戳一戳" 消息.
*
* 仅在手机 QQ 8.4.0 左右版本才受支持. 其他客户端会忽略这些消息.
*
* @see User.nudge 创建 [Nudge] 对象
* @see Bot.nudge 创建 [Nudge] 对象
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public sealed class Nudge {
/**
* 戳的对象. "A 戳了 B" 中的 "B".
*/
public abstract val target: ContactOrBot // User or Bot
/**
* 发送戳一戳该成员的消息.
*
* 需要 [使用协议][BotConfiguration.protocol] [MiraiProtocol.ANDROID_PHONE].
*
* @param receiver 这条 "戳一戳" 消息的接收对象. (不是 "" 动作的对象, 而是接收 "A 戳了 B" 这条消息的对象)
*
* @see MemberNudgedEvent 成员被戳事件
* @see BotNudgedEvent [Bot] 被戳事件
*
* @throws UnsupportedOperationException 当未使用 [安卓协议][MiraiProtocol.ANDROID_PHONE] 时抛出
*
* @return 成功发送时为 `true`. 若对方禁用 "戳一戳" 功能, 返回 `false`.
*/
@JvmBlockingBridge
@MiraiExperimentalAPI
public suspend fun sendTo(receiver: Contact): Boolean {
return receiver.bot.sendNudge(this, receiver)
}
public companion object {
/**
* 发送戳一戳该成员的消息.
*
* 需要 [使用协议][BotConfiguration.protocol] [MiraiProtocol.ANDROID_PHONE].
*
* @see MemberNudgedEvent 成员被戳事件
* @see BotNudgedEvent [Bot] 被戳事件
*
* @throws UnsupportedOperationException 当未使用 [安卓协议][MiraiProtocol.ANDROID_PHONE] 时抛出
*
* @return 成功发送时为 `true`. 若对方禁用 "戳一戳" 功能, 返回 `false`.
*/
@MiraiExperimentalAPI
@JvmBlockingBridge
public suspend fun Contact.sendNudge(nudge: Nudge): Boolean = nudge.sendTo(this)
}
}
/**
* @see Bot.nudge
* @see Nudge
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public data class BotNudge(
public override val target: Bot
) : Nudge()
/**
* @see User.nudge
* @see Nudge
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public sealed class UserNudge : Nudge() {
public abstract override val target: User
}
/**
* @see Member.nudge
* @see Nudge
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public data class MemberNudge(
public override val target: Member
) : UserNudge()
/**
* @see Friend.nudge
* @see Nudge
*/
@MiraiExperimentalAPI
@SinceMirai("1.3.0")
public data class FriendNudge(
public override val target: Friend
) : UserNudge()