mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: support upload resource by NtKernel
Signed-off-by: 白池 <whitechi73@outlook.com>
This commit is contained in:
parent
92ebe0c6a8
commit
fca66f3259
@ -6,7 +6,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public interface IKernelMsgService {
|
public interface IKernelMsgService {
|
||||||
void deleteMsg(Contact contact, ArrayList<Long> msgIdList, IOperateCallback callback);
|
void deleteMsg(Contact contact, ArrayList<Long> msgIdList, IOperateCallback cb);
|
||||||
|
|
||||||
void fetchLongMsg(Contact contact, long msgId);
|
void fetchLongMsg(Contact contact, long msgId);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import io.ktor.utils.io.core.writeFully
|
|||||||
import io.ktor.utils.io.core.writeInt
|
import io.ktor.utils.io.core.writeInt
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.msg.MessageTempHandler
|
||||||
|
|
||||||
import moe.fuqiuluo.shamrock.remote.action.handlers.GetHistoryMsg
|
import moe.fuqiuluo.shamrock.remote.action.handlers.GetHistoryMsg
|
||||||
import moe.fuqiuluo.shamrock.remote.service.listener.AioListener
|
import moe.fuqiuluo.shamrock.remote.service.listener.AioListener
|
||||||
@ -80,11 +81,11 @@ internal object PacketSvc: BaseSvc() {
|
|||||||
fakeReceive("trpc.msg.olpush.OlPushService.MsgPush", 10000, msgPush.toByteArray())
|
fakeReceive("trpc.msg.olpush.OlPushService.MsgPush", 10000, msgPush.toByteArray())
|
||||||
return withTimeoutOrNull(5000L) {
|
return withTimeoutOrNull(5000L) {
|
||||||
suspendCancellableCoroutine {
|
suspendCancellableCoroutine {
|
||||||
AioListener.registerTemporaryMsgListener(msgSeq) {
|
MessageTempHandler.registerTemporaryMsgListener(msgSeq) {
|
||||||
it.resume(this.msgId)
|
it.resume(this.msgId)
|
||||||
}
|
}
|
||||||
it.invokeOnCancellation {
|
it.invokeOnCancellation {
|
||||||
AioListener.unregisterTemporaryMsgListener(msgSeq)
|
MessageTempHandler.unregisterTemporaryMsgListener(msgSeq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: -1L
|
} ?: -1L
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
package moe.fuqiuluo.qqinterface.servlet.ark
|
package moe.fuqiuluo.qqinterface.servlet.ark
|
||||||
|
|
||||||
import com.tencent.mobileqq.pb.ByteStringMicro
|
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
|
||||||
import moe.fuqiuluo.qqinterface.servlet.BaseSvc
|
import moe.fuqiuluo.qqinterface.servlet.BaseSvc
|
||||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
import moe.fuqiuluo.qqinterface.servlet.ark.data.ArkAppInfo
|
||||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
|
||||||
import moe.fuqiuluo.shamrock.remote.service.listener.AioListener
|
|
||||||
import tencent.im.oidb.cmd0xb77.oidb_cmd0xb77
|
import tencent.im.oidb.cmd0xb77.oidb_cmd0xb77
|
||||||
import kotlin.coroutines.resume
|
|
||||||
import kotlin.time.Duration.Companion.seconds
|
|
||||||
|
|
||||||
internal object ArkMsgSvc: BaseSvc() {
|
internal object ArkMsgSvc: BaseSvc() {
|
||||||
fun tryShareMusic(
|
fun tryShareMusic(
|
@ -6,10 +6,10 @@ import io.ktor.client.request.url
|
|||||||
import io.ktor.client.statement.bodyAsText
|
import io.ktor.client.statement.bodyAsText
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.http.encodeURLQueryComponent
|
import io.ktor.http.encodeURLQueryComponent
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.ark.data.Region
|
||||||
import moe.fuqiuluo.shamrock.helper.Level
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.tools.*
|
import moe.fuqiuluo.shamrock.tools.*
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
package moe.fuqiuluo.qqinterface.servlet.ark
|
package moe.fuqiuluo.qqinterface.servlet.ark.data
|
||||||
|
|
||||||
sealed class ArkAppInfo(
|
sealed class ArkAppInfo(
|
||||||
val appId: Long,
|
val appId: Long,
|
||||||
val version: String,
|
val version: String,
|
@ -1,4 +1,4 @@
|
|||||||
package moe.fuqiuluo.qqinterface.servlet.ark
|
package moe.fuqiuluo.qqinterface.servlet.ark.data
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
@ -0,0 +1,34 @@
|
|||||||
|
package moe.fuqiuluo.qqinterface.servlet.msg
|
||||||
|
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||||
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
|
import java.util.Collections
|
||||||
|
|
||||||
|
internal object MessageTempHandler {
|
||||||
|
// 通过MSG SEQ临时监听器
|
||||||
|
private val tempMessageListenerMap = Collections.synchronizedMap(HashMap<Long, suspend MsgRecord.() -> Unit>())
|
||||||
|
|
||||||
|
fun registerTemporaryMsgListener(
|
||||||
|
msgSeq: Long,
|
||||||
|
listener: suspend MsgRecord.() -> Unit
|
||||||
|
) {
|
||||||
|
LogCenter.log({ "注册临时消息监听器: $msgSeq" }, Level.DEBUG)
|
||||||
|
tempMessageListenerMap[msgSeq] = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterTemporaryMsgListener(msgSeq: Long) {
|
||||||
|
tempMessageListenerMap.remove(msgSeq)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun notify(record: MsgRecord): Boolean {
|
||||||
|
tempMessageListenerMap.firstNotNullOfOrNull {
|
||||||
|
if (it.key == record.msgSeq) it else null
|
||||||
|
}?.let {
|
||||||
|
it.value(record)
|
||||||
|
tempMessageListenerMap.remove(it.key)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
@ -12,10 +12,10 @@ import moe.fuqiuluo.qqinterface.servlet.ark.WeatherSvc
|
|||||||
import moe.fuqiuluo.qqinterface.servlet.msg.toJson
|
import moe.fuqiuluo.qqinterface.servlet.msg.toJson
|
||||||
import moe.fuqiuluo.qqinterface.servlet.msg.toSegments
|
import moe.fuqiuluo.qqinterface.servlet.msg.toSegments
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.*
|
import moe.fuqiuluo.qqinterface.servlet.transfile.*
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.PictureResource
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.PictureResource
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Private
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Private
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Transfer
|
import moe.fuqiuluo.qqinterface.servlet.transfile.Transfer
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Troop
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Troop
|
||||||
import moe.fuqiuluo.shamrock.helper.*
|
import moe.fuqiuluo.shamrock.helper.*
|
||||||
import moe.fuqiuluo.shamrock.helper.ActionMsgException
|
import moe.fuqiuluo.shamrock.helper.ActionMsgException
|
||||||
import moe.fuqiuluo.shamrock.helper.Level
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
|
@ -3,7 +3,6 @@ package moe.fuqiuluo.qqinterface.servlet.msg.maker
|
|||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import androidx.exifinterface.media.ExifInterface
|
import androidx.exifinterface.media.ExifInterface
|
||||||
import com.tencent.mobileqq.app.QQAppInterface
|
import com.tencent.mobileqq.app.QQAppInterface
|
||||||
import com.tencent.mobileqq.data.MessageForPic
|
|
||||||
import com.tencent.mobileqq.emoticon.QQSysFaceUtil
|
import com.tencent.mobileqq.emoticon.QQSysFaceUtil
|
||||||
import com.tencent.mobileqq.pb.ByteStringMicro
|
import com.tencent.mobileqq.pb.ByteStringMicro
|
||||||
import com.tencent.mobileqq.qroute.QRoute
|
import com.tencent.mobileqq.qroute.QRoute
|
||||||
@ -17,17 +16,17 @@ import kotlinx.serialization.json.JsonPrimitive
|
|||||||
import moe.fuqiuluo.qqinterface.servlet.CardSvc
|
import moe.fuqiuluo.qqinterface.servlet.CardSvc
|
||||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
|
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
|
||||||
import moe.fuqiuluo.qqinterface.servlet.LbsSvc
|
import moe.fuqiuluo.qqinterface.servlet.LbsSvc
|
||||||
import moe.fuqiuluo.qqinterface.servlet.ark.ArkAppInfo
|
import moe.fuqiuluo.qqinterface.servlet.ark.data.ArkAppInfo
|
||||||
import moe.fuqiuluo.qqinterface.servlet.ark.ArkMsgSvc
|
import moe.fuqiuluo.qqinterface.servlet.ark.ArkMsgSvc
|
||||||
import moe.fuqiuluo.qqinterface.servlet.ark.WeatherSvc
|
import moe.fuqiuluo.qqinterface.servlet.ark.WeatherSvc
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.*
|
import moe.fuqiuluo.qqinterface.servlet.transfile.*
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.FileTransfer
|
import moe.fuqiuluo.qqinterface.servlet.transfile.FileTransfer
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.PictureResource
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.PictureResource
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Private
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Private
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Transfer
|
import moe.fuqiuluo.qqinterface.servlet.transfile.Transfer
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.Troop
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Troop
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.VideoResource
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.VideoResource
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.VoiceResource
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.VoiceResource
|
||||||
import moe.fuqiuluo.shamrock.helper.ActionMsgException
|
import moe.fuqiuluo.shamrock.helper.ActionMsgException
|
||||||
import moe.fuqiuluo.shamrock.helper.ContactHelper
|
import moe.fuqiuluo.shamrock.helper.ContactHelper
|
||||||
import moe.fuqiuluo.shamrock.helper.IllegalParamsException
|
import moe.fuqiuluo.shamrock.helper.IllegalParamsException
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package moe.fuqiuluo.qqinterface.servlet.structures
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class UploadResult(
|
||||||
|
@SerialName("files") val files: List<CommFileInfo>
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CommFileInfo(
|
||||||
|
@SerialName("mode_id") val modeId: Long,
|
||||||
|
@SerialName("name") val fileName: String,
|
||||||
|
@SerialName("size") val fileSize: Long,
|
||||||
|
@SerialName("md5") val md5: String,
|
||||||
|
@SerialName("uuid") val uuid: String,
|
||||||
|
@SerialName("sub_id") val subId: String,
|
||||||
|
)
|
@ -1,14 +1,29 @@
|
|||||||
package moe.fuqiuluo.qqinterface.servlet.transfile
|
package moe.fuqiuluo.qqinterface.servlet.transfile
|
||||||
|
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import androidx.exifinterface.media.ExifInterface
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.CommonFileInfo
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.IOperateCallback
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.PicElement
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.QQNTWrapperUtil
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.RichMediaFilePathInfo
|
||||||
import kotlinx.atomicfu.atomic
|
import kotlinx.atomicfu.atomic
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import kotlinx.serialization.protobuf.ProtoNumber
|
|
||||||
import moe.fuqiuluo.qqinterface.servlet.BaseSvc
|
import moe.fuqiuluo.qqinterface.servlet.BaseSvc
|
||||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.TryUpPicData
|
||||||
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
|
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||||
import moe.fuqiuluo.shamrock.tools.hex2ByteArray
|
import moe.fuqiuluo.shamrock.tools.hex2ByteArray
|
||||||
import moe.fuqiuluo.shamrock.tools.slice
|
import moe.fuqiuluo.shamrock.tools.slice
|
||||||
|
import moe.fuqiuluo.shamrock.utils.FileUtils
|
||||||
|
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
|
||||||
|
import moe.fuqiuluo.shamrock.xposed.helper.msgService
|
||||||
import moe.fuqiuluo.symbols.decodeProtobuf
|
import moe.fuqiuluo.symbols.decodeProtobuf
|
||||||
import protobuf.auto.toByteArray
|
import protobuf.auto.toByteArray
|
||||||
import protobuf.oidb.TrpcOidb
|
import protobuf.oidb.TrpcOidb
|
||||||
@ -31,13 +46,115 @@ import protobuf.oidb.cmd0x388.Cmd0x388ReqBody
|
|||||||
import protobuf.oidb.cmd0x388.Cmd0x388RspBody
|
import protobuf.oidb.cmd0x388.Cmd0x388RspBody
|
||||||
import protobuf.oidb.cmd0x388.TryUpImgReq
|
import protobuf.oidb.cmd0x388.TryUpImgReq
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import kotlin.coroutines.resume
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.nextUInt
|
import kotlin.random.nextUInt
|
||||||
import kotlin.random.nextULong
|
import kotlin.random.nextULong
|
||||||
|
import kotlin.time.Duration
|
||||||
|
|
||||||
internal object NtV2RichMediaSvc: BaseSvc() {
|
internal object NtV2RichMediaSvc: BaseSvc() {
|
||||||
|
private const val GROUP_PIC_UPLOAD_TO = "100000000"
|
||||||
|
|
||||||
private val requestIdSeq = atomic(2L)
|
private val requestIdSeq = atomic(2L)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量上传图片
|
||||||
|
*/
|
||||||
|
suspend fun tryUploadGroupPicByNt(
|
||||||
|
imageFiles: ArrayList<File>,
|
||||||
|
timeout: Duration
|
||||||
|
): Result<MutableList<CommonFileInfo>> {
|
||||||
|
require(imageFiles.size in 1 .. 10) { "imageFiles.size() must be in 1 .. 10" }
|
||||||
|
|
||||||
|
val messages = imageFiles.map { file ->
|
||||||
|
val elem = MsgElement()
|
||||||
|
runCatching {
|
||||||
|
elem.elementType = MsgConstant.KELEMTYPEPIC
|
||||||
|
val pic = PicElement()
|
||||||
|
pic.md5HexStr = QQNTWrapperUtil.CppProxy.genFileMd5Hex(file.absolutePath)
|
||||||
|
val msgService = NTServiceFetcher.kernelService.msgService!!
|
||||||
|
val originalPath = msgService.getRichMediaFilePathForMobileQQSend(
|
||||||
|
RichMediaFilePathInfo(
|
||||||
|
2, 0, pic.md5HexStr, file.name, 1, 0, null, "", true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (!QQNTWrapperUtil.CppProxy.fileIsExist(originalPath) || QQNTWrapperUtil.CppProxy.getFileSize(
|
||||||
|
originalPath
|
||||||
|
) != file.length()
|
||||||
|
) {
|
||||||
|
val thumbPath = msgService.getRichMediaFilePathForMobileQQSend(
|
||||||
|
RichMediaFilePathInfo(
|
||||||
|
2, 0, pic.md5HexStr, file.name, 2, 720, null, "", true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
QQNTWrapperUtil.CppProxy.copyFile(file.absolutePath, originalPath)
|
||||||
|
QQNTWrapperUtil.CppProxy.copyFile(file.absolutePath, thumbPath)
|
||||||
|
}
|
||||||
|
val options = BitmapFactory.Options()
|
||||||
|
options.inJustDecodeBounds = true
|
||||||
|
BitmapFactory.decodeFile(file.absolutePath, options)
|
||||||
|
val exifInterface = ExifInterface(file.absolutePath)
|
||||||
|
val orientation = exifInterface.getAttributeInt(
|
||||||
|
ExifInterface.TAG_ORIENTATION,
|
||||||
|
ExifInterface.ORIENTATION_UNDEFINED
|
||||||
|
)
|
||||||
|
if (orientation != ExifInterface.ORIENTATION_ROTATE_90 && orientation != ExifInterface.ORIENTATION_ROTATE_270) {
|
||||||
|
pic.picWidth = options.outWidth
|
||||||
|
pic.picHeight = options.outHeight
|
||||||
|
} else {
|
||||||
|
pic.picWidth = options.outHeight
|
||||||
|
pic.picHeight = options.outWidth
|
||||||
|
}
|
||||||
|
pic.sourcePath = file.absolutePath
|
||||||
|
pic.fileSize = QQNTWrapperUtil.CppProxy.getFileSize(file.absolutePath)
|
||||||
|
pic.original = true
|
||||||
|
pic.picType = FileUtils.getPicType(file)
|
||||||
|
elem.picElement = pic
|
||||||
|
}.onFailure {
|
||||||
|
LogCenter.log(it.stackTraceToString(), Level.WARN)
|
||||||
|
elem.elementType = 0
|
||||||
|
}
|
||||||
|
return@map elem
|
||||||
|
}.filter {
|
||||||
|
it.elementType == MsgConstant.KELEMTYPEPIC
|
||||||
|
}
|
||||||
|
if (messages.isEmpty()) {
|
||||||
|
return Result.failure(Exception("no valid image files"))
|
||||||
|
}
|
||||||
|
val result: MutableList<CommonFileInfo> = withTimeoutOrNull(timeout) {
|
||||||
|
suspendCancellableCoroutine {
|
||||||
|
val result = mutableListOf<CommonFileInfo>()
|
||||||
|
val uniseq = MessageHelper.generateMsgId(MsgConstant.KCHATTYPEGROUP)
|
||||||
|
val contact = Contact(MsgConstant.KCHATTYPEGROUP, GROUP_PIC_UPLOAD_TO, GROUP_PIC_UPLOAD_TO)
|
||||||
|
RichMediaUploadHandler.registerListener(uniseq.qqMsgId) upload@{
|
||||||
|
if (uniseq.qqMsgId == msgId) {
|
||||||
|
result.add(commonFileInfo)
|
||||||
|
}
|
||||||
|
return@upload false
|
||||||
|
}
|
||||||
|
MessageHelper.sendMessageWithMsgId(
|
||||||
|
contact = contact,
|
||||||
|
message = ArrayList(messages),
|
||||||
|
uniseq = uniseq.qqMsgId
|
||||||
|
) { code, _ ->
|
||||||
|
NTServiceFetcher.kernelService
|
||||||
|
.wrapperSession.msgService
|
||||||
|
.deleteMsg(contact, arrayListOf(uniseq.qqMsgId), null)
|
||||||
|
RichMediaUploadHandler.removeListener(uniseq.qqMsgId)
|
||||||
|
if (code != 110 && code != 4) {
|
||||||
|
it.resume(null)
|
||||||
|
} else {
|
||||||
|
it.resume(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it.invokeOnCancellation {
|
||||||
|
RichMediaUploadHandler.removeListener(uniseq.qqMsgId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: return Result.failure(Exception("timeout"))
|
||||||
|
return Result.success(result)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取NT图片的RKEY
|
* 获取NT图片的RKEY
|
||||||
*/
|
*/
|
||||||
@ -173,6 +290,9 @@ internal object NtV2RichMediaSvc: BaseSvc() {
|
|||||||
LogCenter.log("requestUploadPic => rsp: $rsp")
|
LogCenter.log("requestUploadPic => rsp: $rsp")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用OldBDH获取图片上传状态以及图片上传服务器
|
||||||
|
*/
|
||||||
suspend fun requestUploadGroupPic(
|
suspend fun requestUploadGroupPic(
|
||||||
groupId: ULong,
|
groupId: ULong,
|
||||||
md5: String,
|
md5: String,
|
||||||
@ -215,13 +335,5 @@ internal object NtV2RichMediaSvc: BaseSvc() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class TryUpPicData(
|
|
||||||
@SerialName("ukey") val uKey: ByteArray,
|
|
||||||
@SerialName("exist") val exist: Boolean,
|
|
||||||
@SerialName("file_id") val fileId: ULong,
|
|
||||||
@SerialName("up_ip") var upIp: ArrayList<Long>? = null,
|
|
||||||
@SerialName("up_port") var upPort: ArrayList<Int>? = null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package moe.fuqiuluo.shamrock.remote.service.api
|
package moe.fuqiuluo.qqinterface.servlet.transfile
|
||||||
|
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo
|
import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo
|
||||||
|
|
@ -1,14 +1,19 @@
|
|||||||
package moe.fuqiuluo.qqinterface.servlet.transfile
|
package moe.fuqiuluo.qqinterface.servlet.transfile
|
||||||
|
|
||||||
import com.tencent.mobileqq.data.MessageForPic
|
|
||||||
import com.tencent.mobileqq.data.MessageForShortVideo
|
import com.tencent.mobileqq.data.MessageForShortVideo
|
||||||
import com.tencent.mobileqq.data.MessageRecord
|
import com.tencent.mobileqq.data.MessageRecord
|
||||||
import com.tencent.mobileqq.transfile.FileMsg
|
import com.tencent.mobileqq.transfile.FileMsg
|
||||||
import com.tencent.mobileqq.transfile.TransferRequest
|
import com.tencent.mobileqq.transfile.TransferRequest
|
||||||
import moe.fuqiuluo.shamrock.utils.MD5
|
import moe.fuqiuluo.shamrock.utils.MD5
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.ResourceType.*
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.ResourceType.*
|
||||||
import moe.fuqiuluo.shamrock.helper.TransfileHelper
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.ContactType
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.PictureResource
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Resource
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.ResourceType
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.TransTarget
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.VideoResource
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.transfile.data.VoiceResource
|
||||||
|
|
||||||
internal object Transfer: FileTransfer() {
|
internal object Transfer: FileTransfer() {
|
||||||
private val ROUTE = mapOf<ContactType, Map<ResourceType, suspend TransTarget.(Resource) -> Boolean>>(
|
private val ROUTE = mapOf<ContactType, Map<ResourceType, suspend TransTarget.(Resource) -> Boolean>>(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package moe.fuqiuluo.qqinterface.servlet.transfile
|
package moe.fuqiuluo.qqinterface.servlet.transfile.data
|
||||||
|
|
||||||
import com.tencent.mobileqq.data.MessageRecord
|
import com.tencent.mobileqq.data.MessageRecord
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package moe.fuqiuluo.qqinterface.servlet.transfile
|
package moe.fuqiuluo.qqinterface.servlet.transfile.data
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
package moe.fuqiuluo.qqinterface.servlet.transfile.data
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class TryUpPicData(
|
||||||
|
@SerialName("ukey") val uKey: ByteArray,
|
||||||
|
@SerialName("exist") val exist: Boolean,
|
||||||
|
@SerialName("file_id") val fileId: ULong,
|
||||||
|
@SerialName("up_ip") var upIp: ArrayList<Long>? = null,
|
||||||
|
@SerialName("up_port") var upPort: ArrayList<Int>? = null,
|
||||||
|
)
|
@ -205,27 +205,24 @@ internal object MessageHelper {
|
|||||||
fun sendMessageWithMsgId(
|
fun sendMessageWithMsgId(
|
||||||
contact: Contact,
|
contact: Contact,
|
||||||
message: ArrayList<MsgElement>,
|
message: ArrayList<MsgElement>,
|
||||||
|
uniseq: Long,
|
||||||
callback: IOperateCallback
|
callback: IOperateCallback
|
||||||
): SendMsgResult {
|
): SendMsgResult {
|
||||||
val uniseq = generateMsgId(contact.chatType)
|
|
||||||
val nonMsg: Boolean = message.isEmpty()
|
val nonMsg: Boolean = message.isEmpty()
|
||||||
return if (!nonMsg) {
|
if (!nonMsg) {
|
||||||
val service = QRoute.api(IMsgService::class.java)
|
val service = QRoute.api(IMsgService::class.java)
|
||||||
if (callback is MsgSvc.MessageCallback) {
|
|
||||||
callback.msgHash = uniseq.msgHashId
|
|
||||||
}
|
|
||||||
|
|
||||||
service.sendMsg(
|
service.sendMsg(
|
||||||
contact,
|
contact,
|
||||||
uniseq.qqMsgId,
|
uniseq,
|
||||||
message,
|
message,
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
|
|
||||||
uniseq.copy(msgTime = System.currentTimeMillis())
|
|
||||||
} else {
|
|
||||||
uniseq.copy(msgTime = 0, msgHashId = 0)
|
|
||||||
}
|
}
|
||||||
|
return SendMsgResult(
|
||||||
|
msgTime = if (nonMsg) 0 else System.currentTimeMillis(),
|
||||||
|
msgHashId = 0,
|
||||||
|
qqMsgId = uniseq
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun sendMessageNoCb(
|
suspend fun sendMessageNoCb(
|
||||||
|
@ -3,7 +3,7 @@ package moe.fuqiuluo.shamrock.helper
|
|||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.get
|
||||||
import io.ktor.client.statement.bodyAsText
|
import io.ktor.client.statement.bodyAsText
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import moe.fuqiuluo.qqinterface.servlet.ark.ArkAppInfo
|
import moe.fuqiuluo.qqinterface.servlet.ark.data.ArkAppInfo
|
||||||
import moe.fuqiuluo.qqinterface.servlet.ark.ArkMsgSvc
|
import moe.fuqiuluo.qqinterface.servlet.ark.ArkMsgSvc
|
||||||
import moe.fuqiuluo.shamrock.tools.GlobalClient
|
import moe.fuqiuluo.shamrock.tools.GlobalClient
|
||||||
import moe.fuqiuluo.shamrock.tools.asInt
|
import moe.fuqiuluo.shamrock.tools.asInt
|
||||||
|
@ -24,8 +24,7 @@ internal object SendMsgByResid : IActionHandler() {
|
|||||||
val resId = session.getString("res_id")
|
val resId = session.getString("res_id")
|
||||||
val peerId = session.getString("peer_id")
|
val peerId = session.getString("peer_id")
|
||||||
val messageType = session.getString("message_type")
|
val messageType = session.getString("message_type")
|
||||||
invoke(resId, peerId, messageType)
|
return invoke(peerId, resId, messageType, session.echo)
|
||||||
return ok("ok", session.echo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend operator fun invoke(peerId: String, resId: String, messageType: String, echo: JsonElement = EmptyJsonString): String {
|
suspend operator fun invoke(peerId: String, resId: String, messageType: String, echo: JsonElement = EmptyJsonString): String {
|
||||||
@ -55,4 +54,6 @@ internal object SendMsgByResid : IActionHandler() {
|
|||||||
BaseSvc.sendBufferAW("MessageSvc.PbSendMsg", true, req.toByteArray())
|
BaseSvc.sendBufferAW("MessageSvc.PbSendMsg", true, req.toByteArray())
|
||||||
return ok("ok", echo)
|
return ok("ok", echo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val requiredParams: Array<String> = arrayOf("res_id", "peer_id", "message_type")
|
||||||
}
|
}
|
@ -1,15 +1,18 @@
|
|||||||
package moe.fuqiuluo.shamrock.remote.action.handlers
|
package moe.fuqiuluo.shamrock.remote.action.handlers
|
||||||
|
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||||
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
||||||
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
||||||
import moe.fuqiuluo.shamrock.tools.jsonArray
|
import moe.fuqiuluo.shamrock.tools.jsonArray
|
||||||
import moe.fuqiuluo.symbols.OneBotHandler
|
import moe.fuqiuluo.symbols.OneBotHandler
|
||||||
|
|
||||||
@OneBotHandler("send_private_msg", ["send_private_message"])
|
@OneBotHandler("send_private_msg", ["send_private_message", "send_friend_msg"])
|
||||||
internal object SendPrivateMessage : IActionHandler() {
|
internal object SendPrivateMessage : IActionHandler() {
|
||||||
override suspend fun internalHandle(session: ActionSession): String {
|
override suspend fun internalHandle(session: ActionSession): String {
|
||||||
val userId = session.getLong("user_id")
|
val userId = session.getString("user_id").let {
|
||||||
|
if (it == "self") TicketSvc.getUin() else it
|
||||||
|
}
|
||||||
val groupId = session.getLongOrNull("group_id")
|
val groupId = session.getLongOrNull("group_id")
|
||||||
val chatType = if (groupId == null) MsgConstant.KCHATTYPEC2C else MsgConstant.KCHATTYPETEMPC2CFROMGROUP
|
val chatType = if (groupId == null) MsgConstant.KCHATTYPEC2C else MsgConstant.KCHATTYPETEMPC2CFROMGROUP
|
||||||
val retryCnt = session.getIntOrNull("retry_cnt")
|
val retryCnt = session.getIntOrNull("retry_cnt")
|
||||||
@ -19,21 +22,21 @@ internal object SendPrivateMessage : IActionHandler() {
|
|||||||
val message = session.getString("message")
|
val message = session.getString("message")
|
||||||
SendMessage(
|
SendMessage(
|
||||||
chatType = chatType,
|
chatType = chatType,
|
||||||
peerId = userId.toString(),
|
peerId = userId,
|
||||||
message = message,
|
message = message,
|
||||||
autoEscape = autoEscape,
|
autoEscape = autoEscape,
|
||||||
echo = session.echo,
|
echo = session.echo,
|
||||||
fromId = groupId?.toString() ?: userId.toString(),
|
fromId = groupId?.toString() ?: userId,
|
||||||
retryCnt = retryCnt ?: 5,
|
retryCnt = retryCnt ?: 5,
|
||||||
recallDuration = recallDuration
|
recallDuration = recallDuration
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
SendMessage(
|
SendMessage(
|
||||||
chatType = chatType,
|
chatType = chatType,
|
||||||
peerId = userId.toString(),
|
peerId = userId,
|
||||||
message = if (session.isArray("message")) session.getArray("message") else listOf(session.getObject("message")).jsonArray,
|
message = if (session.isArray("message")) session.getArray("message") else listOf(session.getObject("message")).jsonArray,
|
||||||
echo = session.echo,
|
echo = session.echo,
|
||||||
fromId = groupId?.toString() ?: userId.toString(),
|
fromId = groupId?.toString() ?: userId,
|
||||||
retryCnt = retryCnt ?: 5,
|
retryCnt = retryCnt ?: 5,
|
||||||
recallDuration = recallDuration
|
recallDuration = recallDuration
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,7 @@ import moe.fuqiuluo.shamrock.helper.MessageHelper
|
|||||||
import moe.fuqiuluo.shamrock.helper.TransfileHelper
|
import moe.fuqiuluo.shamrock.helper.TransfileHelper
|
||||||
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
||||||
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
||||||
import moe.fuqiuluo.shamrock.remote.service.api.RichMediaUploadHandler
|
import moe.fuqiuluo.qqinterface.servlet.transfile.RichMediaUploadHandler
|
||||||
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
|
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
|
||||||
import moe.fuqiuluo.shamrock.utils.FileUtils
|
import moe.fuqiuluo.shamrock.utils.FileUtils
|
||||||
import moe.fuqiuluo.shamrock.utils.MD5
|
import moe.fuqiuluo.shamrock.utils.MD5
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
package moe.fuqiuluo.shamrock.remote.action.handlers
|
||||||
|
|
||||||
|
import kotlinx.serialization.json.JsonElement
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.structures.CommFileInfo
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.structures.UploadResult
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.transfile.NtV2RichMediaSvc
|
||||||
|
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
||||||
|
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
||||||
|
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
||||||
|
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
|
||||||
|
import moe.fuqiuluo.shamrock.utils.FileUtils
|
||||||
|
import moe.fuqiuluo.symbols.OneBotHandler
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
@OneBotHandler("upload_group_image", ["upload_group_pic"])
|
||||||
|
internal object UploadGroupPic: IActionHandler() {
|
||||||
|
override suspend fun internalHandle(session: ActionSession): String {
|
||||||
|
val pic = session.getString("file")
|
||||||
|
return invoke(pic, session.echo)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend operator fun invoke(
|
||||||
|
picture: String,
|
||||||
|
echo: JsonElement = EmptyJsonString
|
||||||
|
): String {
|
||||||
|
if (ShamrockConfig.isDev()) {
|
||||||
|
val file = picture.let {
|
||||||
|
val md5 = it.replace(
|
||||||
|
regex = "[{}\\-]".toRegex(),
|
||||||
|
replacement = ""
|
||||||
|
).split(".")[0].lowercase()
|
||||||
|
if (md5.length == 32) {
|
||||||
|
FileUtils.getFileByMd5(it)
|
||||||
|
} else {
|
||||||
|
FileUtils.parseAndSave(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!file.exists()) {
|
||||||
|
return logic("picture file is not exists", echo)
|
||||||
|
}
|
||||||
|
NtV2RichMediaSvc.tryUploadGroupPicByNt(
|
||||||
|
imageFiles = arrayListOf(file),
|
||||||
|
timeout = 30.seconds
|
||||||
|
).onSuccess {
|
||||||
|
return ok(UploadResult(it.map {
|
||||||
|
CommFileInfo(
|
||||||
|
modeId = it.fileModelId,
|
||||||
|
fileName = it.fileName,
|
||||||
|
fileSize = it.fileSize,
|
||||||
|
md5 = it.md5,
|
||||||
|
uuid = it.uuid,
|
||||||
|
subId = it.subId
|
||||||
|
)
|
||||||
|
}), echo)
|
||||||
|
}.onFailure {
|
||||||
|
return logic("upload failed: ${it.message ?: it.toString()}", echo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return logic("upload failed", echo)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val requiredParams: Array<String> = arrayOf("file")
|
||||||
|
}
|
@ -14,16 +14,13 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import kotlinx.serialization.SerialName
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import moe.fuqiuluo.shamrock.helper.ContactHelper
|
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||||
import moe.fuqiuluo.shamrock.helper.TransfileHelper
|
import moe.fuqiuluo.shamrock.helper.TransfileHelper
|
||||||
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
||||||
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
||||||
import moe.fuqiuluo.shamrock.remote.service.api.RichMediaUploadHandler
|
import moe.fuqiuluo.qqinterface.servlet.transfile.RichMediaUploadHandler
|
||||||
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
|
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
|
||||||
import moe.fuqiuluo.shamrock.utils.FileUtils
|
import moe.fuqiuluo.shamrock.utils.FileUtils
|
||||||
import moe.fuqiuluo.shamrock.utils.MD5
|
import moe.fuqiuluo.shamrock.utils.MD5
|
||||||
|
@ -9,6 +9,7 @@ import kotlinx.coroutines.GlobalScope
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
||||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||||
|
import moe.fuqiuluo.qqinterface.servlet.msg.MessageTempHandler
|
||||||
import moe.fuqiuluo.qqinterface.servlet.msg.toCQCode
|
import moe.fuqiuluo.qqinterface.servlet.msg.toCQCode
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
||||||
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
||||||
@ -16,7 +17,7 @@ import moe.fuqiuluo.shamrock.helper.Level
|
|||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.helper.db.MessageDB
|
import moe.fuqiuluo.shamrock.helper.db.MessageDB
|
||||||
import moe.fuqiuluo.shamrock.remote.service.api.GlobalEventTransmitter
|
import moe.fuqiuluo.shamrock.remote.service.api.GlobalEventTransmitter
|
||||||
import moe.fuqiuluo.shamrock.remote.service.api.RichMediaUploadHandler
|
import moe.fuqiuluo.qqinterface.servlet.transfile.RichMediaUploadHandler
|
||||||
import moe.fuqiuluo.shamrock.remote.service.data.push.MessageTempSource
|
import moe.fuqiuluo.shamrock.remote.service.data.push.MessageTempSource
|
||||||
import moe.fuqiuluo.shamrock.remote.service.data.push.PostType
|
import moe.fuqiuluo.shamrock.remote.service.data.push.PostType
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
@ -24,9 +25,6 @@ import java.util.Collections
|
|||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
internal object AioListener : IKernelMsgListener {
|
internal object AioListener : IKernelMsgListener {
|
||||||
// 通过MSG SEQ临时监听器
|
|
||||||
private val tempMessageListenerMap = Collections.synchronizedMap(HashMap<Long, suspend MsgRecord.() -> Unit>())
|
|
||||||
|
|
||||||
override fun onRecvMsg(msgList: ArrayList<MsgRecord>) {
|
override fun onRecvMsg(msgList: ArrayList<MsgRecord>) {
|
||||||
if (msgList.isEmpty()) return
|
if (msgList.isEmpty()) return
|
||||||
|
|
||||||
@ -37,27 +35,9 @@ internal object AioListener : IKernelMsgListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerTemporaryMsgListener(
|
|
||||||
msgSeq: Long,
|
|
||||||
listener: suspend MsgRecord.() -> Unit
|
|
||||||
) {
|
|
||||||
LogCenter.log({ "注册临时消息监听器: $msgSeq" }, Level.DEBUG)
|
|
||||||
tempMessageListenerMap[msgSeq] = listener
|
|
||||||
}
|
|
||||||
|
|
||||||
fun unregisterTemporaryMsgListener(msgSeq: Long) {
|
|
||||||
tempMessageListenerMap.remove(msgSeq)
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun handleMsg(record: MsgRecord) {
|
private suspend fun handleMsg(record: MsgRecord) {
|
||||||
try {
|
try {
|
||||||
tempMessageListenerMap.firstNotNullOfOrNull {
|
if (MessageTempHandler.notify(record)) return
|
||||||
if (it.key == record.msgSeq) it else null
|
|
||||||
}?.let {
|
|
||||||
it.value(record)
|
|
||||||
tempMessageListenerMap.remove(it.key)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (record.msgSeq < 0) return
|
if (record.msgSeq < 0) return
|
||||||
|
|
||||||
val msgHash = MessageHelper.generateMsgIdHash(record.chatType, record.msgId)
|
val msgHash = MessageHelper.generateMsgIdHash(record.chatType, record.msgId)
|
||||||
@ -432,7 +412,7 @@ internal object AioListener : IKernelMsgListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onRichMediaUploadComplete(notifyInfo: FileTransNotifyInfo) {
|
override fun onRichMediaUploadComplete(notifyInfo: FileTransNotifyInfo) {
|
||||||
LogCenter.log("onRichMediaUploadComplete($notifyInfo)", Level.DEBUG)
|
LogCenter.log("[BDH] 资源上传完成(${notifyInfo.trasferStatus}, ${notifyInfo.fileId}, ${notifyInfo.msgId}, ${notifyInfo.commonFileInfo})")
|
||||||
RichMediaUploadHandler.notify(notifyInfo)
|
RichMediaUploadHandler.notify(notifyInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user