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.")
|
println("Full architecture and full compilation.")
|
||||||
abiFilters.add("arm64-v8a")
|
abiFilters.add("arm64-v8a")
|
||||||
abiFilters.add("x86_64")
|
abiFilters.add("x86_64")
|
||||||
|
abiFilters.add("x86")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
create("arm64") {
|
create("arm64") {
|
||||||
|
@ -52,6 +52,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
@ -120,7 +121,7 @@ private fun AppMainView() {
|
|||||||
val coreVersion = remember { mutableStateOf(getShamrockVersion(context)) }
|
val coreVersion = remember { mutableStateOf(getShamrockVersion(context)) }
|
||||||
val coreName = remember { mutableStateOf("Xposed") }
|
val coreName = remember { mutableStateOf("Xposed") }
|
||||||
val voiceSwitch = remember { mutableStateOf(false) }
|
val voiceSwitch = remember { mutableStateOf(false) }
|
||||||
@Suppress("LocalVariableName") val LocalString = LocalString
|
@Suppress("LocalVariableName") val LocalString = LocalString.init()
|
||||||
|
|
||||||
if (!AppRuntime.isInit) {
|
if (!AppRuntime.isInit) {
|
||||||
AppRuntime.state = remember {
|
AppRuntime.state = remember {
|
||||||
@ -147,7 +148,7 @@ private fun AppMainView() {
|
|||||||
|
|
||||||
AppRuntime.requestCount = remember { mutableIntStateOf(0) }
|
AppRuntime.requestCount = remember { mutableIntStateOf(0) }
|
||||||
|
|
||||||
AppRuntime.isInit = false
|
AppRuntime.isInit = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val ctx = LocalContext.current
|
val ctx = LocalContext.current
|
||||||
|
@ -6,7 +6,9 @@ package moe.fuqiuluo.shamrock.ui.theme
|
|||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.ReadOnlyComposable
|
import androidx.compose.runtime.ReadOnlyComposable
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import moe.fuqiuluo.shamrock.R
|
import moe.fuqiuluo.shamrock.R
|
||||||
|
|
||||||
private val LocalStringDefault = Default()
|
private val LocalStringDefault = Default()
|
||||||
@ -164,4 +166,14 @@ open class VarString(
|
|||||||
|
|
||||||
var persistentText: String,
|
var persistentText: String,
|
||||||
var persistentTextDesc: 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,
|
FavAddTextMsg, FavAddImageMsg, FavGetItemContent, FavGetItemList,
|
||||||
|
|
||||||
// OTHER
|
// OTHER
|
||||||
GetDeviceBattery, DownloadFile
|
GetDeviceBattery, DownloadFile, QuickOperation
|
||||||
).forEach {
|
).forEach {
|
||||||
it.alias.forEach { name ->
|
it.alias.forEach { name ->
|
||||||
actionMap[name] = it
|
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.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.remote.action.ActionManager
|
import moe.fuqiuluo.shamrock.remote.action.ActionManager
|
||||||
import moe.fuqiuluo.shamrock.remote.action.ActionSession
|
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.config.ECHO_KEY
|
||||||
import moe.fuqiuluo.shamrock.remote.entries.EmptyObject
|
import moe.fuqiuluo.shamrock.remote.entries.EmptyObject
|
||||||
import moe.fuqiuluo.shamrock.remote.entries.Status
|
import moe.fuqiuluo.shamrock.remote.entries.Status
|
||||||
import moe.fuqiuluo.shamrock.remote.service.api.GlobalEventTransmitter
|
import moe.fuqiuluo.shamrock.remote.service.api.GlobalEventTransmitter
|
||||||
|
|
||||||
internal object HttpService: HttpTransmitServlet() {
|
internal object HttpService: HttpTransmitServlet() {
|
||||||
private val actionMsgTypes = arrayOf(
|
|
||||||
"record", "voice", "video", "markdown"
|
|
||||||
)
|
|
||||||
|
|
||||||
private val jobList = arrayListOf<Job>()
|
private val jobList = arrayListOf<Job>()
|
||||||
|
|
||||||
override fun submitFlowJob(job: Job) {
|
override fun submitFlowJob(job: Job) {
|
||||||
@ -154,41 +151,4 @@ internal object HttpService: HttpTransmitServlet() {
|
|||||||
handler.handle(ActionSession(params, echo))
|
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