diff --git a/src/ntqqapi/api/msg.ts b/src/ntqqapi/api/msg.ts index 8e9b568..eb032a5 100644 --- a/src/ntqqapi/api/msg.ts +++ b/src/ntqqapi/api/msg.ts @@ -263,4 +263,8 @@ export class NTQQMsgApi extends Service { async getServerTime() { return await invoke('nodeIKernelMSFService/getServerTime', []) } + + async fetchUnitedCommendConfig(groups: string[]) { + return await invoke('nodeIKernelUnitedConfigService/fetchUnitedCommendConfig', [{ groups }]) + } } diff --git a/src/ntqqapi/core.ts b/src/ntqqapi/core.ts index b289e3b..035c8d9 100644 --- a/src/ntqqapi/core.ts +++ b/src/ntqqapi/core.ts @@ -19,6 +19,7 @@ import { import { selfInfo, llonebotError } from '../common/globalVars' import { version } from '../version' import { invoke } from './ntcall' +import { Native } from './native/index' declare module 'cordis' { interface Context { @@ -38,9 +39,11 @@ declare module 'cordis' { class Core extends Service { static inject = ['ntMsgApi', 'ntFriendApi', 'ntGroupApi', 'store'] public startTime = 0 + public native constructor(protected ctx: Context, public config: Core.Config) { super(ctx, 'app', true) + this.native = new Native(ctx) } public start() { diff --git a/src/ntqqapi/native/external/crychic-win32-x64.node b/src/ntqqapi/native/external/crychic-win32-x64.node new file mode 100644 index 0000000..5dd43a1 Binary files /dev/null and b/src/ntqqapi/native/external/crychic-win32-x64.node differ diff --git a/src/ntqqapi/native/index.ts b/src/ntqqapi/native/index.ts new file mode 100644 index 0000000..12c2eaa --- /dev/null +++ b/src/ntqqapi/native/index.ts @@ -0,0 +1,55 @@ +import { Context } from 'cordis' +import { Dict } from 'cosmokit' +import { getBuildVersion } from '@/common/utils/misc' +// @ts-expect-error: Unreachable code error +import addon from './external/crychic-win32-x64.node?asset' + +export class Native { + private crychic?: Dict + + constructor(private ctx: Context) { + ctx.on('ready', () => { + this.start() + }) + } + + checkPlatform() { + return process.platform === 'win32' && process.arch === 'x64' + } + + checkVersion() { + const version = getBuildVersion() + // 27187—27597 + return version >= 27187 && version < 28060 + } + + start() { + if (this.crychic) { + return + } + if (!this.checkPlatform()) { + return + } + if (!this.checkVersion()) { + return + } + try { + this.crychic = require(addon) + this.crychic.init() + } catch (e) { + this.ctx.logger.warn('crychic 加载失败', e) + } + } + + async sendFriendPoke(uin: number) { + if (!this.crychic) return + this.crychic.sendFriendPoke(uin) + await this.ctx.ntMsgApi.fetchUnitedCommendConfig(['100243']) + } + + async sendGroupPoke(groupCode: number, memberUin: number) { + if (!this.crychic) return + this.crychic.sendGroupPoke(memberUin, groupCode) + await this.ctx.ntMsgApi.fetchUnitedCommendConfig(['100243']) + } +} diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts index e94beca..b70f836 100644 --- a/src/onebot11/action/index.ts +++ b/src/onebot11/action/index.ts @@ -74,6 +74,8 @@ import { GetGroupNotice } from './go-cqhttp/GetGroupNotice' import { GetRobotUinRange } from './llonebot/GetRobotUinRange' import { DeleteFriend } from './go-cqhttp/DeleteFriend' import { OCRImage } from './go-cqhttp/OCRImage' +import { GroupPoke } from './llonebot/GroupPoke' +import { FriendPoke } from './llonebot/FriendPoke' export function initActionMap(adapter: Adapter) { const actionHandlers = [ @@ -92,6 +94,8 @@ export function initActionMap(adapter: Adapter) { new FetchCustomFace(adapter), new SetMsgEmojiLike(adapter), new GetRobotUinRange(adapter), + new GroupPoke(adapter), + new FriendPoke(adapter), // onebot11 new SendLike(adapter), new GetMsg(adapter), diff --git a/src/onebot11/action/llonebot/FriendPoke.ts b/src/onebot11/action/llonebot/FriendPoke.ts new file mode 100644 index 0000000..6223ddb --- /dev/null +++ b/src/onebot11/action/llonebot/FriendPoke.ts @@ -0,0 +1,25 @@ +import { BaseAction, Schema } from '../BaseAction' +import { ActionName } from '../types' +import { getBuildVersion } from '@/common/utils/misc' + +interface Payload { + user_id: number | string +} + +export class FriendPoke extends BaseAction { + actionName = ActionName.FriendPoke + payloadSchema = Schema.object({ + user_id: Schema.union([Number, String]).required() + }) + + async _handle(payload: Payload) { + if (!this.ctx.app.native.checkPlatform()) { + throw new Error('当前系统平台或架构不支持') + } + if (!this.ctx.app.native.checkVersion()) { + throw new Error(`当前 QQ 版本 ${getBuildVersion()} 不支持,可尝试其他版本 27187—27597`) + } + await this.ctx.app.native.sendFriendPoke(+payload.user_id) + return null + } +} diff --git a/src/onebot11/action/llonebot/GroupPoke.ts b/src/onebot11/action/llonebot/GroupPoke.ts new file mode 100644 index 0000000..5e2cdb0 --- /dev/null +++ b/src/onebot11/action/llonebot/GroupPoke.ts @@ -0,0 +1,27 @@ +import { BaseAction, Schema } from '../BaseAction' +import { ActionName } from '../types' +import { getBuildVersion } from '@/common/utils/misc' + +interface Payload { + group_id: number | string + user_id: number | string +} + +export class GroupPoke extends BaseAction { + actionName = ActionName.GroupPoke + payloadSchema = Schema.object({ + group_id: Schema.union([Number, String]).required(), + user_id: Schema.union([Number, String]).required() + }) + + async _handle(payload: Payload) { + if (!this.ctx.app.native.checkPlatform()) { + throw new Error('当前系统平台或架构不支持') + } + if (!this.ctx.app.native.checkVersion()) { + throw new Error(`当前 QQ 版本 ${getBuildVersion()} 不支持,可尝试其他版本 27187—27597`) + } + await this.ctx.app.native.sendGroupPoke(+payload.group_id, +payload.user_id) + return null + } +} diff --git a/src/onebot11/action/types.ts b/src/onebot11/action/types.ts index 513f28d..a237492 100644 --- a/src/onebot11/action/types.ts +++ b/src/onebot11/action/types.ts @@ -27,6 +27,8 @@ export enum ActionName { SendForwardMsg = 'send_forward_msg', SetMsgEmojiLike = 'set_msg_emoji_like', GetRobotUinRange = 'get_robot_uin_range', + GroupPoke = 'group_poke', + FriendPoke = 'friend_poke', // onebot 11 SendLike = 'send_like', GetLoginInfo = 'get_login_info', diff --git a/src/onebot11/adapter.ts b/src/onebot11/adapter.ts index e6f5efd..abc0cbb 100644 --- a/src/onebot11/adapter.ts +++ b/src/onebot11/adapter.ts @@ -33,12 +33,13 @@ declare module 'cordis' { class OneBot11Adapter extends Service { static inject = [ 'ntMsgApi', 'ntFileApi', 'ntFileCacheApi', 'ntFriendApi', - 'ntGroupApi', 'ntUserApi', 'ntWindowApi', 'ntWebApi', 'store' + 'ntGroupApi', 'ntUserApi', 'ntWindowApi', 'ntWebApi', + 'store', 'app' ] - private ob11WebSocket: OB11WebSocket - private ob11WebSocketReverseManager: OB11WebSocketReverseManager - private ob11Http: OB11Http - private ob11HttpPost: OB11HttpPost + private ob11WebSocket + private ob11WebSocketReverseManager + private ob11Http + private ob11HttpPost constructor(public ctx: Context, public config: OneBot11Adapter.Config) { super(ctx, 'onebot', true)