mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: 支持获取指定QQ收藏的内容 /fav/get_item_content
This commit is contained in:
parent
88beaf8b6f
commit
1490450178
@ -51,6 +51,19 @@ internal object QFavSvc: BaseSvc() {
|
||||
private const val MINOR_VERSION = 9
|
||||
private var seq = 1
|
||||
|
||||
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(
|
||||
uin: Long,
|
||||
name: String,
|
||||
@ -215,7 +228,7 @@ internal object QFavSvc: BaseSvc() {
|
||||
* 4 => pic_list
|
||||
* 5 => file_list
|
||||
*/
|
||||
2 to content
|
||||
2 to content.textToHtml()
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -223,6 +236,10 @@ internal object QFavSvc: BaseSvc() {
|
||||
return sendWeiyunReq(20009, data)
|
||||
}
|
||||
|
||||
private fun String.textToHtml(): String {
|
||||
return replace("\n", "<div><br/></div>")
|
||||
}
|
||||
|
||||
suspend fun sendPicUpBlock(
|
||||
fileSize: Long,
|
||||
offset: Long,
|
||||
@ -300,7 +317,6 @@ internal object QFavSvc: BaseSvc() {
|
||||
override fun onUpdateProgeress(netReq: NetReq, curr: Long, final: Long) {}
|
||||
}
|
||||
val pSKey = getWeiYunPSKey()
|
||||
//LogCenter.log(pSKey)
|
||||
httpNetReq.mHttpMethod = HttpNetReq.HTTP_POST
|
||||
httpNetReq.mSendData = DeflateTools.gzip(packData(packHead(cmd, pSKey), body))
|
||||
httpNetReq.mOutStream = outputStream
|
||||
|
@ -52,7 +52,7 @@ internal object ActionManager {
|
||||
GetWeatherCityCode, GetWeather,
|
||||
|
||||
// FAV
|
||||
FavAddRichMediaMsg, FavAddImageMsg,
|
||||
FavAddTextMsg, FavAddImageMsg, FavGetItemContent,
|
||||
|
||||
// OTHER
|
||||
GetDeviceBattery, DownloadFile
|
||||
|
@ -3,6 +3,8 @@ package moe.fuqiuluo.shamrock.remote.action.handlers
|
||||
import android.graphics.BitmapFactory
|
||||
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
|
||||
@ -40,8 +42,14 @@ internal object FavAddImageMsg: IActionHandler() {
|
||||
FileUtils.parseAndSave(it)
|
||||
}
|
||||
}
|
||||
|
||||
val options = BitmapFactory.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,
|
||||
image = image,
|
||||
groupName = groupName,
|
||||
@ -49,14 +57,12 @@ internal object FavAddImageMsg: IActionHandler() {
|
||||
width = options.outWidth,
|
||||
height = options.outHeight
|
||||
).onSuccess {
|
||||
return if (it.mHttpCode == 200 && it.mResult == 0) {
|
||||
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
|
||||
//LogCenter.log("上传图片请求成功: ${DeflateTools.ungzip(it.mRespData).toHexString()}")
|
||||
//LogCenter.log("图片上传响应: allLength=$allLength, dataLength=$dataLength, headLength=$headLength")
|
||||
readPacket.discardExact(2)
|
||||
ByteArray(headLength).also {
|
||||
readPacket.readFully(it, 0, it.size)
|
||||
@ -66,9 +72,15 @@ internal object FavAddImageMsg: IActionHandler() {
|
||||
}
|
||||
val pb = ProtoUtils.decodeFromByteArray(data)
|
||||
val resp = pb[2, 20010, 1, 2]
|
||||
val picUrl = resp[1].asUtf8String
|
||||
val picId = resp[11].asUtf8String
|
||||
val md5 = resp[4].asUtf8String
|
||||
picUrl = resp[1].asUtf8String
|
||||
picId = resp[11].asUtf8String
|
||||
md5 = resp[4].asUtf8String
|
||||
} else {
|
||||
return logic(it.mErrDesc, echo)
|
||||
}
|
||||
}.onFailure {
|
||||
return error(it.message ?: it.toString(), echo)
|
||||
}
|
||||
|
||||
val sha = CryptTools
|
||||
.getSHA1("/storage/emulated/0/Android/data/com.tencent.mobileqq/Tencent/QQ_Collection/pic/" + md5.uppercase() + "_0")
|
||||
@ -102,19 +114,40 @@ internal object FavAddImageMsg: IActionHandler() {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
ok(picUrl, echo)
|
||||
} else {
|
||||
logic(it.mErrDesc, echo)
|
||||
}
|
||||
}.onFailure {
|
||||
return error(it.message ?: it.toString(), echo)
|
||||
}
|
||||
return ok("请求已提交", echo)
|
||||
return ok(PicInfo(
|
||||
picUrl = picUrl,
|
||||
picId = picId,
|
||||
id = itemId
|
||||
), echo)
|
||||
}
|
||||
|
||||
override fun path(): String = "fav.add_image_msg"
|
||||
|
||||
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
|
||||
)
|
||||
}
|
@ -1,12 +1,21 @@
|
||||
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.helper.LogCenter
|
||||
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 FavAddRichMediaMsg: IActionHandler() {
|
||||
internal object FavAddTextMsg: IActionHandler() {
|
||||
override suspend fun internalHandle(session: ActionSession): String {
|
||||
val uin = session.getLong("user_id")
|
||||
val nickName = session.getString("nick")
|
||||
@ -33,7 +42,23 @@ internal object FavAddRichMediaMsg: IActionHandler() {
|
||||
groupId = groupId
|
||||
).onSuccess {
|
||||
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 {
|
||||
logic(it.mErrDesc, echo)
|
||||
}
|
||||
@ -41,7 +66,12 @@ internal object FavAddRichMediaMsg: IActionHandler() {
|
||||
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")
|
||||
|
||||
@Serializable
|
||||
private data class QFavItem(
|
||||
@SerialName("id") val id: String
|
||||
)
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
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"
|
||||
|
||||
@Serializable
|
||||
private data class ItemContent(
|
||||
@SerialName("content") val content: String
|
||||
)
|
||||
}
|
@ -5,11 +5,8 @@ import io.ktor.server.application.call
|
||||
import io.ktor.server.response.respondText
|
||||
import io.ktor.server.routing.Routing
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.FavAddImageMsg
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.FavAddRichMediaMsg
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.GetFriendList
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.GetFriendSystemMsg
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.GetStrangerInfo
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.IsBlackListUin
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.FavAddTextMsg
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.FavGetItemContent
|
||||
import moe.fuqiuluo.shamrock.tools.fetchOrNull
|
||||
import moe.fuqiuluo.shamrock.tools.fetchOrThrow
|
||||
import moe.fuqiuluo.shamrock.tools.getOrPost
|
||||
@ -24,7 +21,7 @@ fun Routing.fav() {
|
||||
val content = call.fetchOrThrow("content")
|
||||
val groupName = call.fetchOrNull("group_name") ?: ""
|
||||
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") {
|
||||
@ -35,4 +32,9 @@ fun Routing.fav() {
|
||||
val groupId = call.fetchOrNull("group_id")?.toLong() ?: 0L
|
||||
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)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user