11package top.mrxiaom.overflow.internal
22
3+ import kotlinx.coroutines.Job
34import kotlinx.serialization.SerialName
45import kotlinx.serialization.Serializable
6+ import kotlinx.serialization.json.Json
7+ import kotlinx.serialization.json.JsonElement
8+ import kotlinx.serialization.json.buildJsonObject
9+ import kotlinx.serialization.json.jsonObject
10+ import kotlinx.serialization.json.jsonPrimitive
11+ import kotlinx.serialization.json.put
12+ import net.mamoe.mirai.Bot
13+ import net.mamoe.mirai.utils.MiraiLogger
14+ import org.slf4j.Logger
15+ import top.mrxiaom.overflow.BotBuilder
16+ import top.mrxiaom.overflow.internal.utils.SLF4JAdapterLogger
17+
18+ private val JSON = Json {
19+ ignoreUnknownKeys = true
20+ isLenient = true
21+ }
522
623@Serializable
724data class Config (
8- @SerialName(" no_log___DO_NOT_REPORT_IF_YOU_SWITCH_THIS_ON___开启此选项时不接受漏洞反馈 " )
25+ @SerialName(" no_log___DO_NOT_REPORT_IF_YOU_SWITCH_THIS_ON " )
926 var noLogDoNotReportIfYouSwitchThisOn : Boolean = false ,
10- @SerialName(" ws_host" )
11- var wsHost : String = " ws://127.0.0.1:3001" ,
12- @SerialName(" reversed_ws_port" )
13- var reversedWSPort : Int = -1 ,
14- @SerialName(" token" )
15- var token : String = " " ,
27+ @SerialName(" connections" )
28+ var connectionsRaw : List <JsonElement > = listOf(
29+ buildJsonObject {
30+ put("enable", false)
31+ put("type", "websocket")
32+ put("host", "ws://127.0.0.1:3001")
33+ put("token", "")
34+ },
35+ buildJsonObject {
36+ put("enable", false)
37+ put("type", "websocket-reverse")
38+ put("port", 3002)
39+ put("token", "")
40+ },
41+ ),
1642 @SerialName(" no_platform" )
17- val noPlatform : Boolean = false ,
43+ var noPlatform : Boolean = false ,
1844 @SerialName(" use_cq_code" )
19- val useCQCode : Boolean = false ,
45+ var useCQCode : Boolean = false ,
2046 @SerialName(" retry_times" )
2147 var retryTimes : Int = 5 ,
2248 @SerialName(" retry_wait_mills" )
@@ -31,11 +57,188 @@ data class Config(
3157 var resourceCache : CacheConfig = CacheConfig (),
3258 @SerialName(" drop_events_before_connected" )
3359 var dropEventsBeforeConnected : Boolean = true ,
34- )
60+ ) {
61+ internal val connections: List <IConnection > by lazy {
62+ connectionsRaw.map { element ->
63+ val type = element.jsonObject[" type" ]?.jsonPrimitive?.content
64+ ? : throw IllegalArgumentException (" 配置项缺少 type 字段" )
65+
66+ return @map when (type) {
67+ " websocket" -> JSON .decodeFromJsonElement(ConnWebSocket .serializer(), element).invoke(this )
68+ " websocket-reverse" -> JSON .decodeFromJsonElement(ConnWebSocketReverse .serializer(), element).invoke(this )
69+ else -> throw IllegalArgumentException (" 未知的连接类型 $type " )
70+ }
71+ }
72+ }
73+ }
3574@Serializable
3675data class CacheConfig (
3776 @SerialName(" enabled" )
3877 var enabled : Boolean = false ,
3978 @SerialName(" keep_duration_hours" )
4079 var keepDurationHours : Long = 168L ,
4180)
81+
82+ internal interface IConnection {
83+ val enabled: Boolean
84+ suspend fun connect (
85+ printInfo : Boolean = false,
86+ overrideLogger : Logger ? = null,
87+ job : Job ? = null,
88+ ): Bot ?
89+ }
90+
91+ internal abstract class AbstractConnection (
92+ config : Config ,
93+ enable : Boolean ,
94+ noPlatform : Boolean? ,
95+ useCQCode : Boolean? ,
96+ retryTimes : Int? ,
97+ retryWaitMills : Long? ,
98+ retryRestMills : Long? ,
99+ heartbeatCheckSeconds : Int? ,
100+ useGroupUploadEventForFileMessage : Boolean? ,
101+ dropEventsBeforeConnected : Boolean? ,
102+ ) : IConnection {
103+ override val enabled: Boolean = enable
104+ private val noLog = config.noLogDoNotReportIfYouSwitchThisOn
105+ private val noPlatform = noPlatform ? : config.noPlatform
106+ private val useCQCode = useCQCode ? : config.useCQCode
107+ private val retryTimes = retryTimes ? : config.retryTimes
108+ private val retryWaitMills = retryWaitMills ? : config.retryWaitMills
109+ private val retryRestMills = retryRestMills ? : config.retryRestMills
110+ private val heartbeatCheckSeconds = heartbeatCheckSeconds ? : config.heartbeatCheckSeconds
111+ private val useGroupUploadEventForFileMessage = useGroupUploadEventForFileMessage ? : config.useGroupUploadEventForFileMessage
112+ private val dropEventsBeforeConnected = dropEventsBeforeConnected ? : config.dropEventsBeforeConnected
113+
114+ override suspend fun connect (
115+ printInfo : Boolean ,
116+ overrideLogger : Logger ? ,
117+ job : Job ?
118+ ): Bot ? {
119+ val builder = botBuilder()
120+
121+ if (noPlatform) builder.noPlatform()
122+ if (useCQCode) builder.useCQCode()
123+ builder.retryTimes(retryTimes)
124+ builder.retryWaitMills(retryWaitMills)
125+ builder.retryRestMills(retryRestMills)
126+ builder.heartbeatCheckSeconds(heartbeatCheckSeconds)
127+ if (useGroupUploadEventForFileMessage) builder.useGroupUploadEventForFileMessage()
128+ if (! dropEventsBeforeConnected) builder.keepEventsBeforeConnected()
129+
130+ if (! printInfo) builder.noPrintInfo()
131+ if (noLog) {
132+ val miraiLogger = MiraiLogger .Factory .create(Overflow ::class , " Onebot" )
133+ builder.overrideLogger(SLF4JAdapterLogger (miraiLogger))
134+ } else if (overrideLogger != null ) {
135+ builder.overrideLogger(overrideLogger)
136+ }
137+
138+ builder.parentJob(job)
139+
140+ return builder.connect()
141+ }
142+
143+ abstract fun botBuilder (): BotBuilder
144+ }
145+
146+ @Serializable
147+ internal data class ConnWebSocket (
148+ @SerialName(" enable" )
149+ var enable : Boolean ,
150+ @SerialName(" host" )
151+ var host : String ,
152+ @SerialName(" token" )
153+ var token : String = " " ,
154+ // 以下为通用参数
155+ @SerialName(" no_platform" )
156+ var noPlatform : Boolean? = null ,
157+ @SerialName(" use_cq_code" )
158+ var useCQCode : Boolean? = null ,
159+ @SerialName(" retry_times" )
160+ var retryTimes : Int? = null ,
161+ @SerialName(" retry_wait_mills" )
162+ var retryWaitMills : Long? = null ,
163+ @SerialName(" retry_rest_mills" )
164+ var retryRestMills : Long? = null ,
165+ @SerialName(" heartbeat_check_seconds" )
166+ var heartbeatCheckSeconds : Int? = null ,
167+ @SerialName(" use_group_upload_event_for_file_message" )
168+ var useGroupUploadEventForFileMessage : Boolean? = null ,
169+ @SerialName(" drop_events_before_connected" )
170+ var dropEventsBeforeConnected : Boolean? = null ,
171+ ): (Config ) -> IConnection {
172+ override fun invoke (config : Config ) = Impl (config, this )
173+
174+ class Impl (
175+ config : Config ,
176+ private val conn : ConnWebSocket ,
177+ ) : AbstractConnection(
178+ config, conn.enable,
179+ conn.noPlatform,
180+ conn.useCQCode,
181+ conn.retryTimes,
182+ conn.retryWaitMills,
183+ conn.retryRestMills,
184+ conn.heartbeatCheckSeconds,
185+ conn.useGroupUploadEventForFileMessage,
186+ conn.dropEventsBeforeConnected,
187+ ) {
188+ override fun botBuilder (): BotBuilder {
189+ val builder = BotBuilder .positive(conn.host)
190+ if (conn.token.isNotBlank()) builder.token(conn.token)
191+ return builder
192+ }
193+ }
194+ }
195+
196+ @Serializable
197+ internal data class ConnWebSocketReverse (
198+ @SerialName(" enable" )
199+ var enable : Boolean ,
200+ @SerialName(" port" )
201+ var port : Int ,
202+ @SerialName(" token" )
203+ var token : String = " " ,
204+ // 以下为通用参数
205+ @SerialName(" no_platform" )
206+ var noPlatform : Boolean? = null ,
207+ @SerialName(" use_cq_code" )
208+ var useCQCode : Boolean? = null ,
209+ @SerialName(" retry_times" )
210+ var retryTimes : Int? = null ,
211+ @SerialName(" retry_wait_mills" )
212+ var retryWaitMills : Long? = null ,
213+ @SerialName(" retry_rest_mills" )
214+ var retryRestMills : Long? = null ,
215+ @SerialName(" heartbeat_check_seconds" )
216+ var heartbeatCheckSeconds : Int? = null ,
217+ @SerialName(" use_group_upload_event_for_file_message" )
218+ var useGroupUploadEventForFileMessage : Boolean? = null ,
219+ @SerialName(" drop_events_before_connected" )
220+ var dropEventsBeforeConnected : Boolean? = null ,
221+ ): (Config ) -> IConnection {
222+ override fun invoke (config : Config ) = Impl (config, this )
223+
224+ class Impl (
225+ config : Config ,
226+ private val conn : ConnWebSocketReverse ,
227+ ) : AbstractConnection(
228+ config, conn.enable,
229+ conn.noPlatform,
230+ conn.useCQCode,
231+ conn.retryTimes,
232+ conn.retryWaitMills,
233+ conn.retryRestMills,
234+ conn.heartbeatCheckSeconds,
235+ conn.useGroupUploadEventForFileMessage,
236+ conn.dropEventsBeforeConnected,
237+ ) {
238+ override fun botBuilder (): BotBuilder {
239+ val builder = BotBuilder .reversed(conn.port)
240+ if (conn.token.isNotBlank()) builder.token(conn.token)
241+ return builder
242+ }
243+ }
244+ }
0 commit comments