Compare commits

..

3 Commits

Author SHA1 Message Date
linyuchen
51602b987e fix: ws 没有上报群文件上传事件 2024-04-08 00:21:24 +08:00
linyuchen
b501af6e0e feat: 骰子魔法表情 & 猜拳魔法表情 2024-04-07 18:51:26 +08:00
linyuchen
81821e74d8 fix: 手动频繁切换聊天窗口时导致旧的窗口接收不到消息 2024-04-07 17:37:52 +08:00
9 changed files with 506 additions and 364 deletions

View File

@@ -1,10 +1,10 @@
{ {
"manifest_version": 4, "manifest_version": 4,
"type": "extension", "type": "extension",
"name": "LLOneBot v3.21.0", "name": "LLOneBot v3.22.0",
"slug": "LLOneBot", "slug": "LLOneBot",
"description": "使你的NTQQ支持OneBot11协议进行QQ机器人开发, 不支持商店在线更新", "description": "使你的NTQQ支持OneBot11协议进行QQ机器人开发, 不支持商店在线更新",
"version": "3.21.0", "version": "3.22.0",
"icon": "./icon.jpg", "icon": "./icon.jpg",
"authors": [ "authors": [
{ {

View File

@@ -1,6 +1,7 @@
import { import {
AtType, AtType,
ElementType, ElementType,
FaceType,
PicType, PicType,
SendArkElement, SendArkElement,
SendFaceElement, SendFaceElement,
@@ -18,6 +19,7 @@ import {calculateFileMD5, isGIF} from "../common/utils/file";
import {log} from "../common/utils/log"; import {log} from "../common/utils/log";
import {defaultVideoThumb, getVideoInfo} from "../common/utils/video"; import {defaultVideoThumb, getVideoInfo} from "../common/utils/video";
import {encodeSilk} from "../common/utils/audio"; import {encodeSilk} from "../common/utils/audio";
import {isNull} from "../common/utils";
export class SendMsgElementConstructor { export class SendMsgElementConstructor {
@@ -237,7 +239,52 @@ export class SendMsgElementConstructor {
elementId: "", elementId: "",
faceElement: { faceElement: {
faceIndex: faceId, faceIndex: faceId,
faceType: 1 faceType: FaceType.normal
}
}
}
static dice(resultId: number|null): SendFaceElement{
// 实际测试并不能控制结果
// 随机1到6
if (isNull(resultId)) resultId = Math.floor(Math.random() * 6) + 1;
return {
elementType: ElementType.FACE,
elementId: "",
faceElement: {
faceIndex: 358,
faceType: FaceType.dice,
"faceText": "[骰子]",
"packId": "1",
"stickerId": "33",
"sourceType": 1,
"stickerType": 2,
resultId: resultId.toString(),
"surpriseId": "",
// "randomType": 1,
}
}
}
// 猜拳(石头剪刀布)表情
static rps(resultId: number | null): SendFaceElement{
// 实际测试并不能控制结果
if (isNull(resultId)) resultId = Math.floor(Math.random() * 3) + 1;
return {
elementType: ElementType.FACE,
elementId: "",
faceElement: {
"faceIndex": 359,
"faceText": "[包剪锤]",
"faceType": 3,
"packId": "1",
"stickerId": "34",
"sourceType": 1,
"stickerType": 2,
"resultId": resultId.toString(),
"surpriseId": "",
// "randomType": 1,
} }
} }
} }

View File

@@ -1,8 +1,8 @@
import {BrowserWindow} from 'electron'; import {BrowserWindow} from 'electron';
import {NTQQApiClass} from "./ntcall"; import {NTQQApiClass, NTQQApiMethod} from "./ntcall";
import {NTQQMsgApi, sendMessagePool} from "./api/msg" import {NTQQMsgApi, sendMessagePool} from "./api/msg"
import {ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User} from "./types"; import {ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User} from "./types";
import {friends, getGroupMember, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data"; import {friends, getFriend, getGroupMember, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data";
import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent"; import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent";
import {v4 as uuidv4} from "uuid" import {v4 as uuidv4} from "uuid"
import {postOB11Event} from "../onebot11/server/postOB11Event"; import {postOB11Event} from "../onebot11/server/postOB11Event";
@@ -11,7 +11,7 @@ import fs from "fs";
import {dbUtil} from "../common/db"; import {dbUtil} from "../common/db";
import {NTQQGroupApi} from "./api/group"; import {NTQQGroupApi} from "./api/group";
import {log} from "../common/utils/log"; import {log} from "../common/utils/log";
import {sleep} from "../common/utils/helper"; import {isNumeric, sleep} from "../common/utils/helper";
import {OB11Constructor} from "../onebot11/constructor"; import {OB11Constructor} from "../onebot11/constructor";
export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {} export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
@@ -61,6 +61,12 @@ let receiveHooks: Array<{
id: string id: string
}> = [] }> = []
let callHooks: Array<{
method: NTQQApiMethod[],
hookFunc: ((callParams: unknown[]) => void | Promise<void>)
}> = []
export function hookNTQQApiReceive(window: BrowserWindow) { export function hookNTQQApiReceive(window: BrowserWindow) {
const originalSend = window.webContents.send; const originalSend = window.webContents.send;
const patchSend = (channel: string, ...args: NTQQApiReturnData) => { const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
@@ -137,6 +143,27 @@ export function hookNTQQApiCall(window: BrowserWindow) {
HOOK_LOG && log("call NTQQ api", thisArg, args); HOOK_LOG && log("call NTQQ api", thisArg, args);
} catch (e) { } catch (e) {
}
try {
const _args: unknown[] = args[3][1];
const cmdName: NTQQApiMethod = _args[0] as NTQQApiMethod;
const callParams = _args.slice(1);
callHooks.forEach(hook => {
if (hook.method.includes(cmdName)) {
new Promise((resolve, reject) => {
try {
let _ = hook.hookFunc(callParams)
if (hook.hookFunc.constructor.name === "AsyncFunction") {
(_ as Promise<void>).then()
}
} catch (e) {
log("hook call error", e, _args)
}
}).then()
}
})
} catch (e) {
} }
} }
return target.apply(thisArg, args); return target.apply(thisArg, args);
@@ -187,6 +214,16 @@ export function registerReceiveHook<PayloadType>(method: ReceiveCmd | ReceiveCmd
return id; return id;
} }
export function registerCallHook(method: NTQQApiMethod | NTQQApiMethod[], hookFunc: (callParams: unknown[]) => void | Promise<void>): void {
if (!Array.isArray(method)) {
method = [method]
}
callHooks.push({
method,
hookFunc
})
}
export function removeReceiveHook(id: string) { export function removeReceiveHook(id: string) {
const index = receiveHooks.findIndex(h => h.id === id) const index = receiveHooks.findIndex(h => h.id === id)
receiveHooks.splice(index, 1); receiveHooks.splice(index, 1);
@@ -454,3 +491,23 @@ registerReceiveHook<{
} }
} }
}) })
registerCallHook(NTQQApiMethod.DELETE_ACTIVE_CHAT, async (payload) => {
const peerUid = payload[0] as string;
log("激活的聊天窗口被删除,准备重新激活", peerUid);
let chatType = ChatType.friend;
if (isNumeric(peerUid)) {
chatType = ChatType.group;
}
else{
// 检查是否好友
if (!(await getFriend(peerUid))){
chatType = ChatType.temp;
}
}
const peer = {peerUid, chatType}
await sleep(1000);
NTQQMsgApi.activateChat(peer).then((r) => {
log("重新激活聊天窗口", peer, {result: r.result, errMsg: r.errMsg})
});
})

View File

@@ -26,6 +26,7 @@ export enum NTQQApiMethod {
ACTIVE_CHAT_HISTORY = "nodeIKernelMsgService/getMsgsIncludeSelfAndAddActiveChat", // 激活聊天窗口,有时候必须这样才能收到消息, 并返回历史消息 ACTIVE_CHAT_HISTORY = "nodeIKernelMsgService/getMsgsIncludeSelfAndAddActiveChat", // 激活聊天窗口,有时候必须这样才能收到消息, 并返回历史消息
HISTORY_MSG = "nodeIKernelMsgService/getMsgsIncludeSelf", HISTORY_MSG = "nodeIKernelMsgService/getMsgsIncludeSelf",
GET_MULTI_MSG = "nodeIKernelMsgService/getMultiMsg", GET_MULTI_MSG = "nodeIKernelMsgService/getMultiMsg",
DELETE_ACTIVE_CHAT = "nodeIKernelMsgService/deleteActiveChatByUid",
LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike", LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike",
SELF_INFO = "fetchAuthData", SELF_INFO = "fetchAuthData",

View File

@@ -212,9 +212,22 @@ export interface GrayTipElement {
} }
} }
export enum FaceType {
normal=1, // 小黄脸
dice=3 // 骰子
}
export interface FaceElement { export interface FaceElement {
faceIndex: number, faceIndex: number,
faceType: 1 faceType: FaceType,
faceText?: string,
packId?: string,
stickerId?: string,
sourceType?: number,
stickerType?: number,
resultId?: string,
surpriseId?: string,
randomType?: number
} }
export interface MarketFaceElement { export interface MarketFaceElement {

View File

@@ -224,6 +224,14 @@ export async function createSendElements(messageData: OB11MessageData[], target:
} }
} }
break; break;
case OB11MessageDataType.dice:{
const resultId = sendMsg.data?.result
sendElements.push(SendMsgElementConstructor.dice(resultId));
}break;
case OB11MessageDataType.RPS:{
const resultId = sendMsg.data?.result
sendElements.push(SendMsgElementConstructor.rps(resultId));
}break;
} }
} }

View File

@@ -63,7 +63,6 @@ export function unregisterWsEventSender(ws: WebSocketClass) {
export function postWsEvent(event: PostEventType) { export function postWsEvent(event: PostEventType) {
for (const ws of eventWSList) { for (const ws of eventWSList) {
log(ws)
new Promise(() => { new Promise(() => {
wsReply(ws, event); wsReply(ws, event);
}).then() }).then()

View File

@@ -117,7 +117,9 @@ export enum OB11MessageDataType {
node = "node", // 合并转发消息节点 node = "node", // 合并转发消息节点
forward = "forward", // 合并转发消息,用于上报 forward = "forward", // 合并转发消息,用于上报
xml = "xml", xml = "xml",
poke = "poke" poke = "poke",
dice = "dice",
RPS = "rps"
} }
export interface OB11MessageMFace{ export interface OB11MessageMFace{
@@ -126,6 +128,20 @@ export interface OB11MessageMFace{
text: string text: string
} }
} }
export interface OB11MessageDice{
type: OB11MessageDataType.dice,
data: {
result: number
}
}
export interface OB11MessageRPS{
type: OB11MessageDataType.RPS,
data: {
result: number
}
}
export interface OB11MessageText { export interface OB11MessageText {
type: OB11MessageDataType.text, type: OB11MessageDataType.text,
data: { data: {
@@ -226,7 +242,8 @@ export type OB11MessageData =
OB11MessageFace | OB11MessageMFace | OB11MessageFace | OB11MessageMFace |
OB11MessageAt | OB11MessageReply | OB11MessageAt | OB11MessageReply |
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo | OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
OB11MessageNode | OB11MessageCustomMusic | OB11MessageJson | OB11MessagePoke OB11MessageNode | OB11MessageCustomMusic | OB11MessageJson | OB11MessagePoke |
OB11MessageDice | OB11MessageRPS
export interface OB11PostSendMsg { export interface OB11PostSendMsg {
message_type?: "private" | "group" message_type?: "private" | "group"

View File

@@ -1 +1 @@
export const version = "3.21.0" export const version = "3.22.0"