Compare commits

...

50 Commits

Author SHA1 Message Date
手瓜一十雪
236bec11ed release: 2.5.4 2024-09-16 20:57:56 +08:00
手瓜一十雪
de48b0f940 Merge pull request #370 from NapNeko/28060
for: 28060
2024-09-16 20:54:54 +08:00
手瓜一十雪
4885d4db86 support: linux28060 2024-09-16 20:33:27 +08:00
手瓜一十雪
0c7bbda936 feat: Linux28060Appid 2024-09-16 20:29:04 +08:00
手瓜一十雪
fa07c2c1fb update: appid 2024-09-16 19:31:24 +08:00
手瓜一十雪
5d17a191f6 Merge branch 'main' into 28060 2024-09-16 19:12:10 +08:00
手瓜一十雪
67fb74d3c2 fix 2024-09-16 19:07:05 +08:00
手瓜一十雪
dc04cfc1b3 Revert "chore: workflow"
This reverts commit 58cd38c4a8.
2024-09-16 19:03:14 +08:00
手瓜一十雪
d61d481965 Merge branch 'main' into 28060 2024-09-16 19:02:01 +08:00
手瓜一十雪
6b346ee1de fix 2024-09-16 19:01:01 +08:00
手瓜一十雪
d0f248aaf9 fix 2024-09-16 18:53:26 +08:00
手瓜一十雪
85c9227515 Merge branch 'main' into 28060 2024-09-16 18:52:32 +08:00
手瓜一十雪
73b6d3be84 release: 2.5.3 2024-09-16 18:51:26 +08:00
手瓜一十雪
1ff6ce2343 feat: FetchOtherProfileLike 2024-09-16 18:51:05 +08:00
手瓜一十雪
c145935d46 feat: contact 2024-09-16 18:47:51 +08:00
手瓜一十雪
e9ede6924e release: 2.5.2 2024-09-16 18:12:00 +08:00
手瓜一十雪
515a21761d back: linux to 27254 2024-09-16 18:11:33 +08:00
Alen
8d6397028b Revert "style"
This reverts commit 7e74578312.
2024-09-15 17:31:01 +08:00
Alen
7e74578312 style 2024-09-15 17:24:02 +08:00
手瓜一十雪
bd295a4632 Merge branch 'main' into 28060 2024-09-15 17:15:03 +08:00
Alen
166c30fe2c Merge pull request #375 from cnxysoft/test
fix: friend_add
2024-09-15 16:49:10 +08:00
Alen
66c1bab629 fix: friend_add
修复该事件中user_id为0的问题
2024-09-15 16:47:46 +08:00
手瓜一十雪
66656304f9 fix 2024-09-15 16:24:08 +08:00
手瓜一十雪
07f66e379d Merge branch 'main' into 28060 2024-09-15 16:20:37 +08:00
手瓜一十雪
7ae8fd60c4 release: 2.5.1 2024-09-15 16:20:26 +08:00
手瓜一十雪
7275066994 feat: skip Qrcode When Login 2024-09-15 16:18:43 +08:00
手瓜一十雪
385adec186 Merge branch 'main' into 28060 2024-09-15 16:04:19 +08:00
手瓜一十雪
96b5bec5ab feat: revert 2024-09-15 16:04:10 +08:00
手瓜一十雪
6a9ec4e5f0 Merge branch 'main' into 28060 2024-09-15 15:52:52 +08:00
手瓜一十雪
d9851493df fix: #361 2024-09-15 15:51:23 +08:00
手瓜一十雪
efdb520414 Merge branch 'main' into 28060 2024-09-15 15:38:32 +08:00
Alen
5548644aeb Merge pull request #373 from cnxysoft/test
fix: bugs
2024-09-15 15:37:09 +08:00
Alen
e3fcd91b2d Merge branch 'main' into test 2024-09-15 15:29:50 +08:00
手瓜一十雪
2cae30ba88 Merge branch 'main' into 28060 2024-09-15 15:20:52 +08:00
手瓜一十雪
58cd38c4a8 chore: workflow 2024-09-15 15:20:44 +08:00
手瓜一十雪
3300304feb Merge branch 'main' into 28060 2024-09-15 15:00:42 +08:00
手瓜一十雪
f0e376d06b fix: 移除错误action 2024-09-15 14:55:18 +08:00
手瓜一十雪
16f7bb48f2 fix: launcher 28060 2024-09-15 14:34:47 +08:00
手瓜一十雪
7f383dd29b Merge branch 'main' into 28060 2024-09-15 09:49:49 +08:00
手瓜一十雪
3dc529edf4 fix: #369 2024-09-15 09:39:17 +08:00
手瓜一十雪
45dedb4872 fix: 28060 2024-09-15 09:35:10 +08:00
手瓜一十雪
afcdd01c0d fix: typo 9.9.15-28060 2024-09-14 19:22:36 +08:00
手瓜一十雪
1164877e9a Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-09-14 19:10:34 +08:00
手瓜一十雪
fe92a449ba feat: 准备适配9.9.15-28060版本 2024-09-14 19:10:17 +08:00
Alen
401b0e2bd0 fix: 部分语音播放速率异常 2024-09-14 17:50:09 +08:00
手瓜一十雪
cf9c71fcc1 feat: 准备适配9.9.15-28606 2024-09-14 17:24:52 +08:00
Alen
15a2400069 fix: 修复文件删除失败
此处为重复插入待删列表
2024-09-14 11:12:43 +08:00
Alen
d68a39b49e fix: 定义错误 2024-09-14 10:49:43 +08:00
Alen
066ca22e24 Merge pull request #362 from cnxysoft/upmain
fix: 点赞通知解析
2024-09-14 01:24:20 +08:00
Alen
0418b926fe fix: 点赞通知解析失败 2024-09-14 00:42:10 +08:00
29 changed files with 193 additions and 98 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -9,7 +9,7 @@ if %errorLevel% == 0 (
exit exit
) )
set NAPCAT_PATCH_PATH=%cd%\patchNapCat.js set NAPCAT_PATCH_PACKAGE=%cd%\qqnt.json
set NAPCAT_LOAD_PATH=%cd%\loadNapCat.js set NAPCAT_LOAD_PATH=%cd%\loadNapCat.js
set NAPCAT_INJECT_PATH=%cd%\NapCatWinBootHook.dll set NAPCAT_INJECT_PATH=%cd%\NapCatWinBootHook.dll
set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe

View File

@@ -9,7 +9,7 @@ if %errorLevel% == 0 (
exit exit
) )
set NAPCAT_PATCH_PATH=%cd%\patchNapCat.js set NAPCAT_PATCH_PACKAGE=%cd%\qqnt.json
set NAPCAT_LOAD_PATH=%cd%\loadNapCat.js set NAPCAT_LOAD_PATH=%cd%\loadNapCat.js
set NAPCAT_INJECT_PATH=%cd%\NapCatWinBootHook.dll set NAPCAT_INJECT_PATH=%cd%\NapCatWinBootHook.dll
set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe

View File

@@ -1 +0,0 @@
require('./launcher.node').load('external_index', module);

23
launcher/qqnt.json Normal file
View File

@@ -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"
}

View File

@@ -4,7 +4,7 @@
"name": "NapCatQQ", "name": "NapCatQQ",
"slug": "NapCat.Framework", "slug": "NapCat.Framework",
"description": "高性能的 OneBot 11 协议实现", "description": "高性能的 OneBot 11 协议实现",
"version": "2.5.0", "version": "2.5.4",
"icon": "./logo.png", "icon": "./logo.png",
"authors": [ "authors": [
{ {

View File

@@ -2,7 +2,7 @@
"name": "napcat", "name": "napcat",
"private": true, "private": true,
"type": "module", "type": "module",
"version": "2.5.0", "version": "2.5.4",
"scripts": { "scripts": {
"build:framework": "vite build --mode framework", "build:framework": "vite build --mode framework",
"build:shell": "vite build --mode shell", "build:shell": "vite build --mode shell",

View File

@@ -40,12 +40,14 @@ async function convert(filePath: string, pcmPath: string, logger: LogWrapper): P
}); });
} }
async function handleWavFile(file: Buffer, filePath: string, pcmPath: string, logger: LogWrapper): Promise<Buffer> { async function handleWavFile(
file: Buffer, filePath: string, pcmPath: string, logger: LogWrapper
): Promise<{input: Buffer, sampleRate: number}> {
const { fmt } = getWavFileInfo(file); const { fmt } = getWavFileInfo(file);
if (!ALLOW_SAMPLE_RATE.includes(fmt.sampleRate)) { if (!ALLOW_SAMPLE_RATE.includes(fmt.sampleRate)) {
return await convert(filePath, pcmPath, logger); return {input: await convert(filePath, pcmPath, logger), sampleRate: 24000};
} }
return file; return {input: file, sampleRate: fmt.sampleRate};
} }
export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: LogWrapper) { export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: LogWrapper) {
@@ -55,8 +57,10 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log
if (!isSilk(file)) { if (!isSilk(file)) {
logger.log(`语音文件${filePath}需要转换成silk`); logger.log(`语音文件${filePath}需要转换成silk`);
const pcmPath = `${pttPath}.pcm`; const pcmPath = `${pttPath}.pcm`;
const input = isWav(file) ? await handleWavFile(file, filePath, pcmPath, logger) : await convert(filePath, pcmPath, logger); const { input, sampleRate } = isWav(file)
const silk = await encode(input, 24000); ? (await handleWavFile(file, filePath, pcmPath, logger))
: {input: await convert(filePath, pcmPath, logger), sampleRate: 24000};
const silk = await encode(input, sampleRate);
await fsPromise.writeFile(pttPath, silk.data); await fsPromise.writeFile(pttPath, silk.data);
logger.log(`语音文件${filePath}转换成功!`, pttPath, '时长:', silk.duration); logger.log(`语音文件${filePath}转换成功!`, pttPath, '时长:', silk.duration);
return { return {

View File

@@ -163,34 +163,45 @@ export function isEqual(obj1: any, obj2: any) {
export function getDefaultQQVersionConfigInfo(): QQVersionConfigType { export function getDefaultQQVersionConfigInfo(): QQVersionConfigType {
if (os.platform() === 'linux') { if (os.platform() === 'linux') {
return { return {
baseVersion: '3.2.12-27597', baseVersion: '3.2.12.28060',
curVersion: '3.2.12-27597', curVersion: '3.2.12.28060',
prevVersion: '', prevVersion: '',
onErrorVersions: [], 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 { return {
baseVersion: '9.9.15-27597', baseVersion: '9.9.15-28060',
curVersion: '9.9.15-27597', curVersion: '9.9.15-28060',
prevVersion: '', prevVersion: '',
onErrorVersions: [], onErrorVersions: [],
buildId: '27597', buildId: '28060',
}; };
} }
export function getQQPackageInfoPath(exePath: string = ''): string { export function getQQPackageInfoPath(exePath: string = '', version: string): string {
if (os.platform() === 'darwin') { if (os.platform() === 'darwin') {
return path.join(path.dirname(exePath), '..', 'Resources', 'app', 'package.json'); 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 { } 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 { export function getQQVersionConfigPath(exePath: string = ''): string | undefined {
let configVersionInfoPath; let configVersionInfoPath;
if (os.platform() === 'win32') { 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') { } else if (os.platform() === 'darwin') {
const userPath = os.homedir(); const userPath = os.homedir();
const appDataPath = path.resolve(userPath, './Library/Application Support/QQ'); const appDataPath = path.resolve(userPath, './Library/Application Support/QQ');

View File

@@ -19,14 +19,16 @@ export class QQBasicInfoWrapper {
//基础目录获取 //基础目录获取
this.context = context; this.context = context;
this.QQMainPath = process.execPath; this.QQMainPath = process.execPath;
this.QQPackageInfoPath = getQQPackageInfoPath(this.QQMainPath);
this.QQVersionConfigPath = getQQVersionConfigPath(this.QQMainPath); this.QQVersionConfigPath = getQQVersionConfigPath(this.QQMainPath);
//基础信息获取 无快更则启用默认模板填充 //基础信息获取 无快更则启用默认模板填充
this.isQuickUpdate = !!this.QQVersionConfigPath; this.isQuickUpdate = !!this.QQVersionConfigPath;
this.QQVersionConfig = this.isQuickUpdate this.QQVersionConfig = this.isQuickUpdate
? JSON.parse(fs.readFileSync(this.QQVersionConfigPath!).toString()) ? JSON.parse(fs.readFileSync(this.QQVersionConfigPath!).toString())
: getDefaultQQVersionConfigInfo(); : getDefaultQQVersionConfigInfo();
this.QQPackageInfoPath = getQQPackageInfoPath(this.QQMainPath, this.QQVersionConfig?.curVersion!);
this.QQPackageInfo = JSON.parse(fs.readFileSync(this.QQPackageInfoPath).toString()); this.QQPackageInfo = JSON.parse(fs.readFileSync(this.QQPackageInfoPath).toString());
const { appid: IQQVersionAppid, qua: IQQVersionQua } = this.getAppidV2(); const { appid: IQQVersionAppid, qua: IQQVersionQua } = this.getAppidV2();
this.QQVersionAppid = IQQVersionAppid; this.QQVersionAppid = IQQVersionAppid;
@@ -53,23 +55,23 @@ export class QQBasicInfoWrapper {
//此方法不要直接使用 //此方法不要直接使用
getQUAInternal() { getQUAInternal() {
switch (systemPlatform) { switch (systemPlatform) {
case 'linux': case 'linux':
return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
case 'darwin': case 'darwin':
return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
default: default:
return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
} }
} }
getAppidInternal() { getAppidInternal() {
switch (systemPlatform) { switch (systemPlatform) {
case 'linux': case 'linux':
return '537243600'; return '537246140';
case 'darwin': case 'darwin':
return '537243441'; return '537246140';
default: default:
return '537243538'; return '537246092';
} }
} }

View File

@@ -1 +1 @@
export const napCatVersion = '2.5.0'; export const napCatVersion = '2.5.4';

View File

@@ -34,7 +34,13 @@ export class NTQQGroupApi {
} }
this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`); this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`);
} }
async getCoreAndBaseInfo(uids: string[]) {
return await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo',
'nodeStore',
uids,
);
}
async fetchGroupEssenceList(groupCode: string) { async fetchGroupEssenceList(groupCode: string) {
const pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!; const pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
return this.context.session.getGroupService().fetchGroupEssenceList({ return this.context.session.getGroupService().fetchGroupEssenceList({

View File

@@ -1,14 +1,10 @@
{ {
"3.2.12-27597": { "9.9.15-28060":{
"appid": 537243600, "appid": 537246092,
"qua": "V1_LNX_NQ_3.2.12_27597_GW_B" "qua": "V1_WIN_NQ_9.9.15_28060_GW_B"
}, },
"9.9.15-27597": { "3.2.12-28060":{
"appid": 537243441, "appid": 537246140,
"qua": "V1_WIN_NQ_9.9.15_27597_GW_B" "qua": "V1_LNX_NQ_3.2.12_28060_GW_B"
},
"6.9.53-27597": {
"appid": 537243538,
"qua": "V1_MAC_NQ_6.9.53_27597_GW_B"
} }
} }

View File

@@ -45,12 +45,14 @@ export function loadQQWrapper(QQVersion: string): WrapperNodeApi {
let appPath; let appPath;
if (os.platform() === 'darwin') { if (os.platform() === 'darwin') {
appPath = path.resolve(path.dirname(process.execPath), '../Resources/app'); appPath = path.resolve(path.dirname(process.execPath), '../Resources/app');
} else { } else if (os.platform() === 'linux') {
appPath = path.resolve(path.dirname(process.execPath), './resources/app'); 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'); let wrapperNodePath = path.resolve(appPath, 'wrapper.node');
if (!fs.existsSync(wrapperNodePath)) { if (!fs.existsSync(wrapperNodePath)) {
wrapperNodePath = path.join(appPath, `versions/${QQVersion}/wrapper.node`); wrapperNodePath = path.join(appPath, `./resources/app/wrapper.node`);
} }
const nativemodule: any = { exports: {} }; const nativemodule: any = { exports: {} };
process.dlopen(nativemodule, wrapperNodePath); process.dlopen(nativemodule, wrapperNodePath);

View File

@@ -14,9 +14,15 @@ export interface LikeMsgType {
detail: LikeDetailType; detail: LikeDetailType;
} }
export interface ProfileLikeTipType { export interface profileLikeSubTipType {
msg: LikeMsgType; msg: LikeMsgType;
} }
export interface ProfileLikeTipType {
msgType: number;
subType: number;
content: profileLikeSubTipType;
}
export interface SysMessageHeaderType { export interface SysMessageHeaderType {
id: string; id: string;
timestamp: number; timestamp: number;
@@ -78,6 +84,12 @@ export const likeMsg = new pb.Type("likeMsg")
.add(new pb.Field("time", 2, "int32")) .add(new pb.Field("time", 2, "int32"))
.add(new pb.Field("detail", 3, "likeDetail")); .add(new pb.Field("detail", 3, "likeDetail"));
export const profileLikeTip = new pb.Type("profileLikeTip") export const profileLikeSubTip = new pb.Type("profileLikeSubTip")
.add(likeMsg) .add(likeMsg)
.add(new pb.Field("msg", 14, "likeMsg")); .add(new pb.Field("msg", 14, "likeMsg"))
export const profileLikeTip = new pb.Type("profileLikeTip")
.add(profileLikeSubTip)
.add(new pb.Field("msgType", 1, "int32"))
.add(new pb.Field("subType", 2, "int32"))
.add(new pb.Field("content", 203, "profileLikeSubTip"));

View File

@@ -114,7 +114,7 @@ export interface NodeIKernelBuddyService {
reportDoubtBuddyReqUnread(): void; reportDoubtBuddyReqUnread(): void;
getBuddyRecommendContactArkJson(uid: string, phoneNumber: string): Promise<unknown>; getBuddyRecommendContactArkJson(uid: string, phoneNumber: string): Promise<GeneralCallResult & { arkMsg: string }>;
isNull(): boolean; isNull(): boolean;
} }

View File

@@ -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());
}
}

View File

@@ -3,6 +3,7 @@ import { OB11Entities } from '@/onebot/entities';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { calcQQLevel } from '@/common/helper';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
@@ -22,7 +23,8 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
async _handle(payload: Payload) { async _handle(payload: Payload) {
const groupMembers = await this.core.apis.GroupApi.getGroupMembersV2(payload.group_id.toString()); const groupMembers = await this.core.apis.GroupApi.getGroupMembersV2(payload.group_id.toString());
const groupMembersArr = Array.from(groupMembers.values()); const groupMembersArr = Array.from(groupMembers.values());
let uids = groupMembersArr.map(item => item.uid);
//let CoreAndBase = await this.core.apis.GroupApi.getCoreAndBaseInfo(uids)
let _groupMembers = groupMembersArr.map(item => { let _groupMembers = groupMembersArr.map(item => {
return OB11Entities.groupMember(payload.group_id.toString(), item); return OB11Entities.groupMember(payload.group_id.toString(), item);
}); });
@@ -32,34 +34,38 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
for (let i = 0, len = _groupMembers.length; i < len; i++) { for (let i = 0, len = _groupMembers.length; i < len; i++) {
// 保证基础数据有这个 同时避免群管插件过于依赖这个杀了 // 保证基础数据有这个 同时避免群管插件过于依赖这个杀了
_groupMembers[i].join_time = date; const Member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), _groupMembers[i].user_id);
_groupMembers[i].last_sent_time = date; _groupMembers[i].join_time = +(Member?.joinTime ?? date);
_groupMembers[i].last_sent_time = +(Member?.lastSpeakTime ?? date);
MemberMap.set(_groupMembers[i].user_id, _groupMembers[i]); MemberMap.set(_groupMembers[i].user_id, _groupMembers[i]);
} }
const selfRole = groupMembers.get(this.core.selfInfo.uid)?.role; const selfRole = groupMembers.get(this.core.selfInfo.uid)?.role;
const isPrivilege = selfRole === 3 || selfRole === 4; const isPrivilege = selfRole === 3 || selfRole === 4;
_groupMembers.forEach(item => {
item.last_sent_time = date;
item.join_time = date;
});
if (isPrivilege) { if (isPrivilege) {
const webGroupMembers = await this.core.apis.WebApi.getGroupMembers(payload.group_id.toString()); try {
for (let i = 0, len = webGroupMembers.length; i < len; i++) { const webGroupMembers = await this.core.apis.WebApi.getGroupMembers(payload.group_id.toString());
if (!webGroupMembers[i]?.uin) { for (let i = 0, len = webGroupMembers.length; i < len; i++) {
continue; if (!webGroupMembers[i]?.uin) {
} continue;
const MemberData = MemberMap.get(webGroupMembers[i]?.uin); }
if (MemberData) { const MemberData = MemberMap.get(webGroupMembers[i]?.uin);
MemberData.join_time = webGroupMembers[i]?.join_time; if (MemberData) {
MemberData.last_sent_time = webGroupMembers[i]?.last_speak_time; MemberData.join_time = webGroupMembers[i]?.join_time;
MemberData.qage = webGroupMembers[i]?.qage; MemberData.last_sent_time = webGroupMembers[i]?.last_speak_time;
MemberData.level = webGroupMembers[i]?.lv.level.toString(); MemberData.qage = webGroupMembers[i]?.qage;
MemberMap.set(webGroupMembers[i]?.uin, MemberData); MemberData.level = webGroupMembers[i]?.lv.level.toString();
MemberMap.set(webGroupMembers[i]?.uin, MemberData);
}
} }
} catch (e) {
const logger = this.core.context.logger;
logger.logError.bind(logger)('GetGroupMemberList', e);
} }
} }
_groupMembers = Array.from(MemberMap.values()); _groupMembers = Array.from(MemberMap.values());

View File

@@ -68,8 +68,8 @@ import SetGroupPortrait from './go-cqhttp/SetGroupPortrait';
import { FetchCustomFace } from './extends/FetchCustomFace'; import { FetchCustomFace } from './extends/FetchCustomFace';
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivateFile'; import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivateFile';
import { FetchEmojiLike } from './extends/FetchEmojiLike'; import { FetchEmojiLike } from './extends/FetchEmojiLike';
import { FetchUserProfileLike } from './extends/FetchUserProfileLike';
import { NapCatCore } from '@/core'; import { NapCatCore } from '@/core';
import { NapCatOneBot11Adapter } from '@/onebot'; import { NapCatOneBot11Adapter } from '@/onebot';
import GetGuildProfile from './guild/GetGuildProfile'; import GetGuildProfile from './guild/GetGuildProfile';
import SetModelShow from './go-cqhttp/SetModelShow'; 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 { GetGroupFilesByFolder } from '@/onebot/action/go-cqhttp/GetGroupFilesByFolder';
import { GetGroupSystemMsg } from './system/GetSystemMsg'; import { GetGroupSystemMsg } from './system/GetSystemMsg';
export type ActionMap = Map<string, BaseAction<any, any>>; export type ActionMap = Map<string, BaseAction<any, any>>;
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore): ActionMap { export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore): ActionMap {
@@ -178,6 +179,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo
new GetGroupFileSystemInfo(obContext, core), new GetGroupFileSystemInfo(obContext, core),
new GetGroupFilesByFolder(obContext, core), new GetGroupFilesByFolder(obContext, core),
new GetGroupSystemMsg(obContext, core), new GetGroupSystemMsg(obContext, core),
new FetchUserProfileLike(obContext, core),
]; ];
const actionMap = new Map(); const actionMap = new Map();
for (const action of actionHandlers) { for (const action of actionHandlers) {

View File

@@ -16,8 +16,8 @@ export interface InvalidCheckResult {
export enum ActionName { export enum ActionName {
// 以下为扩展napcat扩展 // 以下为扩展napcat扩展
Unknown = 'unknown', Unknown = 'unknown',
SharePeer = 'ArkShareGroup', SharePeer = 'ArkSharePeer',
ShareGroupEx = 'ArkSharePeer', ShareGroupEx = 'ArkShareGroup',
RebootNormal = 'reboot_normal',//无快速登录重新启动 RebootNormal = 'reboot_normal',//无快速登录重新启动
GetRobotUinRange = 'get_robot_uin_range', GetRobotUinRange = 'get_robot_uin_range',
SetOnlineStatus = 'set_online_status', SetOnlineStatus = 'set_online_status',
@@ -118,4 +118,5 @@ export enum ActionName {
DelGroupNotice = '_del_group_notice', DelGroupNotice = '_del_group_notice',
GetGroupInfoEx = "get_group_info_ex", GetGroupInfoEx = "get_group_info_ex",
GetGroupSystemMsg = 'get_group_system_msg', GetGroupSystemMsg = 'get_group_system_msg',
FetchUserProfileLike = "fetch_user_profile_like",
} }

View File

@@ -466,7 +466,6 @@ export class OneBotMsgApi {
sendMsg.data.summary, sendMsg.data.summary,
sendMsg.data.sub_type, sendMsg.data.sub_type,
); );
context.deleteAfterSentFiles.push(sendPicElement.picElement.sourcePath);
return sendPicElement; return sendPicElement;
}, },
@@ -608,6 +607,14 @@ export class OneBotMsgApi {
}), }),
[OB11MessageDataType.miniapp]: async () => undefined, [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) { constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
@@ -630,7 +637,7 @@ export class OneBotMsgApi {
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) { if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
//好友添加成功事件 //好友添加成功事件
if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') { if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') {
return new OB11FriendAddNoticeEvent(this.core, parseInt(msg.peerUin)); return new OB11FriendAddNoticeEvent(this.core, parseInt(msg.peerUin) || Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
} }
} }
} }

View File

@@ -47,7 +47,7 @@ export class OneBotQuickActionApi {
const peerContextMode = msg.message_type == 'private' ? ContextMode.Private : ContextMode.Group; const peerContextMode = msg.message_type == 'private' ? ContextMode.Private : ContextMode.Group;
const peer: Peer = await createContext(this.core, { const peer: Peer = await createContext(this.core, {
message: "", message_type: undefined,
group_id: msg.group_id?.toString(), group_id: msg.group_id?.toString(),
user_id: msg.user_id?.toString(), user_id: msg.user_id?.toString(),
}, peerContextMode); }, peerContextMode);

View File

@@ -13,9 +13,10 @@ export class OneBotUserApi {
this.core = core; this.core = core;
} }
async parseLikeEvent(wrappedBody: Uint8Array): Promise<OB11ProfileLikeEvent | undefined> { async parseLikeEvent(wrappedBody: Uint8Array): Promise<OB11ProfileLikeEvent | undefined> {
const likeTip = profileLikeTip.decode(Uint8Array.from(wrappedBody.slice(12))) as unknown as ProfileLikeTipType; const likeTip = profileLikeTip.decode(Uint8Array.from(wrappedBody)) as unknown as ProfileLikeTipType;
if (likeTip?.msgType !== 0 || likeTip?.subType !== 203) return;
this.core.context.logger.logDebug("收到点赞通知消息"); this.core.context.logger.logDebug("收到点赞通知消息");
const likeMsg = likeTip.msg; const likeMsg = likeTip.content.msg;
if (!likeMsg) return; if (!likeMsg) return;
const detail = likeMsg.detail; const detail = likeMsg.detail;
if (!detail) return; if (!detail) return;

View File

@@ -48,7 +48,8 @@ export class OB11Entities {
}[role]; }[role];
} }
static sex(sex: Sex): OB11UserSex { static sex(sex?: Sex): OB11UserSex {
if (!sex) return OB11UserSex.unknown;
return { return {
[Sex.male]: OB11UserSex.male, [Sex.male]: OB11UserSex.male,
[Sex.female]: OB11UserSex.female, [Sex.female]: OB11UserSex.female,
@@ -126,7 +127,7 @@ export class OB11Entities {
return { return {
group_id: parseInt(peerId), group_id: parseInt(peerId),
folder_id: folder.folderId, folder_id: folder.folderId,
folder:folder.folderId, folder: folder.folderId,
folder_name: folder.folderName, folder_name: folder.folderName,
create_time: folder.createTime, create_time: folder.createTime,
creator: parseInt(folder.createUin), creator: parseInt(folder.createUin),

View File

@@ -62,6 +62,7 @@ export enum OB11MessageDataType {
dice = 'dice', dice = 'dice',
RPS = 'rps', RPS = 'rps',
miniapp = 'miniapp',//json类 miniapp = 'miniapp',//json类
contact = 'contact',
Location = 'location' Location = 'location'
} }
@@ -81,10 +82,15 @@ export interface OB11MessageText {
text: string, // 纯文本 text: string, // 纯文本
} }
} }
export interface OB11MessageContext {
type: OB11MessageDataType.contact,
data: {
id: string,
}
}
export interface OB11MessageFileBase { export interface OB11MessageFileBase {
data: { data: {
file_unique?:string, file_unique?: string,
path?: string; path?: string;
thumb?: string; thumb?: string;
name?: string; name?: string;
@@ -198,7 +204,7 @@ export type OB11MessageData =
OB11MessageAt | OB11MessageReply | OB11MessageAt | OB11MessageReply |
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo | OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson | OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext
export interface OB11PostSendMsg { export interface OB11PostSendMsg {
message_type?: 'private' | 'group' message_type?: 'private' | 'group'

View File

@@ -103,18 +103,21 @@ export async function NCoreInitShell() {
const selfInfo = await new Promise<SelfInfo>((resolve) => { const selfInfo = await new Promise<SelfInfo>((resolve) => {
const loginListener = new NodeIKernelLoginListener(); const loginListener = new NodeIKernelLoginListener();
let isLogined = false;
// from constructor // from constructor
loginListener.onUserLoggedIn = (userid: string) => { loginListener.onUserLoggedIn = (userid: string) => {
logger.logError(`当前账号(${userid})已登录,无法重复登录`); logger.logError(`当前账号(${userid})已登录,无法重复登录`);
}; };
loginListener.onQRCodeLoginSucceed = async (loginResult) => resolve({ loginListener.onQRCodeLoginSucceed = async (loginResult) => {
uid: loginResult.uid, isLogined = true;
uin: loginResult.uin, resolve({
nick: '', // 获取不到 uid: loginResult.uid,
online: true, uin: loginResult.uin,
}); nick: '', // 获取不到
online: true,
});
}
loginListener.onQRCodeGetPicture = ({ pngBase64QrcodeData, qrcodeUrl }) => { loginListener.onQRCodeGetPicture = ({ pngBase64QrcodeData, qrcodeUrl }) => {
//设置WebuiQrcode //设置WebuiQrcode
@@ -138,11 +141,13 @@ export async function NCoreInitShell() {
}; };
loginListener.onQRCodeSessionFailed = (errType: number, errCode: number, errMsg: string) => { loginListener.onQRCodeSessionFailed = (errType: number, errCode: number, errMsg: string) => {
//logger.logError('登录失败(onQRCodeSessionFailed)', errCode, errMsg); //logger.logError('登录失败(onQRCodeSessionFailed)', errCode, errMsg);
logger.logError('[Core] [Login] Login Error,ErrCode: ', errCode, ' ErrMsg:', errMsg); if (!isLogined) {
if (errType == 1 && errCode == 3) { logger.logError('[Core] [Login] Login Error,ErrCode: ', errCode, ' ErrMsg:', errMsg);
// 二维码过期刷新 if (errType == 1 && errCode == 3) {
// 二维码过期刷新
}
loginService.getQRCodePicture();
} }
loginService.getQRCodePicture();
}; };
loginListener.onLoginFailed = (args) => { loginListener.onLoginFailed = (args) => {
//logger.logError('登录失败(onLoginFailed)', args); //logger.logError('登录失败(onLoginFailed)', args);
@@ -189,14 +194,14 @@ export async function NCoreInitShell() {
.then(result => { .then(result => {
if (result.loginErrorInfo.errMsg) { if (result.loginErrorInfo.errMsg) {
logger.logError('快速登录错误:', result.loginErrorInfo.errMsg); logger.logError('快速登录错误:', result.loginErrorInfo.errMsg);
loginService.getQRCodePicture(); if (!isLogined) loginService.getQRCodePicture();
} }
}) })
.catch(); .catch();
}, 1000); }, 1000);
} else { } else {
logger.logError('快速登录失败,未找到该 QQ 历史登录记录,将使用二维码登录方式'); logger.logError('快速登录失败,未找到该 QQ 历史登录记录,将使用二维码登录方式');
loginService.getQRCodePicture(); if (!isLogined) loginService.getQRCodePicture();
} }
} else { } else {
logger.log('没有 -q 指令指定快速登录,将使用二维码登录方式'); logger.log('没有 -q 指令指定快速登录,将使用二维码登录方式');
@@ -204,7 +209,7 @@ export async function NCoreInitShell() {
logger.log(`可用于快速登录的 QQ\n${historyLoginList logger.log(`可用于快速登录的 QQ\n${historyLoginList
.map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`) .map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`)
.join('\n') .join('\n')
}`); }`);
} }
loginService.getQRCodePicture(); loginService.getQRCodePicture();
} }

View File

@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
SettingItem( SettingItem(
'<span id="napcat-update-title">Napcat</span>', '<span id="napcat-update-title">Napcat</span>',
undefined, undefined,
SettingButton('V2.5.0', 'napcat-update-button', 'secondary'), SettingButton('V2.5.4', 'napcat-update-button', 'secondary'),
), ),
]), ]),
SettingList([ SettingList([

View File

@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
SettingItem( SettingItem(
'<span id="napcat-update-title">Napcat</span>', '<span id="napcat-update-title">Napcat</span>',
void 0, void 0,
SettingButton("V2.5.0", "napcat-update-button", "secondary") SettingButton("V2.5.4", "napcat-update-button", "secondary")
) )
]), ]),
SettingList([ SettingList([