Skip to content

Commit

Permalink
send and receive CQCode support (not tested)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrXiaoM committed Jul 8, 2024
1 parent 8b00b45 commit 8316cd6
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 24 deletions.
4 changes: 4 additions & 0 deletions onebot/src/main/kotlin/client/config/BotConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class BotConfig(
* 该选项无法禁止其它插件自行调用网络接口
*/
val noPlatform: Boolean = false,
/**
* 发送消息时,是否使用 CQ 码
*/
val useCQCode: Boolean = false,
/**
* 重连尝试次数
*/
Expand Down
39 changes: 18 additions & 21 deletions onebot/src/main/kotlin/client/core/Bot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ class Bot(
private var idInternal: Long = 0
val id: Long
get() = idInternal

fun JsonObject.addMessage(key: String, msg: String) {
runCatching {
JsonParser.parseString(msg).asJsonArray
}.onSuccess {
if (config.useCQCode) {
addProperty(key, CQCode.fromJson(it))
} else {
add(key, it)
}
}.onFailure {
addProperty(key, msg)
}
}

/**
* 发送消息
*
Expand Down Expand Up @@ -82,13 +97,7 @@ class Bot(
val action = ActionPathEnum.SEND_PRIVATE_MSG
val params = JsonObject()
params.addProperty("user_id", userId)
kotlin.runCatching {
JsonParser.parseString(msg).asJsonArray
}.onSuccess {
params.add("message", it)
}.onFailure {
params.addProperty("message", msg)
}
params.addMessage("message", msg)
params.addProperty("auto_escape", autoEscape)
val result = actionHandler.action(this, action, params)
return result.withToken()
Expand All @@ -107,13 +116,7 @@ class Bot(
val action = ActionPathEnum.SEND_GROUP_MSG
val params = JsonObject()
params.addProperty("group_id", groupId)
kotlin.runCatching {
JsonParser.parseString(msg).asJsonArray
}.onSuccess {
params.add("message", it)
}.onFailure {
params.addProperty("message", msg)
}
params.addMessage("message", msg)
params.addProperty("auto_escape", autoEscape)
val result = actionHandler.action(this, action, params)
return result.withToken()
Expand Down Expand Up @@ -153,13 +156,7 @@ class Bot(
val params = JsonObject()
params.addProperty("guild_id", guildId)
params.addProperty("channel_id", channelId)
kotlin.runCatching {
JsonParser.parseString(msg).asJsonArray
}.onSuccess {
params.add("message", it)
}.onFailure {
params.addProperty("message", msg)
}
params.addMessage("message", msg)
val result = actionHandler.action(this, action, params)
return result.withToken()
}
Expand Down
101 changes: 101 additions & 0 deletions onebot/src/main/kotlin/sdk/util/CQCode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package cn.evolvefield.onebot.sdk.util

import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive

object CQCode {
fun fromJson(json: JsonArray): String {
return buildString {
for (ele in json) {
val obj = ele.asJsonObject
val type = obj["type"].asString
val data = obj["data"]
if (data is JsonObject) {
// 纯文本
if (type == "text") {
append(data["text"].asString
.replace("&", "&")
.replace("[", "[")
.replace("]", "]"))
continue
}
append("[CQ:$type")
for ((key, value) in data.asMap()) {
// 约定: key 不会出现需要转义的字符
append(",$key=")
append(
if (value is JsonPrimitive) {
value.asString
} else {
value.toString()
}.replace("&", "&")
.replace("[", "[")
.replace("]", "]")
.replace(",", ",")
)
}
}
append("]")
}
}
}

fun toJson(s: String): JsonArray {
val array = JsonArray()
fun add(type: String, data: JsonObject.() -> Unit) {
array.add(JsonObject().also {
it.addProperty("type", type)
it.add("data", JsonObject().apply(data))
})
}
fun String.decode(): String {
return replace("&amp", "&")
.replace("[", "[")
.replace("]", "]")
}
fun String.decodeValue(): String {
return decode()
.replace(",", ",")
}
fun StringBuilder.decode(): String {
return toString()
.decode()
.also { clear() }
}
val temp = StringBuilder()
var flag = false
for (c in s) {
if (c == '[' && temp.isNotEmpty()) {
add("text") {
addProperty("text", temp.decode())
}
}
temp.append(c)
if (!flag && temp.startsWith("[CQ:")) flag = true
if (flag && c == ']') {
val cq = temp.substring(4, temp.length - 1)
if (cq.contains(',')) {
val split = cq.split(',')
add(split[0]) {
for (s1 in split.drop(1)) {
if (!s1.contains('=')) continue
val (key, value) = s1
.split('=', limit = 2)
.run { this[0] to this[1].decodeValue() }
addProperty(key, value)
}
}
} else add(cq) { }
temp.clear()
flag = false
}
}
if (temp.isNotEmpty()) {
add("text") {
addProperty("text", temp.decode())
}
}
return array
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package top.mrxiaom.overflow.internal.message

import cn.evolvefield.onebot.sdk.entity.MsgId
import cn.evolvefield.onebot.sdk.util.CQCode
import com.google.gson.JsonParser
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.*
Expand Down Expand Up @@ -239,9 +240,18 @@ internal object OnebotMessages {
* @param source 消息源
*/
internal suspend fun deserializeFromOneBot(bot: RemoteBot, message: String, source: MessageSource? = null): MessageChain {
return kotlin.runCatching { Json.parseToJsonElement(message).jsonArray }
.map { deserializeFromOneBotJson(bot, it, source) }.getOrNull() ?: kotlin.run {
return runCatching {
Json.parseToJsonElement(message).jsonArray
}.map {
deserializeFromOneBotJson(bot, it, source)
}.getOrElse {
return runCatching {
Json.parseToJsonElement(CQCode.toJson(message).toString()).jsonArray
}.map {
deserializeFromOneBotJson(bot, it, source)
}.getOrElse {
source?.plus(message) ?: PlainText(message).toMessageChain()
}
}
}

Expand Down Expand Up @@ -421,7 +431,11 @@ internal object OnebotMessages {

"inline_keyboard" -> { // OpenShamrock
val botAppId = data["bot_appid"].long
val rows = data["rows"]!!.jsonArray.map { e1 ->
val rowsRaw = data["rows"].run {
if (this is JsonArray) this
else Json.parseToJsonElement(string).jsonArray
}
val rows = rowsRaw.jsonArray.map { e1 ->
val obj1 = e1.jsonObject
InlineKeyboardRow(
buttons = obj1["buttons"]!!.jsonArray.map { e2 ->
Expand Down

0 comments on commit 8316cd6

Please sign in to comment.