mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: 修復ファイルリストの取得に失敗しました
This commit is contained in:
parent
68977e4a86
commit
72600364ff
@ -11,6 +11,7 @@ import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import moe.fuqiuluo.proto.protobufOf
|
||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
|
||||
@ -35,45 +36,35 @@ internal abstract class BaseSvc {
|
||||
return ToServiceMsg("mobileqq.service", app.currentAccountUin, cmd)
|
||||
}
|
||||
|
||||
suspend fun sendOidbAW(cmd: String, cmdId: Int, serviceId: Int, data: ByteArray, trpc: Boolean = false): ByteArray? {
|
||||
return suspendCoroutine { continuation ->
|
||||
suspend fun sendOidbAW(cmd: String, cmdId: Int, serviceId: Int, data: ByteArray, trpc: Boolean = false, timeout: Long = 5000L): ByteArray? {
|
||||
return withTimeoutOrNull(timeout) {
|
||||
suspendCoroutine { continuation ->
|
||||
val seq = MsfCore.getNextSeq()
|
||||
val timer = timer(initialDelay = 5000L, period = 5000L) {
|
||||
GlobalScope.launch(Dispatchers.Default) {
|
||||
PacketHandler.unregisterLessHandler(seq)
|
||||
continuation.resume(null)
|
||||
}
|
||||
}
|
||||
GlobalScope.launch(Dispatchers.Default) {
|
||||
DynamicReceiver.register(IPCRequest(cmd, seq) {
|
||||
val buffer = it.getByteArrayExtra("buffer")!!
|
||||
timer.cancel()
|
||||
continuation.resume(buffer)
|
||||
})
|
||||
}
|
||||
if (trpc) sendTrpcOidb(cmd, cmdId, serviceId, data, seq)
|
||||
else sendOidb(cmd, cmdId, serviceId, data, seq)
|
||||
}
|
||||
}?.copyOf()
|
||||
}
|
||||
|
||||
suspend fun sendBufferAW(cmd: String, isPb: Boolean, data: ByteArray): ByteArray? {
|
||||
return suspendCoroutine { continuation ->
|
||||
suspend fun sendBufferAW(cmd: String, isPb: Boolean, data: ByteArray, timeout: Long = 5000L): ByteArray? {
|
||||
return withTimeoutOrNull<ByteArray?>(timeout) {
|
||||
suspendCoroutine { continuation ->
|
||||
val seq = MsfCore.getNextSeq()
|
||||
val timer = timer(initialDelay = 5000L, period = 5000L) {
|
||||
GlobalScope.launch(Dispatchers.Default) {
|
||||
PacketHandler.unregisterLessHandler(seq)
|
||||
continuation.resume(null)
|
||||
}
|
||||
}
|
||||
GlobalScope.launch(Dispatchers.Default) {
|
||||
DynamicReceiver.register(IPCRequest(cmd, seq) {
|
||||
val buffer = it.getByteArrayExtra("buffer")!!
|
||||
timer.cancel()
|
||||
continuation.resume(buffer)
|
||||
})
|
||||
sendBuffer(cmd, isPb, data, seq)
|
||||
}
|
||||
}
|
||||
}?.copyOf()
|
||||
}
|
||||
|
||||
fun sendOidb(cmd: String, cmdId: Int, serviceId: Int, buffer: ByteArray, seq: Int = -1, trpc: Boolean = false) {
|
||||
|
@ -1,12 +1,17 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet
|
||||
|
||||
import com.tencent.mobileqq.pb.ByteStringMicro
|
||||
import io.ktor.util.Deflate
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import moe.fuqiuluo.proto.protobufOf
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
|
||||
import moe.fuqiuluo.shamrock.tools.slice
|
||||
import moe.fuqiuluo.shamrock.tools.toHexString
|
||||
import moe.fuqiuluo.shamrock.utils.DeflateTools
|
||||
import tencent.im.oidb.cmd0x6d8.oidb_0x6d8
|
||||
import tencent.im.oidb.oidb_sso
|
||||
|
||||
@ -92,7 +97,7 @@ internal object FileSvc: BaseSvc() {
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getGroupRootFiles(groupId: Long): GroupFileList {
|
||||
suspend fun getGroupRootFiles(groupId: Long): Result<GroupFileList> {
|
||||
return getGroupFiles(groupId, "/")
|
||||
}
|
||||
|
||||
@ -100,7 +105,7 @@ internal object FileSvc: BaseSvc() {
|
||||
return FileUrl(RichProtoSvc.getGroupFileDownUrl(groupId, fileId, busid))
|
||||
}
|
||||
|
||||
suspend fun getGroupFiles(groupId: Long, folderId: String): GroupFileList {
|
||||
suspend fun getGroupFiles(groupId: Long, folderId: String): Result<GroupFileList> {
|
||||
val fileSystemInfo = getGroupFileSystemInfo(groupId)
|
||||
val rspGetFileListBuffer = sendOidbAW("OidbSvc.0x6d8_1", 1752, 1, oidb_0x6d8.ReqBody().also {
|
||||
it.file_list_info_req.set(oidb_0x6d8.GetFileListReqBody().apply {
|
||||
@ -122,17 +127,20 @@ internal object FileSvc: BaseSvc() {
|
||||
|
||||
uint32_show_onlinedoc_folder.set(0)
|
||||
})
|
||||
}.toByteArray())
|
||||
}.toByteArray(), timeout = 15_000L)
|
||||
|
||||
return kotlin.runCatching {
|
||||
val files = arrayListOf<FileInfo>()
|
||||
val dirs = arrayListOf<FolderInfo>()
|
||||
if (rspGetFileListBuffer != null) {
|
||||
oidb_0x6d8.RspBody().mergeFrom(oidb_sso.OIDBSSOPkg()
|
||||
.mergeFrom(rspGetFileListBuffer.slice(4))
|
||||
.bytes_bodybuffer.get()
|
||||
.toByteArray()).file_list_info_rsp.apply {
|
||||
val oidb = oidb_sso.OIDBSSOPkg().mergeFrom(rspGetFileListBuffer.slice(4).let {
|
||||
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
|
||||
})
|
||||
|
||||
oidb_0x6d8.RspBody().mergeFrom(oidb.bytes_bodybuffer.get().toByteArray())
|
||||
.file_list_info_rsp.apply {
|
||||
rpt_item_list.get().forEach { file ->
|
||||
if (file.uint32_type.get() == 1) {
|
||||
if (file.uint32_type.get() == oidb_0x6d8.GetFileListRspBody.TYPE_FILE) {
|
||||
val fileInfo = file.file_info
|
||||
files.add(FileInfo(
|
||||
groupId = groupId,
|
||||
@ -147,7 +155,8 @@ internal object FileSvc: BaseSvc() {
|
||||
uploadUin = fileInfo.uint64_uploader_uin.get(),
|
||||
uploadNick = fileInfo.str_uploader_name.get()
|
||||
))
|
||||
} else if (file.uint32_type.get() == 2) {
|
||||
}
|
||||
else if (file.uint32_type.get() == oidb_0x6d8.GetFileListRspBody.TYPE_FOLDER) {
|
||||
val folderInfo = file.folder_info
|
||||
dirs.add(FolderInfo(
|
||||
groupId = groupId,
|
||||
@ -158,6 +167,8 @@ internal object FileSvc: BaseSvc() {
|
||||
creator = folderInfo.uint64_create_uin.get(),
|
||||
creatorNick = folderInfo.str_creator_name.get()
|
||||
))
|
||||
} else {
|
||||
LogCenter.log("未知文件类型: ${file.uint32_type.get()}", Level.WARN)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,7 +176,10 @@ internal object FileSvc: BaseSvc() {
|
||||
throw RuntimeException("获取群文件列表失败")
|
||||
}
|
||||
|
||||
return GroupFileList(files, dirs)
|
||||
GroupFileList(files, dirs)
|
||||
}.onFailure {
|
||||
LogCenter.log(it.message + ", buffer: ${rspGetFileListBuffer.toHexString()}", Level.ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
@ -13,7 +13,10 @@ internal object GetGroupRootFiles: IActionHandler() {
|
||||
}
|
||||
|
||||
suspend operator fun invoke(groupId: String, echo: JsonElement = EmptyJsonString): String {
|
||||
return ok(FileSvc.getGroupRootFiles(groupId.toLong()), echo = echo)
|
||||
FileSvc.getGroupRootFiles(groupId.toLong()).onSuccess {
|
||||
return ok(it, echo = echo)
|
||||
}.getOrNull()
|
||||
return error(why = "获取失败,请查看日志", echo = echo)
|
||||
}
|
||||
|
||||
override val requiredParams: Array<String> = arrayOf("group_id")
|
||||
|
@ -14,7 +14,10 @@ internal object GetGroupSubFiles: IActionHandler() {
|
||||
}
|
||||
|
||||
suspend operator fun invoke(groupId: String, folderId: String, echo: JsonElement = EmptyJsonString): String {
|
||||
return ok(FileSvc.getGroupFiles(groupId.toLong(), folderId), echo)
|
||||
FileSvc.getGroupFiles(groupId.toLong(), folderId).onSuccess {
|
||||
return ok(it, echo = echo)
|
||||
}.getOrNull()
|
||||
return error(why = "获取失败,请查看日志", echo = echo)
|
||||
}
|
||||
|
||||
override val requiredParams: Array<String> = arrayOf("group_id", "folder_id")
|
||||
|
@ -9,7 +9,8 @@ data class ServiceConfig(
|
||||
@SerialName("default_token") var defaultToken: String? = null,
|
||||
@SerialName("active_websocket") var activeWebSocket: ConnectionConfig? = null,
|
||||
@SerialName("passive_websocket") var passiveWebSocket: MutableList<ConnectionConfig>? = null,
|
||||
@SerialName("allow-temp-session") var allowTempSession: Boolean = false
|
||||
@SerialName("allow-temp-session") var allowTempSession: Boolean = false,
|
||||
@SerialName("anti_qq_trace") var antiTrace: Boolean = true
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
@ -208,4 +208,8 @@ internal object ShamrockConfig {
|
||||
val mmkv = MMKVFetcher.mmkvWithId("shamrock_config")
|
||||
mmkv.putFloat(key, value)
|
||||
}
|
||||
|
||||
fun isAntiTrace(): Boolean {
|
||||
return Config.antiTrace
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import de.robv.android.xposed.XposedBridge
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
||||
import moe.fuqiuluo.shamrock.tools.hookMethod
|
||||
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader
|
||||
import mqq.app.MobileQQ
|
||||
@ -21,6 +22,7 @@ import mqq.app.MobileQQ
|
||||
class AntiDetection: IAction {
|
||||
override fun invoke(ctx: Context) {
|
||||
antiFindPackage(ctx)
|
||||
if (ShamrockConfig.isAntiTrace())
|
||||
antiTrace()
|
||||
antiMemoryWalking()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user