mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: 绕过资源上传检测
Signed-off-by: 白池 <whitechi73@outlook.com>
This commit is contained in:
parent
54b7eb95a8
commit
661680e60b
@ -162,6 +162,17 @@ object ShamrockConfig {
|
||||
pushUpdate(ctx)
|
||||
}
|
||||
|
||||
fun getUploadResourceGroup(ctx: Context): String {
|
||||
val preferences = ctx.getSharedPreferences("config", 0)
|
||||
return preferences.getString("up_res_group", "100000000")!!
|
||||
}
|
||||
|
||||
fun setUploadResourceGroup(ctx: Context, v: String) {
|
||||
val preferences = ctx.getSharedPreferences("config", 0)
|
||||
preferences.edit().putString("up_res_group", v).apply()
|
||||
pushUpdate(ctx)
|
||||
}
|
||||
|
||||
fun getHttpPort(ctx: Context): Int {
|
||||
val preferences = ctx.getSharedPreferences("config", 0)
|
||||
return preferences.getInt("port", 5700)
|
||||
@ -354,6 +365,7 @@ object ShamrockConfig {
|
||||
"disable_auto_sync_setting" to preferences.getBoolean("disable_auto_sync_setting", false),
|
||||
"forbid_useless_process" to preferences.getBoolean("forbid_useless_process", false),
|
||||
"enable_old_bdh" to preferences.getBoolean("enable_old_bdh", false),
|
||||
"up_res_group" to preferences.getString("up_res_group", ""),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -356,6 +356,36 @@ private fun FunctionCard(
|
||||
return@Function true
|
||||
}
|
||||
|
||||
run {
|
||||
val uploadResourceGroup = remember { mutableStateOf(ShamrockConfig.getUploadResourceGroup(ctx)) }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.absolutePadding(left = 8.dp, right = 8.dp, top = 12.dp, bottom = 0.dp)
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(2.dp),
|
||||
text = "用来上传资源的群聊,错误的资源上传终点可能导致封禁,请自建一个群聊并填写在下方。",
|
||||
color = Color.Red,
|
||||
fontSize = 11.sp
|
||||
)
|
||||
}
|
||||
TextItem(
|
||||
title = "接受资源群聊",
|
||||
desc = "用来上传资源的群聊,请自建一个群聊并填写在下方。",
|
||||
text = uploadResourceGroup,
|
||||
hint = "请输入群号",
|
||||
error = "群号不合法",
|
||||
checker = {
|
||||
it.isNotBlank() && it.toULongOrNull() != null
|
||||
},
|
||||
confirm = {
|
||||
val groupId = uploadResourceGroup.value
|
||||
ShamrockConfig.setUploadResourceGroup(ctx, groupId)
|
||||
AppRuntime.log("设置接受资源群聊为[$groupId]。")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
Function(
|
||||
title = "专业级接口",
|
||||
@ -445,9 +475,7 @@ private fun InfoItem(
|
||||
.fillMaxWidth()
|
||||
.combinedClickable(onDoubleClick = {
|
||||
doubleClick?.invoke(content)
|
||||
}) {
|
||||
true
|
||||
}
|
||||
}) { true }
|
||||
,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
|
@ -338,13 +338,13 @@ internal object MsgSvc : BaseSvc() {
|
||||
else -> MessageHelper.decodeCQCode(data["content"].asString)
|
||||
}.onEach { element ->
|
||||
val elementData = element.asJsonObject["data"].asJsonObject
|
||||
if (element.asJsonObject["type"].asString == "forward")
|
||||
if (element.asJsonObject["type"].asString == "forward") {
|
||||
forwardMsg[elementData["filename"].asString] =
|
||||
elementData["id"].asString
|
||||
}
|
||||
).getOrElse { throw Exception("消息合成失败: $it") }.let {
|
||||
desc[++i] =
|
||||
(data["name"].asStringOrNull ?: data["uin"].asStringOrNull
|
||||
}
|
||||
).getOrElse { error("消息合成失败: $it") }.let {
|
||||
desc[++i] = (data["name"].asStringOrNull ?: data["uin"].asStringOrNull
|
||||
?: TicketSvc.getNickname()) + ": " + it.first
|
||||
it.second
|
||||
}
|
||||
@ -353,8 +353,9 @@ internal object MsgSvc : BaseSvc() {
|
||||
} else {
|
||||
error("消息节点缺少id或content字段")
|
||||
}
|
||||
}.onFailure {
|
||||
LogCenter.log("消息节点解析失败:${it.stackTraceToString()}", Level.WARN)
|
||||
}.getOrElse {
|
||||
LogCenter.log("消息节点解析失败:$it", Level.WARN)
|
||||
null
|
||||
}
|
||||
}.ifEmpty { return Result.failure(Exception("消息节点为空")) }
|
||||
|
@ -261,7 +261,7 @@ internal class ElemMaker {
|
||||
resources = arrayListOf(file),
|
||||
timeout = 30.seconds
|
||||
).getOrThrow().first()
|
||||
LogCenter.log(uploadRet.toString(), Level.DEBUG)
|
||||
LogCenter.log({ uploadRet.toString() }, Level.DEBUG)
|
||||
|
||||
val elem = when (chatType) {
|
||||
MsgConstant.KCHATTYPEGROUP -> Elem(
|
||||
|
@ -1,14 +1,11 @@
|
||||
package moe.fuqiuluo.qqinterface.servlet.transfile
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.media.MediaMetadataRetriever
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import com.tencent.mobileqq.qroute.QRoute
|
||||
import com.tencent.qqnt.aio.adapter.api.IAIOPttApi
|
||||
import com.tencent.qqnt.kernel.nativeinterface.CommonFileInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
||||
import com.tencent.qqnt.kernel.nativeinterface.FileElement
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||
import com.tencent.qqnt.kernel.nativeinterface.PicElement
|
||||
@ -16,28 +13,19 @@ import com.tencent.qqnt.kernel.nativeinterface.PttElement
|
||||
import com.tencent.qqnt.kernel.nativeinterface.QQNTWrapperUtil
|
||||
import com.tencent.qqnt.kernel.nativeinterface.RichMediaFilePathInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.VideoElement
|
||||
import com.tencent.qqnt.msg.api.IMsgUtilApi
|
||||
import kotlinx.atomicfu.atomic
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import moe.fuqiuluo.qqinterface.servlet.BaseSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Private
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.data.Troop
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.data.TryUpPicData
|
||||
import moe.fuqiuluo.qqinterface.servlet.transfile.data.VideoResource
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||
import moe.fuqiuluo.shamrock.helper.TransfileHelper
|
||||
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
||||
import moe.fuqiuluo.shamrock.tools.hex2ByteArray
|
||||
import moe.fuqiuluo.shamrock.tools.slice
|
||||
import moe.fuqiuluo.shamrock.utils.AudioUtils
|
||||
import moe.fuqiuluo.shamrock.utils.FileUtils
|
||||
import moe.fuqiuluo.shamrock.utils.MD5
|
||||
import moe.fuqiuluo.shamrock.utils.MediaType
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
|
||||
import moe.fuqiuluo.shamrock.xposed.helper.msgService
|
||||
@ -63,7 +51,6 @@ import protobuf.oidb.cmd0x388.Cmd0x388ReqBody
|
||||
import protobuf.oidb.cmd0x388.Cmd0x388RspBody
|
||||
import protobuf.oidb.cmd0x388.TryUpImgReq
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
@ -72,14 +59,30 @@ import kotlin.random.nextULong
|
||||
import kotlin.time.Duration
|
||||
|
||||
internal object NtV2RichMediaSvc: BaseSvc() {
|
||||
private const val GROUP_PIC_UPLOAD_TO = "100000000"
|
||||
|
||||
private val requestIdSeq = atomic(2L)
|
||||
|
||||
private fun fetchGroupResUploadTo(): String {
|
||||
return ShamrockConfig.getUpResGroup().ifEmpty { "100000000" }
|
||||
}
|
||||
|
||||
suspend fun tryUploadResourceByNt(
|
||||
chatType: Int,
|
||||
elementType: Int,
|
||||
resources: ArrayList<File>,
|
||||
timeout: Duration,
|
||||
retryCnt: Int = 5
|
||||
): Result<MutableList<CommonFileInfo>> {
|
||||
return internalTryUploadResourceByNt(chatType, elementType, resources, timeout).onFailure {
|
||||
if (retryCnt > 0) {
|
||||
return tryUploadResourceByNt(chatType, elementType, resources, timeout, retryCnt - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量上传图片
|
||||
*/
|
||||
suspend fun tryUploadResourceByNt(
|
||||
private suspend fun internalTryUploadResourceByNt(
|
||||
chatType: Int,
|
||||
elementType: Int,
|
||||
resources: ArrayList<File>,
|
||||
@ -276,8 +279,9 @@ internal object NtV2RichMediaSvc: BaseSvc() {
|
||||
}
|
||||
val contact = when(chatType) {
|
||||
MsgConstant.KCHATTYPEC2C -> MessageHelper.generateContact(chatType, TicketSvc.getUin())
|
||||
else -> Contact(chatType, GROUP_PIC_UPLOAD_TO, GROUP_PIC_UPLOAD_TO)
|
||||
else -> Contact(chatType, fetchGroupResUploadTo(), null)
|
||||
}
|
||||
LogCenter.log(contact.toString())
|
||||
val result = mutableListOf<CommonFileInfo>()
|
||||
withTimeoutOrNull(timeout) {
|
||||
suspendCancellableCoroutine {
|
||||
@ -297,11 +301,13 @@ internal object NtV2RichMediaSvc: BaseSvc() {
|
||||
message = ArrayList(messages),
|
||||
uniseq = uniseq.qqMsgId
|
||||
) { _, _ ->
|
||||
if (contact.chatType == MsgConstant.KCHATTYPEGROUP && contact.peerUid == "100000000") {
|
||||
val kernelService = NTServiceFetcher.kernelService
|
||||
val sessionService = kernelService.wrapperSession
|
||||
val msgService = sessionService.msgService
|
||||
msgService.deleteMsg(contact, arrayListOf(uniseq.qqMsgId), null)
|
||||
}
|
||||
}
|
||||
it.invokeOnCancellation {
|
||||
RichMediaUploadHandler.removeListener(uniseq.qqMsgId)
|
||||
}
|
||||
|
@ -24,13 +24,6 @@ fun Routing.testAction() {
|
||||
return
|
||||
}
|
||||
|
||||
getOrPost("/send_msg_by_resid") {
|
||||
val resId = fetchOrThrow("res_id")
|
||||
val peerId = fetchOrThrow("peer_Id")
|
||||
val messageType = fetchOrThrow("message_type")
|
||||
call.respondText(SendMsgByResid(peerId, resId, messageType))
|
||||
}
|
||||
|
||||
getOrPost("/createUidFromTinyId") {
|
||||
val selfId = fetchOrThrow("selfId").toLong()
|
||||
val peerId = fetchOrThrow("peerId")
|
||||
|
Loading…
x
Reference in New Issue
Block a user