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

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
whitechi73 committed Feb 25, 2024
2 parents ea4cf06 + 1424efd commit 252a352
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 130 deletions.
21 changes: 18 additions & 3 deletions protobuf/src/main/java/protobuf/message/element/CustomFace.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,26 @@ data class CustomFace(
@ProtoNumber(32) var width400: UInt? = null,
@ProtoNumber(33) var height400: UInt? = null,
@ProtoNumber(34) var pbReserve: PbReserve? = null,
){
companion object{
) {
companion object {
@Serializable
data class PbReserve(
@ProtoNumber(1) var field1: Int? = null
@ProtoNumber(1) var field1: Int? = null,
@ProtoNumber(3) var field3: Int? = null,
@ProtoNumber(4) var field4: Int? = null,
@ProtoNumber(10) var field10: Int? = null,
@ProtoNumber(21) var field21: Object1? = null,
@ProtoNumber(31) var field31: String? = null
)

@Serializable
data class Object1(
@ProtoNumber(1) var field1: Int? = null,
@ProtoNumber(2) var field2: String? = null,
@ProtoNumber(3) var field3: Int? = null,
@ProtoNumber(4) var field4: Int? = null,
@ProtoNumber(5) var field5: Int? = null,
@ProtoNumber(7) var md5Str: String? = null
)
}
}
23 changes: 19 additions & 4 deletions protobuf/src/main/java/protobuf/message/element/NotOnlineImage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import kotlinx.serialization.protobuf.ProtoNumber

@Serializable
data class NotOnlineImage(
@ProtoNumber(1) val filePath: ByteArray? = null,
@ProtoNumber(1) val filePath: String? = null,
@ProtoNumber(2) val fileLen: UInt? = null,
@ProtoNumber(3) val downloadPath: ByteArray? = null,
@ProtoNumber(3) val downloadPath: String? = null,
@ProtoNumber(4) val oldVerSendFile: ByteArray? = null,
@ProtoNumber(5) val imgType: UInt? = null,
@ProtoNumber(6) val previewsImage: ByteArray? = null,
@ProtoNumber(7) val picMd5: ByteArray? = null,
@ProtoNumber(8) val picHeight: UInt? = null,
@ProtoNumber(9) val picWidth: UInt? = null,
@ProtoNumber(10) val resId: ByteArray? = null, // md5 + ".jpg"
@ProtoNumber(10) val resId: String? = null, // md5 + ".jpg"
@ProtoNumber(11) val flag: ByteArray? = null,
@ProtoNumber(12) val thumbUrl: String? = null,
@ProtoNumber(13) val original: Boolean? = null,
Expand All @@ -39,8 +39,23 @@ data class NotOnlineImage(
@Serializable
data class PbReserve(
@ProtoNumber(1) var field1: Int? = null,
@ProtoNumber(3) var field3: Int? = null,
@ProtoNumber(4) var field4: Int? = null,
@ProtoNumber(8) var field8: String? = null,
@ProtoNumber(30) var url: String? = null
@ProtoNumber(10) var field10: Int? = null,
@ProtoNumber(20) var field20: Object1? = null,
@ProtoNumber(30) var url: String? = null,
@ProtoNumber(31) var md5Str: String? = null
)

@Serializable
data class Object1(
@ProtoNumber(1) var field1: Int? = null,
@ProtoNumber(2) var field2: String? = null,
@ProtoNumber(3) var field3: Int? = null,
@ProtoNumber(4) var field4: Int? = null,
@ProtoNumber(5) var field5: Int? = null,
@ProtoNumber(7) var field7: String? = null
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package moe.fuqiuluo.qqinterface.servlet.msg

import com.tencent.qqnt.kernel.nativeinterface.MsgElement
import moe.fuqiuluo.qqinterface.servlet.msg.converter.ElemConverter
import moe.fuqiuluo.qqinterface.servlet.msg.converter.MsgElementConverter
import moe.fuqiuluo.qqinterface.servlet.msg.converter.NtMsgElementConverter
import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.helper.MessageHelper
Expand Down Expand Up @@ -56,7 +56,7 @@ internal suspend fun List<MsgElement>.toSegments(chatType: Int, peerId: String,
val messageData = arrayListOf<MessageSegment>()
this.forEach { msg ->
kotlin.runCatching {
val converter = MsgElementConverter[msg.elementType]
val converter = NtMsgElementConverter[msg.elementType]
converter?.invoke(chatType, peerId, subPeer, msg)
?: throw UnsupportedOperationException("不支持的消息element类型:${msg.elementType}")
}.onSuccess {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@ import moe.fuqiuluo.shamrock.tools.hex2ByteArray

internal typealias IMsgElementConverter = suspend (Int, String, String, MsgElement) -> MessageSegment

internal object MsgElementConverter {
internal object NtMsgElementConverter {
private val convertMap = hashMapOf(
MsgConstant.KELEMTYPETEXT to MsgElementConverter::convertTextElem,
MsgConstant.KELEMTYPEFACE to MsgElementConverter::convertFaceElem,
MsgConstant.KELEMTYPEPIC to MsgElementConverter::convertImageElem,
MsgConstant.KELEMTYPEPTT to MsgElementConverter::convertVoiceElem,
MsgConstant.KELEMTYPEVIDEO to MsgElementConverter::convertVideoElem,
MsgConstant.KELEMTYPEMARKETFACE to MsgElementConverter::convertMarketFaceElem,
MsgConstant.KELEMTYPEARKSTRUCT to MsgElementConverter::convertStructJsonElem,
MsgConstant.KELEMTYPEREPLY to MsgElementConverter::convertReplyElem,
MsgConstant.KELEMTYPEGRAYTIP to MsgElementConverter::convertGrayTipsElem,
MsgConstant.KELEMTYPEFILE to MsgElementConverter::convertFileElem,
MsgConstant.KELEMTYPEMARKDOWN to MsgElementConverter::convertMarkdownElem,
MsgConstant.KELEMTYPETEXT to NtMsgElementConverter::convertTextElem,
MsgConstant.KELEMTYPEFACE to NtMsgElementConverter::convertFaceElem,
MsgConstant.KELEMTYPEPIC to NtMsgElementConverter::convertImageElem,
MsgConstant.KELEMTYPEPTT to NtMsgElementConverter::convertVoiceElem,
MsgConstant.KELEMTYPEVIDEO to NtMsgElementConverter::convertVideoElem,
MsgConstant.KELEMTYPEMARKETFACE to NtMsgElementConverter::convertMarketFaceElem,
MsgConstant.KELEMTYPEARKSTRUCT to NtMsgElementConverter::convertStructJsonElem,
MsgConstant.KELEMTYPEREPLY to NtMsgElementConverter::convertReplyElem,
MsgConstant.KELEMTYPEGRAYTIP to NtMsgElementConverter::convertGrayTipsElem,
MsgConstant.KELEMTYPEFILE to NtMsgElementConverter::convertFileElem,
MsgConstant.KELEMTYPEMARKDOWN to NtMsgElementConverter::convertMarkdownElem,
//MsgConstant.KELEMTYPEMULTIFORWARD to MsgElementConverter::convertXmlMultiMsgElem,
//MsgConstant.KELEMTYPESTRUCTLONGMSG to MsgElementConverter::convertXmlLongMsgElem,
MsgConstant.KELEMTYPEFACEBUBBLE to MsgElementConverter::convertBubbleFaceElem,
MsgConstant.KELEMTYPEINLINEKEYBOARD to MsgElementConverter::convertInlineKeyboardElem
MsgConstant.KELEMTYPEFACEBUBBLE to NtMsgElementConverter::convertBubbleFaceElem,
MsgConstant.KELEMTYPEINLINEKEYBOARD to NtMsgElementConverter::convertInlineKeyboardElem
)

operator fun get(type: Int): IMsgElementConverter? = convertMap[type]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package moe.fuqiuluo.qqinterface.servlet.msg.maker

import android.graphics.BitmapFactory
import androidx.exifinterface.media.ExifInterface
import com.tencent.qqnt.kernel.nativeinterface.*
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import kotlinx.serialization.json.JsonObject
import moe.fuqiuluo.qqinterface.servlet.CardSvc
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
Expand All @@ -11,23 +11,12 @@ import moe.fuqiuluo.qqinterface.servlet.TicketSvc
import moe.fuqiuluo.qqinterface.servlet.ark.WeatherSvc
import moe.fuqiuluo.qqinterface.servlet.msg.toJson
import moe.fuqiuluo.qqinterface.servlet.msg.toSegments
import moe.fuqiuluo.qqinterface.servlet.transfile.*
import moe.fuqiuluo.qqinterface.servlet.transfile.data.PictureResource
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Private
import moe.fuqiuluo.qqinterface.servlet.transfile.Transfer
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Troop
import moe.fuqiuluo.qqinterface.servlet.transfile.NtV2RichMediaSvc
import moe.fuqiuluo.shamrock.helper.*
import moe.fuqiuluo.shamrock.helper.ActionMsgException
import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.helper.LogicException
import moe.fuqiuluo.shamrock.helper.MessageHelper.messageArrayToMessageElements
import moe.fuqiuluo.shamrock.helper.ParamsException
import moe.fuqiuluo.shamrock.tools.*
import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.utils.FileUtils
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
import moe.fuqiuluo.shamrock.xposed.helper.msgService
import protobuf.auto.toByteArray
import protobuf.message.Elem
import protobuf.message.element.*
Expand All @@ -36,8 +25,9 @@ import java.io.File
import java.nio.ByteBuffer
import kotlin.random.Random
import kotlin.random.nextULong
import kotlin.time.Duration.Companion.seconds

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

internal object ElemMaker {
private val makerArray = hashMapOf(
Expand All @@ -46,30 +36,30 @@ internal object ElemMaker {
"face" to ElemMaker::createFaceElem,
"pic" to ElemMaker::createImageElem,
"image" to ElemMaker::createImageElem,
// "voice" to MessageElementMaker::createRecordElem,
// "record" to MessageElementMaker::createRecordElem,
// "video" to MessageElementMaker::createVideoElem,
// "voice" to ElemMaker::createRecordElem,
// "record" to ElemMaker::createRecordElem,
// "video" to ElemMaker::createVideoElem,
"markdown" to ElemMaker::createMarkdownElem,
"button" to ElemMaker::createButtonElem,
"inline_keyboard" to ElemMaker::createButtonElem,
"dice" to ElemMaker::createNewDiceElem,
"rps" to ElemMaker::createNewRpsElem,
"poke" to ElemMaker::createPokeElem,
// "anonymous" to MessageElementMaker::createAnonymousElem,
// "share" to MessageElementMaker::createShareElem,
// "contact" to MessageElementMaker::createContactElem,
// "location" to MessageElementMaker::createLocationElem,
// "music" to MessageElementMaker::createMusicElem,
// "anonymous" to ElemMaker::createAnonymousElem,
// "share" to ElemMaker::createShareElem,
// "contact" to ElemMaker::createContactElem,
// "location" to ElemMaker::createLocationElem,
// "music" to ElemMaker::createMusicElem,
"reply" to ElemMaker::createReplyElem,
// "touch" to MessageElementMaker::createTouchElem,
// "touch" to ElemMaker::createTouchElem,
"weather" to ElemMaker::createWeatherElem,
"json" to ElemMaker::createJsonElem,
// "node" to MessageMaker::createNodeElem,
//"forward" to MessageMaker::createForwardElem,
//"multi_msg" to MessageMaker::createLongMsgStruct,
//"bubble_face" to MessageElementMaker::createBubbleFaceElem,
//"bubble_face" to ElemMaker::createBubbleFaceElem,
)

operator fun get(type: String): IMessageElementMaker? = makerArray[type]
operator fun get(type: String): IElemMaker? = makerArray[type]

private suspend fun createTextElem(
chatType: Int,
Expand Down Expand Up @@ -226,26 +216,6 @@ internal object ElemMaker {
}
requireNotNull(file)

val md5HexStr = QQNTWrapperUtil.CppProxy.genFileMd5Hex(file.absolutePath)
val msgService = NTServiceFetcher.kernelService.msgService!!
val originalPath = msgService.getRichMediaFilePathForMobileQQSend(
RichMediaFilePathInfo(
2, 0, 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, 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)
Expand All @@ -264,53 +234,77 @@ internal object ElemMaker {
picHeight = options.outWidth
}

val uploadRet = NtV2RichMediaSvc.tryUploadResourceByNt(
chatType = chatType,
elementType = MsgConstant.KELEMTYPEPIC,
resources = arrayListOf(file),
timeout = 30.seconds
).getOrThrow().first()
LogCenter.log(uploadRet.toString(), Level.DEBUG)

val elem = when (chatType) {
MsgConstant.KCHATTYPEGROUP -> {
Transfer with Troop(peerId) trans PictureResource(file)
Elem(
customFace = CustomFace(
filePath = "${md5HexStr.substring(0, 8)}-${md5HexStr.substring(8, 4)}-${
md5HexStr.substring(
12,
4
)
}-${md5HexStr.substring(16, 4)}-${md5HexStr.substring(20, 12)}.${FileUtils.getFileType(file)}",
fileId = 0u,
serverIp = 0u,
serverPort = 0u,
fileType = 1001u,
useful = 1u,
md5 = md5HexStr.hex2ByteArray(),
bizType = data["subType"].asIntOrNull?.toUInt(),
imageType = FileUtils.getPicType(file).toUInt(),
width = picWidth.toUInt(),
height = picHeight.toUInt(),
size = QQNTWrapperUtil.CppProxy.getFileSize(file.absolutePath).toUInt(),
origin = isOriginal,
thumbWidth = 0u,
thumbHeight = 0u,
pbReserve = CustomFace.Companion.PbReserve(field1 = 0)
MsgConstant.KCHATTYPEGROUP -> Elem(
customFace = CustomFace(
filePath = uploadRet.fileName,
fileId = uploadRet.uuid.toUInt(),
serverIp = 0u,
serverPort = 0u,
fileType = FileUtils.getPicType(file).toUInt(),
useful = 1u,
md5 = uploadRet.md5.hex2ByteArray(),
bizType = data["subType"].asIntOrNull?.toUInt(),
imageType = FileUtils.getPicType(file).toUInt(),
width = picWidth.toUInt(),
height = picHeight.toUInt(),
size = uploadRet.fileSize.toUInt(),
origin = isOriginal,
thumbWidth = 0u,
thumbHeight = 0u,
pbReserve = CustomFace.Companion.PbReserve(
field1 = 0,
field3 = 0,
field4 = 0,
field10 = 0,
field21 = CustomFace.Companion.Object1(
field1 = 0,
field2 = "",
field3 = 0,
field4 = 0,
field5 = 0,
md5Str = uploadRet.md5
)
)
)
}
)

MsgConstant.KCHATTYPEC2C -> {
Transfer with Private(peerId) trans PictureResource(file)
Elem(
notOnlineImage = NotOnlineImage(
filePath = "${md5HexStr}.${FileUtils.getFileType(file)}".toByteArray(),
fileLen = QQNTWrapperUtil.CppProxy.getFileSize(file.absolutePath).toUInt(),
downloadPath = "".toByteArray(),
imgType = FileUtils.getPicType(file).toUInt(),
picMd5 = md5HexStr.hex2ByteArray(),
picHeight = picWidth.toUInt(),
picWidth = picHeight.toUInt(),
resId = "".toByteArray(),
original = isOriginal, // true
pbReserve = NotOnlineImage.Companion.PbReserve(field1 = 0)
MsgConstant.KCHATTYPEC2C -> Elem(
notOnlineImage = NotOnlineImage(
filePath = uploadRet.fileName,
fileLen = uploadRet.fileSize.toUInt(),
downloadPath = uploadRet.uuid,
imgType = FileUtils.getPicType(file).toUInt(),
picMd5 = uploadRet.md5.hex2ByteArray(),
picHeight = picWidth.toUInt(),
picWidth = picHeight.toUInt(),
resId = uploadRet.uuid,
original = isOriginal, // true
pbReserve = NotOnlineImage.Companion.PbReserve(
field1 = 0,
field3 = 0,
field4 = 0,
field10 = 0,
field20 = NotOnlineImage.Companion.Object1(
field1 = 0,
field2 = "",
field3 = 0,
field4 = 0,
field5 = 0,
field7 = "",
),
md5Str = uploadRet.md5
)
)
}
)

else -> throw LogicException("Not supported chatType($chatType) for PictureMsg")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ internal object NtMsgElementMaker {
"new_dice" to NtMsgElementMaker::createNewDiceElem,
"new_rps" to NtMsgElementMaker::createNewRpsElem,
"basketball" to NtMsgElementMaker::createBasketballElem,
//"node" to MessageMaker::createNodeElem,
//"multi_msg" to MessageMaker::createLongMsgStruct,
"bubble_face" to NtMsgElementMaker::createBubbleFaceElem,
"button" to NtMsgElementMaker::createInlineKeywordElem,
Expand Down Expand Up @@ -179,17 +178,6 @@ internal object NtMsgElementMaker {
return Result.success(elem)
}

// private suspend fun createNodeElem(
// chatType: Int,
// msgId: Long,
// peerId: String,
// data: JsonObject
// ): Result<MsgElement> {
// data.checkAndThrow("data")
// SendForwardMessage(MsgConstant.KCHATTYPEC2C, TicketSvc.getUin(), data["content"].asJsonArray)
//
// }

private suspend fun createBasketballElem(
chatType: Int,
msgId: Long,
Expand Down
Loading

0 comments on commit 252a352

Please sign in to comment.