Compare commits

...

11 Commits

Author SHA1 Message Date
idranme
0d27ef7ebc Merge pull request #502 from LLOneBot/dev
release: 4.1.4
2024-11-09 22:29:16 +08:00
idranme
479e8c9d25 optimize 2024-11-09 22:21:04 +08:00
linyuchen
e3dffa24f8 Merge branch 'dev' 2024-11-09 21:40:06 +08:00
linyuchen
30b8793ee1 fix: 修复 IPC 超时 2024-11-09 21:37:41 +08:00
linyuchen
edf7a97269 Merge branch 'dev' 2024-11-08 18:27:06 +08:00
linyuchen
47b068737d chore: bump version, add author 2024-11-08 06:05:17 +08:00
linyuchen
bfb67188ce fix: DownloadFile接口参数url和base64二选一即可 2024-11-08 05:45:21 +08:00
linyuchen
7ad384d407 fix: 发送文件路径包含#%时发送失败 2024-11-08 05:44:55 +08:00
idranme
66335ddf9b Merge pull request #492 from LLOneBot/dev
release: 4.1.2
2024-10-27 12:11:50 +08:00
idranme
f7926c2e1b chore: bump versions 2024-10-27 12:07:21 +08:00
idranme
b669e28038 fix 2024-10-27 12:06:33 +08:00
11 changed files with 55 additions and 22 deletions

View File

@@ -4,7 +4,7 @@
"name": "LLOneBot", "name": "LLOneBot",
"slug": "LLOneBot", "slug": "LLOneBot",
"description": "实现 OneBot 11 和 Satori 协议,用于 QQ 机器人开发", "description": "实现 OneBot 11 和 Satori 协议,用于 QQ 机器人开发",
"version": "4.1.1", "version": "4.1.4",
"icon": "./icon.webp", "icon": "./icon.webp",
"authors": [ "authors": [
{ {

View File

@@ -26,23 +26,23 @@
"cosmokit": "^1.6.3", "cosmokit": "^1.6.3",
"express": "^5.0.1", "express": "^5.0.1",
"fluent-ffmpeg": "^2.1.3", "fluent-ffmpeg": "^2.1.3",
"minato": "^3.6.0", "minato": "^3.6.1",
"protobufjs": "^7.4.0", "protobufjs": "^7.4.0",
"silk-wasm": "^3.6.1", "silk-wasm": "^3.6.3",
"ts-case-convert": "^2.1.0", "ts-case-convert": "^2.1.0",
"ws": "^8.18.0" "ws": "^8.18.0"
}, },
"devDependencies": { "devDependencies": {
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/express": "^5.0.0", "@types/express": "^5.0.0",
"@types/fluent-ffmpeg": "^2.1.26", "@types/fluent-ffmpeg": "^2.1.27",
"@types/node": "^20.14.15", "@types/node": "^20.14.15",
"@types/ws": "^8.5.12", "@types/ws": "^8.5.13",
"electron": "^31.4.0", "electron": "^31.4.0",
"electron-vite": "^2.3.0", "electron-vite": "^2.3.0",
"protobufjs-cli": "^1.1.3", "protobufjs-cli": "^1.1.3",
"typescript": "^5.6.3", "typescript": "^5.6.3",
"vite": "^5.4.9", "vite": "^5.4.10",
"vite-plugin-cp": "^4.0.8" "vite-plugin-cp": "^4.0.8"
}, },
"packageManager": "yarn@4.5.1" "packageManager": "yarn@4.5.1"

View File

@@ -122,8 +122,11 @@ export async function uri2local(ctx: Context, uri: string, needExt?: boolean): P
const { type } = checkUriType(uri) const { type } = checkUriType(uri)
if (type === FileUriType.FileURL) { if (type === FileUriType.FileURL) {
const filePath = fileURLToPath(uri) const fileUri = uri.replace('%', '%25').replace('#', '%23')
const filePath = fileURLToPath(fileUri)
const fileName = path.basename(filePath) const fileName = path.basename(filePath)
// console.log('fileURLToPath', filePath)
// console.log('fileName', fileName)
return { success: true, errMsg: '', fileName, path: filePath, isLocal: true } return { success: true, errMsg: '', fileName, path: filePath, isLocal: true }
} }

View File

@@ -0,0 +1,9 @@
import { BrowserWindow } from 'electron'
import { log } from '@/common/utils'
export function getAllWindowIds(): number[] {
const allWindows = BrowserWindow.getAllWindows();
const ids = allWindows.map(window => window.id);
log('getAllWindowIds', ids);
return ids;
}

View File

@@ -180,18 +180,16 @@ function onLoad() {
if (self.uin) { if (self.uin) {
clearInterval(intervalId) clearInterval(intervalId)
log('process pid', process.pid) log('process pid', process.pid)
const config = getConfigUtil().getConfig() const config = getConfigUtil().getConfig()
if (config.enableLLOB && (config.satori.enable || config.ob11.enable)) { if (config.enableLLOB && (config.satori.enable || config.ob11.enable)) {
startHook() startHook()
await ctx.sleep(550) await ctx.sleep(600)
} else { } else {
llonebotError.otherError = 'LLOneBot 未启动' llonebotError.otherError = 'LLOneBot 未启动'
log('LLOneBot 开关设置为关闭,不启动 LLOneBot') log('LLOneBot 开关设置为关闭,不启动 LLOneBot')
return return
} }
ctx.plugin(Log, { ctx.plugin(Log, {
enable: config.log!, enable: config.log!,
filename: logFileName filename: logFileName
@@ -225,7 +223,7 @@ function onLoad() {
started = true started = true
llonebotError.otherError = '' llonebotError.otherError = ''
} }
}, 600) }, 500)
} }
// 创建窗口时触发 // 创建窗口时触发

View File

@@ -43,7 +43,7 @@ export class NTQQFileApi extends Service {
msgId, msgId,
elemId: elementId, elemId: elementId,
videoCodecFormat: 0, videoCodecFormat: 0,
params: { exParams: {
downSourceType: 1, downSourceType: 1,
triggerType: 1 triggerType: 1
} }

View File

@@ -40,6 +40,8 @@ const callHooks: Array<{
}> = [] }> = []
export function startHook() { export function startHook() {
log('start hook')
const senderExclude = Symbol() const senderExclude = Symbol()
ipcMain.emit = new Proxy(ipcMain.emit, { ipcMain.emit = new Proxy(ipcMain.emit, {
@@ -50,7 +52,6 @@ export function startHook() {
if (logHook) { if (logHook) {
log('request', args) log('request', args)
} }
const event = args[1] const event = args[1]
if (event.sender && !event.sender[senderExclude]) { if (event.sender && !event.sender[senderExclude]) {
event.sender[senderExclude] = true event.sender[senderExclude] = true
@@ -70,10 +71,12 @@ export function startHook() {
delete hookApiCallbacks[callbackId] delete hookApiCallbacks[callbackId]
} }
} else if (args[2]) { } else if (args[2]) {
for (const receiveData of args[2]) { if (['IPC_DOWN_2', 'IPC_DOWN_3'].includes(args[0])) {
for (const hook of receiveHooks.values()) { for (const receiveData of args[2]) {
if (hook.method.includes(receiveData.cmdName)) { for (const hook of receiveHooks.values()) {
Promise.resolve(hook.hookFunc(receiveData.payload)) if (hook.method.includes(receiveData.cmdName)) {
Promise.resolve(hook.hookFunc(receiveData.payload))
}
} }
} }
} }

View File

@@ -1,6 +1,6 @@
import { ipcMain } from 'electron' import { ipcMain } from 'electron'
import { hookApiCallbacks, registerReceiveHook, removeReceiveHook } from './hook' import { hookApiCallbacks, registerReceiveHook, removeReceiveHook } from './hook'
import { getBuildVersion, log } from '../common/utils' import { log } from '../common/utils'
import { randomUUID } from 'node:crypto' import { randomUUID } from 'node:crypto'
import { import {
GeneralCallResult, GeneralCallResult,
@@ -108,13 +108,26 @@ interface InvokeOptions<ReturnType> {
timeout?: number timeout?: number
} }
let channel: NTChannel
function getChannel() {
if (channel) {
return channel
}
if (ipcMain.eventNames().includes(NTChannel.IPC_UP_2)) {
return channel = NTChannel.IPC_UP_2
} else {
return channel = NTChannel.IPC_UP_3
}
}
export function invoke< export function invoke<
R extends Awaited<ReturnType<Extract<NTService[S][M], (...args: any) => unknown>>>, R extends Awaited<ReturnType<Extract<NTService[S][M], (...args: any) => unknown>>>,
S extends keyof NTService = any, S extends keyof NTService = any,
M extends keyof NTService[S] & string = any M extends keyof NTService[S] & string = any
>(method: Extract<unknown, `${S}/${M}`> | string, args: unknown[], options: InvokeOptions<R> = {}) { >(method: Extract<unknown, `${S}/${M}`> | string, args: unknown[], options: InvokeOptions<R> = {}) {
const className = options.className ?? NTClass.NT_API const className = options.className ?? NTClass.NT_API
const channel = options.channel ?? getBuildVersion() >= 28788 ? NTChannel.IPC_UP_3 : NTChannel.IPC_UP_2 const channel = options.channel ?? getChannel()
const timeout = options.timeout ?? 5000 const timeout = options.timeout ?? 5000
const afterFirstCmd = options.afterFirstCmd ?? true const afterFirstCmd = options.afterFirstCmd ?? true
let eventName = className + '-' + channel[channel.length - 1] let eventName = className + '-' + channel[channel.length - 1]

View File

@@ -23,8 +23,8 @@ interface FileResponse {
export class DownloadFile extends BaseAction<Payload, FileResponse> { export class DownloadFile extends BaseAction<Payload, FileResponse> {
actionName = ActionName.GoCQHTTP_DownloadFile actionName = ActionName.GoCQHTTP_DownloadFile
payloadSchema = Schema.object({ payloadSchema = Schema.object({
url: String, url: Schema.string(),
base64: String, base64: Schema.string(),
headers: Schema.union([String, Schema.array(String)]) headers: Schema.union([String, Schema.array(String)])
}) })

View File

@@ -478,6 +478,13 @@ export namespace OB11Entities {
) )
} }
} }
else if (groupElement.type === TipGroupElementType.MemberIncrease) {
const { memberUid, adminUid } = groupElement
if (memberUid !== selfInfo.uid) return
ctx.logger.info('收到群成员增加消息', groupElement)
const adminUin = adminUid ? await ctx.ntUserApi.getUinByUid(adminUid) : selfInfo.uin
return new OB11GroupIncreaseEvent(+msg.peerUid, +selfInfo.uin, +adminUin)
}
} }
else if (element.fileElement) { else if (element.fileElement) {
return new OB11GroupUploadNoticeEvent(+msg.peerUid, +msg.senderUin!, { return new OB11GroupUploadNoticeEvent(+msg.peerUid, +msg.senderUin!, {

View File

@@ -1 +1 @@
export const version = '4.1.1' export const version = '4.1.4'