Shamrock: feat: 精华消息

This commit is contained in:
ikechan8370 2023-11-20 18:36:46 +08:00
parent 46c83f5cb9
commit 16f77de5a6
6 changed files with 131 additions and 2 deletions

View File

@ -22,7 +22,10 @@ import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withTimeoutOrNull
import moe.fuqiuluo.proto.ProtoUtils
import moe.fuqiuluo.proto.asUtf8String
import moe.fuqiuluo.proto.protobufOf
import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
import moe.fuqiuluo.shamrock.tools.putBuf32Long
import moe.fuqiuluo.shamrock.tools.slice
@ -32,6 +35,7 @@ import mqq.app.MobileQQ
import tencent.im.oidb.cmd0x89a.oidb_0x89a
import tencent.im.oidb.cmd0x8a0.oidb_0x8a0
import tencent.im.oidb.cmd0x8fc.Oidb_0x8fc
import tencent.im.oidb.oidb_sso
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.nio.ByteBuffer
@ -139,6 +143,51 @@ internal object GroupSvc: BaseSvc() {
return true
}
suspend fun setEssenceMessage(groupId: Long, seq: Long, rand: Long): Pair<Boolean, String> {
val array = protobufOf(
1 to groupId,
2 to seq,
3 to rand
).toByteArray()
val buffer = sendOidbAW("OidbSvc.0xeac_1", 3756, 1, array)
val body = oidb_sso.OIDBSSOPkg()
if (buffer == null) {
return Pair(false, "unknown error")
}
body.mergeFrom(buffer.slice(4))
val result = ProtoUtils.decodeFromByteArray(body.bytes_bodybuffer.get().toByteArray())
return if (result.has(1)) {
LogCenter.log("设置群精华失败: ${result[1].asUtf8String}")
Pair(false, "设置群精华失败: ${result[1].asUtf8String}")
} else {
LogCenter.log("设置群精华 -> $groupId:$seq")
Pair(true, "ok")
}
}
suspend fun deleteEssenceMessage(groupId: Long, seq: Long, rand: Long): Pair<Boolean, String> {
val array = protobufOf(
1 to groupId,
2 to seq,
3 to rand
).toByteArray()
val buffer = sendOidbAW("OidbSvc.0xeac_2", 3756, 2, array)
val body = oidb_sso.OIDBSSOPkg()
if (buffer == null) {
return Pair(false, "unknown error")
}
body.mergeFrom(buffer.slice(4))
val result = ProtoUtils.decodeFromByteArray(body.bytes_bodybuffer.get().toByteArray())
return if (result.has(1)) {
LogCenter.log("移除群精华失败: ${result[1].asUtf8String}")
Pair(false, "移除群精华失败: ${result[1].asUtf8String}")
} else {
LogCenter.log("移除群精华 -> $groupId:$seq")
Pair(true, "ok")
}
}
fun setGroupAdmin(groupId: Long, userId: Long, enable: Boolean) {
val buffer = ByteBuffer.allocate(9)
buffer.putBuf32Long(groupId)

View File

@ -29,7 +29,7 @@ internal object ActionManager {
// GroupActions
ModifyTroopName, LeaveTroop, KickTroopMember, BanTroopMember, SetGroupWholeBan, SetGroupAdmin,
ModifyTroopMemberName, SetGroupUnique, GetTroopHonor, GroupPoke,
ModifyTroopMemberName, SetGroupUnique, GetTroopHonor, GroupPoke, SetEssenceMessage, DeleteEssenceMessage,
// MSG ACTIONS
SendMessage, DeleteMessage, GetMsg, GetForwardMsg, SendGroupForwardMsg, SendGroupMessage, SendPrivateMessage,

View File

@ -0,0 +1,34 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
internal object DeleteEssenceMessage: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val messageId = session.getInt("message_id")
return invoke(messageId, session.echo)
}
suspend operator fun invoke(messageId: Int, echo: JsonElement = EmptyJsonString): String {
val msg = MsgSvc.getMsg(messageId).onFailure {
return logic("Obtain msg failed, please check your msg_id.", echo)
}.getOrThrow()
val (success, tip) = GroupSvc.deleteEssenceMessage(
if (msg.chatType == MsgConstant.KCHATTYPEGROUP) msg.peerUin else 0,
msg.msgSeq,
msg.msgRandom
)
return if (success) {
ok("成功", echo)
} else {
logic(tip, echo)
}
}
override fun path(): String = "delete_essence_message"
}

View File

@ -22,7 +22,7 @@ internal object GetMsg: IActionHandler() {
val msg = MsgSvc.getMsg(msgHash).onFailure {
return logic("Obtain msg failed, please check your msg_id.", echo)
}.getOrThrow()
val seq = msg.clientSeq.toInt()
val seq = msg.msgSeq.toInt()
return ok(MessageDetail(
time = msg.msgTime.toInt(),
msgType = MessageHelper.obtainDetailTypeByMsgType(msg.chatType),

View File

@ -0,0 +1,35 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
internal object SetEssenceMessage: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val messageId = session.getInt("message_id")
return invoke(messageId, session.echo)
}
suspend operator fun invoke(messageId: Int, echo: JsonElement = EmptyJsonString): String {
val msg = MsgSvc.getMsg(messageId).onFailure {
return logic("Obtain msg failed, please check your msg_id.", echo)
}.getOrThrow()
val (success, tip) = GroupSvc.setEssenceMessage(
if (msg.chatType == MsgConstant.KCHATTYPEGROUP) msg.peerUin else 0,
msg.msgSeq,
msg.msgRandom
)
return if (success) {
ok("成功", echo)
} else {
logic(tip, echo)
}
}
override fun path(): String = "set_essence_message"
}

View File

@ -95,4 +95,15 @@ fun Routing.troopAction() {
val groupId = fetchOrThrow("group_id").toLong()
call.respondText(KickTroopMember(groupId, userId), ContentType.Application.Json)
}
getOrPost("/set_essence_msg") {
val messageId = fetchOrThrow("message_id").toInt()
call.respondText(SetEssenceMessage(messageId), ContentType.Application.Json)
}
getOrPost("/delete_essence_msg") {
val messageId = fetchOrThrow("message_id").toInt()
call.respondText(DeleteEssenceMessage(messageId), ContentType.Application.Json)
}
}