mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
110 lines
4.0 KiB
Kotlin
110 lines
4.0 KiB
Kotlin
package moe.fuqiuluo.qqinterface.servlet
|
|
|
|
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
|
import com.tencent.qqnt.kernel.nativeinterface.IKernelMsgService
|
|
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
|
import io.ktor.utils.io.core.BytePacketBuilder
|
|
import io.ktor.utils.io.core.readBytes
|
|
import io.ktor.utils.io.core.writeFully
|
|
import io.ktor.utils.io.core.writeInt
|
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
import kotlinx.coroutines.withTimeoutOrNull
|
|
|
|
import moe.fuqiuluo.shamrock.remote.action.handlers.GetHistoryMsg
|
|
import moe.fuqiuluo.shamrock.remote.service.listener.AioListener
|
|
import moe.fuqiuluo.shamrock.tools.broadcast
|
|
import moe.fuqiuluo.shamrock.utils.DeflateTools
|
|
import protobuf.message.element.LightAppElem
|
|
import protobuf.message.PushMsgBody
|
|
import protobuf.message.ContentHead
|
|
import protobuf.message.Elem
|
|
import protobuf.message.RichText
|
|
import protobuf.message.ResponseHead
|
|
import protobuf.message.MsgBody
|
|
import protobuf.push.MessagePush
|
|
import mqq.app.MobileQQ
|
|
import protobuf.auto.toByteArray
|
|
import kotlin.coroutines.resume
|
|
|
|
internal object PacketSvc: BaseSvc() {
|
|
/**
|
|
* 伪造收到Json卡片消息
|
|
*/
|
|
suspend fun fakeSelfRecvJsonMsg(msgService: IKernelMsgService, content: String): Long {
|
|
return fakeReceiveSelfMsg(msgService) {
|
|
listOf(
|
|
Elem(
|
|
lightApp = LightAppElem((byteArrayOf(1) + DeflateTools.compress(content.toByteArray())))
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
private suspend fun fakeReceiveSelfMsg(msgService: IKernelMsgService, builder: () -> List<Elem>): Long {
|
|
val latestMsg = withTimeoutOrNull(3000) {
|
|
suspendCancellableCoroutine {
|
|
msgService.getMsgs(Contact(MsgConstant.KCHATTYPEC2C, app.currentUid, ""), 0L, 1, true) { code, why, msgs ->
|
|
it.resume(GetHistoryMsg.GetMsgResult(code, why, msgs))
|
|
}
|
|
}
|
|
}?.data?.firstOrNull()
|
|
val msgSeq = (latestMsg?.msgSeq ?: 0) + 1
|
|
|
|
val msgPush = MessagePush(
|
|
msgBody = PushMsgBody(
|
|
msgHead = ResponseHead(
|
|
peer = app.longAccountUin,
|
|
peerUid = app.currentUid,
|
|
flag = 1001,
|
|
receiver = app.longAccountUin,
|
|
receiverUid = app.currentUid
|
|
),
|
|
contentHead = ContentHead(
|
|
msgType = 166,
|
|
msgSubType = 11,
|
|
msgSeq = msgSeq,
|
|
msgViaRandom = msgSeq,
|
|
msgTime = System.currentTimeMillis() / 1000,
|
|
u2 = 1,
|
|
sequence = msgSeq,
|
|
msgRandom = msgService.getMsgUniqueId(System.currentTimeMillis()),
|
|
u4 = msgSeq - 2,
|
|
u5 = msgSeq
|
|
),
|
|
body = MsgBody(RichText(
|
|
elements = builder()
|
|
))
|
|
)
|
|
)
|
|
|
|
fakeReceive("trpc.msg.olpush.OlPushService.MsgPush", 10000, msgPush.toByteArray())
|
|
return withTimeoutOrNull(5000L) {
|
|
suspendCancellableCoroutine {
|
|
AioListener.registerTemporaryMsgListener(msgSeq) {
|
|
it.resume(this.msgId)
|
|
}
|
|
it.invokeOnCancellation {
|
|
AioListener.unregisterTemporaryMsgListener(msgSeq)
|
|
}
|
|
}
|
|
} ?: -1L
|
|
}
|
|
|
|
/**
|
|
* 伪造QQ收到某个包
|
|
*/
|
|
private fun fakeReceive(cmd: String, seq: Int, buffer: ByteArray) {
|
|
MobileQQ.getContext().broadcast("msf") {
|
|
putExtra("__cmd", "fake_packet")
|
|
putExtra("package_cmd", cmd)
|
|
putExtra("package_uin", app.currentUin)
|
|
putExtra("package_seq", seq)
|
|
val wupBuffer = BytePacketBuilder().apply {
|
|
writeInt(buffer.size + 4)
|
|
writeFully(buffer)
|
|
}.build()
|
|
putExtra("package_buffer", wupBuffer.readBytes())
|
|
wupBuffer.release()
|
|
}
|
|
}
|
|
} |