mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
Merge branch 'v2' of https://github.com/NapNeko/NapCatQQ into v2
This commit is contained in:
commit
509b123064
@ -26,7 +26,7 @@
|
|||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.0.0",
|
||||||
"@types/qrcode-terminal": "^0.12.2",
|
"@types/qrcode-terminal": "^0.12.2",
|
||||||
"@types/ws": "^8.5.10",
|
"@types/ws": "^8.5.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
||||||
"@typescript-eslint/parser": "^7.4.0",
|
"@typescript-eslint/parser": "^7.4.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
@ -46,6 +46,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^8.13.0",
|
"ajv": "^8.13.0",
|
||||||
|
"async-mutex": "^0.5.0",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"commander": "^12.1.0",
|
"commander": "^12.1.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
@ -59,6 +60,6 @@
|
|||||||
"qrcode-terminal": "^0.12.0",
|
"qrcode-terminal": "^0.12.0",
|
||||||
"silk-wasm": "^3.6.1",
|
"silk-wasm": "^3.6.1",
|
||||||
"strtok3": "8.0.1",
|
"strtok3": "8.0.1",
|
||||||
"ws": "^8.16.0"
|
"ws": "^8.18.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
|||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||||
|
|
||||||
const SchemaData = {
|
const SchemaData = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
@ -18,15 +19,14 @@ const SchemaData = {
|
|||||||
|
|
||||||
type Payload = FromSchema<typeof SchemaData>;
|
type Payload = FromSchema<typeof SchemaData>;
|
||||||
|
|
||||||
export class FetchEmojioLike extends BaseAction<Payload, any> {
|
export class FetchEmojiLike extends BaseAction<Payload, any> {
|
||||||
actionName = ActionName.FetchEmojioLike;
|
actionName = ActionName.FetchEmojiLike;
|
||||||
PayloadSchema = SchemaData;
|
PayloadSchema = SchemaData;
|
||||||
protected async _handle(payload: Payload) {
|
protected async _handle(payload: Payload) {
|
||||||
const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi;
|
const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi;
|
||||||
const msgIdPeer = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
|
const msgIdPeer = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
|
||||||
if(!msgIdPeer) throw new Error('消息不存在');
|
if(!msgIdPeer) throw new Error('消息不存在');
|
||||||
const msg = (await NTQQMsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0];
|
const msg = (await NTQQMsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0];
|
||||||
const ret = await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer,msg.msgSeq,payload.emojiId,payload.emojiType,payload.count);
|
return await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer, msg.msgSeq, payload.emojiId, payload.emojiType, payload.count);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -35,7 +35,6 @@ import GetImage from './file/GetImage';
|
|||||||
import GetRecord from './file/GetRecord';
|
import GetRecord from './file/GetRecord';
|
||||||
import { GoCQHTTPMarkMsgAsRead, MarkAllMsgAsRead, MarkGroupMsgAsRead, MarkPrivateMsgAsRead } from './msg/MarkMsgAsRead';
|
import { GoCQHTTPMarkMsgAsRead, MarkAllMsgAsRead, MarkGroupMsgAsRead, MarkPrivateMsgAsRead } from './msg/MarkMsgAsRead';
|
||||||
import GoCQHTTPUploadGroupFile from './go-cqhttp/UploadGroupFile';
|
import GoCQHTTPUploadGroupFile from './go-cqhttp/UploadGroupFile';
|
||||||
import GetGroupAddRequest from '@/onebot/action/extends/GetGroupAddRequest';
|
|
||||||
import SetQQAvatar from '@/onebot/action/extends/SetQQAvatar';
|
import SetQQAvatar from '@/onebot/action/extends/SetQQAvatar';
|
||||||
import GoCQHTTPDownloadFile from './go-cqhttp/DownloadFile';
|
import GoCQHTTPDownloadFile from './go-cqhttp/DownloadFile';
|
||||||
import GoCQHTTPGetGroupMsgHistory from './go-cqhttp/GetGroupMsgHistory';
|
import GoCQHTTPGetGroupMsgHistory from './go-cqhttp/GetGroupMsgHistory';
|
||||||
@ -73,13 +72,13 @@ import { GetProfileLike } from './extends/GetProfileLike';
|
|||||||
import SetGroupHeader from './extends/SetGroupHeader';
|
import SetGroupHeader from './extends/SetGroupHeader';
|
||||||
import { FetchCustomFace } from './extends/FetchCustomFace';
|
import { FetchCustomFace } from './extends/FetchCustomFace';
|
||||||
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivareFile';
|
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivareFile';
|
||||||
import { FetchEmojioLike } from './extends/FetchEmojioLike';
|
import { FetchEmojiLike } from './extends/FetchEmojiLike';
|
||||||
import { NapCatCore } from '@/core';
|
import { NapCatCore } from '@/core';
|
||||||
import { NapCatOneBot11Adapter } from '../main';
|
import { NapCatOneBot11Adapter } from '../main';
|
||||||
|
|
||||||
export function createActionMap(onebotContext: NapCatOneBot11Adapter, coreContext: NapCatCore) {
|
export function createActionMap(onebotContext: NapCatOneBot11Adapter, coreContext: NapCatCore) {
|
||||||
const actionHandlers = [
|
const actionHandlers = [
|
||||||
new FetchEmojioLike(onebotContext,coreContext),
|
new FetchEmojiLike(onebotContext,coreContext),
|
||||||
new GetFile(onebotContext,coreContext),
|
new GetFile(onebotContext,coreContext),
|
||||||
new SetSelfProfile(onebotContext,coreContext),
|
new SetSelfProfile(onebotContext,coreContext),
|
||||||
new shareGroupEx(onebotContext,coreContext),
|
new shareGroupEx(onebotContext,coreContext),
|
||||||
|
@ -104,5 +104,5 @@ export enum ActionName {
|
|||||||
FetchCustomFace = 'fetch_custom_face',
|
FetchCustomFace = 'fetch_custom_face',
|
||||||
GOCQHTTP_UploadPrivateFile = 'upload_private_file',
|
GOCQHTTP_UploadPrivateFile = 'upload_private_file',
|
||||||
TestApi01 = 'test_api_01',
|
TestApi01 = 'test_api_01',
|
||||||
FetchEmojioLike = 'fetch_emoji_like'
|
FetchEmojiLike = 'fetch_emoji_like'
|
||||||
}
|
}
|
||||||
|
9
src/onebot/network/index.ts
Normal file
9
src/onebot/network/index.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import BaseAction from '@/onebot/action/BaseAction';
|
||||||
|
import { OB11BaseEvent } from '@/onebot/event/OB11BaseEvent';
|
||||||
|
|
||||||
|
export interface IOB11NetworkAdapter {
|
||||||
|
registerAction<T extends BaseAction<P, R>, P, R>(action: T): void;
|
||||||
|
onEvent<T extends OB11BaseEvent>(event: T): void;
|
||||||
|
open(): void | Promise<void>;
|
||||||
|
close(): void | Promise<void>;
|
||||||
|
}
|
72
src/onebot/network/passive-websocket.ts
Normal file
72
src/onebot/network/passive-websocket.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { IOB11NetworkAdapter } from './index';
|
||||||
|
import { OB11BaseEvent } from '@/onebot/event/OB11BaseEvent';
|
||||||
|
import BaseAction from '@/onebot/action/BaseAction';
|
||||||
|
import { WebSocket, WebSocketServer } from 'ws';
|
||||||
|
import { Mutex } from 'async-mutex';
|
||||||
|
|
||||||
|
export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||||
|
wsServer: WebSocketServer;
|
||||||
|
wsClients: WebSocket[] = [];
|
||||||
|
wsClientsMutex = new Mutex();
|
||||||
|
isOpen: boolean = false;
|
||||||
|
hasBeenClosed: boolean = false;
|
||||||
|
|
||||||
|
private actionMap: Map<string, BaseAction<any, any>> = new Map();
|
||||||
|
|
||||||
|
constructor(ip: string, port: number, token: string) {
|
||||||
|
this.wsServer = new WebSocketServer({ port: port, host: ip });
|
||||||
|
this.wsServer.on('connection', async (wsClient) => {
|
||||||
|
if (!this.isOpen) {
|
||||||
|
wsClient.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (token) {
|
||||||
|
const incomingToken = wsClient.url.split('?')[1]?.split('=')[1];
|
||||||
|
if (incomingToken !== token) {
|
||||||
|
wsClient.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wsClient.on('message', (message) => {
|
||||||
|
// TODO: extract action name and payload from the message, then call the corresponding action.
|
||||||
|
});
|
||||||
|
wsClient.once('close', () => {
|
||||||
|
this.wsClientsMutex.runExclusive(async () => {
|
||||||
|
const index = this.wsClients.indexOf(wsClient);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.wsClients.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
await this.wsClientsMutex.runExclusive(async () => {
|
||||||
|
this.wsClients.push(wsClient);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
registerAction<T extends BaseAction<P, R>, P, R>(action: T) {
|
||||||
|
this.actionMap.set(action.actionName, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
onEvent<T extends OB11BaseEvent>(event: T) {
|
||||||
|
this.wsClientsMutex.runExclusive(async () => {
|
||||||
|
this.wsClients.forEach((wsClient) => {
|
||||||
|
// wsClient.send(JSON.stringify(event));
|
||||||
|
// TODO: wrap the event, and send the wrapped to the client.
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
if (this.hasBeenClosed) {
|
||||||
|
throw new Error('Cannot open a closed WebSocket server');
|
||||||
|
}
|
||||||
|
this.isOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async close() {
|
||||||
|
this.isOpen = false;
|
||||||
|
this.hasBeenClosed = true;
|
||||||
|
this.wsServer.close();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user