mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: 对QQ9支持,并尝试修复#181
This commit is contained in:
parent
d44150ea1a
commit
e92c227bba
@ -62,6 +62,7 @@ android {
|
||||
println("Full architecture and full compilation.")
|
||||
abiFilters.add("arm64-v8a")
|
||||
abiFilters.add("x86_64")
|
||||
abiFilters.add("x86")
|
||||
}
|
||||
}
|
||||
create("arm64") {
|
||||
|
@ -52,6 +52,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.res.painterResource
|
||||
@ -120,7 +121,7 @@ private fun AppMainView() {
|
||||
val coreVersion = remember { mutableStateOf(getShamrockVersion(context)) }
|
||||
val coreName = remember { mutableStateOf("Xposed") }
|
||||
val voiceSwitch = remember { mutableStateOf(false) }
|
||||
@Suppress("LocalVariableName") val LocalString = LocalString
|
||||
@Suppress("LocalVariableName") val LocalString = LocalString.init()
|
||||
|
||||
if (!AppRuntime.isInit) {
|
||||
AppRuntime.state = remember {
|
||||
@ -147,7 +148,7 @@ private fun AppMainView() {
|
||||
|
||||
AppRuntime.requestCount = remember { mutableIntStateOf(0) }
|
||||
|
||||
AppRuntime.isInit = false
|
||||
AppRuntime.isInit = true
|
||||
}
|
||||
|
||||
val ctx = LocalContext.current
|
||||
|
@ -6,7 +6,9 @@ package moe.fuqiuluo.shamrock.ui.theme
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import moe.fuqiuluo.shamrock.R
|
||||
|
||||
private val LocalStringDefault = Default()
|
||||
@ -164,4 +166,14 @@ open class VarString(
|
||||
|
||||
var persistentText: String,
|
||||
var persistentTextDesc: String
|
||||
)
|
||||
) {
|
||||
private var inited = false
|
||||
|
||||
@Composable
|
||||
fun init(): VarString {
|
||||
if (inited) return this
|
||||
|
||||
inited = true
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ internal object ActionManager {
|
||||
FavAddTextMsg, FavAddImageMsg, FavGetItemContent, FavGetItemList,
|
||||
|
||||
// OTHER
|
||||
GetDeviceBattery, DownloadFile
|
||||
GetDeviceBattery, DownloadFile, QuickOperation
|
||||
).forEach {
|
||||
it.alias.forEach { name ->
|
||||
actionMap[name] = it
|
||||
|
@ -0,0 +1,148 @@
|
||||
package moe.fuqiuluo.shamrock.remote.action.handlers
|
||||
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||
import kotlinx.serialization.json.JsonArray
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.MsgSvc
|
||||
import moe.fuqiuluo.qqinterface.servlet.TicketSvc
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
||||
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
|
||||
import moe.fuqiuluo.shamrock.remote.service.HttpService
|
||||
import moe.fuqiuluo.shamrock.tools.asBoolean
|
||||
import moe.fuqiuluo.shamrock.tools.asBooleanOrNull
|
||||
import moe.fuqiuluo.shamrock.tools.asInt
|
||||
import moe.fuqiuluo.shamrock.tools.asIntOrNull
|
||||
import moe.fuqiuluo.shamrock.tools.asJsonObject
|
||||
import moe.fuqiuluo.shamrock.tools.asLong
|
||||
import moe.fuqiuluo.shamrock.tools.asString
|
||||
import moe.fuqiuluo.shamrock.tools.json
|
||||
import moe.fuqiuluo.shamrock.tools.jsonArray
|
||||
|
||||
internal object QuickOperation: IActionHandler() {
|
||||
val actionMsgTypes = arrayOf(
|
||||
"record", "voice", "video", "markdown"
|
||||
)
|
||||
|
||||
override suspend fun internalHandle(session: ActionSession): String {
|
||||
val botId = session.getLong("self_id")
|
||||
if (botId != TicketSvc.getLongUin()) {
|
||||
return logic("当前登录账号和输入的`self_id`不一致", session.echo)
|
||||
}
|
||||
val context = session.getObject("context")
|
||||
//val msgType = context["message_type"].asString
|
||||
val msgHash = context["message_id"].asInt
|
||||
//val peerId = context[when(msgType) {
|
||||
// "group" -> "group_id"
|
||||
// "private" -> "user_id"
|
||||
// else -> error("unknown message type: $msgType")
|
||||
//}].asLong
|
||||
val record = MsgSvc.getMsg(msgHash).getOrNull()
|
||||
?: return logic("获取源消息失败", session.echo)
|
||||
|
||||
val operation = session.getObject("operation")
|
||||
|
||||
if (operation.containsKey("reply")) {
|
||||
LogCenter.log({ "websocket quickly reply successfully" }, Level.DEBUG)
|
||||
val autoEscape = operation["auto_escape"].asBooleanOrNull ?: false
|
||||
val atSender = operation["at_sender"].asBooleanOrNull ?: false
|
||||
val autoReply = operation["auto_reply"].asBooleanOrNull ?: true
|
||||
val message = operation["reply"]
|
||||
if (message is JsonPrimitive) {
|
||||
if (autoEscape) {
|
||||
val msgList = mutableSetOf<JsonElement>()
|
||||
msgList.add(mapOf(
|
||||
"type" to "text",
|
||||
"data" to mapOf(
|
||||
"text" to message.asString
|
||||
)
|
||||
).json)
|
||||
quicklyReply(
|
||||
record,
|
||||
msgList.jsonArray,
|
||||
msgHash,
|
||||
atSender,
|
||||
autoReply
|
||||
)
|
||||
} else {
|
||||
val messageArray = MessageHelper.decodeCQCode(message.asString)
|
||||
quicklyReply(
|
||||
record,
|
||||
messageArray,
|
||||
msgHash,
|
||||
atSender,
|
||||
autoReply
|
||||
)
|
||||
}
|
||||
} else if (message is JsonArray) {
|
||||
quicklyReply(
|
||||
record,
|
||||
message,
|
||||
msgHash,
|
||||
atSender,
|
||||
autoReply
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (MsgConstant.KCHATTYPEGROUP == record.chatType && operation.containsKey("delete") && operation["delete"].asBoolean) {
|
||||
MsgSvc.recallMsg(msgHash)
|
||||
}
|
||||
if (MsgConstant.KCHATTYPEGROUP == record.chatType && operation.containsKey("kick") && operation["kick"].asBoolean) {
|
||||
GroupSvc.kickMember(record.peerUin, false, record.senderUin)
|
||||
}
|
||||
if (MsgConstant.KCHATTYPEGROUP == record.chatType && operation.containsKey("ban") && operation["ban"].asBoolean) {
|
||||
val banTime = operation["ban_duration"].asIntOrNull ?: (30 * 60)
|
||||
if (banTime <= 0) return logic("禁言时间必须大于0", session.echo)
|
||||
GroupSvc.banMember(record.peerUin, record.senderUin, banTime)
|
||||
}
|
||||
|
||||
return logic("操作成功", session.echo)
|
||||
}
|
||||
|
||||
override fun path(): String = ".handle_quick_operation_async"
|
||||
|
||||
override val requiredParams: Array<String> = arrayOf("context", "operation", "self_id")
|
||||
|
||||
suspend fun quicklyReply(
|
||||
record: MsgRecord,
|
||||
message: JsonArray,
|
||||
msgHash: Int,
|
||||
atSender: Boolean,
|
||||
autoReply: Boolean
|
||||
) {
|
||||
val messageList = mutableListOf<JsonElement>()
|
||||
message.filter {
|
||||
it.asJsonObject["type"]?.asString in actionMsgTypes
|
||||
}.let {
|
||||
if (it.isNotEmpty()) {
|
||||
it.map { listOf(it) }.forEach {
|
||||
MsgSvc.sendToAio(record.chatType, record.peerUin.toString(), it.jsonArray)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (autoReply) messageList.add(mapOf(
|
||||
"type" to "reply",
|
||||
"data" to mapOf(
|
||||
"id" to msgHash
|
||||
)
|
||||
).json) // 添加回复
|
||||
if (MsgConstant.KCHATTYPEGROUP == record.chatType && atSender) {
|
||||
messageList.add(mapOf(
|
||||
"type" to "at",
|
||||
"data" to mapOf(
|
||||
"qq" to record.senderUin
|
||||
)
|
||||
).json) // 添加@发送者
|
||||
}
|
||||
messageList.addAll(message)
|
||||
MsgSvc.sendToAio(record.chatType, record.peerUin.toString(), JsonArray(messageList))
|
||||
}
|
||||
}
|
@ -27,16 +27,13 @@ import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.remote.action.ActionManager
|
||||
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
||||
import moe.fuqiuluo.shamrock.remote.action.handlers.QuickOperation.quicklyReply
|
||||
import moe.fuqiuluo.shamrock.remote.config.ECHO_KEY
|
||||
import moe.fuqiuluo.shamrock.remote.entries.EmptyObject
|
||||
import moe.fuqiuluo.shamrock.remote.entries.Status
|
||||
import moe.fuqiuluo.shamrock.remote.service.api.GlobalEventTransmitter
|
||||
|
||||
internal object HttpService: HttpTransmitServlet() {
|
||||
private val actionMsgTypes = arrayOf(
|
||||
"record", "voice", "video", "markdown"
|
||||
)
|
||||
|
||||
private val jobList = arrayListOf<Job>()
|
||||
|
||||
override fun submitFlowJob(job: Job) {
|
||||
@ -154,41 +151,4 @@ internal object HttpService: HttpTransmitServlet() {
|
||||
handler.handle(ActionSession(params, echo))
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun quicklyReply(
|
||||
record: MsgRecord,
|
||||
message: JsonArray,
|
||||
msgHash: Int,
|
||||
atSender: Boolean,
|
||||
autoReply: Boolean
|
||||
) {
|
||||
val messageList = mutableListOf<JsonElement>()
|
||||
message.filter {
|
||||
it.asJsonObject["type"]?.asString in actionMsgTypes
|
||||
}.let {
|
||||
if (it.isNotEmpty()) {
|
||||
it.map { listOf(it) }.forEach {
|
||||
MsgSvc.sendToAio(record.chatType, record.peerUin.toString(), it.jsonArray)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (autoReply) messageList.add(mapOf(
|
||||
"type" to "reply",
|
||||
"data" to mapOf(
|
||||
"id" to msgHash
|
||||
)
|
||||
).json) // 添加回复
|
||||
if (MsgConstant.KCHATTYPEGROUP == record.chatType && atSender) {
|
||||
messageList.add(mapOf(
|
||||
"type" to "at",
|
||||
"data" to mapOf(
|
||||
"qq" to record.senderUin
|
||||
)
|
||||
).json) // 添加@发送者
|
||||
}
|
||||
messageList.addAll(message)
|
||||
MsgSvc.sendToAio(record.chatType, record.peerUin.toString(), JsonArray(messageList))
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user