Skip to content

Commit

Permalink
Merge pull request #51 from simple-robot/dev/support-#49
Browse files Browse the repository at this point in the history
UnknownEvent 增加 rawJson 来直接获取解析后的 JsonObject
  • Loading branch information
ForteScarlet authored Jun 20, 2024
2 parents c465ba2 + cfd43e4 commit 6e5e03a
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 11 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/P.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ object P {
override val homepage: String get() = HOMEPAGE


private val baseVersion = v(0, 6, 0)
private val baseVersion = v(0, 7, 0)

val snapshotVersion = baseVersion - Version.SNAPSHOT
override val version = if (isSnapshot()) snapshotVersion else baseVersion
Expand Down
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ ktor-client-winhttp = { group = "io.ktor", name = "ktor-client-winhttp", version
# see https://ktor.io/docs/http-client-engines.html#darwin
ktor-client-darwin = { group = "io.ktor", name = "ktor-client-darwin", version.ref = "ktor" }

ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }
ktor-server-ws = { module = "io.ktor:ktor-server-websockets", version.ref = "ktor" }

# log4j
log4j-api = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j" }
log4j-core = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4j" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ kotlin {
implementation(libs.kotlinPoet)
implementation(libs.kotlinx.coroutines.reactor)
api(libs.ktor.client.java)
implementation(libs.ktor.server.netty)
implementation(libs.ktor.server.ws)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonPrimitive
Expand Down Expand Up @@ -369,7 +370,11 @@ internal class OneBotBotImpl(
}
}

receiveEvent(currentSession)
kotlin.runCatching {
receiveEvent(currentSession)
}.onFailure { ex ->
logger.error("Event reception is interrupted: {}", ex.message, ex)
}

// The Session is done or dead,
// or the job is done.
Expand Down Expand Up @@ -448,6 +453,8 @@ internal class OneBotBotImpl(
}
} ?: continue

logger.debug("Received raw event: {}", eventRaw)

val event = kotlin.runCatching {
resolveRawEvent(eventRaw)
}.getOrElse { e ->
Expand All @@ -460,9 +467,9 @@ internal class OneBotBotImpl(
)
// 接收的事件解析出现错误,
// 这应该是预期外的情况,
// 直接终止 session 和 Bot
// 直接终止 session, 但是不终止 Bot,
// 只有当重连次数用尽才考虑终止 Bot。
session.closeExceptionally(ex)
job.cancel(exMsg, ex)

throw ex
}
Expand All @@ -489,10 +496,10 @@ internal class OneBotBotImpl(
val subTypeFieldName = resolveEventSubTypeFieldName(postType) ?: "${postType}_type"
val subType = obj[subTypeFieldName]?.jsonPrimitive?.content

fun toUnknown(): UnknownEvent {
fun toUnknown(reason: Throwable? = null): UnknownEvent {
val time = obj["time"]?.jsonPrimitive?.long ?: -1L
val selfId = obj["self_id"]?.jsonPrimitive?.long?.ID ?: 0L.ID
return UnknownEvent(time, selfId, postType, text)
return UnknownEvent(time, selfId, postType, text, obj, reason)
}

if (subType == null) {
Expand All @@ -501,7 +508,29 @@ internal class OneBotBotImpl(
}

resolveEventSerializer(postType, subType)?.let {
return OneBot11.DefaultJson.decodeFromJsonElement(it, obj)
return try {
OneBot11.DefaultJson.decodeFromJsonElement(it, obj)
} catch (serEx: SerializationException) {
logger.error(
"Received raw event '{}' decode failed because of serialization: {}" +
"It will be pushed as an UnknownEvent",
text,
serEx.message,
serEx
)

toUnknown(serEx)
} catch (argEx: IllegalArgumentException) {
logger.error(
"Received raw event '{}' decode failed because of illegal argument: {}" +
"It will be pushed as an UnknownEvent",
text,
argEx.message,
argEx
)

toUnknown(argEx)
}
} ?: run {
return toUnknown()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ kotlin {
commonMain.dependencies {
implementation(libs.simbot.api)
implementation(libs.simbot.common.annotations)
implementation(libs.kotlinx.serialization.json)
implementation(project(":simbot-component-onebot-common"))

api(project(":simbot-component-onebot-v11:simbot-component-onebot-v11-common"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@

package love.forte.simbot.component.onebot.v11.event

import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.JsonObject
import love.forte.simbot.annotations.FragileSimbotAPI
import love.forte.simbot.common.id.LongID

import love.forte.simbot.component.onebot.common.annotations.InternalOneBotAPI

/**
* 用于“兜底”的 [RawEvent] 类型实现。
Expand All @@ -28,6 +30,15 @@ import love.forte.simbot.common.id.LongID
*
* [UnknownEvent] 要求事件体必须包括 [time], [selfId] 和 [postType]。
*
* 如果 [UnknownEvent] 是由于某些异常而产生(例如原本事件进行序列化但是失败了),
* 那么失败的原因则会通过 [reason] 提供。
*
* ### 内部构造
*
* [UnknownEvent] 应当始终由内部使用、构造,
* 不要在其他地方自行构造 [UnknownEvent],
* 它的构造函数不保证任何源码或二进制兼容。
*
* ### FragileAPI
*
* 这是一个具有**特殊规则**的事件类型。
Expand All @@ -37,12 +48,41 @@ import love.forte.simbot.common.id.LongID
* @author ForteScarlet
*/
@FragileSimbotAPI
public data class UnknownEvent(
public class UnknownEvent @InternalOneBotAPI constructor(
override val time: Long,
override val selfId: LongID,
override val postType: String,
/**
* 原始的JSON字符串
* 原始的JSON字符串,
* 也是判断 [UnknownEvent] 之间是否相同的**唯一依据**。
*/
public val raw: String,
) : RawEvent

/**
* [raw] 对应解析的 [JsonObject] 对象。
*/
public val rawJson: JsonObject,

/**
* 如果是由于异常而产生,则此处为异常的原因。
* 通常会是 [SerializationException]。
*/
public val reason: Throwable? = null,

) : RawEvent {
override fun toString(): String =
"UnknownEvent(time=$time, selfId=$selfId, postType='$postType')"

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is UnknownEvent) return false

if (raw != other.raw) return false

return true
}

override fun hashCode(): Int {
return raw.hashCode()
}
}

0 comments on commit 6e5e03a

Please sign in to comment.