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.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import moe.fuqiuluo.proto.protobufOf
|
import moe.fuqiuluo.proto.protobufOf
|
||||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||||
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
|
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
|
||||||
@ -35,45 +36,35 @@ internal abstract class BaseSvc {
|
|||||||
return ToServiceMsg("mobileqq.service", app.currentAccountUin, cmd)
|
return ToServiceMsg("mobileqq.service", app.currentAccountUin, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun sendOidbAW(cmd: String, cmdId: Int, serviceId: Int, data: ByteArray, trpc: Boolean = false): ByteArray? {
|
suspend fun sendOidbAW(cmd: String, cmdId: Int, serviceId: Int, data: ByteArray, trpc: Boolean = false, timeout: Long = 5000L): ByteArray? {
|
||||||
return suspendCoroutine { continuation ->
|
return withTimeoutOrNull(timeout) {
|
||||||
val seq = MsfCore.getNextSeq()
|
suspendCoroutine { continuation ->
|
||||||
val timer = timer(initialDelay = 5000L, period = 5000L) {
|
val seq = MsfCore.getNextSeq()
|
||||||
GlobalScope.launch(Dispatchers.Default) {
|
GlobalScope.launch(Dispatchers.Default) {
|
||||||
PacketHandler.unregisterLessHandler(seq)
|
DynamicReceiver.register(IPCRequest(cmd, seq) {
|
||||||
continuation.resume(null)
|
val buffer = it.getByteArrayExtra("buffer")!!
|
||||||
|
continuation.resume(buffer)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
if (trpc) sendTrpcOidb(cmd, cmdId, serviceId, data, seq)
|
||||||
|
else sendOidb(cmd, cmdId, serviceId, data, seq)
|
||||||
}
|
}
|
||||||
GlobalScope.launch(Dispatchers.Default) {
|
}?.copyOf()
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun sendBufferAW(cmd: String, isPb: Boolean, data: ByteArray): ByteArray? {
|
suspend fun sendBufferAW(cmd: String, isPb: Boolean, data: ByteArray, timeout: Long = 5000L): ByteArray? {
|
||||||
return suspendCoroutine { continuation ->
|
return withTimeoutOrNull<ByteArray?>(timeout) {
|
||||||
val seq = MsfCore.getNextSeq()
|
suspendCoroutine { continuation ->
|
||||||
val timer = timer(initialDelay = 5000L, period = 5000L) {
|
val seq = MsfCore.getNextSeq()
|
||||||
GlobalScope.launch(Dispatchers.Default) {
|
GlobalScope.launch(Dispatchers.Default) {
|
||||||
PacketHandler.unregisterLessHandler(seq)
|
DynamicReceiver.register(IPCRequest(cmd, seq) {
|
||||||
continuation.resume(null)
|
val buffer = it.getByteArrayExtra("buffer")!!
|
||||||
|
continuation.resume(buffer)
|
||||||
|
})
|
||||||
|
sendBuffer(cmd, isPb, data, seq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlobalScope.launch(Dispatchers.Default) {
|
}?.copyOf()
|
||||||
DynamicReceiver.register(IPCRequest(cmd, seq) {
|
|
||||||
val buffer = it.getByteArrayExtra("buffer")!!
|
|
||||||
timer.cancel()
|
|
||||||
continuation.resume(buffer)
|
|
||||||
})
|
|
||||||
sendBuffer(cmd, isPb, data, seq)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendOidb(cmd: String, cmdId: Int, serviceId: Int, buffer: ByteArray, seq: Int = -1, trpc: Boolean = false) {
|
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
|
package moe.fuqiuluo.qqinterface.servlet
|
||||||
|
|
||||||
import com.tencent.mobileqq.pb.ByteStringMicro
|
import com.tencent.mobileqq.pb.ByteStringMicro
|
||||||
|
import io.ktor.util.Deflate
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import moe.fuqiuluo.proto.protobufOf
|
import moe.fuqiuluo.proto.protobufOf
|
||||||
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
|
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.EMPTY_BYTE_ARRAY
|
||||||
import moe.fuqiuluo.shamrock.tools.slice
|
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.cmd0x6d8.oidb_0x6d8
|
||||||
import tencent.im.oidb.oidb_sso
|
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, "/")
|
return getGroupFiles(groupId, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +105,7 @@ internal object FileSvc: BaseSvc() {
|
|||||||
return FileUrl(RichProtoSvc.getGroupFileDownUrl(groupId, fileId, busid))
|
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 fileSystemInfo = getGroupFileSystemInfo(groupId)
|
||||||
val rspGetFileListBuffer = sendOidbAW("OidbSvc.0x6d8_1", 1752, 1, oidb_0x6d8.ReqBody().also {
|
val rspGetFileListBuffer = sendOidbAW("OidbSvc.0x6d8_1", 1752, 1, oidb_0x6d8.ReqBody().also {
|
||||||
it.file_list_info_req.set(oidb_0x6d8.GetFileListReqBody().apply {
|
it.file_list_info_req.set(oidb_0x6d8.GetFileListReqBody().apply {
|
||||||
@ -122,17 +127,20 @@ internal object FileSvc: BaseSvc() {
|
|||||||
|
|
||||||
uint32_show_onlinedoc_folder.set(0)
|
uint32_show_onlinedoc_folder.set(0)
|
||||||
})
|
})
|
||||||
}.toByteArray())
|
}.toByteArray(), timeout = 15_000L)
|
||||||
|
|
||||||
val files = arrayListOf<FileInfo>()
|
return kotlin.runCatching {
|
||||||
val dirs = arrayListOf<FolderInfo>()
|
val files = arrayListOf<FileInfo>()
|
||||||
if (rspGetFileListBuffer != null) {
|
val dirs = arrayListOf<FolderInfo>()
|
||||||
oidb_0x6d8.RspBody().mergeFrom(oidb_sso.OIDBSSOPkg()
|
if (rspGetFileListBuffer != null) {
|
||||||
.mergeFrom(rspGetFileListBuffer.slice(4))
|
val oidb = oidb_sso.OIDBSSOPkg().mergeFrom(rspGetFileListBuffer.slice(4).let {
|
||||||
.bytes_bodybuffer.get()
|
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
|
||||||
.toByteArray()).file_list_info_rsp.apply {
|
})
|
||||||
|
|
||||||
|
oidb_0x6d8.RspBody().mergeFrom(oidb.bytes_bodybuffer.get().toByteArray())
|
||||||
|
.file_list_info_rsp.apply {
|
||||||
rpt_item_list.get().forEach { file ->
|
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
|
val fileInfo = file.file_info
|
||||||
files.add(FileInfo(
|
files.add(FileInfo(
|
||||||
groupId = groupId,
|
groupId = groupId,
|
||||||
@ -147,7 +155,8 @@ internal object FileSvc: BaseSvc() {
|
|||||||
uploadUin = fileInfo.uint64_uploader_uin.get(),
|
uploadUin = fileInfo.uint64_uploader_uin.get(),
|
||||||
uploadNick = fileInfo.str_uploader_name.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
|
val folderInfo = file.folder_info
|
||||||
dirs.add(FolderInfo(
|
dirs.add(FolderInfo(
|
||||||
groupId = groupId,
|
groupId = groupId,
|
||||||
@ -158,14 +167,19 @@ internal object FileSvc: BaseSvc() {
|
|||||||
creator = folderInfo.uint64_create_uin.get(),
|
creator = folderInfo.uint64_create_uin.get(),
|
||||||
creatorNick = folderInfo.str_creator_name.get()
|
creatorNick = folderInfo.str_creator_name.get()
|
||||||
))
|
))
|
||||||
|
} else {
|
||||||
|
LogCenter.log("未知文件类型: ${file.uint32_type.get()}", Level.WARN)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw RuntimeException("获取群文件列表失败")
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw RuntimeException("获取群文件列表失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
return GroupFileList(files, dirs)
|
GroupFileList(files, dirs)
|
||||||
|
}.onFailure {
|
||||||
|
LogCenter.log(it.message + ", buffer: ${rspGetFileListBuffer.toHexString()}", Level.ERROR)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@ -13,7 +13,10 @@ internal object GetGroupRootFiles: IActionHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend operator fun invoke(groupId: String, echo: JsonElement = EmptyJsonString): String {
|
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")
|
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 {
|
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")
|
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("default_token") var defaultToken: String? = null,
|
||||||
@SerialName("active_websocket") var activeWebSocket: ConnectionConfig? = null,
|
@SerialName("active_websocket") var activeWebSocket: ConnectionConfig? = null,
|
||||||
@SerialName("passive_websocket") var passiveWebSocket: MutableList<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
|
@Serializable
|
||||||
|
@ -208,4 +208,8 @@ internal object ShamrockConfig {
|
|||||||
val mmkv = MMKVFetcher.mmkvWithId("shamrock_config")
|
val mmkv = MMKVFetcher.mmkvWithId("shamrock_config")
|
||||||
mmkv.putFloat(key, value)
|
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 de.robv.android.xposed.XposedHelpers
|
||||||
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.remote.service.config.ShamrockConfig
|
||||||
import moe.fuqiuluo.shamrock.tools.hookMethod
|
import moe.fuqiuluo.shamrock.tools.hookMethod
|
||||||
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader
|
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader
|
||||||
import mqq.app.MobileQQ
|
import mqq.app.MobileQQ
|
||||||
@ -21,7 +22,8 @@ import mqq.app.MobileQQ
|
|||||||
class AntiDetection: IAction {
|
class AntiDetection: IAction {
|
||||||
override fun invoke(ctx: Context) {
|
override fun invoke(ctx: Context) {
|
||||||
antiFindPackage(ctx)
|
antiFindPackage(ctx)
|
||||||
antiTrace()
|
if (ShamrockConfig.isAntiTrace())
|
||||||
|
antiTrace()
|
||||||
antiMemoryWalking()
|
antiMemoryWalking()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user