diff --git a/app/src/main/cpp/md5.cpp b/app/src/main/cpp/md5.cpp index 2b98015..32542c5 100644 --- a/app/src/main/cpp/md5.cpp +++ b/app/src/main/cpp/md5.cpp @@ -61,8 +61,8 @@ const std::byte MD5::PADDING[64] = { (byte) 0x80 }; const char MD5::HEX[16] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f' + '8', '9', 'A', 'B', + 'C', 'D', 'E', 'F' }; diff --git a/qqinterface/build.gradle.kts b/qqinterface/build.gradle.kts index 0240519..09dbdbe 100644 --- a/qqinterface/build.gradle.kts +++ b/qqinterface/build.gradle.kts @@ -10,7 +10,6 @@ android { defaultConfig { minSdk = 24 - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") } @@ -36,7 +35,4 @@ dependencies { implementation("androidx.core:core-ktx:1.9.0") implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.9.0") - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") } \ No newline at end of file diff --git a/qqinterface/src/main/java/com/tencent/mobileqq/transfile/BaseTransFileController.java b/qqinterface/src/main/java/com/tencent/mobileqq/transfile/BaseTransFileController.java index 2def2b0..7085b22 100644 --- a/qqinterface/src/main/java/com/tencent/mobileqq/transfile/BaseTransFileController.java +++ b/qqinterface/src/main/java/com/tencent/mobileqq/transfile/BaseTransFileController.java @@ -8,6 +8,11 @@ import java.util.concurrent.atomic.AtomicBoolean; import mqq.app.AppRuntime; public class BaseTransFileController implements ITransFileController { + @Override + public boolean containsProcessor(String name, long uin) { + return false; + } + @Override public IHttpCommunicatorListener findProcessor(String str) { return null; diff --git a/qqinterface/src/main/java/com/tencent/mobileqq/transfile/api/ITransFileController.java b/qqinterface/src/main/java/com/tencent/mobileqq/transfile/api/ITransFileController.java index 0b49fa2..b8b69d9 100644 --- a/qqinterface/src/main/java/com/tencent/mobileqq/transfile/api/ITransFileController.java +++ b/qqinterface/src/main/java/com/tencent/mobileqq/transfile/api/ITransFileController.java @@ -14,7 +14,7 @@ public interface ITransFileController extends IRuntimeService { //@Deprecated //void addProcessor(String str, IHttpCommunicatorListener iHttpCommunicatorListener); - //boolean containsProcessor(String str, long j2); + boolean containsProcessor(String name, long uin); IHttpCommunicatorListener findProcessor(String str); diff --git a/xposed/build.gradle.kts b/xposed/build.gradle.kts index 56af105..b6f5fea 100644 --- a/xposed/build.gradle.kts +++ b/xposed/build.gradle.kts @@ -13,7 +13,6 @@ android { defaultConfig { minSdk = 24 - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") externalNativeBuild { cmake { @@ -50,6 +49,9 @@ android { } dependencies { + compileOnly ("de.robv.android.xposed:api:82") + compileOnly (project(":qqinterface")) + implementation("androidx.core:core-ktx:1.9.0") implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.9.0") @@ -93,12 +95,5 @@ dependencies { //ksp("androidx.room:room-compiler:$roomVersion") // optional - Kotlin Extensions and Coroutines support for Room implementation("androidx.room:room-ktx:$roomVersion") - - compileOnly ("de.robv.android.xposed:api:82") - compileOnly (project(":qqinterface")) - - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") } diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/MessageMaker.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/MessageMaker.kt index e458188..09a710b 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/MessageMaker.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/MessageMaker.kt @@ -539,7 +539,7 @@ internal object MessageMaker { file = FileUtils.parseAndSave(data["url"].asString) } if (!file.exists()) { - throw LogicException("Voice(${file.name}) file is not exists, please check your filename.") + return Result.failure(LogicException("Voice(${file.name}) file is not exists, please check your filename.")) } val isMagic = data["magic"].asStringOrNull == "1" @@ -580,11 +580,14 @@ internal object MessageMaker { // QQNTWrapperUtil.CppProxy.copyFile(file.absolutePath, originalPath) //} - Transfer with when (chatType) { + if(!(Transfer with when (chatType) { MsgConstant.KCHATTYPEGROUP -> Troop(peerId) MsgConstant.KCHATTYPEC2C -> Private(peerId) + MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> Private(peerId) else -> error("Not supported chatType($chatType) for RecordMsg") - } trans VoiceResource(file) + } trans VoiceResource(file))) { + return Result.failure(RuntimeException("上传语音失败: $file")) + } val elem = MsgElement() elem.elementType = MsgConstant.KELEMTYPEPTT diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/transfile/FileTransfer.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/transfile/FileTransfer.kt index d8ac6ac..16d7f56 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/transfile/FileTransfer.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/transfile/FileTransfer.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.coroutines.withTimeoutOrNull import moe.fuqiuluo.shamrock.utils.MD5 import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher import mqq.app.AppRuntime @@ -73,30 +74,34 @@ internal abstract class FileTransfer { transferRequest: TransferRequest, wait: Boolean ): Boolean { - val service = runtime.getRuntimeService(ITransFileController::class.java, "all") - if(service.transferAsync(transferRequest)) { - if (!wait) { // 如果无需等待直接返回 - return true - } - return suspendCancellableCoroutine { continuation -> - val waiter = GlobalScope.launch { - while ( - service.findProcessor(transferRequest.keyForTransfer) != null - // 如果上传处理器依旧存在,说明没有上传成功 - ) { - delay(100) + return withTimeoutOrNull(60_000) { + val service = runtime.getRuntimeService(ITransFileController::class.java, "all") + if(service.transferAsync(transferRequest)) { + if (!wait) { // 如果无需等待直接返回 + return@withTimeoutOrNull true + } + suspendCancellableCoroutine { continuation -> + GlobalScope.launch { + while ( + //service.findProcessor( + // transferRequest.keyForTransfer // uin + uniseq + //) != null + service.containsProcessor(runtime.currentAccountUin, transferRequest.mUniseq) + // 如果上传处理器依旧存在,说明没有上传成功 + && service.isWorking.get() + ) { + delay(100) + } + continuation.resume(true) + } + // 实现取消上传器 + // 目前没什么用 + continuation.invokeOnCancellation { + continuation.resume(false) } - continuation.resume(true) } - // 实现取消上传器 - // 目前没什么用 - continuation.invokeOnCancellation { - waiter.cancel() - continuation.resume(false) - } - } - } - return false + } else false + } ?: false } companion object { diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/transfile/Transfer.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/transfile/Transfer.kt index 99cf851..a751609 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/transfile/Transfer.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/transfile/Transfer.kt @@ -24,12 +24,12 @@ internal object Transfer: FileTransfer() { ) suspend fun uploadC2CVideo( - groupId: String, + userId: String, file: File, thumb: File, wait: Boolean = true ): Boolean { - return transC2CResource(groupId, file, FileMsg.TRANSFILE_TYPE_SHORT_VIDEO_C2C, BUSI_TYPE_SHORT_VIDEO, wait) { + return transC2CResource(userId, file, FileMsg.TRANSFILE_TYPE_SHORT_VIDEO_C2C, BUSI_TYPE_SHORT_VIDEO, wait) { it.mSourceVideoCodecFormat = VIDEO_FORMAT_MP4 it.mRec = MessageForShortVideo().also { it.busiType = BUSI_TYPE_SHORT_VIDEO @@ -56,11 +56,11 @@ internal object Transfer: FileTransfer() { } suspend fun uploadC2CVoice( - groupId: String, + userId: String, file: File, wait: Boolean = true ): Boolean { - return transC2CResource(groupId, file, FileMsg.TRANSFILE_TYPE_PTT, 1002, wait) { + return transC2CResource(userId, file, FileMsg.TRANSFILE_TYPE_PTT, 1002, wait) { it.mPttUploadPanel = 3 it.mPttCompressFinish = true it.mIsPttPreSend = true diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/actions/AntiDetection.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/actions/AntiDetection.kt index 0e62eaf..76b9202 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/actions/AntiDetection.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/actions/AntiDetection.kt @@ -2,6 +2,7 @@ package moe.fuqiuluo.shamrock.xposed.actions import android.content.Context +import android.content.pm.PackageManager import android.os.Build import moe.fuqiuluo.shamrock.tools.hookMethod @@ -12,12 +13,24 @@ class AntiDetection: IAction { override fun invoke(ctx: Context) { antiTrace() antiMemoryWalking() + antiFindPackage() } val isModuleStack = fun String.(): Boolean { return contains("fuqiuluo") || contains("shamrock") || contains("whitechi") || contains("lsposed") || contains("xposed") } + private fun antiFindPackage() { + //PackageManager::class.java.hookMethod("getApplicationInfo").before { + // val packageName = it.args[0] as String + // if(packageName == "moe.fuqiuluo.shamrock") { + // it.throwable = PackageManager.NameNotFoundException() + // } else if (packageName == "moe.fuqiuluo.shamrock.hided") { + // it.args[0] = "moe.fuqiuluo.shamrock" + // } + //} + } + private fun antiMemoryWalking() { val c = Class.forName("dalvik.system.VMDebug") //val startMethodTracingMethod = c.getDeclaredMethod(