make ts happy

This commit is contained in:
idranme
2024-08-06 01:47:51 +08:00
parent a9902d9109
commit 897f691d6c
64 changed files with 485 additions and 420 deletions

View File

@@ -27,6 +27,7 @@
"ws": "^8.18.0" "ws": "^8.18.0"
}, },
"devDependencies": { "devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^4.17.20", "@types/express": "^4.17.20",
"@types/fluent-ffmpeg": "^2.1.24", "@types/fluent-ffmpeg": "^2.1.24",
"@types/node": "^20.11.24", "@types/node": "^20.11.24",

View File

@@ -1,7 +1,5 @@
import fs from 'fs' import fs from 'node:fs'
import fsPromise from 'fs/promises'
import { Config, OB11Config } from './types' import { Config, OB11Config } from './types'
import { mergeNewProperties } from './utils/helper' import { mergeNewProperties } from './utils/helper'
import path from 'node:path' import path from 'node:path'
import { selfInfo } from './data' import { selfInfo } from './data'

View File

@@ -45,7 +45,7 @@ export async function getFriend(uinOrUid: string): Promise<Friend | undefined> {
if (friend) { if (friend) {
friends.push(friend) friends.push(friend)
} }
} catch (e) { } catch (e: any) {
log('刷新好友列表失败', e.stack.toString()) log('刷新好友列表失败', e.stack.toString())
} }
} }

View File

@@ -14,9 +14,9 @@ class DBUtil {
public readonly DB_KEY_PREFIX_FILE = 'file_' public readonly DB_KEY_PREFIX_FILE = 'file_'
public readonly DB_KEY_PREFIX_GROUP_NOTIFY = 'group_notify_' public readonly DB_KEY_PREFIX_GROUP_NOTIFY = 'group_notify_'
private readonly DB_KEY_RECEIVED_TEMP_UIN_MAP = 'received_temp_uin_map' private readonly DB_KEY_RECEIVED_TEMP_UIN_MAP = 'received_temp_uin_map'
public db: Level public db: Level | undefined
public cache: Record<string, RawMessage | string | FileCache | GroupNotify | ReceiveTempUinMap> = {} // <msg_id_ | msg_short_id_ | msg_seq_id_><id>: RawMessage public cache: Record<string, RawMessage | string | FileCache | GroupNotify | ReceiveTempUinMap> = {} // <msg_id_ | msg_short_id_ | msg_seq_id_><id>: RawMessage
private currentShortId: number private currentShortId: number | undefined
/* /*
* 数据库结构 * 数据库结构
@@ -44,7 +44,7 @@ class DBUtil {
this.db = new Level(DB_PATH, { valueEncoding: 'json' }) this.db = new Level(DB_PATH, { valueEncoding: 'json' })
console.log('llonebot init db success') console.log('llonebot init db success')
resolve(null) resolve(null)
} catch (e) { } catch (e: any) {
console.log('init db fail', e.stack.toString()) console.log('init db fail', e.stack.toString())
setTimeout(initDB, 300) setTimeout(initDB, 300)
} }
@@ -72,13 +72,13 @@ class DBUtil {
public async getReceivedTempUinMap(): Promise<ReceiveTempUinMap> { public async getReceivedTempUinMap(): Promise<ReceiveTempUinMap> {
try { try {
this.cache[this.DB_KEY_RECEIVED_TEMP_UIN_MAP] = JSON.parse(await this.db.get(this.DB_KEY_RECEIVED_TEMP_UIN_MAP)) this.cache[this.DB_KEY_RECEIVED_TEMP_UIN_MAP] = JSON.parse(await this.db?.get(this.DB_KEY_RECEIVED_TEMP_UIN_MAP)!)
} catch (e) { } } catch (e) { }
return (this.cache[this.DB_KEY_RECEIVED_TEMP_UIN_MAP] || {}) as ReceiveTempUinMap return (this.cache[this.DB_KEY_RECEIVED_TEMP_UIN_MAP] || {}) as ReceiveTempUinMap
} }
public setReceivedTempUinMap(data: ReceiveTempUinMap) { public setReceivedTempUinMap(data: ReceiveTempUinMap) {
this.cache[this.DB_KEY_RECEIVED_TEMP_UIN_MAP] = data this.cache[this.DB_KEY_RECEIVED_TEMP_UIN_MAP] = data
this.db.put(this.DB_KEY_RECEIVED_TEMP_UIN_MAP, JSON.stringify(data)).then() this.db?.put(this.DB_KEY_RECEIVED_TEMP_UIN_MAP, JSON.stringify(data)).then()
} }
private addCache(msg: RawMessage) { private addCache(msg: RawMessage) {
const longIdKey = this.DB_KEY_PREFIX_MSG_ID + msg.msgId const longIdKey = this.DB_KEY_PREFIX_MSG_ID + msg.msgId
@@ -91,30 +91,30 @@ class DBUtil {
this.cache = {} this.cache = {}
} }
async getMsgByShortId(shortMsgId: number): Promise<RawMessage> { async getMsgByShortId(shortMsgId: number): Promise<RawMessage | undefined> {
const shortMsgIdKey = this.DB_KEY_PREFIX_MSG_SHORT_ID + shortMsgId const shortMsgIdKey = this.DB_KEY_PREFIX_MSG_SHORT_ID + shortMsgId
if (this.cache[shortMsgIdKey]) { if (this.cache[shortMsgIdKey]) {
// log("getMsgByShortId cache", shortMsgIdKey, this.cache[shortMsgIdKey]) // log("getMsgByShortId cache", shortMsgIdKey, this.cache[shortMsgIdKey])
return this.cache[shortMsgIdKey] as RawMessage return this.cache[shortMsgIdKey] as RawMessage
} }
try { try {
const longId = await this.db.get(shortMsgIdKey) const longId = await this.db?.get(shortMsgIdKey)
const msg = await this.getMsgByLongId(longId) const msg = await this.getMsgByLongId(longId!)
this.addCache(msg) this.addCache(msg!)
return msg return msg
} catch (e) { } catch (e: any) {
log('getMsgByShortId db error', e.stack.toString()) log('getMsgByShortId db error', e.stack.toString())
} }
} }
async getMsgByLongId(longId: string): Promise<RawMessage> { async getMsgByLongId(longId: string): Promise<RawMessage | undefined> {
const longIdKey = this.DB_KEY_PREFIX_MSG_ID + longId const longIdKey = this.DB_KEY_PREFIX_MSG_ID + longId
if (this.cache[longIdKey]) { if (this.cache[longIdKey]) {
return this.cache[longIdKey] as RawMessage return this.cache[longIdKey] as RawMessage
} }
try { try {
const data = await this.db.get(longIdKey) const data = await this.db?.get(longIdKey)
const msg = JSON.parse(data) const msg = JSON.parse(data!)
this.addCache(msg) this.addCache(msg)
return msg return msg
} catch (e) { } catch (e) {
@@ -122,17 +122,17 @@ class DBUtil {
} }
} }
async getMsgBySeqId(seqId: string): Promise<RawMessage> { async getMsgBySeqId(seqId: string): Promise<RawMessage | undefined> {
const seqIdKey = this.DB_KEY_PREFIX_MSG_SEQ_ID + seqId const seqIdKey = this.DB_KEY_PREFIX_MSG_SEQ_ID + seqId
if (this.cache[seqIdKey]) { if (this.cache[seqIdKey]) {
return this.cache[seqIdKey] as RawMessage return this.cache[seqIdKey] as RawMessage
} }
try { try {
const longId = await this.db.get(seqIdKey) const longId = await this.db?.get(seqIdKey)
const msg = await this.getMsgByLongId(longId) const msg = await this.getMsgByLongId(longId!)
this.addCache(msg) this.addCache(msg!)
return msg return msg
} catch (e) { } catch (e: any) {
log('getMsgBySeqId db error', e.stack.toString()) log('getMsgBySeqId db error', e.stack.toString())
} }
} }
@@ -141,7 +141,7 @@ class DBUtil {
// 有则更新,无则添加 // 有则更新,无则添加
// log("addMsg", msg.msgId, msg.msgSeq, msg.msgShortId); // log("addMsg", msg.msgId, msg.msgSeq, msg.msgShortId);
const longIdKey = this.DB_KEY_PREFIX_MSG_ID + msg.msgId const longIdKey = this.DB_KEY_PREFIX_MSG_ID + msg.msgId
let existMsg = this.cache[longIdKey] as RawMessage let existMsg: RawMessage | undefined = this.cache[longIdKey] as RawMessage
if (!existMsg) { if (!existMsg) {
try { try {
existMsg = await this.getMsgByLongId(msg.msgId) existMsg = await this.getMsgByLongId(msg.msgId)
@@ -161,13 +161,13 @@ class DBUtil {
msg.msgShortId = shortMsgId msg.msgShortId = shortMsgId
this.addCache(msg) this.addCache(msg)
// log("新增消息记录", msg.msgId) // log("新增消息记录", msg.msgId)
this.db.put(shortIdKey, msg.msgId).then().catch() this.db?.put(shortIdKey, msg.msgId).then().catch()
this.db.put(longIdKey, JSON.stringify(msg)).then().catch() this.db?.put(longIdKey, JSON.stringify(msg)).then().catch()
try { try {
await this.db.get(seqIdKey) await this.db?.get(seqIdKey)
} catch (e) { } catch (e) {
// log("新的seqId", seqIdKey) // log("新的seqId", seqIdKey)
this.db.put(seqIdKey, msg.msgId).then().catch() this.db?.put(seqIdKey, msg.msgId).then().catch()
} }
if (!this.cache[seqIdKey]) { if (!this.cache[seqIdKey]) {
this.cache[seqIdKey] = msg this.cache[seqIdKey] = msg
@@ -178,7 +178,7 @@ class DBUtil {
async updateMsg(msg: RawMessage) { async updateMsg(msg: RawMessage) {
const longIdKey = this.DB_KEY_PREFIX_MSG_ID + msg.msgId const longIdKey = this.DB_KEY_PREFIX_MSG_ID + msg.msgId
let existMsg = this.cache[longIdKey] as RawMessage let existMsg: RawMessage | undefined = this.cache[longIdKey] as RawMessage
if (!existMsg) { if (!existMsg) {
try { try {
existMsg = await this.getMsgByLongId(msg.msgId) existMsg = await this.getMsgByLongId(msg.msgId)
@@ -187,18 +187,18 @@ class DBUtil {
} }
} }
Object.assign(existMsg, msg) Object.assign(existMsg!, msg)
this.db.put(longIdKey, JSON.stringify(existMsg)).then().catch() this.db?.put(longIdKey, JSON.stringify(existMsg)).then().catch()
const shortIdKey = this.DB_KEY_PREFIX_MSG_SHORT_ID + existMsg.msgShortId const shortIdKey = this.DB_KEY_PREFIX_MSG_SHORT_ID + existMsg?.msgShortId
const seqIdKey = this.DB_KEY_PREFIX_MSG_SEQ_ID + msg.msgSeq const seqIdKey = this.DB_KEY_PREFIX_MSG_SEQ_ID + msg.msgSeq
if (!this.cache[seqIdKey]) { if (!this.cache[seqIdKey]) {
this.cache[seqIdKey] = existMsg this.cache[seqIdKey] = existMsg!
} }
this.db.put(shortIdKey, msg.msgId).then().catch() this.db?.put(shortIdKey, msg.msgId).then().catch()
try { try {
await this.db.get(seqIdKey) await this.db?.get(seqIdKey)
} catch (e) { } catch (e) {
this.db.put(seqIdKey, msg.msgId).then().catch() this.db?.put(seqIdKey, msg.msgId).then().catch()
// log("更新seqId error", e.stack, seqIdKey); // log("更新seqId error", e.stack, seqIdKey);
} }
// log("更新消息", existMsg.msgSeq, existMsg.msgShortId, existMsg.msgId); // log("更新消息", existMsg.msgSeq, existMsg.msgShortId, existMsg.msgId);
@@ -208,15 +208,15 @@ class DBUtil {
const key = 'msg_current_short_id' const key = 'msg_current_short_id'
if (this.currentShortId === undefined) { if (this.currentShortId === undefined) {
try { try {
let id: string = await this.db.get(key) const id = await this.db?.get(key)
this.currentShortId = parseInt(id) this.currentShortId = parseInt(id!)
} catch (e) { } catch (e) {
this.currentShortId = -2147483640 this.currentShortId = -2147483640
} }
} }
this.currentShortId++ this.currentShortId++
this.db.put(key, this.currentShortId.toString()).then().catch() this.db?.put(key, this.currentShortId.toString()).then().catch()
return this.currentShortId return this.currentShortId
} }
@@ -229,8 +229,8 @@ class DBUtil {
delete cacheDBData['downloadFunc'] delete cacheDBData['downloadFunc']
this.cache[fileNameOrUuid] = data this.cache[fileNameOrUuid] = data
try { try {
await this.db.put(key, JSON.stringify(cacheDBData)) await this.db?.put(key, JSON.stringify(cacheDBData))
} catch (e) { } catch (e: any) {
log('addFileCache db error', e.stack.toString()) log('addFileCache db error', e.stack.toString())
} }
} }
@@ -241,8 +241,8 @@ class DBUtil {
return this.cache[key] as FileCache return this.cache[key] as FileCache
} }
try { try {
let data = await this.db.get(key) const data = await this.db?.get(key)
return JSON.parse(data) return JSON.parse(data!)
} catch (e) { } catch (e) {
// log("getFileCache db error", e.stack.toString()) // log("getFileCache db error", e.stack.toString())
} }
@@ -255,7 +255,7 @@ class DBUtil {
return return
} }
this.cache[key] = notify this.cache[key] = notify
this.db.put(key, JSON.stringify(notify)).then().catch() this.db?.put(key, JSON.stringify(notify)).then().catch()
} }
async getGroupNotify(seq: string): Promise<GroupNotify | undefined> { async getGroupNotify(seq: string): Promise<GroupNotify | undefined> {
@@ -264,8 +264,8 @@ class DBUtil {
return this.cache[key] as GroupNotify return this.cache[key] as GroupNotify
} }
try { try {
let data = await this.db.get(key) const data = await this.db?.get(key)
return JSON.parse(data) return JSON.parse(data!)
} catch (e) { } catch (e) {
// log("getGroupNotify db error", e.stack.toString()) // log("getGroupNotify db error", e.stack.toString())
} }

View File

@@ -1,5 +1,5 @@
import express, { Express, Request, Response } from 'express' import express, { Express, Request, Response } from 'express'
import http from 'http' import http from 'node:http'
import cors from 'cors' import cors from 'cors'
import { log } from '../utils/log' import { log } from '../utils/log'
import { getConfigUtil } from '../config' import { getConfigUtil } from '../config'
@@ -10,7 +10,7 @@ type RegisterHandler = (res: Response, payload: any) => Promise<any>
export abstract class HttpServerBase { export abstract class HttpServerBase {
name: string = 'LLOneBot' name: string = 'LLOneBot'
private readonly expressAPP: Express private readonly expressAPP: Express
private server: http.Server = null private server: http.Server | null = null
constructor() { constructor() {
this.expressAPP = express() this.expressAPP = express()
@@ -38,7 +38,7 @@ export abstract class HttpServerBase {
let clientToken = '' let clientToken = ''
const authHeader = req.get('authorization') const authHeader = req.get('authorization')
if (authHeader) { if (authHeader) {
clientToken = authHeader.split('Bearer ').pop() clientToken = authHeader.split('Bearer ').pop()!
log('receive http header token', clientToken) log('receive http header token', clientToken)
} else if (req.query.access_token) { } else if (req.query.access_token) {
if (Array.isArray(req.query.access_token)) { if (Array.isArray(req.query.access_token)) {
@@ -62,7 +62,7 @@ export abstract class HttpServerBase {
}) })
this.listen(port) this.listen(port)
llonebotError.httpServerError = '' llonebotError.httpServerError = ''
} catch (e) { } catch (e: any) {
log('HTTP服务启动失败', e.toString()) log('HTTP服务启动失败', e.toString())
llonebotError.httpServerError = 'HTTP服务启动失败, ' + e.toString() llonebotError.httpServerError = 'HTTP服务启动失败, ' + e.toString()
} }
@@ -103,7 +103,7 @@ export abstract class HttpServerBase {
log('收到http请求', url, payload) log('收到http请求', url, payload)
try { try {
res.send(await handler(res, payload)) res.send(await handler(res, payload))
} catch (e) { } catch (e: any) {
this.handleFailed(res, payload, e.stack.toString()) this.handleFailed(res, payload, e.stack.toString())
} }
}) })

View File

@@ -6,7 +6,7 @@ import { getConfigUtil } from '../config'
import { llonebotError } from '../data' import { llonebotError } from '../data'
class WebsocketClientBase { class WebsocketClientBase {
private wsClient: WebSocket private wsClient: WebSocket | undefined
constructor() { } constructor() { }
@@ -20,7 +20,7 @@ class WebsocketClientBase {
} }
export class WebsocketServerBase { export class WebsocketServerBase {
private ws: WebSocketServer = null private ws: WebSocketServer | null = null
constructor() { constructor() {
console.log(`llonebot websocket service started`) console.log(`llonebot websocket service started`)
@@ -30,22 +30,22 @@ export class WebsocketServerBase {
try { try {
this.ws = new WebSocketServer({ port, maxPayload: 1024 * 1024 * 1024 }) this.ws = new WebSocketServer({ port, maxPayload: 1024 * 1024 * 1024 })
llonebotError.wsServerError = '' llonebotError.wsServerError = ''
} catch (e) { } catch (e: any) {
llonebotError.wsServerError = '正向ws服务启动失败, ' + e.toString() llonebotError.wsServerError = '正向ws服务启动失败, ' + e.toString()
} }
this.ws.on('connection', (wsClient, req) => { this.ws?.on('connection', (wsClient, req) => {
const url = req.url.split('?').shift() const url = req.url?.split('?').shift()
this.authorize(wsClient, req) this.authorize(wsClient, req)
this.onConnect(wsClient, url, req) this.onConnect(wsClient, url!, req)
wsClient.on('message', async (msg) => { wsClient.on('message', async (msg) => {
this.onMessage(wsClient, url, msg.toString()) this.onMessage(wsClient, url!, msg.toString())
}) })
}) })
} }
stop() { stop() {
llonebotError.wsServerError = '' llonebotError.wsServerError = ''
this.ws.close((err) => { this.ws?.close((err) => {
log('ws server close failed!', err) log('ws server close failed!', err)
}) })
this.ws = null this.ws = null

View File

@@ -114,7 +114,7 @@ export async function encodeSilk(filePath: string) {
let duration = 0 let duration = 0
try { try {
duration = getDuration(silk) / 1000 duration = getDuration(silk) / 1000
} catch (e) { } catch (e: any) {
log('获取语音文件时长失败, 使用文件大小推测时长', filePath, e.stack) log('获取语音文件时长失败, 使用文件大小推测时长', filePath, e.stack)
duration = await guessDuration(filePath) duration = await guessDuration(filePath)
} }
@@ -125,7 +125,7 @@ export async function encodeSilk(filePath: string) {
duration, duration,
} }
} }
} catch (error) { } catch (error: any) {
log('convert silk failed', error.stack) log('convert silk failed', error.stack)
return {} return {}
} }

View File

@@ -52,7 +52,7 @@ export async function file2base64(path: string) {
const data = await fsPromise.readFile(path) const data = await fsPromise.readFile(path)
// 转换为Base64编码 // 转换为Base64编码
result.data = data.toString('base64') result.data = data.toString('base64')
} catch (err) { } catch (err: any) {
result.err = err.toString() result.err = err.toString()
} }
return result return result
@@ -119,7 +119,7 @@ type Uri2LocalRes = {
isLocal: boolean isLocal: boolean
} }
export async function uri2local(uri: string, fileName: string = null): Promise<Uri2LocalRes> { export async function uri2local(uri: string, fileName: string | null = null): Promise<Uri2LocalRes> {
let res = { let res = {
success: false, success: false,
errMsg: '', errMsg: '',
@@ -132,10 +132,10 @@ export async function uri2local(uri: string, fileName: string = null): Promise<U
fileName = randomUUID() fileName = randomUUID()
} }
let filePath = path.join(TEMP_DIR, fileName) let filePath = path.join(TEMP_DIR, fileName)
let url = null let url: URL | null = null
try { try {
url = new URL(uri) url = new URL(uri)
} catch (e) { } catch (e: any) {
res.errMsg = `uri ${uri} 解析失败,` + e.toString() + ` 可能${uri}不存在` res.errMsg = `uri ${uri} 解析失败,` + e.toString() + ` 可能${uri}不存在`
return res return res
} }
@@ -153,10 +153,10 @@ export async function uri2local(uri: string, fileName: string = null): Promise<U
} }
} else if (url.protocol == 'http:' || url.protocol == 'https:') { } else if (url.protocol == 'http:' || url.protocol == 'https:') {
// 下载文件 // 下载文件
let buffer: Buffer = null let buffer: Buffer | null = null
try { try {
buffer = await httpDownload(uri) buffer = await httpDownload(uri)
} catch (e) { } catch (e: any) {
res.errMsg = `${url}下载失败,` + e.toString() res.errMsg = `${url}下载失败,` + e.toString()
return res return res
} }
@@ -208,7 +208,7 @@ export async function uri2local(uri: string, fileName: string = null): Promise<U
// } // }
if (!res.isLocal && !res.ext) { if (!res.isLocal && !res.ext) {
try { try {
let ext: string = (await fileType.fileTypeFromFile(filePath)).ext const ext = (await fileType.fileTypeFromFile(filePath))?.ext
if (ext) { if (ext) {
log('获取文件类型', ext, filePath) log('获取文件类型', ext, filePath)
await fsPromise.rename(filePath, filePath + `.${ext}`) await fsPromise.rename(filePath, filePath + `.${ext}`)

View File

@@ -41,7 +41,7 @@ export function mergeNewProperties(newObj: any, oldObj: any) {
}) })
} }
export function isNull(value: any) { export function isNull(value: any): value is null | undefined | void {
return value === undefined || value === null return value === undefined || value === null
} }

View File

@@ -91,7 +91,7 @@ export async function getRemoteVersionByMirror(mirrorGithub: string) {
releasePage = (await httpDownload(mirrorGithub + '/LLOneBot/LLOneBot/releases')).toString() releasePage = (await httpDownload(mirrorGithub + '/LLOneBot/LLOneBot/releases')).toString()
// log("releasePage", releasePage); // log("releasePage", releasePage);
if (releasePage === 'error') return '' if (releasePage === 'error') return ''
return releasePage.match(new RegExp('(?<=(tag/v)).*?(?=("))'))[0] return releasePage.match(new RegExp('(?<=(tag/v)).*?(?=("))'))?.[0]
} catch {} } catch {}
return '' return ''
} }

View File

@@ -31,10 +31,10 @@ export async function getVideoInfo(filePath: string) {
console.log('未找到视频流信息。') console.log('未找到视频流信息。')
} }
resolve({ resolve({
width: videoStream.width, width: videoStream?.width!,
height: videoStream.height, height: videoStream?.height!,
time: parseInt(videoStream.duration), time: parseInt(videoStream?.duration!),
format: metadata.format.format_name, format: metadata.format.format_name!,
size, size,
filePath, filePath,
}) })
@@ -67,7 +67,7 @@ export async function encodeMp4(filePath: string) {
return videoInfo return videoInfo
} }
export function checkFfmpeg(newPath: string = null): Promise<boolean> { export function checkFfmpeg(newPath: string | null = null): Promise<boolean> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
log('开始检查ffmpeg', newPath) log('开始检查ffmpeg', newPath)
if (newPath) { if (newPath) {

View File

@@ -123,7 +123,7 @@ function onLoad() {
return return
} }
dialog dialog
.showMessageBox(mainWindow, { .showMessageBox(mainWindow!, {
type: 'question', type: 'question',
buttons: ['确认', '取消'], buttons: ['确认', '取消'],
defaultId: 0, // 默认选中的按钮0 代表第一个按钮,即 "确认" defaultId: 0, // 默认选中的按钮0 代表第一个按钮,即 "确认"
@@ -210,7 +210,7 @@ function onLoad() {
}>([ReceiveCmdS.NEW_MSG, ReceiveCmdS.NEW_ACTIVE_MSG], async (payload) => { }>([ReceiveCmdS.NEW_MSG, ReceiveCmdS.NEW_ACTIVE_MSG], async (payload) => {
try { try {
await postReceiveMsg(payload.msgList) await postReceiveMsg(payload.msgList)
} catch (e) { } catch (e: any) {
log('report message error: ', e.stack.toString()) log('report message error: ', e.stack.toString())
} }
}) })
@@ -254,7 +254,7 @@ function onLoad() {
// log("reportSelfMessage", payload) // log("reportSelfMessage", payload)
try { try {
await postReceiveMsg([payload.msgRecord]) await postReceiveMsg([payload.msgRecord])
} catch (e) { } catch (e: any) {
log('report self message error: ', e.stack.toString()) log('report self message error: ', e.stack.toString())
} }
}) })
@@ -332,7 +332,7 @@ function onLoad() {
if (notify.user2.uid) { if (notify.user2.uid) {
// 是被踢的 // 是被踢的
const member2 = await getGroupMember(notify.group.groupCode, notify.user2.uid) const member2 = await getGroupMember(notify.group.groupCode, notify.user2.uid)
operatorId = member2.uin operatorId = member2?.uin!
subType = 'kick' subType = 'kick'
} }
let groupDecreaseEvent = new OB11GroupDecreaseEvent( let groupDecreaseEvent = new OB11GroupDecreaseEvent(
@@ -342,14 +342,12 @@ function onLoad() {
subType, subType,
) )
postOb11Event(groupDecreaseEvent, true) postOb11Event(groupDecreaseEvent, true)
} catch (e) { } catch (e: any) {
log('获取群通知的成员信息失败', notify, e.stack.toString()) log('获取群通知的成员信息失败', notify, e.stack.toString())
} }
} }
else if ([GroupNotifyTypes.JOIN_REQUEST, GroupNotifyTypes.JOIN_REQUEST_BY_INVITED].includes(notify.type)) { else if ([GroupNotifyTypes.JOIN_REQUEST, GroupNotifyTypes.JOIN_REQUEST_BY_INVITED].includes(notify.type)) {
log('有加群请求') log('有加群请求')
let groupRequestEvent = new OB11GroupRequestEvent()
groupRequestEvent.group_id = parseInt(notify.group.groupCode)
let requestQQ = uidMaps[notify.user1.uid] let requestQQ = uidMaps[notify.user1.uid]
if (!requestQQ) { if (!requestQQ) {
try { try {
@@ -358,40 +356,47 @@ function onLoad() {
log('获取加群人QQ号失败', e) log('获取加群人QQ号失败', e)
} }
} }
groupRequestEvent.user_id = parseInt(requestQQ) || 0 let invitorId: number
groupRequestEvent.sub_type = 'add'
groupRequestEvent.comment = notify.postscript
groupRequestEvent.flag = notify.seq
if (notify.type == GroupNotifyTypes.JOIN_REQUEST_BY_INVITED) { if (notify.type == GroupNotifyTypes.JOIN_REQUEST_BY_INVITED) {
// groupRequestEvent.sub_type = 'invite' // groupRequestEvent.sub_type = 'invite'
let invitorQQ = uidMaps[notify.user2.uid] let invitorQQ = uidMaps[notify.user2.uid]
if (!invitorQQ) { if (!invitorQQ) {
try { try {
let invitor = (await NTQQUserApi.getUserDetailInfo(notify.user2.uid)) let invitor = (await NTQQUserApi.getUserDetailInfo(notify.user2.uid))
groupRequestEvent.invitor_id = parseInt(invitor.uin) invitorId = parseInt(invitor.uin)
} catch (e) { } catch (e) {
groupRequestEvent.invitor_id = 0 invitorId = 0
log('获取邀请人QQ号失败', e) log('获取邀请人QQ号失败', e)
} }
} }
} }
const groupRequestEvent = new OB11GroupRequestEvent(
parseInt(notify.group.groupCode),
parseInt(requestQQ) || 0,
notify.seq,
notify.postscript,
invitorId!,
'add'
)
postOb11Event(groupRequestEvent) postOb11Event(groupRequestEvent)
} }
else if (notify.type == GroupNotifyTypes.INVITE_ME) { else if (notify.type == GroupNotifyTypes.INVITE_ME) {
log('收到邀请我加群通知') log('收到邀请我加群通知')
let groupInviteEvent = new OB11GroupRequestEvent() let userId = uidMaps[notify.user2.uid]
groupInviteEvent.group_id = parseInt(notify.group.groupCode) if (!userId) {
let user_id = uidMaps[notify.user2.uid] userId = (await NTQQUserApi.getUserDetailInfo(notify.user2.uid))?.uin
if (!user_id) {
user_id = (await NTQQUserApi.getUserDetailInfo(notify.user2.uid))?.uin
} }
groupInviteEvent.user_id = parseInt(user_id) const groupInviteEvent = new OB11GroupRequestEvent(
groupInviteEvent.sub_type = 'invite' parseInt(notify.group.groupCode),
// groupInviteEvent.invitor_id = parseInt(user_id) parseInt(userId),
groupInviteEvent.flag = notify.seq notify.seq,
undefined,
undefined,
'invite'
)
postOb11Event(groupInviteEvent) postOb11Event(groupInviteEvent)
} }
} catch (e) { } catch (e: any) {
log('解析群通知失败', e.stack.toString()) log('解析群通知失败', e.stack.toString())
} }
} }
@@ -403,19 +408,18 @@ function onLoad() {
registerReceiveHook<FriendRequestNotify>(ReceiveCmdS.FRIEND_REQUEST, async (payload) => { registerReceiveHook<FriendRequestNotify>(ReceiveCmdS.FRIEND_REQUEST, async (payload) => {
for (const req of payload.data.buddyReqs) { for (const req of payload.data.buddyReqs) {
let flag = req.friendUid + req.reqTime const flag = req.friendUid + req.reqTime
if (req.isUnread && parseInt(req.reqTime) > startTime / 1000) { if (req.isUnread && parseInt(req.reqTime) > startTime / 1000) {
friendRequests[flag] = req friendRequests[flag] = req
log('有新的好友请求', req) log('有新的好友请求', req)
let friendRequestEvent = new OB11FriendRequestEvent() let userId: number
try { try {
let requester = await NTQQUserApi.getUserDetailInfo(req.friendUid) const requester = await NTQQUserApi.getUserDetailInfo(req.friendUid)
friendRequestEvent.user_id = parseInt(requester.uin) userId = parseInt(requester.uin)
} catch (e) { } catch (e) {
log('获取加好友者QQ号失败', e) log('获取加好友者QQ号失败', e)
} }
friendRequestEvent.flag = flag const friendRequestEvent = new OB11FriendRequestEvent(userId!, req.extWords, flag)
friendRequestEvent.comment = req.extWords
postOb11Event(friendRequestEvent) postOb11Event(friendRequestEvent)
} }
} }
@@ -438,7 +442,7 @@ function onLoad() {
uidMaps[value] = key uidMaps[value] = key
} }
}) })
NTEventDispatch.init({ ListenerMap: wrapperConstructor, WrapperSession: wrapperApi.NodeIQQNTWrapperSession }) NTEventDispatch.init({ ListenerMap: wrapperConstructor, WrapperSession: wrapperApi.NodeIQQNTWrapperSession! })
try { try {
log('start get groups') log('start get groups')
const _groups = await NTQQGroupApi.getGroups() const _groups = await NTQQGroupApi.getGroups()
@@ -509,7 +513,7 @@ function onLoad() {
selfInfo.nick = userInfo.nick selfInfo.nick = userInfo.nick
return return
} }
} catch (e) { } catch (e: any) {
log('get self nickname failed', e.stack) log('get self nickname failed', e.stack)
} }
if (getSelfNickCount < 10) { if (getSelfNickCount < 10) {
@@ -537,7 +541,7 @@ function onBrowserWindowCreated(window: BrowserWindow) {
try { try {
hookNTQQApiCall(window) hookNTQQApiCall(window)
hookNTQQApiReceive(window) hookNTQQApiReceive(window)
} catch (e) { } catch (e: any) {
log('LLOneBot hook error: ', e.toString()) log('LLOneBot hook error: ', e.toString())
} }
} }

View File

@@ -22,7 +22,7 @@ import { Peer } from '@/ntqqapi/types/msg'
export class NTQQFileApi { export class NTQQFileApi {
static async getVideoUrl(peer: Peer, msgId: string, elementId: string): Promise<string> { static async getVideoUrl(peer: Peer, msgId: string, elementId: string): Promise<string> {
const session = wrapperApi.NodeIQQNTWrapperSession const session = wrapperApi.NodeIQQNTWrapperSession
return (await session.getRichMediaService().getVideoPlayUrlV2(peer, return (await session?.getRichMediaService().getVideoPlayUrlV2(peer,
msgId, msgId,
elementId, elementId,
0, 0,

View File

@@ -70,9 +70,9 @@ export class NTQQFriendApi {
static async getBuddyV2(refresh = false): Promise<FriendV2[]> { static async getBuddyV2(refresh = false): Promise<FriendV2[]> {
const uids: string[] = [] const uids: string[] = []
const session = wrapperApi.NodeIQQNTWrapperSession const session = wrapperApi.NodeIQQNTWrapperSession
const buddyService = session.getBuddyService() const buddyService = session?.getBuddyService()
const buddyListV2 = refresh ? await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) const buddyListV2 = refresh ? await buddyService?.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService?.getBuddyListV2('0', BuddyListReqType.KNOMAL)
uids.push(...buddyListV2.data.flatMap(item => item.buddyUids)) uids.push(...buddyListV2?.data.flatMap(item => item.buddyUids)!)
const data = await NTEventDispatch.CallNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>( const data = await NTEventDispatch.CallNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
) )

View File

@@ -135,7 +135,7 @@ export class NTQQGroupApi {
} }
static async handleGroupRequest(seq: string, operateType: GroupRequestOperateTypes, reason?: string) { static async handleGroupRequest(seq: string, operateType: GroupRequestOperateTypes, reason?: string) {
const notify: GroupNotify = await dbUtil.getGroupNotify(seq) const notify = await dbUtil.getGroupNotify(seq)
if (!notify) { if (!notify) {
throw `${seq}对应的加群通知不存在` throw `${seq}对应的加群通知不存在`
} }
@@ -303,27 +303,27 @@ export class NTQQGroupApi {
const session = wrapperApi.NodeIQQNTWrapperSession const session = wrapperApi.NodeIQQNTWrapperSession
// 代码没测过 // 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
let MsgData = await session.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false) let MsgData = await session?.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false)
let param = { let param = {
groupCode: GroupCode, groupCode: GroupCode,
msgRandom: parseInt(MsgData.msgList[0].msgRandom), msgRandom: parseInt(MsgData.msgList[0].msgRandom),
msgSeq: parseInt(MsgData.msgList[0].msgSeq) msgSeq: parseInt(MsgData.msgList[0].msgSeq)
} }
// GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数 // GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数
return session.getGroupService().removeGroupEssence(param) return session?.getGroupService().removeGroupEssence(param)
} }
static async addGroupEssence(GroupCode: string, msgId: string) { static async addGroupEssence(GroupCode: string, msgId: string) {
const session = wrapperApi.NodeIQQNTWrapperSession const session = wrapperApi.NodeIQQNTWrapperSession
// 代码没测过 // 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
let MsgData = await session.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false) let MsgData = await session?.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false)
let param = { let param = {
groupCode: GroupCode, groupCode: GroupCode,
msgRandom: parseInt(MsgData.msgList[0].msgRandom), msgRandom: parseInt(MsgData.msgList[0].msgRandom),
msgSeq: parseInt(MsgData.msgList[0].msgSeq) msgSeq: parseInt(MsgData.msgList[0].msgSeq)
} }
// GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数 // GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数
return session.getGroupService().addGroupEssence(param) return session?.getGroupService().addGroupEssence(param)
} }
} }

View File

@@ -33,7 +33,7 @@ async function sendWaiter(peer: Peer, waitComplete = true, timeout: number = 100
} }
await waitLastSend() await waitLastSend()
let sentMessage: RawMessage = null let sentMessage: RawMessage | null = null
sendMessagePool[peerUid] = async (rawMessage: RawMessage) => { sendMessagePool[peerUid] = async (rawMessage: RawMessage) => {
delete sendMessagePool[peerUid] delete sendMessagePool[peerUid]
sentMessage = rawMessage sentMessage = rawMessage
@@ -290,6 +290,6 @@ export class NTQQMsgApi {
} }
static async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) { static async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) {
const session = wrapperApi.NodeIQQNTWrapperSession const session = wrapperApi.NodeIQQNTWrapperSession
return await session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z); return await session?.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z);
} }
} }

View File

@@ -196,7 +196,7 @@ export class NTQQUserApi {
static async getPSkey(domains: string[]): Promise<Map<string, string>> { static async getPSkey(domains: string[]): Promise<Map<string, string>> {
const session = wrapperApi.NodeIQQNTWrapperSession const session = wrapperApi.NodeIQQNTWrapperSession
const res = await session.getTipOffService().getPskey(domains, true) const res = await session?.getTipOffService().getPskey(domains, true)
if (res.result !== 0) { if (res.result !== 0) {
throw new Error(`获取Pskey失败: ${res.errMsg}`) throw new Error(`获取Pskey失败: ${res.errMsg}`)
} }
@@ -205,6 +205,6 @@ export class NTQQUserApi {
static async getClientKey(): Promise<ClientKeyData> { static async getClientKey(): Promise<ClientKeyData> {
const session = wrapperApi.NodeIQQNTWrapperSession const session = wrapperApi.NodeIQQNTWrapperSession
return await session.getTicketService().forceFetchClientKey('') return await session?.getTicketService().forceFetchClientKey('')
} }
} }

View File

@@ -121,20 +121,20 @@ export interface GroupEssenceMsgRet {
} }
export class WebApi { export class WebApi {
static async getGroupEssenceMsg(GroupCode: string, page_start: string): Promise<GroupEssenceMsgRet> { static async getGroupEssenceMsg(GroupCode: string, page_start: string): Promise<GroupEssenceMsgRet | undefined> {
const { cookies: CookieValue, bkn: Bkn } = (await NTQQUserApi.getCookies('qun.qq.com')) const { cookies: CookieValue, bkn: Bkn } = (await NTQQUserApi.getCookies('qun.qq.com'))
const url = 'https://qun.qq.com/cgi-bin/group_digest/digest_list?bkn=' + Bkn + '&group_code=' + GroupCode + '&page_start=' + page_start + '&page_limit=20'; const url = 'https://qun.qq.com/cgi-bin/group_digest/digest_list?bkn=' + Bkn + '&group_code=' + GroupCode + '&page_start=' + page_start + '&page_limit=20'
let ret; let ret: GroupEssenceMsgRet
try { try {
ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>(url, 'GET', '', { 'Cookie': CookieValue }); ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>(url, 'GET', '', { 'Cookie': CookieValue })
} catch { } catch {
return undefined; return undefined
} }
//console.log(url, CookieValue); //console.log(url, CookieValue)
if (ret.retcode !== 0) { if (ret.retcode !== 0) {
return undefined; return undefined
} }
return ret; return ret
} }
static async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> { static async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> {

View File

@@ -27,7 +27,7 @@ export class NTQQWindowApi {
static async openWindow<R = GeneralCallResult>( static async openWindow<R = GeneralCallResult>(
ntQQWindow: NTQQWindow, ntQQWindow: NTQQWindow,
args: any[], args: any[],
cbCmd: ReceiveCmd = null, cbCmd: ReceiveCmd | null = null,
autoCloseSeconds: number = 2, autoCloseSeconds: number = 2,
) { ) {
const result = await callNTQQApi<R>({ const result = await callNTQQApi<R>({

View File

@@ -283,7 +283,7 @@ export class SendMsgElementConstructor {
if (faceId >= 222){ if (faceId >= 222){
faceType = 2 faceType = 2
} }
if (face.AniStickerType){ if (face?.AniStickerType){
faceType = 3; faceType = 3;
} }
return { return {
@@ -292,10 +292,10 @@ export class SendMsgElementConstructor {
faceElement: { faceElement: {
faceIndex: faceId, faceIndex: faceId,
faceType, faceType,
faceText: face.QDes, faceText: face?.QDes,
stickerId: face.AniStickerId, stickerId: face?.AniStickerId,
stickerType: face.AniStickerType, stickerType: face?.AniStickerType,
packId: face.AniStickerPackId, packId: face?.AniStickerPackId,
sourceType: 1, sourceType: 1,
}, },
} }
@@ -329,7 +329,7 @@ export class SendMsgElementConstructor {
stickerId: '33', stickerId: '33',
sourceType: 1, sourceType: 1,
stickerType: 2, stickerType: 2,
resultId: resultId.toString(), resultId: resultId?.toString(),
surpriseId: '', surpriseId: '',
// "randomType": 1, // "randomType": 1,
}, },
@@ -351,7 +351,7 @@ export class SendMsgElementConstructor {
stickerId: '34', stickerId: '34',
sourceType: 1, sourceType: 1,
stickerType: 2, stickerType: 2,
resultId: resultId.toString(), resultId: resultId?.toString(),
surpriseId: '', surpriseId: '',
// "randomType": 1, // "randomType": 1,
}, },

View File

@@ -123,7 +123,7 @@ export function hookNTQQApiReceive(window: BrowserWindow) {
delete hookApiCallbacks[callbackId] delete hookApiCallbacks[callbackId]
} }
} }
} catch (e) { } catch (e: any) {
log('hookNTQQApiReceive error', e.stack.toString(), args) log('hookNTQQApiReceive error', e.stack.toString(), args)
} }
originalSend.call(window.webContents, channel, ...args) originalSend.call(window.webContents, channel, ...args)
@@ -157,7 +157,7 @@ export function hookNTQQApiCall(window: BrowserWindow) {
try { try {
let _ = hook.hookFunc(callParams) let _ = hook.hookFunc(callParams)
if (hook.hookFunc.constructor.name === 'AsyncFunction') { if (hook.hookFunc.constructor.name === 'AsyncFunction') {
;(_ as Promise<void>).then() (_ as Promise<void>).then()
} }
} catch (e) { } catch (e) {
log('hook call error', e, _args) log('hook call error', e, _args)
@@ -296,7 +296,7 @@ async function processGroupEvent(payload: { groupList: Group[] }) {
// 判断bot是否是管理员如果是管理员不需要从这里得知有人退群这里的退群无法得知是主动退群还是被踢 // 判断bot是否是管理员如果是管理员不需要从这里得知有人退群这里的退群无法得知是主动退群还是被踢
let bot = await getGroupMember(group.groupCode, selfInfo.uin) let bot = await getGroupMember(group.groupCode, selfInfo.uin)
if (bot.role == GroupMemberRole.admin || bot.role == GroupMemberRole.owner) { if (bot?.role == GroupMemberRole.admin || bot?.role == GroupMemberRole.owner) {
continue continue
} }
for (const member of oldMembers) { for (const member of oldMembers) {
@@ -320,7 +320,7 @@ async function processGroupEvent(payload: { groupList: Group[] }) {
} }
updateGroups(newGroupList, false).then() updateGroups(newGroupList, false).then()
} catch (e) { } catch (e: any) {
updateGroups(payload.groupList).then() updateGroups(payload.groupList).then()
log('更新群信息错误', e.stack.toString()) log('更新群信息错误', e.stack.toString())
} }
@@ -372,10 +372,11 @@ export async function startHook() {
) )
} else if (member.role != existMember.role) { } else if (member.role != existMember.role) {
log('有管理员变动通知') log('有管理员变动通知')
let groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent() const groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent(
groupAdminNoticeEvent.group_id = parseInt(groupCode) member.role == GroupMemberRole.admin ? 'set' : 'unset',
groupAdminNoticeEvent.user_id = parseInt(member.uin) parseInt(groupCode),
groupAdminNoticeEvent.sub_type = member.role == GroupMemberRole.admin ? 'set' : 'unset' parseInt(member.uin)
)
postOb11Event(groupAdminNoticeEvent, true) postOb11Event(groupAdminNoticeEvent, true)
} }
Object.assign(existMember, member) Object.assign(existMember, member)
@@ -453,7 +454,7 @@ export async function startHook() {
const pttPath = msgElement.pttElement?.filePath const pttPath = msgElement.pttElement?.filePath
const filePath = msgElement.fileElement?.filePath const filePath = msgElement.fileElement?.filePath
const videoPath = msgElement.videoElement?.filePath const videoPath = msgElement.videoElement?.filePath
const videoThumbPath: string[] = [...msgElement.videoElement?.thumbPath.values()] const videoThumbPath: string[] = [...msgElement.videoElement.thumbPath?.values()!]
const pathList = [picPath, ...picThumbPath, pttPath, filePath, videoPath, ...videoThumbPath] const pathList = [picPath, ...picThumbPath, pttPath, filePath, videoPath, ...videoThumbPath]
if (msgElement.picElement) { if (msgElement.picElement) {
pathList.push(...Object.values(msgElement.picElement.thumbPath)) pathList.push(...Object.values(msgElement.picElement.thumbPath))
@@ -471,7 +472,7 @@ export async function startHook() {
}) })
} }
} }
}, getConfigUtil().getConfig().autoDeleteFileSecond * 1000) }, getConfigUtil().getConfig().autoDeleteFileSecond! * 1000)
} }
} }
}) })
@@ -486,7 +487,7 @@ export async function startHook() {
if (sendCallback) { if (sendCallback) {
try { try {
sendCallback(message) sendCallback(message)
} catch (e) { } catch (e: any) {
log('receive self msg error', e.stack) log('receive self msg error', e.stack)
} }
} }
@@ -518,8 +519,8 @@ export async function startHook() {
NTQQMsgApi.getMsgHistory(peer, '', 20).then(({ msgList }) => { NTQQMsgApi.getMsgHistory(peer, '', 20).then(({ msgList }) => {
let lastTempMsg = msgList.pop() let lastTempMsg = msgList.pop()
log('激活窗口之前的第一条临时会话消息:', lastTempMsg) log('激活窗口之前的第一条临时会话消息:', lastTempMsg)
if (Date.now() / 1000 - parseInt(lastTempMsg.msgTime) < 5) { if (Date.now() / 1000 - parseInt(lastTempMsg?.msgTime!) < 5) {
OB11Constructor.message(lastTempMsg).then((r) => postOb11Event(r)) OB11Constructor.message(lastTempMsg!).then((r) => postOb11Event(r))
} }
}) })
}) })
@@ -550,5 +551,4 @@ export async function startHook() {
log('重新激活聊天窗口', peer, { result: r.result, errMsg: r.errMsg }) log('重新激活聊天窗口', peer, { result: r.result, errMsg: r.errMsg })
}) })
}) })
} }

View File

@@ -1,7 +1,6 @@
import { ipcMain } from 'electron' import { ipcMain } from 'electron'
import { hookApiCallbacks, ReceiveCmd, ReceiveCmdS, registerReceiveHook, removeReceiveHook } from './hook' import { hookApiCallbacks, ReceiveCmd, ReceiveCmdS, registerReceiveHook, removeReceiveHook } from './hook'
import { log } from '../common/utils/log' import { log } from '../common/utils/log'
import { NTQQWindow, NTQQWindowApi, NTQQWindows } from './api/window'
import { HOOK_LOG } from '../common/config' import { HOOK_LOG } from '../common/config'
import { randomUUID } from 'node:crypto' import { randomUUID } from 'node:crypto'

View File

@@ -4,8 +4,8 @@ import { OB11Return } from '../types'
import { log } from '../../common/utils/log' import { log } from '../../common/utils/log'
class BaseAction<PayloadType, ReturnDataType> { abstract class BaseAction<PayloadType, ReturnDataType> {
actionName: ActionName abstract actionName: ActionName
protected async check(payload: PayloadType): Promise<BaseCheckResult> { protected async check(payload: PayloadType): Promise<BaseCheckResult> {
return { return {
@@ -21,7 +21,7 @@ class BaseAction<PayloadType, ReturnDataType> {
try { try {
const resData = await this._handle(payload) const resData = await this._handle(payload)
return OB11Response.ok(resData) return OB11Response.ok(resData)
} catch (e) { } catch (e: any) {
log('发生错误', e) log('发生错误', e)
return OB11Response.error(e?.toString() || e?.stack?.toString() || '未知错误,可能操作超时', 200) return OB11Response.error(e?.toString() || e?.stack?.toString() || '未知错误,可能操作超时', 200)
} }
@@ -35,7 +35,7 @@ class BaseAction<PayloadType, ReturnDataType> {
try { try {
const resData = await this._handle(payload) const resData = await this._handle(payload)
return OB11Response.ok(resData, echo) return OB11Response.ok(resData, echo)
} catch (e) { } catch (e: any) {
log('发生错误', e) log('发生错误', e)
return OB11Response.error(e.stack?.toString() || e.toString(), 1200, echo) return OB11Response.error(e.stack?.toString() || e.toString(), 1200, echo)
} }

View File

@@ -20,7 +20,7 @@ export interface GetFileResponse {
base64?: string base64?: string
} }
export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> { export abstract class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
private getElement(msg: RawMessage, elementId: string): VideoElement | FileElement { private getElement(msg: RawMessage, elementId: string): VideoElement | FileElement {
let element = msg.elements.find((e) => e.elementId === elementId) let element = msg.elements.find((e) => e.elementId === elementId)
if (!element) { if (!element) {
@@ -41,7 +41,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
// 等待文件下载完成 // 等待文件下载完成
msg = await dbUtil.getMsgByLongId(cache.msgId) msg = await dbUtil.getMsgByLongId(cache.msgId)
log('下载完成后的msg', msg) log('下载完成后的msg', msg)
cache.filePath = this.getElement(msg, cache.elementId).filePath cache.filePath = this.getElement(msg!, cache.elementId).filePath
await checkFileReceived(cache.filePath, 10 * 1000) await checkFileReceived(cache.filePath, 10 * 1000)
dbUtil.addFileCache(file, cache).then() dbUtil.addFileCache(file, cache).then()
} }

View File

@@ -14,7 +14,7 @@ export default class GetRecord extends GetFileBase {
protected async _handle(payload: Payload): Promise<GetFileResponse> { protected async _handle(payload: Payload): Promise<GetFileResponse> {
let res = await super._handle(payload) let res = await super._handle(payload)
res.file = await decodeSilk(res.file, payload.out_format) res.file = await decodeSilk(res.file!, payload.out_format)
res.file_name = path.basename(res.file) res.file_name = path.basename(res.file)
res.file_size = fs.statSync(res.file).size.toString() res.file_size = fs.statSync(res.file).size.toString()
if (getConfigUtil().getConfig().enableLocalFile2Url){ if (getConfigUtil().getConfig().enableLocalFile2Url){

View File

@@ -1,6 +1,6 @@
import BaseAction from '../BaseAction' import BaseAction from '../BaseAction'
import { OB11ForwardMessage, OB11Message, OB11MessageData } from '../../types' import { OB11ForwardMessage, OB11Message, OB11MessageData } from '../../types'
import { NTQQMsgApi, Peer } from '../../../ntqqapi/api' import { NTQQMsgApi } from '@/ntqqapi/api'
import { dbUtil } from '../../../common/db' import { dbUtil } from '../../../common/db'
import { OB11Constructor } from '../../constructor' import { OB11Constructor } from '../../constructor'
import { ActionName } from '../types' import { ActionName } from '../types'
@@ -37,12 +37,13 @@ export class GoCQHTTGetForwardMsgAction extends BaseAction<Payload, any> {
let messages = await Promise.all( let messages = await Promise.all(
msgList.map(async (msg) => { msgList.map(async (msg) => {
let resMsg = await OB11Constructor.message(msg) let resMsg = await OB11Constructor.message(msg)
resMsg.message_id = await dbUtil.addMsg(msg) resMsg.message_id = (await dbUtil.addMsg(msg))!
return resMsg return resMsg
}), }),
) )
messages.map((msg) => { messages.map(v => {
;(<OB11ForwardMessage>msg).content = msg.message const msg = v as Partial<OB11ForwardMessage>
msg.content = msg.message
delete msg.message delete msg.message
}) })
return { messages } return { messages }

View File

@@ -6,7 +6,6 @@ import { ChatType } from '../../../ntqqapi/types'
import { dbUtil } from '../../../common/db' import { dbUtil } from '../../../common/db'
import { NTQQMsgApi } from '../../../ntqqapi/api/msg' import { NTQQMsgApi } from '../../../ntqqapi/api/msg'
import { OB11Constructor } from '../../constructor' import { OB11Constructor } from '../../constructor'
import { log } from '../../../common/utils'
interface Payload { interface Payload {
group_id: number group_id: number

View File

@@ -1,11 +1,12 @@
import BaseAction from '../BaseAction' import BaseAction from '../BaseAction'
import { getGroup, getUidByUin } from '../../../common/data' import { getGroup, getUidByUin } from '@/common/data'
import { ActionName } from '../types' import { ActionName } from '../types'
import { SendMsgElementConstructor } from '../../../ntqqapi/constructor' import { SendMsgElementConstructor } from '@/ntqqapi/constructor'
import { ChatType, SendFileElement } from '../../../ntqqapi/types' import { ChatType, SendFileElement } from '@/ntqqapi/types'
import fs from 'fs' import fs from 'fs'
import { NTQQMsgApi, Peer } from '../../../ntqqapi/api/msg' import { NTQQMsgApi } from '@/ntqqapi/api/msg'
import { uri2local } from '../../../common/utils' import { uri2local } from '@/common/utils'
import { Peer } from '@/ntqqapi/types'
interface Payload { interface Payload {
user_id: number user_id: number
@@ -20,9 +21,9 @@ class GoCQHTTPUploadFileBase extends BaseAction<Payload, null> {
getPeer(payload: Payload): Peer { getPeer(payload: Payload): Peer {
if (payload.user_id) { if (payload.user_id) {
return { chatType: ChatType.friend, peerUid: getUidByUin(payload.user_id.toString()) } return { chatType: ChatType.friend, peerUid: getUidByUin(payload.user_id.toString())! }
} }
return { chatType: ChatType.group, peerUid: payload.group_id.toString() } return { chatType: ChatType.group, peerUid: payload.group_id?.toString()! }
} }
protected async _handle(payload: Payload): Promise<null> { protected async _handle(payload: Payload): Promise<null> {

View File

@@ -1,24 +1,24 @@
import { GroupEssenceMsgRet, WebApi } from "@/ntqqapi/api"; import { GroupEssenceMsgRet, WebApi } from '@/ntqqapi/api'
import BaseAction from "../BaseAction"; import BaseAction from '../BaseAction'
import { ActionName } from "../types"; import { ActionName } from '../types'
interface PayloadType { interface PayloadType {
group_id: number; group_id: number
pages?: number; pages?: number
} }
export class GetGroupEssence extends BaseAction<PayloadType, GroupEssenceMsgRet> { export class GetGroupEssence extends BaseAction<PayloadType, GroupEssenceMsgRet | void> {
actionName = ActionName.GoCQHTTP_GetEssenceMsg; actionName = ActionName.GoCQHTTP_GetEssenceMsg
protected async _handle(payload: PayloadType) { protected async _handle(payload: PayloadType) {
throw '此 api 暂不支持' throw '此 api 暂不支持'
const ret = await WebApi.getGroupEssenceMsg(payload.group_id.toString(), payload.pages?.toString() || '0'); const ret = await WebApi.getGroupEssenceMsg(payload.group_id.toString(), payload.pages?.toString() || '0')
if (!ret) { if (!ret) {
throw new Error('获取失败'); throw new Error('获取失败')
} }
// ret.map((item) => { // ret.map((item) => {
// //
// }) // })
return ret; return ret
} }
} }

View File

@@ -1,22 +1,23 @@
import { WebApi, WebHonorType } from "@/ntqqapi/api"; import { WebApi, WebHonorType } from '@/ntqqapi/api'
import { ActionName } from "../types"; import { ActionName } from '../types'
import BaseAction from "../BaseAction"; import BaseAction from '../BaseAction'
interface Payload { interface Payload {
group_id: number, group_id: number
type?: WebHonorType type?: WebHonorType
} }
export class GetGroupHonorInfo extends BaseAction<Payload, Array<any>> { export class GetGroupHonorInfo extends BaseAction<Payload, Array<any>> {
actionName = ActionName.GetGroupHonorInfo; actionName = ActionName.GetGroupHonorInfo
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
// console.log(await NTQQUserApi.getRobotUinRange()); // console.log(await NTQQUserApi.getRobotUinRange())
if (!payload.group_id) { if (!payload.group_id) {
throw '缺少参数group_id'; throw '缺少参数group_id'
} }
if (!payload.type) { if (!payload.type) {
payload.type = WebHonorType.ALL; payload.type = WebHonorType.ALL
} }
return await WebApi.getGroupHonorInfo(payload.group_id.toString(), payload.type); return await WebApi.getGroupHonorInfo(payload.group_id.toString(), payload.type)
} }
} }

View File

@@ -2,13 +2,11 @@ import SendMsg from '../msg/SendMsg'
import { ActionName, BaseCheckResult } from '../types' import { ActionName, BaseCheckResult } from '../types'
import { OB11PostSendMsg } from '../../types' import { OB11PostSendMsg } from '../../types'
import { log } from '../../../common/utils/log'
class SendGroupMsg extends SendMsg { class SendGroupMsg extends SendMsg {
actionName = ActionName.SendGroupMsg actionName = ActionName.SendGroupMsg
protected async check(payload: OB11PostSendMsg): Promise<BaseCheckResult> { protected async check(payload: OB11PostSendMsg): Promise<BaseCheckResult> {
delete payload.user_id delete (payload as Partial<OB11PostSendMsg>).user_id
payload.message_type = 'group' payload.message_type = 'group'
return super.check(payload) return super.check(payload)
} }

View File

@@ -1,9 +1,10 @@
import BaseAction from '../BaseAction' import BaseAction from '../BaseAction'
import { NTQQMsgApi, Peer } from '../../../ntqqapi/api' import { NTQQMsgApi } from '@/ntqqapi/api'
import { ChatType, RawMessage } from '../../../ntqqapi/types' import { ChatType, RawMessage } from '@/ntqqapi/types'
import { dbUtil } from '../../../common/db' import { dbUtil } from '@/common/db'
import { getUidByUin } from '../../../common/data' import { getUidByUin } from '@/common/data'
import { ActionName } from '../types' import { ActionName } from '../types'
import { Peer } from '@/ntqqapi/types'
interface Payload { interface Payload {
message_id: number message_id: number
@@ -15,16 +16,16 @@ interface Response {
message_id: number message_id: number
} }
class ForwardSingleMsg extends BaseAction<Payload, Response> { abstract class ForwardSingleMsg extends BaseAction<Payload, Response> {
protected async getTargetPeer(payload: Payload): Promise<Peer> { protected async getTargetPeer(payload: Payload): Promise<Peer> {
if (payload.user_id) { if (payload.user_id) {
return { chatType: ChatType.friend, peerUid: getUidByUin(payload.user_id.toString()) } return { chatType: ChatType.friend, peerUid: getUidByUin(payload.user_id.toString())! }
} }
return { chatType: ChatType.group, peerUid: payload.group_id.toString() } return { chatType: ChatType.group, peerUid: payload.group_id.toString() }
} }
protected async _handle(payload: Payload): Promise<Response> { protected async _handle(payload: Payload): Promise<Response> {
const msg = await dbUtil.getMsgByShortId(payload.message_id) const msg = (await dbUtil.getMsgByShortId(payload.message_id))!
const peer = await this.getTargetPeer(payload) const peer = await this.getTargetPeer(payload)
const sentMsg = await NTQQMsgApi.forwardMsg( const sentMsg = await NTQQMsgApi.forwardMsg(
{ {
@@ -35,7 +36,7 @@ class ForwardSingleMsg extends BaseAction<Payload, Response> {
[msg.msgId], [msg.msgId],
) )
const ob11MsgId = await dbUtil.addMsg(sentMsg) const ob11MsgId = await dbUtil.addMsg(sentMsg)
return {message_id: ob11MsgId} return { message_id: ob11MsgId! }
} }
} }

View File

@@ -142,7 +142,7 @@ export async function createSendElements(
.RemainAtAllCountForUin .RemainAtAllCountForUin
log(`${groupCode}剩余at全体次数`, remainAtAllCount) log(`${groupCode}剩余at全体次数`, remainAtAllCount)
const self = await getGroupMember((target as Group)?.groupCode, selfInfo.uin) const self = await getGroupMember((target as Group)?.groupCode, selfInfo.uin)
isAdmin = self.role === GroupMemberRole.admin || self.role === GroupMemberRole.owner isAdmin = self?.role === GroupMemberRole.admin || self?.role === GroupMemberRole.owner
} catch (e) { } catch (e) {
} }
} }
@@ -171,8 +171,8 @@ export async function createSendElements(
SendMsgElementConstructor.reply( SendMsgElementConstructor.reply(
replyMsg.msgSeq, replyMsg.msgSeq,
replyMsg.msgId, replyMsg.msgId,
replyMsg.senderUin, replyMsg.senderUin!,
replyMsg.senderUin, replyMsg.senderUin!,
), ),
) )
} }
@@ -251,7 +251,7 @@ export async function createSendElements(
await SendMsgElementConstructor.pic( await SendMsgElementConstructor.pic(
path, path,
sendMsg.data.summary || '', sendMsg.data.summary || '',
<PicSubType>parseInt(sendMsg.data?.subType?.toString()) || 0, <PicSubType>parseInt(sendMsg.data?.subType?.toString()!) || 0,
), ),
) )
} }
@@ -266,16 +266,16 @@ export async function createSendElements(
case OB11MessageDataType.poke: { case OB11MessageDataType.poke: {
let qq = sendMsg.data?.qq || sendMsg.data?.id let qq = sendMsg.data?.qq || sendMsg.data?.id
if (qq) { if (qq) {
if ('groupCode' in target) { if ('groupCode' in target!) {
crychic.sendGroupPoke(target.groupCode, qq.toString()) crychic.sendGroupPoke(target.groupCode, qq.toString())
} }
else { else {
if (!qq) { if (!qq) {
qq = parseInt(target.uin) qq = parseInt(target?.uin!)
} }
crychic.sendFriendPoke(qq.toString()) crychic.sendFriendPoke(qq.toString())
} }
sendElements.push(SendMsgElementConstructor.poke('', '')) sendElements.push(SendMsgElementConstructor.poke('', '')!)
} }
} }
break break
@@ -387,10 +387,10 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
let group: Group | undefined = undefined let group: Group | undefined = undefined
let friend: Friend | undefined = undefined let friend: Friend | undefined = undefined
const genGroupPeer = async () => { const genGroupPeer = async () => {
group = await getGroup(payload.group_id.toString()) group = await getGroup(payload.group_id?.toString()!)
peer.chatType = ChatType.group peer.chatType = ChatType.group
// peer.name = group.name // peer.name = group.name
peer.peerUid = group.groupCode peer.peerUid = group?.groupCode!
} }
const genFriendPeer = () => { const genFriendPeer = () => {
@@ -429,8 +429,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
if (this.getSpecialMsgNum(messages, OB11MessageDataType.node)) { if (this.getSpecialMsgNum(messages, OB11MessageDataType.node)) {
try { try {
const returnMsg = await this.handleForwardNode(peer, messages as OB11MessageNode[], group) const returnMsg = await this.handleForwardNode(peer, messages as OB11MessageNode[], group)
return { message_id: returnMsg.msgShortId } return { message_id: returnMsg?.msgShortId! }
} catch (e) { } catch (e: any) {
throw '发送转发消息失败 ' + e.toString() throw '发送转发消息失败 ' + e.toString()
} }
} }
@@ -447,8 +447,9 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
} }
const postData: MusicSignPostData = { ...music.data } const postData: MusicSignPostData = { ...music.data }
if (type === 'custom' && music.data.content) { if (type === 'custom' && music.data.content) {
;(postData as CustomMusicSignPostData).singer = music.data.content const data = postData as CustomMusicSignPostData
delete (postData as OB11MessageCustomMusic['data']).content data.singer = music.data.content
delete (data as OB11MessageCustomMusic['data']).content
} }
if (type === 'custom') { if (type === 'custom') {
const customMusicData = music.data as CustomMusicSignPostData const customMusicData = music.data as CustomMusicSignPostData
@@ -493,7 +494,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
const returnMsg = await sendMsg(peer, sendElements, deleteAfterSentFiles) const returnMsg = await sendMsg(peer, sendElements, deleteAfterSentFiles)
deleteAfterSentFiles.map((f) => fs.unlink(f, () => { deleteAfterSentFiles.map((f) => fs.unlink(f, () => {
})) }))
return { message_id: returnMsg.msgShortId } return { message_id: returnMsg.msgShortId! }
} }
private getSpecialMsgNum(message: OB11MessageData[], msgType: OB11MessageDataType): number { private getSpecialMsgNum(message: OB11MessageData[], msgType: OB11MessageDataType): number {
@@ -503,7 +504,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
return 0 return 0
} }
private async cloneMsg(msg: RawMessage): Promise<RawMessage> { private async cloneMsg(msg: RawMessage): Promise<RawMessage | undefined> {
log('克隆的目标消息', msg) log('克隆的目标消息', msg)
let sendElements: SendMessageElement[] = [] let sendElements: SendMessageElement[] = []
for (const ele of msg.elements) { for (const ele of msg.elements) {
@@ -549,11 +550,11 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
if (nodeId) { if (nodeId) {
let nodeMsg = await dbUtil.getMsgByShortId(parseInt(nodeId)) let nodeMsg = await dbUtil.getMsgByShortId(parseInt(nodeId))
if (!needClone) { if (!needClone) {
nodeMsgIds.push(nodeMsg.msgId) nodeMsgIds.push(nodeMsg?.msgId!)
} }
else { else {
if (nodeMsg.peerUid !== selfInfo.uid) { if (nodeMsg?.peerUid !== selfInfo.uid) {
const cloneMsg = await this.cloneMsg(nodeMsg) const cloneMsg = await this.cloneMsg(nodeMsg!)
if (cloneMsg) { if (cloneMsg) {
nodeMsgIds.push(cloneMsg.msgId) nodeMsgIds.push(cloneMsg.msgId)
} }
@@ -605,7 +606,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
// 检查srcPeer是否一致不一致则需要克隆成自己的消息, 让所有srcPeer都变成自己的使其保持一致才能够转发 // 检查srcPeer是否一致不一致则需要克隆成自己的消息, 让所有srcPeer都变成自己的使其保持一致才能够转发
let nodeMsgArray: Array<RawMessage> = [] let nodeMsgArray: Array<RawMessage> = []
let srcPeer: Peer = null let srcPeer: Peer | null = null
let needSendSelf = false let needSendSelf = false
for (const [index, msgId] of nodeMsgIds.entries()) { for (const [index, msgId] of nodeMsgIds.entries()) {
const nodeMsg = await dbUtil.getMsgByLongId(msgId) const nodeMsg = await dbUtil.getMsgByLongId(msgId)
@@ -648,7 +649,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
} }
try { try {
log('开发转发', nodeMsgIds) log('开发转发', nodeMsgIds)
return await NTQQMsgApi.multiForwardMsg(srcPeer, destPeer, nodeMsgIds) return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, nodeMsgIds)
} catch (e) { } catch (e) {
log('forward failed', e) log('forward failed', e)
return null return null

View File

@@ -71,17 +71,17 @@ async function handleMsg(msg: OB11Message, quickAction: QuickOperationPrivateMes
peerUid: msg.user_id.toString(), peerUid: msg.user_id.toString(),
} }
if (msg.message_type == 'private') { if (msg.message_type == 'private') {
peer.peerUid = getUidByUin(msg.user_id.toString()) peer.peerUid = getUidByUin(msg.user_id.toString())!
if (msg.sub_type === 'group') { if (msg.sub_type === 'group') {
peer.chatType = ChatType.temp peer.chatType = ChatType.temp
} }
} }
else { else {
peer.chatType = ChatType.group peer.chatType = ChatType.group
peer.peerUid = msg.group_id.toString() peer.peerUid = msg.group_id?.toString()!
} }
if (reply) { if (reply) {
let group: Group = null let group: Group | null = null
let replyMessage: OB11MessageData[] = [] let replyMessage: OB11MessageData[] = []
if (ob11Config.enableQOAutoQuote) { if (ob11Config.enableQOAutoQuote) {
replyMessage.push({ replyMessage.push({
@@ -93,7 +93,7 @@ async function handleMsg(msg: OB11Message, quickAction: QuickOperationPrivateMes
} }
if (msg.message_type == 'group') { if (msg.message_type == 'group') {
group = await getGroup(msg.group_id.toString()) group = (await getGroup(msg.group_id?.toString()!))!
if ((quickAction as QuickOperationGroupMessage).at_sender) { if ((quickAction as QuickOperationGroupMessage).at_sender) {
replyMessage.push({ replyMessage.push({
type: 'at', type: 'at',
@@ -104,7 +104,7 @@ async function handleMsg(msg: OB11Message, quickAction: QuickOperationPrivateMes
} }
} }
replyMessage = replyMessage.concat(convertMessage2List(reply, quickAction.auto_escape)) replyMessage = replyMessage.concat(convertMessage2List(reply, quickAction.auto_escape))
const { sendElements, deleteAfterSentFiles } = await createSendElements(replyMessage, group) const { sendElements, deleteAfterSentFiles } = await createSendElements(replyMessage, group!)
log(`发送消息给`, peer, sendElements) log(`发送消息给`, peer, sendElements)
sendMsg(peer, sendElements, deleteAfterSentFiles, false).then().catch(log) sendMsg(peer, sendElements, deleteAfterSentFiles, false).then().catch(log)
} }
@@ -112,15 +112,15 @@ async function handleMsg(msg: OB11Message, quickAction: QuickOperationPrivateMes
const groupMsgQuickAction = quickAction as QuickOperationGroupMessage const groupMsgQuickAction = quickAction as QuickOperationGroupMessage
// handle group msg // handle group msg
if (groupMsgQuickAction.delete) { if (groupMsgQuickAction.delete) {
NTQQMsgApi.recallMsg(peer, [rawMessage.msgId]).then().catch(log) NTQQMsgApi.recallMsg(peer, [rawMessage?.msgId!]).then().catch(log)
} }
if (groupMsgQuickAction.kick) { if (groupMsgQuickAction.kick) {
NTQQGroupApi.kickMember(peer.peerUid, [rawMessage.senderUid]).then().catch(log) NTQQGroupApi.kickMember(peer.peerUid, [rawMessage?.senderUid!]).then().catch(log)
} }
if (groupMsgQuickAction.ban) { if (groupMsgQuickAction.ban) {
NTQQGroupApi.banMember(peer.peerUid, [ NTQQGroupApi.banMember(peer.peerUid, [
{ {
uid: rawMessage.senderUid, uid: rawMessage?.senderUid!,
timeStamp: groupMsgQuickAction.ban_duration || 60 * 30, timeStamp: groupMsgQuickAction.ban_duration || 60 * 30,
}, },
]).then().catch(log) ]).then().catch(log)

View File

@@ -1,9 +1,8 @@
import BaseAction from '../BaseAction' import BaseAction from '../BaseAction'
import { ActionName } from '../types' import { ActionName } from '../types'
import fs from 'fs' import fs from 'node:fs'
import Path from 'path' import Path from 'node:path'
import { ChatType, ChatCacheListItemBasic, CacheFileType } from '../../../ntqqapi/types' import { ChatType, ChatCacheListItemBasic, CacheFileType } from '../../../ntqqapi/types'
import { dbUtil } from '../../../common/db'
import { NTQQFileApi, NTQQFileCacheApi } from '../../../ntqqapi/api/file' import { NTQQFileApi, NTQQFileCacheApi } from '../../../ntqqapi/api/file'
export default class CleanCache extends BaseAction<void, void> { export default class CleanCache extends BaseAction<void, void> {
@@ -12,14 +11,16 @@ export default class CleanCache extends BaseAction<void, void> {
protected _handle(): Promise<void> { protected _handle(): Promise<void> {
return new Promise<void>(async (res, rej) => { return new Promise<void>(async (res, rej) => {
try { try {
// dbUtil.clearCache(); // dbUtil.clearCache()
const cacheFilePaths: string[] = [] const cacheFilePaths: string[] = []
await NTQQFileCacheApi.setCacheSilentScan(false) await NTQQFileCacheApi.setCacheSilentScan(false)
cacheFilePaths.push(await NTQQFileCacheApi.getHotUpdateCachePath()) cacheFilePaths.push(await NTQQFileCacheApi.getHotUpdateCachePath())
cacheFilePaths.push(await NTQQFileCacheApi.getDesktopTmpPath()) cacheFilePaths.push(await NTQQFileCacheApi.getDesktopTmpPath())
;(await NTQQFileCacheApi.getCacheSessionPathList()).forEach((e) => cacheFilePaths.push(e.value))
const list = await NTQQFileCacheApi.getCacheSessionPathList()
list.forEach((e) => cacheFilePaths.push(e.value))
// await NTQQApi.addCacheScannedPaths(); // XXX: 调用就崩溃,原因目前还未知 // await NTQQApi.addCacheScannedPaths(); // XXX: 调用就崩溃,原因目前还未知
const cacheScanResult = await NTQQFileCacheApi.scanCache() const cacheScanResult = await NTQQFileCacheApi.scanCache()

View File

@@ -8,7 +8,7 @@ export default class GetStatus extends BaseAction<any, OB11Status> {
protected async _handle(payload: any): Promise<OB11Status> { protected async _handle(payload: any): Promise<OB11Status> {
return { return {
online: selfInfo.online, online: selfInfo.online!,
good: true, good: true,
} }
} }

View File

@@ -19,7 +19,7 @@ export default class SendLike extends BaseAction<Payload, null> {
const friend = await getFriend(qq) const friend = await getFriend(qq)
let uid: string let uid: string
if (!friend) { if (!friend) {
uid = getUidByUin(qq) uid = getUidByUin(qq)!
} else { } else {
uid = friend.uid uid = friend.uid
} }

View File

@@ -39,7 +39,7 @@ import { NTQQFileApi } from '../ntqqapi/api/file'
import { NTQQMsgApi } from '../ntqqapi/api/msg' import { NTQQMsgApi } from '../ntqqapi/api/msg'
import { calcQQLevel } from '../common/utils/qqlevel' import { calcQQLevel } from '../common/utils/qqlevel'
import { log } from '../common/utils/log' import { log } from '../common/utils/log'
import { sleep } from '../common/utils/helper' import { isNull, sleep } from '../common/utils/helper'
import { getConfigUtil } from '../common/config' import { getConfigUtil } from '../common/config'
import { OB11GroupTitleEvent } from './event/notice/OB11GroupTitleEvent' import { OB11GroupTitleEvent } from './event/notice/OB11GroupTitleEvent'
import { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent' import { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent'
@@ -67,14 +67,14 @@ export class OB11Constructor {
const message_type = msg.chatType == ChatType.group ? 'group' : 'private' const message_type = msg.chatType == ChatType.group ? 'group' : 'private'
const resMsg: OB11Message = { const resMsg: OB11Message = {
self_id: parseInt(selfInfo.uin), self_id: parseInt(selfInfo.uin),
user_id: parseInt(msg.senderUin), user_id: parseInt(msg.senderUin!),
time: parseInt(msg.msgTime) || Date.now(), time: parseInt(msg.msgTime) || Date.now(),
message_id: msg.msgShortId, message_id: msg.msgShortId!,
real_id: msg.msgShortId, real_id: msg.msgShortId!,
message_seq: msg.msgShortId, message_seq: msg.msgShortId!,
message_type: msg.chatType == ChatType.group ? 'group' : 'private', message_type: msg.chatType == ChatType.group ? 'group' : 'private',
sender: { sender: {
user_id: parseInt(msg.senderUin), user_id: parseInt(msg.senderUin!),
nickname: msg.sendNickName, nickname: msg.sendNickName,
card: msg.sendMemberName || '', card: msg.sendMemberName || '',
}, },
@@ -91,7 +91,7 @@ export class OB11Constructor {
if (msg.chatType == ChatType.group) { if (msg.chatType == ChatType.group) {
resMsg.sub_type = 'normal' resMsg.sub_type = 'normal'
resMsg.group_id = parseInt(msg.peerUin) resMsg.group_id = parseInt(msg.peerUin)
const member = await getGroupMember(msg.peerUin, msg.senderUin) const member = await getGroupMember(msg.peerUin, msg.senderUin!)
if (member) { if (member) {
resMsg.sender.role = OB11Constructor.groupMemberRole(member.role) resMsg.sender.role = OB11Constructor.groupMemberRole(member.role)
resMsg.sender.nickname = member.nick resMsg.sender.nickname = member.nick
@@ -99,7 +99,7 @@ export class OB11Constructor {
} }
else if (msg.chatType == ChatType.friend) { else if (msg.chatType == ChatType.friend) {
resMsg.sub_type = 'friend' resMsg.sub_type = 'friend'
const friend = await getFriend(msg.senderUin) const friend = await getFriend(msg.senderUin!)
if (friend) { if (friend) {
resMsg.sender.nickname = friend.nick resMsg.sender.nickname = friend.nick
} }
@@ -140,7 +140,7 @@ export class OB11Constructor {
message_data = { message_data = {
type: OB11MessageDataType.at, type: OB11MessageDataType.at,
data: { data: {
qq, qq: qq!,
name name
} }
} }
@@ -160,12 +160,12 @@ export class OB11Constructor {
const replyMsg = await dbUtil.getMsgBySeqId(element.replyElement.replayMsgSeq) const replyMsg = await dbUtil.getMsgBySeqId(element.replyElement.replayMsgSeq)
// log("找到回复消息", replyMsg.msgShortId, replyMsg.msgId) // log("找到回复消息", replyMsg.msgShortId, replyMsg.msgId)
if (replyMsg) { if (replyMsg) {
message_data['data']['id'] = replyMsg.msgShortId.toString() message_data['data']['id'] = replyMsg.msgShortId?.toString()
} }
else { else {
continue continue
} }
} catch (e) { } catch (e: any) {
log('获取不到引用的消息', e.stack, element.replyElement.replayMsgSeq) log('获取不到引用的消息', e.stack, element.replyElement.replayMsgSeq)
} }
} }
@@ -221,12 +221,12 @@ export class OB11Constructor {
) )
} }
dbUtil dbUtil
.addFileCache(videoOrFileElement.fileUuid, { .addFileCache(videoOrFileElement.fileUuid!, {
msgId: msg.msgId, msgId: msg.msgId,
elementId: element.elementId, elementId: element.elementId,
fileName: videoOrFileElement.fileName, fileName: videoOrFileElement.fileName,
filePath: videoOrFileElement.filePath, filePath: videoOrFileElement.filePath,
fileSize: videoOrFileElement.fileSize, fileSize: videoOrFileElement.fileSize!,
downloadFunc: async () => { downloadFunc: async () => {
await NTQQFileApi.downloadMedia( await NTQQFileApi.downloadMedia(
msg.msgId, msg.msgId,
@@ -234,7 +234,7 @@ export class OB11Constructor {
msg.peerUid, msg.peerUid,
element.elementId, element.elementId,
ob11MessageDataType == OB11MessageDataType.video ob11MessageDataType == OB11MessageDataType.video
? (videoOrFileElement as VideoElement).thumbPath.get(0) ? (videoOrFileElement as VideoElement).thumbPath?.get(0)
: null, : null,
videoOrFileElement.filePath, videoOrFileElement.filePath,
) )
@@ -297,7 +297,7 @@ export class OB11Constructor {
message_data['data']['emoji_id'] = element.marketFaceElement.emojiId message_data['data']['emoji_id'] = element.marketFaceElement.emojiId
message_data['data']['emoji_package_id'] = String(element.marketFaceElement.emojiPackageId) message_data['data']['emoji_package_id'] = String(element.marketFaceElement.emojiPackageId)
message_data['data']['key'] = element.marketFaceElement.key message_data['data']['key'] = element.marketFaceElement.key
mFaceCache.set(md5, element.marketFaceElement.faceName) mFaceCache.set(md5, element.marketFaceElement.faceName!)
} }
else if (element.markdownElement) { else if (element.markdownElement) {
message_data['type'] = OB11MessageDataType.markdown message_data['type'] = OB11MessageDataType.markdown
@@ -321,7 +321,7 @@ export class OB11Constructor {
return resMsg return resMsg
} }
static async PrivateEvent(msg: RawMessage): Promise<OB11BaseNoticeEvent> { static async PrivateEvent(msg: RawMessage): Promise<OB11BaseNoticeEvent | void> {
if (msg.chatType !== ChatType.friend) { if (msg.chatType !== ChatType.friend) {
return return
} }
@@ -350,7 +350,7 @@ export class OB11Constructor {
} }
} }
static async GroupEvent(msg: RawMessage): Promise<OB11GroupNoticeEvent> { static async GroupEvent(msg: RawMessage): Promise<OB11GroupNoticeEvent | void> {
if (msg.chatType !== ChatType.group) { if (msg.chatType !== ChatType.group) {
return return
} }
@@ -360,10 +360,10 @@ export class OB11Constructor {
const event = new OB11GroupCardEvent( const event = new OB11GroupCardEvent(
parseInt(msg.peerUid), parseInt(msg.peerUid),
parseInt(msg.senderUin), parseInt(msg.senderUin),
msg.sendMemberName, msg.sendMemberName!,
member.cardName, member.cardName,
) )
member.cardName = msg.sendMemberName member.cardName = msg.sendMemberName!
return event return event
} }
} }
@@ -393,10 +393,10 @@ export class OB11Constructor {
} }
else if (groupElement.type === TipGroupElementType.ban) { else if (groupElement.type === TipGroupElementType.ban) {
log('收到群群员禁言提示', groupElement) log('收到群群员禁言提示', groupElement)
const memberUid = groupElement.shutUp.member.uid const memberUid = groupElement.shutUp?.member.uid
const adminUid = groupElement.shutUp.admin.uid const adminUid = groupElement.shutUp?.admin.uid
let memberUin: string = '' let memberUin: string = ''
let duration = parseInt(groupElement.shutUp.duration) let duration = parseInt(groupElement.shutUp?.duration!)
let sub_type: 'ban' | 'lift_ban' = duration > 0 ? 'ban' : 'lift_ban' let sub_type: 'ban' | 'lift_ban' = duration > 0 ? 'ban' : 'lift_ban'
if (memberUid) { if (memberUid) {
memberUin = memberUin =
@@ -410,7 +410,7 @@ export class OB11Constructor {
} }
} }
const adminUin = const adminUin =
(await getGroupMember(msg.peerUid, adminUid))?.uin || (await NTQQUserApi.getUserDetailInfo(adminUid))?.uin (await getGroupMember(msg.peerUid, adminUid!))?.uin || (await NTQQUserApi.getUserDetailInfo(adminUid!))?.uin
if (memberUin && adminUin) { if (memberUin && adminUin) {
return new OB11GroupBanEvent( return new OB11GroupBanEvent(
parseInt(msg.peerUid), parseInt(msg.peerUid),
@@ -443,8 +443,8 @@ export class OB11Constructor {
} }
} }
else if (element.fileElement) { else if (element.fileElement) {
return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), { return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin!), {
id: element.fileElement.fileUuid, id: element.fileElement.fileUuid!,
name: element.fileElement.fileName, name: element.fileElement.fileName,
size: parseInt(element.fileElement.fileSize), size: parseInt(element.fileElement.fileSize),
busid: element.fileElement.fileBizId || 0, busid: element.fileElement.fileBizId || 0,
@@ -476,13 +476,13 @@ export class OB11Constructor {
if (!msg) { if (!msg) {
return return
} }
return new OB11GroupMsgEmojiLikeEvent(parseInt(msg.peerUid), parseInt(senderUin), msg.msgShortId, [ return new OB11GroupMsgEmojiLikeEvent(parseInt(msg.peerUid), parseInt(senderUin), msg.msgShortId!, [
{ {
emoji_id: emojiId, emoji_id: emojiId,
count: 1, count: 1,
}, },
]) ])
} catch (e) { } catch (e: any) {
log('解析表情回应消息失败', e.stack) log('解析表情回应消息失败', e.stack)
} }
} }
@@ -495,8 +495,8 @@ export class OB11Constructor {
if (xmlElement?.content) { if (xmlElement?.content) {
const regex = /jp="(\d+)"/g const regex = /jp="(\d+)"/g
let matches = [] const matches: string[] = []
let match = null let match: RegExpExecArray | null = null
while ((match = regex.exec(xmlElement.content)) !== null) { while ((match = regex.exec(xmlElement.content)) !== null) {
matches.push(match[1]) matches.push(match[1])
@@ -557,20 +557,22 @@ export class OB11Constructor {
} }
let msgList = (await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true)).msgList let msgList = (await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true)).msgList
const origMsg = await dbUtil.getMsgByLongId(msgList[0].msgId) const origMsg = await dbUtil.getMsgByLongId(msgList[0].msgId)
const postMsg = await dbUtil.getMsgBySeqId(origMsg.msgSeq) ?? origMsg const postMsg = await dbUtil.getMsgBySeqId(origMsg?.msgSeq!) ?? origMsg
// 如果 senderUin 为 0可能是 历史消息 或 自身消息 // 如果 senderUin 为 0可能是 历史消息 或 自身消息
if (msgList[0].senderUin === '0') { if (msgList[0].senderUin === '0') {
msgList[0].senderUin = postMsg?.senderUin ?? selfInfo.uin msgList[0].senderUin = postMsg?.senderUin ?? selfInfo.uin
} }
return new OB11GroupEssenceEvent(parseInt(msg.peerUid), postMsg.msgShortId, parseInt(msgList[0].senderUin)) return new OB11GroupEssenceEvent(parseInt(msg.peerUid), postMsg?.msgShortId!, parseInt(msgList[0].senderUin))
// 获取MsgSeq+Peer可获取具体消息 // 获取MsgSeq+Peer可获取具体消息
} }
if (grayTipElement.jsonGrayTipElement.busiId == 2407) { if (grayTipElement.jsonGrayTipElement.busiId == 2407) {
const memberUin = json.items[1].param[0] const memberUin = json.items[1].param[0]
const title = json.items[3].txt const title = json.items[3].txt
log('收到群成员新头衔消息', json) log('收到群成员新头衔消息', json)
getGroupMember(msg.peerUid, memberUin).then((member) => { getGroupMember(msg.peerUid, memberUin).then(member => {
if (!isNull(member)) {
member.memberSpecialTitle = title member.memberSpecialTitle = title
}
}) })
return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title) return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title)
} }
@@ -592,16 +594,16 @@ export class OB11Constructor {
const revokeElement = msgElement.grayTipElement.revokeElement const revokeElement = msgElement.grayTipElement.revokeElement
if (isGroup) { if (isGroup) {
const operator = await getGroupMember(msg.peerUid, revokeElement.operatorUid) const operator = await getGroupMember(msg.peerUid, revokeElement.operatorUid)
const sender = await getGroupMember(msg.peerUid, revokeElement.origMsgSenderUid) const sender = await getGroupMember(msg.peerUid, revokeElement.origMsgSenderUid!)
return new OB11GroupRecallNoticeEvent( return new OB11GroupRecallNoticeEvent(
parseInt(msg.peerUid), parseInt(msg.peerUid),
parseInt(sender.uin), parseInt(sender?.uin!),
parseInt(operator.uin), parseInt(operator?.uin!),
msg.msgShortId, msg.msgShortId!,
) )
} }
else { else {
return new OB11FriendRecallNoticeEvent(parseInt(msg.senderUin), msg.msgShortId) return new OB11FriendRecallNoticeEvent(parseInt(msg.senderUin!), msg.msgShortId!)
} }
} }
@@ -610,7 +612,7 @@ export class OB11Constructor {
user_id: parseInt(friend.uin), user_id: parseInt(friend.uin),
nickname: friend.nick, nickname: friend.nick,
remark: friend.remark, remark: friend.remark,
sex: OB11Constructor.sex(friend.sex), sex: OB11Constructor.sex(friend.sex!),
level: (friend.qqLevel && calcQQLevel(friend.qqLevel)) || 0, level: (friend.qqLevel && calcQQLevel(friend.qqLevel)) || 0,
} }
} }
@@ -668,7 +670,7 @@ export class OB11Constructor {
user_id: parseInt(member.uin), user_id: parseInt(member.uin),
nickname: member.nick, nickname: member.nick,
card: member.cardName, card: member.cardName,
sex: OB11Constructor.sex(member.sex), sex: OB11Constructor.sex(member.sex!),
age: 0, age: 0,
area: '', area: '',
level: 0, level: 0,
@@ -690,7 +692,7 @@ export class OB11Constructor {
...user, ...user,
user_id: parseInt(user.uin), user_id: parseInt(user.uin),
nickname: user.nick, nickname: user.nick,
sex: OB11Constructor.sex(user.sex), sex: OB11Constructor.sex(user.sex!),
age: 0, age: 0,
qid: user.qid, qid: user.qid,
login_days: 0, login_days: 0,

View File

@@ -11,5 +11,5 @@ export enum EventType {
export abstract class OB11BaseEvent { export abstract class OB11BaseEvent {
time = Math.floor(Date.now() / 1000) time = Math.floor(Date.now() / 1000)
self_id = parseInt(selfInfo.uin) self_id = parseInt(selfInfo.uin)
post_type: EventType abstract post_type: EventType
} }

View File

@@ -2,5 +2,5 @@ import { EventType, OB11BaseEvent } from '../OB11BaseEvent'
export abstract class OB11BaseMetaEvent extends OB11BaseEvent { export abstract class OB11BaseMetaEvent extends OB11BaseEvent {
post_type = EventType.META post_type = EventType.META
meta_event_type: string abstract meta_event_type: string
} }

View File

@@ -2,5 +2,14 @@ import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'
export class OB11GroupAdminNoticeEvent extends OB11GroupNoticeEvent { export class OB11GroupAdminNoticeEvent extends OB11GroupNoticeEvent {
notice_type = 'group_admin' notice_type = 'group_admin'
sub_type: 'set' | 'unset' // "set" | "unset" sub_type: 'set' | 'unset'
group_id: number
user_id: number
constructor(subType: 'set' | 'unset', groupId: number, userId: number) {
super()
this.sub_type = subType
this.group_id = groupId
this.user_id = userId
}
} }

View File

@@ -5,6 +5,8 @@ export class OB11GroupBanEvent extends OB11GroupNoticeEvent {
operator_id: number operator_id: number
duration: number duration: number
sub_type: 'ban' | 'lift_ban' sub_type: 'ban' | 'lift_ban'
group_id: number
user_id: number
constructor(groupId: number, userId: number, operatorId: number, duration: number, sub_type: 'ban' | 'lift_ban') { constructor(groupId: number, userId: number, operatorId: number, duration: number, sub_type: 'ban' | 'lift_ban') {
super() super()

View File

@@ -4,6 +4,8 @@ export class OB11GroupCardEvent extends OB11GroupNoticeEvent {
notice_type = 'group_card' notice_type = 'group_card'
card_new: string card_new: string
card_old: string card_old: string
group_id: number
user_id: number
constructor(groupId: number, userId: number, cardNew: string, cardOld: string) { constructor(groupId: number, userId: number, cardNew: string, cardOld: string) {
super() super()

View File

@@ -6,6 +6,8 @@ export class OB11GroupDecreaseEvent extends OB11GroupNoticeEvent {
notice_type = 'group_decrease' notice_type = 'group_decrease'
sub_type: GroupDecreaseSubType = 'leave' // TODO: 实现其他几种子类型的识别 ("leave" | "kick" | "kick_me") sub_type: GroupDecreaseSubType = 'leave' // TODO: 实现其他几种子类型的识别 ("leave" | "kick" | "kick_me")
operator_id: number operator_id: number
group_id: number
user_id: number
constructor(groupId: number, userId: number, operatorId: number, subType: GroupDecreaseSubType = 'leave') { constructor(groupId: number, userId: number, operatorId: number, subType: GroupDecreaseSubType = 'leave') {
super() super()

View File

@@ -1,14 +1,16 @@
import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent';
export class OB11GroupEssenceEvent extends OB11GroupNoticeEvent { export class OB11GroupEssenceEvent extends OB11GroupNoticeEvent {
notice_type = 'essence'; notice_type = 'essence'
message_id: number; message_id: number
sender_id: number; sender_id: number
sub_type: 'add' | 'delete' = 'add'; sub_type: 'add' | 'delete' = 'add'
group_id: number
user_id: number = 0
constructor(groupId: number, message_id: number, sender_id: number) { constructor(groupId: number, message_id: number, sender_id: number) {
super(); super()
this.group_id = groupId; this.group_id = groupId
this.message_id = message_id; this.message_id = message_id
this.sender_id = sender_id; this.sender_id = sender_id
} }
} }

View File

@@ -1,10 +1,14 @@
import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent' import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'
type GroupIncreaseSubType = 'approve' | 'invite' type GroupIncreaseSubType = 'approve' | 'invite'
export class OB11GroupIncreaseEvent extends OB11GroupNoticeEvent { export class OB11GroupIncreaseEvent extends OB11GroupNoticeEvent {
notice_type = 'group_increase' notice_type = 'group_increase'
operator_id: number operator_id: number
sub_type: GroupIncreaseSubType sub_type: GroupIncreaseSubType
group_id: number
user_id: number
constructor(groupId: number, userId: number, operatorId: number, subType: GroupIncreaseSubType = 'approve') { constructor(groupId: number, userId: number, operatorId: number, subType: GroupIncreaseSubType = 'approve') {
super() super()
this.group_id = groupId this.group_id = groupId

View File

@@ -1,6 +1,7 @@
import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent' import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent'
export abstract class OB11GroupNoticeEvent extends OB11BaseNoticeEvent { export abstract class OB11GroupNoticeEvent extends OB11BaseNoticeEvent {
group_id: number abstract group_id: number
user_id: number abstract user_id: number
abstract notice_type: string
} }

View File

@@ -4,6 +4,8 @@ export class OB11GroupRecallNoticeEvent extends OB11GroupNoticeEvent {
notice_type = 'group_recall' notice_type = 'group_recall'
operator_id: number operator_id: number
message_id: number message_id: number
group_id: number
user_id: number
constructor(groupId: number, userId: number, operatorId: number, messageId: number) { constructor(groupId: number, userId: number, operatorId: number, messageId: number) {
super() super()

View File

@@ -4,6 +4,8 @@ export class OB11GroupTitleEvent extends OB11GroupNoticeEvent {
notice_type = 'notify' notice_type = 'notify'
sub_type = 'title' sub_type = 'title'
title: string title: string
group_id: number
user_id: number
constructor(groupId: number, userId: number, title: string) { constructor(groupId: number, userId: number, title: string) {
super() super()

View File

@@ -10,6 +10,8 @@ export interface GroupUploadFile {
export class OB11GroupUploadNoticeEvent extends OB11GroupNoticeEvent { export class OB11GroupUploadNoticeEvent extends OB11GroupNoticeEvent {
notice_type = 'group_upload' notice_type = 'group_upload'
file: GroupUploadFile file: GroupUploadFile
group_id: number
user_id: number
constructor(groupId: number, userId: number, file: GroupUploadFile) { constructor(groupId: number, userId: number, file: GroupUploadFile) {
super() super()

View File

@@ -8,14 +8,17 @@ export interface MsgEmojiLike {
export class OB11GroupMsgEmojiLikeEvent extends OB11GroupNoticeEvent { export class OB11GroupMsgEmojiLikeEvent extends OB11GroupNoticeEvent {
notice_type = 'group_msg_emoji_like' notice_type = 'group_msg_emoji_like'
message_id: number message_id: number
sub_type: 'ban' | 'lift_ban' sub_type?: 'ban' | 'lift_ban'
likes: MsgEmojiLike[] likes: MsgEmojiLike[]
group_id: number
user_id: number
constructor(groupId: number, userId: number, messageId: number, likes: MsgEmojiLike[]) { constructor(groupId: number, userId: number, messageId: number, likes: MsgEmojiLike[], sub_type?: 'ban' | 'lift_ban') {
super() super()
this.group_id = groupId this.group_id = groupId
this.user_id = userId // 可为空表示是对别人的消息操作如果是对bot自己的消息则不为空 this.user_id = userId // 可为空表示是对别人的消息操作如果是对bot自己的消息则不为空
this.message_id = messageId this.message_id = messageId
this.likes = likes this.likes = likes
this.sub_type = sub_type
} }
} }

View File

@@ -1,16 +1,15 @@
import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent' import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent'
import { selfInfo } from '../../../common/data'
import { OB11BaseEvent } from '../OB11BaseEvent'
class OB11PokeEvent extends OB11BaseNoticeEvent { abstract class OB11PokeEvent extends OB11BaseNoticeEvent {
notice_type = 'notify' notice_type = 'notify'
sub_type = 'poke' sub_type = 'poke'
target_id = 0 target_id = 0
user_id: number abstract user_id: number
raw_message: any raw_message: any
} }
export class OB11FriendPokeEvent extends OB11PokeEvent { export class OB11FriendPokeEvent extends OB11PokeEvent {
user_id: number
constructor(user_id: number, target_id: number, raw_message: any) { constructor(user_id: number, target_id: number, raw_message: any) {
super(); super();
@@ -21,6 +20,7 @@ export class OB11FriendPokeEvent extends OB11PokeEvent {
} }
export class OB11GroupPokeEvent extends OB11PokeEvent { export class OB11GroupPokeEvent extends OB11PokeEvent {
user_id: number
group_id: number group_id: number
constructor(group_id: number, user_id: number = 0, target_id: number = 0, raw_message: any) { constructor(group_id: number, user_id: number = 0, target_id: number = 0, raw_message: any) {
super() super()

View File

@@ -4,7 +4,15 @@ import { EventType } from '../OB11BaseEvent'
export class OB11FriendRequestEvent extends OB11BaseNoticeEvent { export class OB11FriendRequestEvent extends OB11BaseNoticeEvent {
post_type = EventType.REQUEST post_type = EventType.REQUEST
user_id: number user_id: number
request_type: 'friend' = 'friend' request_type: 'friend'
comment: string comment: string
flag: string flag: string
constructor(userId: number, comment: string, flag: string, requestType: 'friend' = 'friend') {
super()
this.user_id = userId
this.comment = comment
this.flag = flag
this.request_type = requestType
}
} }

View File

@@ -1,11 +1,24 @@
import { OB11GroupNoticeEvent } from '../notice/OB11GroupNoticeEvent' import { OB11BaseNoticeEvent } from '../notice/OB11BaseNoticeEvent'
import { EventType } from '../OB11BaseEvent' import { EventType } from '../OB11BaseEvent'
export class OB11GroupRequestEvent extends OB11GroupNoticeEvent { export class OB11GroupRequestEvent extends OB11BaseNoticeEvent {
post_type = EventType.REQUEST post_type = EventType.REQUEST
request_type: 'group' = 'group' request_type: 'group'
sub_type: 'add' | 'invite' = 'add' sub_type: 'add' | 'invite'
invitor_id: number | undefined = undefined invitor_id: number | undefined
comment: string comment?: string
flag: string flag: string
group_id: number
user_id: number
constructor(groupId: number, userId: number, flag: string, comment?: string, invitorId?: number, subType: 'add' | 'invite' = 'add', requestType: 'group' = 'group') {
super()
this.group_id = groupId
this.user_id = userId
this.comment = comment
this.flag = flag
this.request_type = requestType
this.sub_type = subType
this.invitor_id = invitorId
}
} }

View File

@@ -1,5 +1,4 @@
import { PostEventType } from "./post-ob11-event" import { PostEventType } from './post-ob11-event'
interface HttpEventType { interface HttpEventType {
seq: number seq: number
@@ -11,32 +10,30 @@ interface HttpUserType {
userSeq: number userSeq: number
} }
let curentSeq:number = 0; let curentSeq: number = 0
let eventList:HttpEventType[] = []; const eventList: HttpEventType[] = []
let httpUser:Record<string,HttpUserType> = {}; const httpUser: Record<string, HttpUserType> = {}
export function postHttpEvent(event: PostEventType) { export function postHttpEvent(event: PostEventType) {
curentSeq += 1; curentSeq += 1
eventList.push({ eventList.push({
seq: curentSeq, seq: curentSeq,
event: event event: event
}); });
while (eventList.length > 100) { while (eventList.length > 100) {
eventList.shift(); eventList.shift()
} }
} }
export async function getHttpEvent(userKey: string, timeout = 0) { export async function getHttpEvent(userKey: string, timeout = 0) {
let toRetEvent = []; const toRetEvent: PostEventType[] = []
// 清除过时的user5分钟没访问过的user将被删除 // 清除过时的user5分钟没访问过的user将被删除
let now = Date.now(); const now = Date.now();
for (let key in httpUser) { for (let key in httpUser) {
let user = httpUser[key]; let user = httpUser[key]
if (now - user.lastAccessTime > 1000 * 60 * 5) { if (now - user.lastAccessTime > 1000 * 60 * 5) {
delete httpUser[key]; delete httpUser[key]
} }
} }
@@ -48,21 +45,21 @@ export async function getHttpEvent(userKey:string,timeout = 0) {
} }
} }
let user = httpUser[userKey]; const user = httpUser[userKey]
// 等待数据到来,暂时先这么写吧...... // 等待数据到来,暂时先这么写吧......
while (curentSeq == user.userSeq && Date.now() - now < timeout) { while (curentSeq == user.userSeq && Date.now() - now < timeout) {
await new Promise( resolve => setTimeout(resolve, 10) ); await new Promise(resolve => setTimeout(resolve, 10))
} }
// 取数据 // 取数据
for (let i = 0; i < eventList.length; i++) { for (let i = 0; i < eventList.length; i++) {
let evt = eventList[i]; let evt = eventList[i]
if (evt.seq > user.userSeq) { if (evt.seq > user.userSeq) {
toRetEvent.push(evt.event); toRetEvent.push(evt.event)
} }
} }
// 更新user数据 // 更新user数据
user.lastAccessTime = Date.now(); user.lastAccessTime = Date.now()
user.userSeq = curentSeq; user.userSeq = curentSeq
return toRetEvent; return toRetEvent
} }

View File

@@ -40,7 +40,7 @@ class HTTPHeart {
} }
this.intervalId = setInterval(() => { this.intervalId = setInterval(() => {
// ws的心跳是ws自己维护的 // ws的心跳是ws自己维护的
postOb11Event(new OB11HeartbeatEvent(selfInfo.online, true, heartInterval), false, false) postOb11Event(new OB11HeartbeatEvent(selfInfo.online!, true, heartInterval!), false, false)
}, heartInterval) }, heartInterval)
} }

View File

@@ -43,7 +43,7 @@ export function postOb11Event(msg: PostEventType, reportSelf = false, postWs = t
} }
if (config.ob11.enableHttpPost) { if (config.ob11.enableHttpPost) {
const msgStr = JSON.stringify(msg) const msgStr = JSON.stringify(msg)
const hmac = crypto.createHmac('sha1', config.ob11.httpSecret) const hmac = crypto.createHmac('sha1', config.ob11.httpSecret!)
hmac.update(msgStr) hmac.update(msgStr)
const sig = hmac.digest('hex') const sig = hmac.digest('hex')
let headers = { let headers = {
@@ -83,5 +83,4 @@ export function postOb11Event(msg: PostEventType, reportSelf = false, postWs = t
// 不上报心跳 // 不上报心跳
postHttpEvent(msg) postHttpEvent(msg)
} }
} }

View File

@@ -15,7 +15,7 @@ import { version } from '../../../version'
export let rwsList: ReverseWebsocket[] = [] export let rwsList: ReverseWebsocket[] = []
export class ReverseWebsocket { export class ReverseWebsocket {
public websocket: WebSocketClass public websocket?: WebSocketClass
public url: string public url: string
private running: boolean = false private running: boolean = false
@@ -27,38 +27,38 @@ export class ReverseWebsocket {
public stop() { public stop() {
this.running = false this.running = false
this.websocket.close() this.websocket?.close()
} }
public onopen() { public onopen() {
wsReply(this.websocket, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT)) wsReply(this.websocket!, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT))
} }
public async onmessage(msg: string) { public async onmessage(msg: string) {
let receiveData: { action: ActionName; params: any; echo?: any } = { action: null, params: {} } let receiveData: { action: ActionName | null; params: any; echo?: any } = { action: null, params: {} }
let echo = null let echo = null
try { try {
receiveData = JSON.parse(msg.toString()) receiveData = JSON.parse(msg.toString())
echo = receiveData.echo echo = receiveData.echo
log('收到反向Websocket消息', receiveData) log('收到反向Websocket消息', receiveData)
} catch (e) { } catch (e) {
return wsReply(this.websocket, OB11Response.error('json解析失败请检查数据格式', 1400, echo)) return wsReply(this.websocket!, OB11Response.error('json解析失败请检查数据格式', 1400, echo))
} }
const action: BaseAction<any, any> = actionMap.get(receiveData.action) const action: BaseAction<any, any> = actionMap.get(receiveData.action!)!
if (!action) { if (!action) {
return wsReply(this.websocket, OB11Response.error('不支持的api ' + receiveData.action, 1404, echo)) return wsReply(this.websocket!, OB11Response.error('不支持的api ' + receiveData.action, 1404, echo))
} }
try { try {
let handleResult = await action.websocketHandle(receiveData.params, echo) let handleResult = await action.websocketHandle(receiveData.params, echo)
wsReply(this.websocket, handleResult) wsReply(this.websocket!, handleResult)
} catch (e) { } catch (e) {
wsReply(this.websocket, OB11Response.error(`api处理出错:${e}`, 1200, echo)) wsReply(this.websocket!, OB11Response.error(`api处理出错:${e}`, 1200, echo))
} }
} }
public onclose = function () { public onclose = () => {
log('反向ws断开', this.url) log('反向ws断开', this.url)
unregisterWsEventSender(this.websocket) unregisterWsEventSender(this.websocket!)
if (this.running) { if (this.running) {
this.reconnect() this.reconnect()
} }
@@ -104,7 +104,7 @@ export class ReverseWebsocket {
this.websocket.on('error', log) this.websocket.on('error', log)
const wsClientInterval = setInterval(() => { const wsClientInterval = setInterval(() => {
postWsEvent(new OB11HeartbeatEvent(selfInfo.online, true, heartInterval)) postWsEvent(new OB11HeartbeatEvent(selfInfo.online!, true, heartInterval!))
}, heartInterval) // 心跳包 }, heartInterval) // 心跳包
this.websocket.on('close', () => { this.websocket.on('close', () => {
clearInterval(wsClientInterval) clearInterval(wsClientInterval)
@@ -121,7 +121,7 @@ class OB11ReverseWebsockets {
new Promise(() => { new Promise(() => {
try { try {
rwsList.push(new ReverseWebsocket(url)) rwsList.push(new ReverseWebsocket(url))
} catch (e) { } catch (e: any) {
log(e.stack) log(e.stack)
} }
}).then() }).then()
@@ -132,7 +132,7 @@ class OB11ReverseWebsockets {
for (let rws of rwsList) { for (let rws of rwsList) {
try { try {
rws.stop() rws.stop()
} catch (e) { } catch (e: any) {
log('反向ws关闭:', e.stack) log('反向ws关闭:', e.stack)
} }
} }

View File

@@ -13,15 +13,13 @@ import { selfInfo } from '../../../common/data'
import { log } from '../../../common/utils/log' import { log } from '../../../common/utils/log'
import { getConfigUtil } from '../../../common/config' import { getConfigUtil } from '../../../common/config'
let heartbeatRunning = false
class OB11WebsocketServer extends WebsocketServerBase { class OB11WebsocketServer extends WebsocketServerBase {
authorizeFailed(wsClient: WebSocket) { authorizeFailed(wsClient: WebSocket) {
wsClient.send(JSON.stringify(OB11Response.res(null, 'failed', 1403, 'token验证失败'))) wsClient.send(JSON.stringify(OB11Response.res(null, 'failed', 1403, 'token验证失败')))
} }
async handleAction(wsClient: WebSocket, actionName: string, params: any, echo?: any) { async handleAction(wsClient: WebSocket, actionName: string, params: any, echo?: any) {
const action: BaseAction<any, any> = actionMap.get(actionName) const action: BaseAction<any, any> = actionMap.get(actionName)!
if (!action) { if (!action) {
return wsReply(wsClient, OB11Response.error('不支持的api ' + actionName, 1404, echo)) return wsReply(wsClient, OB11Response.error('不支持的api ' + actionName, 1404, echo))
} }
@@ -29,7 +27,7 @@ class OB11WebsocketServer extends WebsocketServerBase {
let handleResult = await action.websocketHandle(params, echo) let handleResult = await action.websocketHandle(params, echo)
handleResult.echo = echo handleResult.echo = echo
wsReply(wsClient, handleResult) wsReply(wsClient, handleResult)
} catch (e) { } catch (e: any) {
wsReply(wsClient, OB11Response.error(`api处理出错:${e.stack}`, 1200, echo)) wsReply(wsClient, OB11Response.error(`api处理出错:${e.stack}`, 1200, echo))
} }
} }
@@ -37,7 +35,7 @@ class OB11WebsocketServer extends WebsocketServerBase {
onConnect(wsClient: WebSocket, url: string, req: IncomingMessage) { onConnect(wsClient: WebSocket, url: string, req: IncomingMessage) {
if (url == '/api' || url == '/api/' || url == '/') { if (url == '/api' || url == '/api/' || url == '/') {
wsClient.on('message', async (msg) => { wsClient.on('message', async (msg) => {
let receiveData: { action: ActionName; params: any; echo?: any } = { action: null, params: {} } let receiveData: { action: ActionName | null; params: any; echo?: any } = { action: null, params: {} }
let echo = null let echo = null
try { try {
receiveData = JSON.parse(msg.toString()) receiveData = JSON.parse(msg.toString())
@@ -46,7 +44,7 @@ class OB11WebsocketServer extends WebsocketServerBase {
} catch (e) { } catch (e) {
return wsReply(wsClient, OB11Response.error('json解析失败请检查数据格式', 1400, echo)) return wsReply(wsClient, OB11Response.error('json解析失败请检查数据格式', 1400, echo))
} }
this.handleAction(wsClient, receiveData.action, receiveData.params, receiveData.echo).then() this.handleAction(wsClient, receiveData.action!, receiveData.params, receiveData.echo).then()
}) })
} }
if (url == '/event' || url == '/event/' || url == '/') { if (url == '/event' || url == '/event/' || url == '/') {
@@ -61,7 +59,7 @@ class OB11WebsocketServer extends WebsocketServerBase {
} }
const { heartInterval } = getConfigUtil().getConfig() const { heartInterval } = getConfigUtil().getConfig()
const wsClientInterval = setInterval(() => { const wsClientInterval = setInterval(() => {
postWsEvent(new OB11HeartbeatEvent(selfInfo.online, true, heartInterval)) postWsEvent(new OB11HeartbeatEvent(selfInfo.online!, true, heartInterval!))
}, heartInterval) // 心跳包 }, heartInterval) // 心跳包
wsClient.on('close', () => { wsClient.on('close', () => {
log('event上报ws客户端已断开') log('event上报ws客户端已断开')

View File

@@ -12,7 +12,7 @@ export function wsReply(wsClient: WebSocketClass, data: OB11Response | PostEvent
} }
wsClient.send(JSON.stringify(packet)) wsClient.send(JSON.stringify(packet))
log('ws 消息上报', wsClient.url || '', data) log('ws 消息上报', wsClient.url || '', data)
} catch (e) { } catch (e: any) {
log('websocket 回复失败', e.stack, data) log('websocket 回复失败', e.stack, data)
} }
} }

View File

@@ -1,6 +1,6 @@
export const SettingItem = ( export const SettingItem = (
title: string, title: string,
subtitle?: string, subtitle?: string | null,
action?: string, action?: string,
id?: string, id?: string,
visible: boolean = true, visible: boolean = true,

View File

@@ -30,11 +30,11 @@ window.customElements.define(
super() super()
this.attachShadow({ mode: 'open' }) this.attachShadow({ mode: 'open' })
this.shadowRoot.append(SelectTemplate.content.cloneNode(true)) this.shadowRoot?.append(SelectTemplate.content.cloneNode(true))
this._button = this.shadowRoot.querySelector('div[part="button"]') this._button = this.shadowRoot?.querySelector('div[part="button"]')!
this._text = this.shadowRoot.querySelector('input[part="current-text"]') this._text = this.shadowRoot?.querySelector('input[part="current-text"]')!
this._context = this.shadowRoot.querySelector('ul[part="option-list"]') this._context = this.shadowRoot?.querySelector('ul[part="option-list"]')!
const buttonClick = () => { const buttonClick = () => {
const isHidden = this._context.classList.toggle('hidden') const isHidden = this._context.classList.toggle('hidden')
@@ -46,7 +46,8 @@ window.customElements.define(
} }
this._button.addEventListener('click', buttonClick) this._button.addEventListener('click', buttonClick)
this._context.addEventListener('click', ({ target }: MouseEventExtend) => { this._context.addEventListener('click', e => {
const { target } = e as MouseEventExtend
if (target.tagName !== 'SETTING-OPTION') return if (target.tagName !== 'SETTING-OPTION') return
buttonClick() buttonClick()
@@ -55,7 +56,7 @@ window.customElements.define(
this.querySelectorAll('setting-option[is-selected]').forEach((dom) => dom.toggleAttribute('is-selected')) this.querySelectorAll('setting-option[is-selected]').forEach((dom) => dom.toggleAttribute('is-selected'))
target.toggleAttribute('is-selected') target.toggleAttribute('is-selected')
this._text.value = target.textContent this._text.value = target.textContent!
this.dispatchEvent( this.dispatchEvent(
new CustomEvent('selected', { new CustomEvent('selected', {
bubbles: true, bubbles: true,
@@ -68,7 +69,7 @@ window.customElements.define(
) )
}) })
this._text.value = this.querySelector('setting-option[is-selected]').textContent this._text.value = this.querySelector('setting-option[is-selected]')?.textContent!
} }
}, },
) )

View File

@@ -12,16 +12,16 @@ function aprilFoolsEgg(node: Element) {
let today = new Date() let today = new Date()
if (today.getDate() === 1) { if (today.getDate() === 1) {
console.log('超时空猫猫!!!') console.log('超时空猫猫!!!')
node.querySelector('.name').innerHTML = 'ChronoCat' node.querySelector('.name')!.innerHTML = 'ChronoCat'
} }
} }
function initSideBar() { function initSideBar() {
document.querySelectorAll('.nav-item.liteloader').forEach((node) => { document.querySelectorAll('.nav-item.liteloader').forEach((node) => {
if (node.textContent.startsWith('LLOneBot')) { if (node.textContent?.startsWith('LLOneBot')) {
aprilFoolsEgg(node) aprilFoolsEgg(node)
let iconEle = node.querySelector('.q-icon') let iconEle = node.querySelector('.q-icon')
iconEle.innerHTML = iconSvg iconEle!.innerHTML = iconSvg
} }
}) })
} }
@@ -234,29 +234,29 @@ async function onSettingWindowCreated(view: Element) {
await new Promise((res) => setTimeout(() => res(true), 1000)) await new Promise((res) => setTimeout(() => res(true), 1000))
const errDom = document.querySelector('#llonebot-error') || doc.querySelector('#llonebot-error') const errDom = document.querySelector('#llonebot-error') || doc.querySelector('#llonebot-error')
const errCodeDom = errDom.querySelector('code') const errCodeDom = errDom?.querySelector('code')
const errMsg = await window.llonebot.getError() const errMsg = await window.llonebot.getError()
if (!errMsg) { if (!errMsg) {
errDom.classList.remove('show') errDom?.classList.remove('show')
} else { } else {
errDom.classList.add('show') errDom?.classList.add('show')
} }
errCodeDom.innerHTML = errMsg errCodeDom!.innerHTML = errMsg
} }
showError().then() showError().then()
// 外链按钮 // 外链按钮
doc.querySelector('#open-github').addEventListener('click', () => { doc.querySelector('#open-github')?.addEventListener('click', () => {
window.LiteLoader.api.openExternal('https://github.com/LLOneBot/LLOneBot') window.LiteLoader.api.openExternal('https://github.com/LLOneBot/LLOneBot')
}) })
doc.querySelector('#open-telegram').addEventListener('click', () => { doc.querySelector('#open-telegram')?.addEventListener('click', () => {
window.LiteLoader.api.openExternal('https://t.me/+nLZEnpne-pQ1OWFl') window.LiteLoader.api.openExternal('https://t.me/+nLZEnpne-pQ1OWFl')
}) })
doc.querySelector('#open-qq-group').addEventListener('click', () => { doc.querySelector('#open-qq-group')?.addEventListener('click', () => {
window.LiteLoader.api.openExternal('https://qm.qq.com/q/bDnHRG38aI') window.LiteLoader.api.openExternal('https://qm.qq.com/q/bDnHRG38aI')
}) })
doc.querySelector('#open-docs').addEventListener('click', () => { doc.querySelector('#open-docs')?.addEventListener('click', () => {
window.LiteLoader.api.openExternal('https://llonebot.github.io/') window.LiteLoader.api.openExternal('https://llonebot.github.io/')
}) })
// 生成反向地址列表 // 生成反向地址列表
@@ -303,14 +303,14 @@ async function onSettingWindowCreated(view: Element) {
} }
const addReverseHost = (type: string, doc: Document = document, inputAttr: any = {}) => { const addReverseHost = (type: string, doc: Document = document, inputAttr: any = {}) => {
const hostContainerDom = doc.body.querySelector(`#config-ob11-${type}-list`) const hostContainerDom = doc.body.querySelector(`#config-ob11-${type}-list`)
hostContainerDom.appendChild(buildHostListItem(type, '', ob11Config[type].length, inputAttr)) hostContainerDom?.appendChild(buildHostListItem(type, '', ob11Config[type].length, inputAttr))
ob11Config[type].push('') ob11Config[type].push('')
} }
const initReverseHost = (type: string, doc: Document = document) => { const initReverseHost = (type: string, doc: Document = document) => {
const hostContainerDom = doc.body.querySelector(`#config-ob11-${type}-list`) const hostContainerDom = doc.body.querySelector(`#config-ob11-${type}-list`)
;[...hostContainerDom.childNodes].forEach((dom) => dom.remove()) ;[...hostContainerDom?.childNodes!].forEach((dom) => dom.remove())
buildHostList(ob11Config[type], type).forEach((dom) => { buildHostList(ob11Config[type], type).forEach((dom) => {
hostContainerDom.appendChild(dom) hostContainerDom?.appendChild(dom)
}) })
} }
initReverseHost('httpHosts', doc) initReverseHost('httpHosts', doc)
@@ -318,42 +318,43 @@ async function onSettingWindowCreated(view: Element) {
doc doc
.querySelector('#config-ob11-httpHosts-add') .querySelector('#config-ob11-httpHosts-add')
.addEventListener('click', () => ?.addEventListener('click', () =>
addReverseHost('httpHosts', document, { placeholder: '如http://127.0.0.1:5140/onebot' }), addReverseHost('httpHosts', document, { placeholder: '如http://127.0.0.1:5140/onebot' }),
) )
doc doc
.querySelector('#config-ob11-wsHosts-add') .querySelector('#config-ob11-wsHosts-add')
.addEventListener('click', () => ?.addEventListener('click', () =>
addReverseHost('wsHosts', document, { placeholder: '如ws://127.0.0.1:5140/onebot' }), addReverseHost('wsHosts', document, { placeholder: '如ws://127.0.0.1:5140/onebot' }),
) )
doc.querySelector('#config-ffmpeg-select').addEventListener('click', () => { doc.querySelector('#config-ffmpeg-select')?.addEventListener('click', () => {
window.llonebot.selectFile().then((path) => { window.llonebot.selectFile().then((path) => {
if (!isEmpty(path)) { if (!isEmpty(path)) {
setConfig('ffmpeg', path) setConfig('ffmpeg', path)
document.querySelector('#config-ffmpeg-path-text').innerHTML = path document.querySelector('#config-ffmpeg-path-text')!.innerHTML = path
} }
}) })
}) })
doc.querySelector('#config-open-log-path').addEventListener('click', () => { doc.querySelector('#config-open-log-path')?.addEventListener('click', () => {
window.LiteLoader.api.openPath(window.LiteLoader.plugins['LLOneBot'].path.data) window.LiteLoader.api.openPath(window.LiteLoader.plugins['LLOneBot'].path.data)
}) })
// 开关 // 开关
doc.querySelectorAll('setting-switch[data-config-key]').forEach((dom: HTMLElement) => { doc.querySelectorAll('setting-switch[data-config-key]').forEach(element => {
const dom = element as HTMLElement
dom.addEventListener('click', () => { dom.addEventListener('click', () => {
const active = dom.getAttribute('is-active') === null const active = dom.getAttribute('is-active') === null
setConfig(dom.dataset.configKey, active) setConfig(dom.dataset.configKey!, active)
if (active) dom.setAttribute('is-active', '') if (active) dom.setAttribute('is-active', '')
else dom.removeAttribute('is-active') else dom.removeAttribute('is-active')
if (!isEmpty(dom.dataset.controlDisplayId)) { if (!isEmpty(dom.dataset.controlDisplayId)) {
const displayDom = document.querySelector(`#${dom.dataset.controlDisplayId}`) const displayDom = document.querySelector(`#${dom.dataset.controlDisplayId}`)
if (active) displayDom.removeAttribute('is-hidden') if (active) displayDom?.removeAttribute('is-hidden')
else displayDom.setAttribute('is-hidden', '') else displayDom?.setAttribute('is-hidden', '')
} }
}) })
}) })
@@ -361,28 +362,31 @@ async function onSettingWindowCreated(view: Element) {
// 输入框 // 输入框
doc doc
.querySelectorAll('setting-item .q-input input.q-input__inner[data-config-key]') .querySelectorAll('setting-item .q-input input.q-input__inner[data-config-key]')
.forEach((dom: HTMLInputElement) => { .forEach(element => {
const dom = element as HTMLInputElement
dom.addEventListener('input', () => { dom.addEventListener('input', () => {
const Type = dom.getAttribute('type') const Type = dom.getAttribute('type')
const configKey = dom.dataset.configKey const configKey = dom.dataset.configKey
const configValue = Type === 'number' ? (parseInt(dom.value) >= 1 ? parseInt(dom.value) : 1) : dom.value const configValue = Type === 'number' ? (parseInt(dom.value) >= 1 ? parseInt(dom.value) : 1) : dom.value
setConfig(configKey, configValue) setConfig(configKey!, configValue)
}) })
}) })
// 下拉框 // 下拉框
doc.querySelectorAll('ob-setting-select[data-config-key]').forEach((dom: HTMLElement) => { doc?.querySelectorAll('ob-setting-select[data-config-key]').forEach(element => {
dom.addEventListener('selected', (e: CustomEvent) => { const dom = element as HTMLElement
dom?.addEventListener('selected', e => {
const { detail } = e as CustomEvent
const configKey = dom.dataset.configKey const configKey = dom.dataset.configKey
const configValue = e.detail.value const configValue = detail.value
setConfig(configKey, configValue) setConfig(configKey!, configValue)
}) })
}) })
// 保存按钮 // 保存按钮
doc.querySelector('#config-ob11-save').addEventListener('click', () => { doc.querySelector('#config-ob11-save')?.addEventListener('click', () => {
config.ob11 = ob11Config config.ob11 = ob11Config
window.llonebot.setConfig(false, config) window.llonebot.setConfig(false, config)
@@ -446,7 +450,7 @@ function init() {
} }
if (location.hash === '#/blank') { if (location.hash === '#/blank') {
;(window as any).navigation.addEventListener('navigatesuccess', init, { once: true }) globalThis.navigation.addEventListener('navigatesuccess', init, { once: true })
} else { } else {
init() init()
} }

View File

@@ -3,7 +3,8 @@
"target": "ESNext", "target": "ESNext",
"module": "commonjs", "module": "commonjs",
"outDir": "./dist", "outDir": "./dist",
"strict": false, "strict": true,
"noImplicitAny": false,
"esModuleInterop": true, "esModuleInterop": true,
"allowJs": true, "allowJs": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
@@ -23,6 +24,12 @@
}, },
"noEmit": true "noEmit": true
}, },
"include": ["src/*", "src/**/*", "scripts/*"], "include": [
"exclude": ["node_modules"] "src/*",
"src/**/*",
"scripts/*"
],
"exclude": [
"node_modules"
]
} }