diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3e2a2096..bedb58ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,15 +8,17 @@ jobs: Build-LiteLoader: runs-on: ubuntu-latest steps: - - name: Clone Main Repository uses: actions/checkout@v4 - + with: + repository: 'NapNeko/NapCatQQ' + submodules: true + ref: main + token: ${{ secrets.NAPCAT_BUILD }} - name: Use Node.js 20.X uses: actions/setup-node@v4 with: node-version: 20.x - - name: Build NuCat Framework run: | npm i @@ -25,25 +27,25 @@ jobs: npm i --omit=dev rm package-lock.json cd .. - - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: NapCat.Framework path: dist - Build-Shell: runs-on: ubuntu-latest steps: - - name: Clone Main Repository uses: actions/checkout@v4 - + with: + repository: 'NapNeko/NapCatQQ' + submodules: true + ref: main + token: ${{ secrets.NAPCAT_BUILD }} - name: Use Node.js 20.X uses: actions/setup-node@v4 with: node-version: 20.x - - name: Build NuCat LiteLoader run: | npm i @@ -52,7 +54,6 @@ jobs: npm i --omit=dev rm package-lock.json cd .. - - name: Upload Artifact uses: actions/upload-artifact@v4 with: diff --git a/launcher/NapCatWinBootHook.dll b/launcher/NapCatWinBootHook.dll index cd6ff346..0ad9943f 100644 Binary files a/launcher/NapCatWinBootHook.dll and b/launcher/NapCatWinBootHook.dll differ diff --git a/launcher/NapCatWinBootMain.exe b/launcher/NapCatWinBootMain.exe index 9cd3132b..5d054fbd 100644 Binary files a/launcher/NapCatWinBootMain.exe and b/launcher/NapCatWinBootMain.exe differ diff --git a/launcher/launcher-win10.bat b/launcher/launcher-win10.bat index c70be0a2..9ed9b106 100644 --- a/launcher/launcher-win10.bat +++ b/launcher/launcher-win10.bat @@ -9,7 +9,7 @@ if %errorLevel% == 0 ( exit ) -set NAPCAT_PATCH_PATH=%cd%\patchNapCat.js +set NAPCAT_PATCH_PACKAGE=%cd%\qqnt.json set NAPCAT_LOAD_PATH=%cd%\loadNapCat.js set NAPCAT_INJECT_PATH=%cd%\NapCatWinBootHook.dll set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe diff --git a/launcher/launcher.bat b/launcher/launcher.bat index 370bd1b1..c92f57b4 100644 --- a/launcher/launcher.bat +++ b/launcher/launcher.bat @@ -9,7 +9,7 @@ if %errorLevel% == 0 ( exit ) -set NAPCAT_PATCH_PATH=%cd%\patchNapCat.js +set NAPCAT_PATCH_PACKAGE=%cd%\qqnt.json set NAPCAT_LOAD_PATH=%cd%\loadNapCat.js set NAPCAT_INJECT_PATH=%cd%\NapCatWinBootHook.dll set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe diff --git a/launcher/patchNapCat.js b/launcher/patchNapCat.js deleted file mode 100644 index 83a04e1f..00000000 --- a/launcher/patchNapCat.js +++ /dev/null @@ -1 +0,0 @@ -require('./launcher.node').load('external_index', module); \ No newline at end of file diff --git a/launcher/qqnt.json b/launcher/qqnt.json new file mode 100644 index 00000000..9d3ef880 --- /dev/null +++ b/launcher/qqnt.json @@ -0,0 +1,23 @@ +{ + "name": "qq-chat", + "version": "9.9.15-28060", + "type": "module", + "private": true, + "description": "QQ", + "productName": "QQ", + "author": { + "name": "Tencent", + "email": "QQ-Team@tencent.com" + }, + "homepage": "https://im.qq.com", + "sideEffects": true, + "bin": { + "qd": "externals/devtools/cli/index.js" + }, + "main": "./loadNapCat.js", + "buildVersion": "28060", + "isPureShell": true, + "isByteCodeShell": true, + "platform": "win32", + "eleArch": "x64" +} \ No newline at end of file diff --git a/manifest.json b/manifest.json index 91bb7bff..370b3860 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "name": "NapCatQQ", "slug": "NapCat.Framework", "description": "高性能的 OneBot 11 协议实现", - "version": "2.5.1", + "version": "2.5.4", "icon": "./logo.png", "authors": [ { diff --git a/package.json b/package.json index d7248fe2..de526d21 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "napcat", "private": true, "type": "module", - "version": "2.5.1", + "version": "2.5.4", "scripts": { "build:framework": "vite build --mode framework", "build:shell": "vite build --mode shell", diff --git a/src/common/helper.ts b/src/common/helper.ts index c758c3a9..11a6222f 100644 --- a/src/common/helper.ts +++ b/src/common/helper.ts @@ -163,34 +163,45 @@ export function isEqual(obj1: any, obj2: any) { export function getDefaultQQVersionConfigInfo(): QQVersionConfigType { if (os.platform() === 'linux') { return { - baseVersion: '3.2.12-27597', - curVersion: '3.2.12-27597', + baseVersion: '3.2.12.28060', + curVersion: '3.2.12.28060', prevVersion: '', onErrorVersions: [], - buildId: '27597', + buildId: '27254', + }; + } + if (os.platform() === 'darwin') { + return { + baseVersion: '6.9.53.28060', + curVersion: '6.9.53.28060', + prevVersion: '', + onErrorVersions: [], + buildId: '28060', }; } return { - baseVersion: '9.9.15-27597', - curVersion: '9.9.15-27597', + baseVersion: '9.9.15-28060', + curVersion: '9.9.15-28060', prevVersion: '', onErrorVersions: [], - buildId: '27597', + buildId: '28060', }; } -export function getQQPackageInfoPath(exePath: string = ''): string { +export function getQQPackageInfoPath(exePath: string = '', version: string): string { if (os.platform() === 'darwin') { return path.join(path.dirname(exePath), '..', 'Resources', 'app', 'package.json'); + } else if (os.platform() === 'linux') { + return path.join(path.dirname(exePath), './resources/app/package.json'); } else { - return path.join(path.dirname(exePath), 'resources', 'app', 'package.json'); + return path.join(path.dirname(exePath), './versions/' + version + '/resources/app/package.json'); } } export function getQQVersionConfigPath(exePath: string = ''): string | undefined { let configVersionInfoPath; if (os.platform() === 'win32') { - configVersionInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'versions', 'config.json'); + configVersionInfoPath = path.join(path.dirname(exePath), 'versions', 'config.json'); } else if (os.platform() === 'darwin') { const userPath = os.homedir(); const appDataPath = path.resolve(userPath, './Library/Application Support/QQ'); diff --git a/src/common/qq-basic-info.ts b/src/common/qq-basic-info.ts index 4184902b..4209e974 100644 --- a/src/common/qq-basic-info.ts +++ b/src/common/qq-basic-info.ts @@ -19,14 +19,16 @@ export class QQBasicInfoWrapper { //基础目录获取 this.context = context; this.QQMainPath = process.execPath; - this.QQPackageInfoPath = getQQPackageInfoPath(this.QQMainPath); this.QQVersionConfigPath = getQQVersionConfigPath(this.QQMainPath); + //基础信息获取 无快更则启用默认模板填充 this.isQuickUpdate = !!this.QQVersionConfigPath; this.QQVersionConfig = this.isQuickUpdate ? JSON.parse(fs.readFileSync(this.QQVersionConfigPath!).toString()) : getDefaultQQVersionConfigInfo(); + + this.QQPackageInfoPath = getQQPackageInfoPath(this.QQMainPath, this.QQVersionConfig?.curVersion!); this.QQPackageInfo = JSON.parse(fs.readFileSync(this.QQPackageInfoPath).toString()); const { appid: IQQVersionAppid, qua: IQQVersionQua } = this.getAppidV2(); this.QQVersionAppid = IQQVersionAppid; @@ -53,23 +55,23 @@ export class QQBasicInfoWrapper { //此方法不要直接使用 getQUAInternal() { switch (systemPlatform) { - case 'linux': - return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; - case 'darwin': - return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; - default: - return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + case 'linux': + return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + case 'darwin': + return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + default: + return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; } } getAppidInternal() { switch (systemPlatform) { - case 'linux': - return '537243600'; - case 'darwin': - return '537243441'; - default: - return '537243538'; + case 'linux': + return '537246140'; + case 'darwin': + return '537246140'; + default: + return '537246092'; } } diff --git a/src/common/version.ts b/src/common/version.ts index 60516350..725085f8 100644 --- a/src/common/version.ts +++ b/src/common/version.ts @@ -1 +1 @@ -export const napCatVersion = '2.5.1'; +export const napCatVersion = '2.5.4'; diff --git a/src/core/external/appid.json b/src/core/external/appid.json index 50d410db..0c5c764c 100644 --- a/src/core/external/appid.json +++ b/src/core/external/appid.json @@ -1,18 +1,10 @@ { - "3.2.12-27597": { - "appid": 537243600, - "qua": "V1_LNX_NQ_3.2.12_27597_GW_B" - }, - "9.9.15-27597": { - "appid": 537243441, - "qua": "V1_WIN_NQ_9.9.15_27597_GW_B" - }, - "6.9.53-27597": { - "appid": 537243538, - "qua": "V1_MAC_NQ_6.9.53_27597_GW_B" - }, "9.9.15-28060":{ "appid": 537246092, "qua": "V1_WIN_NQ_9.9.15_28060_GW_B" + }, + "3.2.12-28060":{ + "appid": 537246140, + "qua": "V1_LNX_NQ_3.2.12_28060_GW_B" } } diff --git a/src/core/index.ts b/src/core/index.ts index cf6667b2..0a44c32e 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -45,12 +45,14 @@ export function loadQQWrapper(QQVersion: string): WrapperNodeApi { let appPath; if (os.platform() === 'darwin') { appPath = path.resolve(path.dirname(process.execPath), '../Resources/app'); - } else { + } else if (os.platform() === 'linux') { appPath = path.resolve(path.dirname(process.execPath), './resources/app'); + } else { + appPath = path.resolve(path.dirname(process.execPath), `./versions/${QQVersion}/`); } let wrapperNodePath = path.resolve(appPath, 'wrapper.node'); if (!fs.existsSync(wrapperNodePath)) { - wrapperNodePath = path.join(appPath, `versions/${QQVersion}/wrapper.node`); + wrapperNodePath = path.join(appPath, `./resources/app/wrapper.node`); } const nativemodule: any = { exports: {} }; process.dlopen(nativemodule, wrapperNodePath); diff --git a/src/core/services/NodeIKernelBuddyService.ts b/src/core/services/NodeIKernelBuddyService.ts index 9273d05d..ac96b5a3 100644 --- a/src/core/services/NodeIKernelBuddyService.ts +++ b/src/core/services/NodeIKernelBuddyService.ts @@ -114,7 +114,7 @@ export interface NodeIKernelBuddyService { reportDoubtBuddyReqUnread(): void; - getBuddyRecommendContactArkJson(uid: string, phoneNumber: string): Promise; + getBuddyRecommendContactArkJson(uid: string, phoneNumber: string): Promise; isNull(): boolean; } diff --git a/src/onebot/action/extends/FetchUserProfileLike.ts b/src/onebot/action/extends/FetchUserProfileLike.ts new file mode 100644 index 00000000..c420014b --- /dev/null +++ b/src/onebot/action/extends/FetchUserProfileLike.ts @@ -0,0 +1,11 @@ +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; + +export class FetchUserProfileLike extends BaseAction<{ qq: number }, any> { + actionName = ActionName.FetchUserProfileLike; + + async _handle(payload: { qq: number }) { + if (!payload.qq) throw new Error('qq is required'); + return await this.core.apis.UserApi.getUidByUinV2(payload.qq.toString()); + } +} diff --git a/src/onebot/action/index.ts b/src/onebot/action/index.ts index c55e9b0a..edbeffb1 100644 --- a/src/onebot/action/index.ts +++ b/src/onebot/action/index.ts @@ -68,8 +68,8 @@ import SetGroupPortrait from './go-cqhttp/SetGroupPortrait'; import { FetchCustomFace } from './extends/FetchCustomFace'; import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivateFile'; import { FetchEmojiLike } from './extends/FetchEmojiLike'; +import { FetchUserProfileLike } from './extends/FetchUserProfileLike'; import { NapCatCore } from '@/core'; - import { NapCatOneBot11Adapter } from '@/onebot'; import GetGuildProfile from './guild/GetGuildProfile'; import SetModelShow from './go-cqhttp/SetModelShow'; @@ -85,6 +85,7 @@ import { GetGroupRootFiles } from '@/onebot/action/go-cqhttp/GetGroupRootFiles'; import { GetGroupFilesByFolder } from '@/onebot/action/go-cqhttp/GetGroupFilesByFolder'; import { GetGroupSystemMsg } from './system/GetSystemMsg'; + export type ActionMap = Map>; export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore): ActionMap { @@ -178,6 +179,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo new GetGroupFileSystemInfo(obContext, core), new GetGroupFilesByFolder(obContext, core), new GetGroupSystemMsg(obContext, core), + new FetchUserProfileLike(obContext, core), ]; const actionMap = new Map(); for (const action of actionHandlers) { diff --git a/src/onebot/action/types.ts b/src/onebot/action/types.ts index 54d8cd68..77c153f8 100644 --- a/src/onebot/action/types.ts +++ b/src/onebot/action/types.ts @@ -118,4 +118,5 @@ export enum ActionName { DelGroupNotice = '_del_group_notice', GetGroupInfoEx = "get_group_info_ex", GetGroupSystemMsg = 'get_group_system_msg', + FetchUserProfileLike = "fetch_user_profile_like", } diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 919a51ae..9e74a146 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -607,6 +607,14 @@ export class OneBotMsgApi { }), [OB11MessageDataType.miniapp]: async () => undefined, + + [OB11MessageDataType.contact]: async ({ data }, context) => { + let arkJson = await this.core.apis.UserApi.getBuddyRecommendContactArkJson(data.id.toString(), ''); + return this.ob11ToRawConverters.json({ + data: { data: arkJson.arkMsg }, + type: OB11MessageDataType.json + }, context); + } }; constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore) { @@ -629,7 +637,7 @@ export class OneBotMsgApi { if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) { //好友添加成功事件 if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') { - return new OB11FriendAddNoticeEvent(this.core, parseInt(msg.peerUin || await this.core.apis.UserApi.getUinByUidV2(msg.peerUid))); + return new OB11FriendAddNoticeEvent(this.core, parseInt(msg.peerUin) || Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid))); } } } diff --git a/src/onebot/types/message.ts b/src/onebot/types/message.ts index bf2f3530..0ef01c9b 100644 --- a/src/onebot/types/message.ts +++ b/src/onebot/types/message.ts @@ -62,6 +62,7 @@ export enum OB11MessageDataType { dice = 'dice', RPS = 'rps', miniapp = 'miniapp',//json类 + contact = 'contact', Location = 'location' } @@ -81,10 +82,15 @@ export interface OB11MessageText { text: string, // 纯文本 } } - +export interface OB11MessageContext { + type: OB11MessageDataType.contact, + data: { + id: string, + } +} export interface OB11MessageFileBase { data: { - file_unique?:string, + file_unique?: string, path?: string; thumb?: string; name?: string; @@ -198,7 +204,7 @@ export type OB11MessageData = OB11MessageAt | OB11MessageReply | OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo | OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson | - OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward + OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext export interface OB11PostSendMsg { message_type?: 'private' | 'group' diff --git a/src/shell/napcat.ts b/src/shell/napcat.ts index bef7f21b..6943110f 100644 --- a/src/shell/napcat.ts +++ b/src/shell/napcat.ts @@ -103,18 +103,21 @@ export async function NCoreInitShell() { const selfInfo = await new Promise((resolve) => { const loginListener = new NodeIKernelLoginListener(); - + let isLogined = false; // from constructor loginListener.onUserLoggedIn = (userid: string) => { logger.logError(`当前账号(${userid})已登录,无法重复登录`); }; - loginListener.onQRCodeLoginSucceed = async (loginResult) => resolve({ - uid: loginResult.uid, - uin: loginResult.uin, - nick: '', // 获取不到 - online: true, - }); + loginListener.onQRCodeLoginSucceed = async (loginResult) => { + isLogined = true; + resolve({ + uid: loginResult.uid, + uin: loginResult.uin, + nick: '', // 获取不到 + online: true, + }); + } loginListener.onQRCodeGetPicture = ({ pngBase64QrcodeData, qrcodeUrl }) => { //设置WebuiQrcode @@ -138,11 +141,13 @@ export async function NCoreInitShell() { }; loginListener.onQRCodeSessionFailed = (errType: number, errCode: number, errMsg: string) => { //logger.logError('登录失败(onQRCodeSessionFailed)', errCode, errMsg); - logger.logError('[Core] [Login] Login Error,ErrCode: ', errCode, ' ErrMsg:', errMsg); - if (errType == 1 && errCode == 3) { - // 二维码过期刷新 + if (!isLogined) { + logger.logError('[Core] [Login] Login Error,ErrCode: ', errCode, ' ErrMsg:', errMsg); + if (errType == 1 && errCode == 3) { + // 二维码过期刷新 + } + loginService.getQRCodePicture(); } - loginService.getQRCodePicture(); }; loginListener.onLoginFailed = (args) => { //logger.logError('登录失败(onLoginFailed)', args); @@ -189,14 +194,14 @@ export async function NCoreInitShell() { .then(result => { if (result.loginErrorInfo.errMsg) { logger.logError('快速登录错误:', result.loginErrorInfo.errMsg); - loginService.getQRCodePicture(); + if (!isLogined) loginService.getQRCodePicture(); } }) .catch(); }, 1000); } else { logger.logError('快速登录失败,未找到该 QQ 历史登录记录,将使用二维码登录方式'); - loginService.getQRCodePicture(); + if (!isLogined) loginService.getQRCodePicture(); } } else { logger.log('没有 -q 指令指定快速登录,将使用二维码登录方式'); @@ -204,7 +209,7 @@ export async function NCoreInitShell() { logger.log(`可用于快速登录的 QQ:\n${historyLoginList .map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`) .join('\n') - }`); + }`); } loginService.getQRCodePicture(); } diff --git a/src/webui/ui/NapCat.ts b/src/webui/ui/NapCat.ts index ef87090a..668075db 100644 --- a/src/webui/ui/NapCat.ts +++ b/src/webui/ui/NapCat.ts @@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) { SettingItem( 'Napcat', undefined, - SettingButton('V2.5.1', 'napcat-update-button', 'secondary'), + SettingButton('V2.5.4', 'napcat-update-button', 'secondary'), ), ]), SettingList([ diff --git a/static/assets/renderer.js b/static/assets/renderer.js index fa3d67e8..41ce6a91 100644 --- a/static/assets/renderer.js +++ b/static/assets/renderer.js @@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) { SettingItem( 'Napcat', void 0, - SettingButton("V2.5.1", "napcat-update-button", "secondary") + SettingButton("V2.5.4", "napcat-update-button", "secondary") ) ]), SettingList([