Skip to content
This repository has been archived by the owner on Aug 12, 2024. It is now read-only.

Commit

Permalink
refactor send_forward_msg(暂时只支持收发文字消息)
Browse files Browse the repository at this point in the history
  • Loading branch information
Simplxss committed Feb 21, 2024
1 parent 75633f7 commit 8762966
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 97 deletions.
7 changes: 4 additions & 3 deletions protobuf/src/main/java/protobuf/message/MessageContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class MessageContent(
@ProtoNumber(1) val msgType: Int = Int.MIN_VALUE,
@ProtoNumber(2) val msgSubType: Int = Int.MIN_VALUE,
@ProtoNumber(2) val msgSubType: Int? = null,
@ProtoNumber(3) val u1: Int? = null,
@ProtoNumber(4) val msgViaRandom: Long = Long.MIN_VALUE,
@ProtoNumber(5) val msgSeq: Long = Long.MIN_VALUE,
@ProtoNumber(5) val msgSeq_: Long? = null,
@ProtoNumber(6) val msgTime: Long? = null,
@ProtoNumber(7) val u2: Int? = null,
@ProtoNumber(8) val u6: Int? = null,
@ProtoNumber(9) val u7: Int? = null,
@ProtoNumber(11) val u3: Long? = null,
@ProtoNumber(11) val msgSeq: Long? = null,
@ProtoNumber(12) val msgRandom: Long = Long.MIN_VALUE,
@ProtoNumber(14) val u4: Long? = null,
@ProtoNumber(15) val forwardHead: ForwardHead? = null,
Expand Down
2 changes: 1 addition & 1 deletion protobuf/src/main/java/protobuf/message/MessageElement.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ data class MessageElement(
@ProtoNumber(1) val text: TextElement? = null,
@ProtoNumber(2) val face: FaceElement? = null,
@ProtoNumber(51) val json: JsonElement? = null,
@ProtoNumber(53) val commElem: CommonElement? = null,
@ProtoNumber(53) val comm: CommonElement? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -299,14 +299,15 @@ internal object MsgSvc : BaseSvc() {
time = msg.content?.msgTime?.toInt() ?: 0,
msgType = MessageHelper.obtainDetailTypeByMsgType(chatType),
msgId = 0, // MessageHelper.generateMsgIdHash(chatType, msg.content!!.msgViaRandom), msgViaRandom 为空
realId = msg.content!!.msgSeq.toInt(),
realId = msg.content!!.msgSeq?.toInt() ?: 0,
sender = MessageSender(
msg.head?.peer ?: 0,
msg.head?.groupInfo?.memberCard?.ifEmpty { msg.head?.forward?.friendName } ?: "",
msg.head?.groupInfo?.memberCard?.ifEmpty { msg.head?.forward?.friendName }
?: msg.head?.forward?.friendName ?: "",
"unknown",
0,
msg.head?.peerUid ?: "u_",
msg.head?.peerUid?: "u_"
msg.head?.peerUid ?: "",
msg.head?.peerUid ?: ""
),
message = msg.body?.rich?.elements?.toSegments(chatType, msg.head?.peer.toString(), "0")
?.toListMap() ?: emptyList(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ internal object PacketSvc: BaseSvc() {
msgViaRandom = msgSeq,
msgTime = System.currentTimeMillis() / 1000,
u2 = 1,
u3 = msgSeq,
msgSeq_ = msgSeq,
msgRandom = msgService.getMsgUniqueId(System.currentTimeMillis()),
u4 = msgSeq - 2,
u5 = msgSeq
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import kotlinx.io.core.readUInt
import moe.fuqiuluo.qqinterface.servlet.msg.MessageSegment
import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.tools.asJsonObject
import moe.fuqiuluo.shamrock.tools.asString
import protobuf.message.MessageElement


Expand All @@ -23,6 +26,8 @@ internal suspend fun List<MessageElement>.toSegments(
2
} else if (msg.json != null) {
51
} else if (msg.comm != null) {
53
} else
throw UnsupportedOperationException("不支持的消息element类型:$msg")
val converter = MessageElementConverter[elementType]
Expand All @@ -45,13 +50,13 @@ internal typealias IMessageElementConverter = suspend (Int, String, String, Mess

internal object MessageElementConverter {
private val convertMap = hashMapOf(
1 to MessageElementConverter::convertTextElem,
1 to MessageElementConverter::convertTextElem,
// MsgConstant.KELEMTYPEFACE to MessageElementConverter::convertFaceElem,
// MsgConstant.KELEMTYPEPIC to MessageElementConverter::convertImageElem,
// MsgConstant.KELEMTYPEPTT to MessageElementConverter::convertVoiceElem,
// MsgConstant.KELEMTYPEVIDEO to MessageElementConverter::convertVideoElem,
// MsgConstant.KELEMTYPEMARKETFACE to MessageElementConverter::convertMarketFaceElem,
// MsgConstant.KELEMTYPEARKSTRUCT to MessageElementConverter::convertStructJsonElem,
51 to MessageElementConverter::convertStructJsonElem,
// MsgConstant.KELEMTYPEREPLY to MessageElementConverter::convertReplyElem,
// MsgConstant.KELEMTYPEGRAYTIP to MessageElementConverter::convertGrayTipsElem,
// MsgConstant.KELEMTYPEFILE to MessageElementConverter::convertFileElem,
Expand Down Expand Up @@ -328,71 +333,74 @@ internal object MessageElementConverter {
// }
// }
//
// /**
// * JSON消息转消息段
// */
// private suspend fun convertStructJsonElem(
// chatType: Int,
// peerId: String,
// subPeer: String,
// element: MessageElement
// ): MessageSegment {
// val data = element.arkElement.bytesData.asJsonObject
// return when (data["app"].asString) {
// "com.tencent.multimsg" -> {
// val info = data["meta"].asJsonObject["detail"].asJsonObject
// MessageSegment(
// type = "forward",
// data = mapOf(
// "id" to info["resid"].asString
// )
// )
// }
//
// "com.tencent.troopsharecard" -> {
// val info = data["meta"].asJsonObject["contact"].asJsonObject
// MessageSegment(
// type = "contact",
// data = hashMapOf(
// "type" to "group",
// "id" to info["jumpUrl"].asString.split("group_code=")[1]
// )
// )
// }
//
// "com.tencent.contact.lua" -> {
// val info = data["meta"].asJsonObject["contact"].asJsonObject
// MessageSegment(
// type = "contact",
// data = hashMapOf(
// "type" to "private",
// "id" to info["jumpUrl"].asString.split("uin=")[1]
// )
// )
// }
//
// "com.tencent.map" -> {
// val info = data["meta"].asJsonObject["Location.Search"].asJsonObject
// MessageSegment(
// type = "location",
// data = hashMapOf(
// "lat" to info["lat"].asString,
// "lon" to info["lng"].asString,
// "content" to info["address"].asString,
// "title" to info["name"].asString
// )
// )
// }
//
// else -> MessageSegment(
// type = "json",
// data = mapOf(
// "data" to element.arkElement.bytesData.asJsonObject.toString()
// )
// )
// }
// }
//
/**
* JSON消息转消息段
*/
private suspend fun convertStructJsonElem(
chatType: Int,
peerId: String,
subPeer: String,
element: MessageElement
): MessageSegment {
val data = element.json!!.data!!
val jsonStr =
(if (data[0].toInt() == 1) DeflateTools.uncompress(data.sliceArray(1 until data.size)) else data.sliceArray(1 until data.size)).toString()
val json = jsonStr.asJsonObject
return when (json["app"].asString) {
"com.tencent.multimsg" -> {
val info = json["meta"].asJsonObject["detail"].asJsonObject
MessageSegment(
type = "forward",
data = mapOf(
"id" to info["resid"].asString
)
)
}

"com.tencent.troopsharecard" -> {
val info = json["meta"].asJsonObject["contact"].asJsonObject
MessageSegment(
type = "contact",
data = hashMapOf(
"type" to "group",
"id" to info["jumpUrl"].asString.split("group_code=")[1]
)
)
}

"com.tencent.contact.lua" -> {
val info = json["meta"].asJsonObject["contact"].asJsonObject
MessageSegment(
type = "contact",
data = hashMapOf(
"type" to "private",
"id" to info["jumpUrl"].asString.split("uin=")[1]
)
)
}

"com.tencent.map" -> {
val info = json["meta"].asJsonObject["Location.Search"].asJsonObject
MessageSegment(
type = "location",
data = hashMapOf(
"lat" to info["lat"].asString,
"lon" to info["lng"].asString,
"content" to info["address"].asString,
"title" to info["name"].asString
)
)
}

else -> MessageSegment(
type = "json",
data = mapOf(
"data" to jsonStr
)
)
}
}

// /**
// * 回复消息转消息段
// */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package moe.fuqiuluo.qqinterface.servlet.msg.messageelement

import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import kotlinx.serialization.json.JsonObject
import moe.fuqiuluo.qqinterface.servlet.GProSvc
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
import moe.fuqiuluo.shamrock.helper.*
import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.helper.ParamsException
import moe.fuqiuluo.shamrock.tools.asInt
import moe.fuqiuluo.shamrock.tools.asString
import moe.fuqiuluo.shamrock.tools.*
import moe.fuqiuluo.shamrock.utils.DeflateTools
import protobuf.message.MessageElement
import protobuf.message.element.FaceElement
import protobuf.message.element.JsonElement
import protobuf.message.element.TextElement
import java.nio.ByteBuffer

internal typealias IMessageElementMaker = suspend (Int, Long, String, JsonObject) -> Result<MessageElement>

Expand All @@ -20,7 +26,7 @@ internal object MessageElementMaker {
// "image" to MessageElementMaker::createImageElem,
// "voice" to MessageElementMaker::createRecordElem,
// "record" to MessageElementMaker::createRecordElem,
// "at" to MessageElementMaker::createAtElem,
"at" to MessageElementMaker::createAtElem,
// "video" to MessageElementMaker::createVideoElem,
// "markdown" to MessageElementMaker::createMarkdownElem,
// "dice" to MessageElementMaker::createDiceElem,
Expand Down Expand Up @@ -71,6 +77,88 @@ internal object MessageElementMaker {
return Result.success(elem)
}

private suspend fun createAtElem(
chatType: Int,
msgId: Long,
peerId: String,
data: JsonObject
): Result<MessageElement> {
return if (chatType == MsgConstant.KCHATTYPEGROUP) {
data.checkAndThrow("qq")

val qq: Long
val type: Int
lateinit var display: String
when (val qqStr = data["qq"].asString) {
"0", "all" -> {
qq = 0
type = 1
display = "@全体成员"
}

"online" -> {
qq = 0
type = 64
display = "@在线成员"
}

else -> {
qq = qqStr.toLong()
type = 0
display =
"@" + (data["name"].asStringOrNull ?: GroupSvc.getTroopMemberInfoByUinV2(peerId, qqStr, true)
.onSuccess {
it.troopnick
.ifEmpty { it.friendnick }
.ifEmpty { qqStr }
}.onFailure {
LogCenter.log("无法获取群成员信息: $qqStr", Level.ERROR)
})
}
}

val attr6: ByteBuffer = ByteBuffer.allocate(6)
attr6.put(byteArrayOf(0, 1, 0, 0, 0))
attr6.putChar(display.length.toChar())
attr6.putChar(type.toChar())
attr6.putBuf32Long(qq)
attr6.put(byteArrayOf(0, 0))
val elem = MessageElement(
text = TextElement(text = display, attr6Buf = attr6.array())
)
Result.success(elem)
} else if (chatType == MsgConstant.KCHATTYPEGUILD) {
data.checkAndThrow("qq")

val qq: Long
val type: Int
lateinit var display: String
when (val qqStr = data["qq"].asString) {
"0", "all" -> {
type = 2
display = "@全体成员"
}

else -> {
qq = qqStr.toLong()
type = 2
display =
"@" + (data["name"].asStringOrNull ?: GProSvc.getUserGuildInfo(0UL, 0UL)
.onSuccess {
it.nickName.ifNullOrEmpty(qqStr)
}.onFailure {
LogCenter.log("无法获取频道组成员信息: $qqStr", Level.ERROR)
})
}
}

val elem = MessageElement(
text = TextElement(text = display, pbReserve = TextElement.Companion.TextResvAttr(atType = type))
)
Result.success(elem)
} else Result.failure(ActionMsgException)
}

private suspend fun createJsonElem(
chatType: Int,
msgId: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ internal object MsgElementConverter {
//MsgConstant.KELEMTYPEMULTIFORWARD to MsgElementConverter::convertXmlMultiMsgElem,
//MsgConstant.KELEMTYPESTRUCTLONGMSG to MsgElementConverter::convertXmlLongMsgElem,
MsgConstant.KELEMTYPEFACEBUBBLE to MsgElementConverter::convertBubbleFaceElem,
MsgConstant.KELEMTYPEINLINEKEYBOARD to MsgElementConverter::convertInlineKeyboardElem,
MsgConstant.KELEMTYPEINLINEKEYBOARD to MsgElementConverter::convertInlineKeyboardElem
)

operator fun get(type: Int): IMsgElementConverter? = convertMap[type]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -755,19 +755,19 @@ internal object MsgElementMaker {
at.atNtUid = "0"
}

"online" -> {
at.content = "@在线成员"
at.atType = MsgConstant.ATTYPEONLINE
at.atNtUid = "0"
}

"admin" -> {
at.content = "@管理员"
at.atRoleId = 1
at.atType = MsgConstant.ATTYPEROLE
at.atNtUid = "0"
}

"online" -> {
at.content = "@在线成员"
at.atType = MsgConstant.ATTYPEONLINE
at.atNtUid = "0"
}

else -> {
val name = data["name"].asStringOrNull
if (name == null) {
Expand Down
Loading

0 comments on commit 8762966

Please sign in to comment.