4 Commits

10 changed files with 364 additions and 70 deletions

View File

@ -176,9 +176,6 @@ internal object MsgSvc: BaseSvc() {
fromId: String = peedId, fromId: String = peedId,
retryCnt: Int = 3 retryCnt: Int = 3
): Result<Pair<Long, Int>> { ): Result<Pair<Long, Int>> {
//LogCenter.log(message.toString(), Level.ERROR)
//callback.msgHash = result.second 什么垃圾代码万一cb比你快你不就寄了
// 主动临时消息 // 主动临时消息
when (chatType) { when (chatType) {
MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> { MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> {
@ -188,13 +185,7 @@ internal object MsgSvc: BaseSvc() {
} }
} }
} }
val result = MessageHelper.sendMessageWithoutMsgId( val result = MessageHelper.sendMessageWithoutMsgId(chatType, peedId, message, fromId, MessageCallback(peedId, 0))
chatType,
peedId,
message,
fromId,
MessageCallback(peedId, 0)
)
return if (result.isFailure return if (result.isFailure
&& result.exceptionOrNull()?.javaClass == SendMsgException::class.java && result.exceptionOrNull()?.javaClass == SendMsgException::class.java
&& retryCnt > 0) { && retryCnt > 0) {

View File

@ -51,6 +51,47 @@ internal object QFavSvc: BaseSvc() {
private const val MINOR_VERSION = 9 private const val MINOR_VERSION = 9
private var seq = 1 private var seq = 1
suspend fun getItemList(
category: Int,
startPos: Int,
pageSize: Int,
): Result<NetResp> {
val data = protobufMapOf {
it[1] = mapOf(
20000 to mapOf(
/**
* "type", "bid", "category", "start_time", "order_type", "start_pos", "page_size", "sync_policy", "req_source"
*/
1 to 0,
2 to 0,
3 to category,
//4 to System.currentTimeMillis() - 1000 * 60,
//4 to System.currentTimeMillis(),
4 to 0,
5 to 0,
6 to startPos,
7 to pageSize,
8 to 0,
9 to 0
)
)
}.toByteArray()
return sendWeiyunReq(20000, data)
}
suspend fun getItemContent(
id: String
): Result<NetResp> {
val data = protobufMapOf {
it[1] = mapOf(
20001 to mapOf(
1 to id
)
)
}.toByteArray()
return sendWeiyunReq(20001, data)
}
suspend fun addImageMsg( suspend fun addImageMsg(
uin: Long, uin: Long,
name: String, name: String,
@ -215,7 +256,7 @@ internal object QFavSvc: BaseSvc() {
* 4 => pic_list * 4 => pic_list
* 5 => file_list * 5 => file_list
*/ */
2 to content 2 to content.textToHtml()
) )
) )
) )
@ -223,6 +264,10 @@ internal object QFavSvc: BaseSvc() {
return sendWeiyunReq(20009, data) return sendWeiyunReq(20009, data)
} }
private fun String.textToHtml(): String {
return replace("\n", "<div><br/></div>")
}
suspend fun sendPicUpBlock( suspend fun sendPicUpBlock(
fileSize: Long, fileSize: Long,
offset: Long, offset: Long,
@ -300,7 +345,6 @@ internal object QFavSvc: BaseSvc() {
override fun onUpdateProgeress(netReq: NetReq, curr: Long, final: Long) {} override fun onUpdateProgeress(netReq: NetReq, curr: Long, final: Long) {}
} }
val pSKey = getWeiYunPSKey() val pSKey = getWeiYunPSKey()
//LogCenter.log(pSKey)
httpNetReq.mHttpMethod = HttpNetReq.HTTP_POST httpNetReq.mHttpMethod = HttpNetReq.HTTP_POST
httpNetReq.mSendData = DeflateTools.gzip(packData(packHead(cmd, pSKey), body)) httpNetReq.mSendData = DeflateTools.gzip(packData(packHead(cmd, pSKey), body))
httpNetReq.mOutStream = outputStream httpNetReq.mOutStream = outputStream

View File

@ -9,6 +9,7 @@ import com.tencent.qqnt.msg.api.IMsgService
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
@ -38,7 +39,11 @@ internal object MessageHelper {
): Pair<Long, Int> { ): Pair<Long, Int> {
val uniseq = generateMsgId(chatType) val uniseq = generateMsgId(chatType)
val msg = messageArrayToMessageElements(chatType, uniseq.second, peerId, decodeCQCode(message)).also { val msg = messageArrayToMessageElements(chatType, uniseq.second, peerId, decodeCQCode(message)).also {
if (it.second.isEmpty() && !it.first) error("消息合成失败,请查看日志或者检查输入。") if (it.second.isEmpty() && !it.first) {
error("消息合成失败,请查看日志或者检查输入。")
} else if (it.second.isEmpty()) {
return System.currentTimeMillis() to 0
}
}.second.filter { }.second.filter {
it.elementType != -1 it.elementType != -1
} as ArrayList<MsgElement> } as ArrayList<MsgElement>
@ -59,6 +64,12 @@ internal object MessageHelper {
}.second.filter { }.second.filter {
it.elementType != -1 it.elementType != -1
} as ArrayList<MsgElement> } as ArrayList<MsgElement>
// ActionMsg No Care
if (msg.isEmpty()) {
return Result.success(System.currentTimeMillis() to 0)
}
val totalSize = msg.filter { val totalSize = msg.filter {
it.elementType == MsgConstant.KELEMTYPEPIC || it.elementType == MsgConstant.KELEMTYPEPIC ||
it.elementType == MsgConstant.KELEMTYPEPTT || it.elementType == MsgConstant.KELEMTYPEPTT ||
@ -67,11 +78,11 @@ internal object MessageHelper {
(it.picElement?.fileSize ?: 0) + (it.pttElement?.fileSize (it.picElement?.fileSize ?: 0) + (it.pttElement?.fileSize
?: 0) + (it.videoElement?.fileSize ?: 0) ?: 0) + (it.videoElement?.fileSize ?: 0)
}.reduceOrNull { a, b -> a + b } ?: 0 }.reduceOrNull { a, b -> a + b } ?: 0
val estimateTime = (totalSize / (300 * 1024)) * 1000 + 2000
val estimateTime = (totalSize / (300 * 1024)) * 1000 + 5000
lateinit var sendResultPair: Pair<Long, Int> lateinit var sendResultPair: Pair<Long, Int>
val sendRet = withTimeoutOrNull<Pair<Int, String>>(estimateTime) { val sendRet = withTimeoutOrNull<Pair<Int, String>>(estimateTime) {
suspendCoroutine { suspendCancellableCoroutine {
GlobalScope.launch { GlobalScope.launch {
sendResultPair = sendMessageWithoutMsgId( sendResultPair = sendMessageWithoutMsgId(
chatType, chatType,

View File

@ -52,7 +52,7 @@ internal object ActionManager {
GetWeatherCityCode, GetWeather, GetWeatherCityCode, GetWeather,
// FAV // FAV
FavAddRichMediaMsg, FavAddImageMsg, FavAddTextMsg, FavAddImageMsg, FavGetItemContent, FavGetItemList,
// OTHER // OTHER
GetDeviceBattery, DownloadFile GetDeviceBattery, DownloadFile

View File

@ -3,6 +3,8 @@ package moe.fuqiuluo.shamrock.remote.action.handlers
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.proto.ProtoUtils import moe.fuqiuluo.proto.ProtoUtils
import moe.fuqiuluo.proto.asUtf8String import moe.fuqiuluo.proto.asUtf8String
@ -40,8 +42,14 @@ internal object FavAddImageMsg: IActionHandler() {
FileUtils.parseAndSave(it) FileUtils.parseAndSave(it)
} }
} }
val options = BitmapFactory.Options() val options = BitmapFactory.Options()
BitmapFactory.decodeFile(image.absolutePath, options) BitmapFactory.decodeFile(image.absolutePath, options)
lateinit var picUrl: String
lateinit var picId: String
lateinit var itemId: String
lateinit var md5: String
QFavSvc.applyUpImageMsg(uin, nickName, QFavSvc.applyUpImageMsg(uin, nickName,
image = image, image = image,
groupName = groupName, groupName = groupName,
@ -49,14 +57,12 @@ internal object FavAddImageMsg: IActionHandler() {
width = options.outWidth, width = options.outWidth,
height = options.outHeight height = options.outHeight
).onSuccess { ).onSuccess {
return if (it.mHttpCode == 200 && it.mResult == 0) { if (it.mHttpCode == 200 && it.mResult == 0) {
val readPacket = ByteReadPacket(DeflateTools.ungzip(it.mRespData)) val readPacket = ByteReadPacket(DeflateTools.ungzip(it.mRespData))
readPacket.discardExact(6) readPacket.discardExact(6)
val allLength = readPacket.readInt() val allLength = readPacket.readInt()
val dataLength = readPacket.readInt() val dataLength = readPacket.readInt()
val headLength = allLength - dataLength - 16 val headLength = allLength - dataLength - 16
//LogCenter.log("上传图片请求成功: ${DeflateTools.ungzip(it.mRespData).toHexString()}")
//LogCenter.log("图片上传响应: allLength=$allLength, dataLength=$dataLength, headLength=$headLength")
readPacket.discardExact(2) readPacket.discardExact(2)
ByteArray(headLength).also { ByteArray(headLength).also {
readPacket.readFully(it, 0, it.size) readPacket.readFully(it, 0, it.size)
@ -66,55 +72,82 @@ internal object FavAddImageMsg: IActionHandler() {
} }
val pb = ProtoUtils.decodeFromByteArray(data) val pb = ProtoUtils.decodeFromByteArray(data)
val resp = pb[2, 20010, 1, 2] val resp = pb[2, 20010, 1, 2]
val picUrl = resp[1].asUtf8String picUrl = resp[1].asUtf8String
val picId = resp[11].asUtf8String picId = resp[11].asUtf8String
val md5 = resp[4].asUtf8String md5 = resp[4].asUtf8String
val sha = CryptTools
.getSHA1("/storage/emulated/0/Android/data/com.tencent.mobileqq/Tencent/QQ_Collection/pic/" + md5.uppercase() + "_0")
image.inputStream().use {
var offset = 0L
val block = ByteArray(131072)
var rest = image.length()
do {
val length = if (rest <= 131072) rest else 131072L
if(it.read(block, 0, length.toInt()) != -1) {
QFavSvc.sendPicUpBlock(
fileSize = image.length(),
offset = offset,
block = block,
blockSize = length,
pid = picId,
sha = sha
).onFailure {
return error(it.message ?: it.toString(), echo)
}
offset += length
rest -= length
} else {
rest = -1
}
} while (rest > 0)
}
QFavSvc.addImageMsg(
uin, nickName, groupId, groupName, picUrl, picId, options.outWidth, options.outHeight, image.length(), md5.uppercase()
).onFailure {
return error(it.message ?: it.toString(), echo)
}
ok(picUrl, echo)
} else { } else {
logic(it.mErrDesc, echo) return logic(it.mErrDesc, echo)
} }
}.onFailure { }.onFailure {
return error(it.message ?: it.toString(), echo) return error(it.message ?: it.toString(), echo)
} }
return ok("请求已提交", echo)
val sha = CryptTools
.getSHA1("/storage/emulated/0/Android/data/com.tencent.mobileqq/Tencent/QQ_Collection/pic/" + md5.uppercase() + "_0")
image.inputStream().use {
var offset = 0L
val block = ByteArray(131072)
var rest = image.length()
do {
val length = if (rest <= 131072) rest else 131072L
if(it.read(block, 0, length.toInt()) != -1) {
QFavSvc.sendPicUpBlock(
fileSize = image.length(),
offset = offset,
block = block,
blockSize = length,
pid = picId,
sha = sha
).onFailure {
return error(it.message ?: it.toString(), echo)
}
offset += length
rest -= length
} else {
rest = -1
}
} while (rest > 0)
}
QFavSvc.addImageMsg(
uin, nickName, groupId, groupName, picUrl, picId, options.outWidth, options.outHeight, image.length(), md5.uppercase()
).onFailure {
return error(it.message ?: it.toString(), echo)
}.onSuccess {
if (it.mHttpCode == 200 && it.mResult == 0) {
val readPacket = ByteReadPacket(DeflateTools.ungzip(it.mRespData))
readPacket.discardExact(6)
val allLength = readPacket.readInt()
val dataLength = readPacket.readInt()
val headLength = allLength - dataLength - 16
readPacket.discardExact(2)
ByteArray(headLength).also {
readPacket.readFully(it, 0, it.size)
}
val data = ByteArray(dataLength).also {
readPacket.readFully(it, 0, it.size)
}
val pb = ProtoUtils.decodeFromByteArray(data)
itemId = pb[2, 20009, 1].asUtf8String
}
}
return ok(PicInfo(
picUrl = picUrl,
picId = picId,
id = itemId
), echo)
} }
override fun path(): String = "fav.add_image_msg" override fun path(): String = "fav.add_image_msg"
override val requiredParams: Array<String> = arrayOf("user_id", "nick", "file") override val requiredParams: Array<String> = arrayOf("user_id", "nick", "file")
@Serializable
private data class PicInfo(
@SerialName("pic_url") val picUrl: String,
@SerialName("pic_id") val picId: String,
@SerialName("id") val id: String
)
} }

View File

@ -1,12 +1,21 @@
package moe.fuqiuluo.shamrock.remote.action.handlers package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.proto.ProtoUtils
import moe.fuqiuluo.proto.asUtf8String
import moe.fuqiuluo.qqinterface.servlet.QFavSvc import moe.fuqiuluo.qqinterface.servlet.QFavSvc
import moe.fuqiuluo.shamrock.helper.LogCenter
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.EmptyJsonString import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools
internal object FavAddRichMediaMsg: IActionHandler() { internal object FavAddTextMsg: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val uin = session.getLong("user_id") val uin = session.getLong("user_id")
val nickName = session.getString("nick") val nickName = session.getString("nick")
@ -33,7 +42,23 @@ internal object FavAddRichMediaMsg: IActionHandler() {
groupId = groupId groupId = groupId
).onSuccess { ).onSuccess {
return if (it.mHttpCode == 200 && it.mResult == 0) { return if (it.mHttpCode == 200 && it.mResult == 0) {
ok("成功", echo) val readPacket = ByteReadPacket(DeflateTools.ungzip(it.mRespData))
readPacket.discardExact(6)
val allLength = readPacket.readInt()
val dataLength = readPacket.readInt()
val headLength = allLength - dataLength - 16
readPacket.discardExact(2)
ByteArray(headLength).also {
readPacket.readFully(it, 0, it.size)
}
val data = ByteArray(dataLength).also {
readPacket.readFully(it, 0, it.size)
}
val pb = ProtoUtils.decodeFromByteArray(data)
ok(data = QFavItem(
pb[2, 20009, 1].asUtf8String
), echo)
} else { } else {
logic(it.mErrDesc, echo) logic(it.mErrDesc, echo)
} }
@ -41,7 +66,12 @@ internal object FavAddRichMediaMsg: IActionHandler() {
return ok("请求已提交", echo) return ok("请求已提交", echo)
} }
override fun path(): String = "fav.add_rich_media_msg" override fun path(): String = "fav.add_text_msg"
override val requiredParams: Array<String> = arrayOf("user_id", "nick", "content") override val requiredParams: Array<String> = arrayOf("user_id", "nick", "content")
@Serializable
private data class QFavItem(
@SerialName("id") val id: String
)
} }

View File

@ -0,0 +1,57 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.proto.ProtoUtils
import moe.fuqiuluo.proto.asUtf8String
import moe.fuqiuluo.qqinterface.servlet.QFavSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools
internal object FavGetItemContent: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val id = session.getString("id")
return invoke(id, session.echo)
}
suspend operator fun invoke(
id: String,
echo: JsonElement = EmptyJsonString
): String {
val respData = DeflateTools.ungzip(QFavSvc.getItemContent(id).onSuccess {
if (it.mHttpCode != 200 || it.mResult != 0) {
return logic(it.mErrDesc, echo)
}
}.getOrThrow().mRespData)
val readPacket = ByteReadPacket(respData)
readPacket.discardExact(6)
val allLength = readPacket.readInt()
val dataLength = readPacket.readInt()
val headLength = allLength - dataLength - 16
readPacket.discardExact(2)
ByteArray(headLength).also {
readPacket.readFully(it, 0, it.size)
}
val data = ByteArray(dataLength).also {
readPacket.readFully(it, 0, it.size)
}
val pb = ProtoUtils.decodeFromByteArray(data)
return ok(ItemContent(pb[2, 20001, 1, 8, 2].asUtf8String))
}
override fun path(): String = "fav.get_item_content"
override val requiredParams: Array<String> = arrayOf("id")
@Serializable
private data class ItemContent(
@SerialName("content") val content: String
)
}

View File

@ -0,0 +1,117 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.proto.ProtoUtils
import moe.fuqiuluo.proto.asInt
import moe.fuqiuluo.proto.asList
import moe.fuqiuluo.proto.asLong
import moe.fuqiuluo.proto.asMap
import moe.fuqiuluo.proto.asULong
import moe.fuqiuluo.proto.asUtf8String
import moe.fuqiuluo.qqinterface.servlet.QFavSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools
internal object FavGetItemList: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val category = session.getInt("category")
val startPos = session.getInt("start_pos")
val pageSize = session.getInt("page_size")
return invoke(category, startPos, pageSize, session.echo)
}
suspend operator fun invoke(
category: Int,
startPos: Int,
pageSize: Int,
echo: JsonElement = EmptyJsonString
): String {
if (pageSize <= 1) {
return logic("page_size must be greater than 1", echo)
}
val result = DeflateTools.ungzip(QFavSvc.getItemList(
category = category,
startPos = startPos,
pageSize = pageSize
).onSuccess {
if (it.mHttpCode != 200 || it.mResult != 0) {
return logic("fav.get_item_list failed", echo)
}
}.getOrThrow().mRespData)
val readPacket = ByteReadPacket(result)
readPacket.discardExact(6)
val allLength = readPacket.readInt()
val dataLength = readPacket.readInt()
val headLength = allLength - dataLength - 16
readPacket.discardExact(2)
ByteArray(headLength).also {
readPacket.readFully(it, 0, it.size)
}
val data = ByteArray(dataLength).also {
readPacket.readFully(it, 0, it.size)
}
val pb = ProtoUtils.decodeFromByteArray(data)
val itemList = arrayListOf<Item>()
val rawItemList = pb[2, 20000, 1].asList
rawItemList.value.forEach {
val item = it.asMap
val itemId = item[1].asUtf8String
val authorType = item[4, 1].asInt
val author = item[4, 2].asULong
val authorName = item[4, 3].asUtf8String
val groupName: String
val groupId: Long
if (authorType == 2) {
groupName = item[4, 5].asUtf8String
groupId = item[4, 4].asULong
} else {
groupName = ""
groupId = 0L
}
val clientVersion = item[7].asUtf8String
val time = item[9].asLong
itemList.add(Item(
id = itemId,
authorType = authorType,
author = author,
authorName = authorName,
groupName = groupName,
groupId = groupId,
clientVersion = clientVersion,
time = time
))
}
return ok(ItemList(itemList), echo)
}
override val requiredParams: Array<String> = arrayOf("category", "start_pos", "page_size")
override fun path(): String = "fav.get_item_list"
@Serializable
private data class ItemList(
val items: List<Item>
)
@Serializable
private data class Item(
@SerialName("id") val id: String,
@SerialName("author_type") val authorType: Int,
@SerialName("author") val author: Long,
@SerialName("author_name") val authorName: String,
@SerialName("group_name") val groupName: String,
@SerialName("group_id") val groupId: Long,
@SerialName("client_version") val clientVersion: String,
@SerialName("time") val time: Long
)
}

View File

@ -5,11 +5,9 @@ import io.ktor.server.application.call
import io.ktor.server.response.respondText import io.ktor.server.response.respondText
import io.ktor.server.routing.Routing import io.ktor.server.routing.Routing
import moe.fuqiuluo.shamrock.remote.action.handlers.FavAddImageMsg import moe.fuqiuluo.shamrock.remote.action.handlers.FavAddImageMsg
import moe.fuqiuluo.shamrock.remote.action.handlers.FavAddRichMediaMsg import moe.fuqiuluo.shamrock.remote.action.handlers.FavAddTextMsg
import moe.fuqiuluo.shamrock.remote.action.handlers.GetFriendList import moe.fuqiuluo.shamrock.remote.action.handlers.FavGetItemContent
import moe.fuqiuluo.shamrock.remote.action.handlers.GetFriendSystemMsg import moe.fuqiuluo.shamrock.remote.action.handlers.FavGetItemList
import moe.fuqiuluo.shamrock.remote.action.handlers.GetStrangerInfo
import moe.fuqiuluo.shamrock.remote.action.handlers.IsBlackListUin
import moe.fuqiuluo.shamrock.tools.fetchOrNull import moe.fuqiuluo.shamrock.tools.fetchOrNull
import moe.fuqiuluo.shamrock.tools.fetchOrThrow import moe.fuqiuluo.shamrock.tools.fetchOrThrow
import moe.fuqiuluo.shamrock.tools.getOrPost import moe.fuqiuluo.shamrock.tools.getOrPost
@ -24,7 +22,7 @@ fun Routing.fav() {
val content = call.fetchOrThrow("content") val content = call.fetchOrThrow("content")
val groupName = call.fetchOrNull("group_name") ?: "" val groupName = call.fetchOrNull("group_name") ?: ""
val groupId = call.fetchOrNull("group_id")?.toLong() ?: 0L val groupId = call.fetchOrNull("group_id")?.toLong() ?: 0L
call.respondText(FavAddRichMediaMsg(uin, nickName, time, content, groupName, groupId), ContentType.Application.Json) call.respondText(FavAddTextMsg(uin, nickName, time, content, groupName, groupId), ContentType.Application.Json)
} }
getOrPost("/fav/add_image_msg") { getOrPost("/fav/add_image_msg") {
@ -35,4 +33,16 @@ fun Routing.fav() {
val groupId = call.fetchOrNull("group_id")?.toLong() ?: 0L val groupId = call.fetchOrNull("group_id")?.toLong() ?: 0L
call.respondText(FavAddImageMsg(uin, nickName, file, groupName, groupId), ContentType.Application.Json) call.respondText(FavAddImageMsg(uin, nickName, file, groupName, groupId), ContentType.Application.Json)
} }
getOrPost("/fav/get_item_content") {
val id = call.fetchOrThrow("id")
call.respondText(FavGetItemContent(id), ContentType.Application.Json)
}
getOrPost("/fav/get_item_list") {
val category = call.fetchOrThrow("category").toInt()
val startPos = call.fetchOrThrow("start_pos").toInt()
val pageSize = call.fetchOrThrow("page_size").toInt()
call.respondText(FavGetItemList(category, startPos, pageSize), ContentType.Application.Json)
}
} }

View File

@ -16,6 +16,7 @@ import mqq.app.MobileQQ
internal class HookForDebug: IAction { internal class HookForDebug: IAction {
override fun invoke(ctx: Context) { override fun invoke(ctx: Context) {
/*
val httpEngineService = AppRuntimeFetcher.appRuntime val httpEngineService = AppRuntimeFetcher.appRuntime
.getRuntimeService(IHttpEngineService::class.java, "all") .getRuntimeService(IHttpEngineService::class.java, "all")
httpEngineService.javaClass.hookMethod("sendReq").before { httpEngineService.javaClass.hookMethod("sendReq").before {
@ -28,7 +29,7 @@ internal class HookForDebug: IAction {
LogCenter.log("请求地址: ${req.mReqUrl}") LogCenter.log("请求地址: ${req.mReqUrl}")
LogCenter.log("请求: ${req.toInnerValuesString(NetReq::class.java)}") LogCenter.log("请求: ${req.toInnerValuesString(NetReq::class.java)}")
} }
} }*/
} }
} }