mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
71ae08706b | ||
![]() |
50dd798757 | ||
![]() |
0c8cf73746 | ||
![]() |
1bee811312 | ||
![]() |
b4c0068637 | ||
![]() |
f484c6e5fe | ||
![]() |
7a08187c5f | ||
![]() |
c4d7d5a0d4 | ||
![]() |
d22f5d369c | ||
![]() |
d76503995c | ||
![]() |
eab930c083 | ||
![]() |
42b23a6c9c | ||
![]() |
8d94f24c71 | ||
![]() |
6ac74c39d9 | ||
![]() |
836eb7b708 |
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
## To Be Continued
|
## To Be Continued
|
||||||
当前版本请使用低于27187 (不包含) 高于26702 (包含) 的QQ版本运行
|
当前版本请使用内核构建版本(版本号最后的五位数)为 26702 至 26909 的 PC NTQQ 运行。
|
||||||
|
|
||||||
|
高版本QQ NapCat已完成兼容 暂时不发布 直至版本2.0.x结束。
|
||||||
|
|
||||||
## 项目介绍
|
## 项目介绍
|
||||||
NapCatQQ 是现代化的基于 NTQQ 的 Bot 协议端实现。
|
NapCatQQ 是现代化的基于 NTQQ 的 Bot 协议端实现。
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
"name": "NapCatQQ",
|
"name": "NapCatQQ",
|
||||||
"slug": "NapCat.Framework",
|
"slug": "NapCat.Framework",
|
||||||
"description": "高性能的 OneBot 11 协议实现",
|
"description": "高性能的 OneBot 11 协议实现",
|
||||||
"version": "2.0.32",
|
"version": "2.0.35",
|
||||||
"icon": "./logo.png",
|
"icon": "./logo.png",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"name": "napcat",
|
"name": "napcat",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.0.32",
|
"version": "2.0.35",
|
||||||
"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",
|
||||||
|
@@ -2,7 +2,7 @@ import path, { dirname } from 'path';
|
|||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
export const napcat_version = '2.0.32';
|
export const napcat_version = '2.0.35';
|
||||||
|
|
||||||
export class NapCatPathWrapper {
|
export class NapCatPathWrapper {
|
||||||
binaryPath: string;
|
binaryPath: string;
|
||||||
|
@@ -261,7 +261,7 @@ export class NTQQGroupApi {
|
|||||||
(
|
(
|
||||||
'NodeIKernelGroupListener/onMemberInfoChange',
|
'NodeIKernelGroupListener/onMemberInfoChange',
|
||||||
1,
|
1,
|
||||||
forced ? 5000 : 500,
|
forced ? 5000 : 250,
|
||||||
(params) => {
|
(params) => {
|
||||||
return params === GroupCode;
|
return params === GroupCode;
|
||||||
},
|
},
|
||||||
@@ -269,7 +269,7 @@ export class NTQQGroupApi {
|
|||||||
const EventFunc = this.core.eventWrapper.createEventFunction<EventType>('NodeIKernelGroupService/getMemberInfo');
|
const EventFunc = this.core.eventWrapper.createEventFunction<EventType>('NodeIKernelGroupService/getMemberInfo');
|
||||||
const retData = await EventFunc!(GroupCode, [uid], forced);
|
const retData = await EventFunc!(GroupCode, [uid], forced);
|
||||||
if (retData.result !== 0) {
|
if (retData.result !== 0) {
|
||||||
throw new Error(`获取群成员信息失败: ${retData.errMsg}`);
|
throw new Error(`${retData.errMsg}`);
|
||||||
}
|
}
|
||||||
const result = await Listener as unknown;
|
const result = await Listener as unknown;
|
||||||
let member: GroupMember | undefined;
|
let member: GroupMember | undefined;
|
||||||
|
@@ -120,20 +120,23 @@ export class NTQQUserApi {
|
|||||||
...profile.simpleInfo.vasInfo,
|
...profile.simpleInfo.vasInfo,
|
||||||
...profile.commonExt,
|
...profile.commonExt,
|
||||||
...profile.simpleInfo.baseInfo,
|
...profile.simpleInfo.baseInfo,
|
||||||
qqLevel: profile.commonExt.qqLevel,
|
qqLevel: profile.commonExt?.qqLevel,
|
||||||
age: profile.simpleInfo.baseInfo.age,
|
age: profile.simpleInfo.baseInfo.age,
|
||||||
pendantId: '',
|
pendantId: '',
|
||||||
};
|
};
|
||||||
return RetUser;
|
return RetUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserDetailInfo(uid: string) {
|
async getUserDetailInfo(uid: string): Promise<User> {
|
||||||
const ret = await this.fetchUserDetailInfo(uid, UserDetailSource.KDB);
|
try {
|
||||||
if (ret.uin === '0') {
|
let retUser = await this.fetchUserDetailInfo(uid, UserDetailSource.KDB);
|
||||||
console.log('[NapCat] [Mark] getUserDetailInfo Mode1 Failed.')
|
if (retUser.uin !== '0') {
|
||||||
return await this.fetchUserDetailInfo(uid, UserDetailSource.KSERVER);
|
return retUser;
|
||||||
}
|
}
|
||||||
return ret;
|
} catch (e) {
|
||||||
|
}
|
||||||
|
this.context.logger.logDebug('[NapCat] [Mark] getUserDetailInfo Mode1 Failed.');
|
||||||
|
return this.fetchUserDetailInfo(uid, UserDetailSource.KSERVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
async modifySelfProfile(param: ModifyProfileParams) {
|
async modifySelfProfile(param: ModifyProfileParams) {
|
||||||
@@ -207,9 +210,9 @@ export class NTQQUserApi {
|
|||||||
|
|
||||||
//后期改成流水线处理
|
//后期改成流水线处理
|
||||||
async getUinByUidV2(Uid: string) {
|
async getUinByUidV2(Uid: string) {
|
||||||
let uin = (await this.context.session.getProfileService().getUinByUid('FriendsServiceImpl', [Uid])).get(Uid);
|
let uin = (await this.context.session.getGroupService().getUinByUids([Uid])).uins.get(Uid);
|
||||||
if (uin) return uin;
|
if (uin) return uin;
|
||||||
uin = (await this.context.session.getGroupService().getUinByUids([Uid])).uins.get(Uid);
|
uin = (await this.context.session.getProfileService().getUinByUid('FriendsServiceImpl', [Uid])).get(Uid);
|
||||||
if (uin) return uin;
|
if (uin) return uin;
|
||||||
uin = (await this.context.session.getUixConvertService().getUin([Uid])).uinInfo.get(Uid);
|
uin = (await this.context.session.getUixConvertService().getUin([Uid])).uinInfo.get(Uid);
|
||||||
if (uin) return uin;
|
if (uin) return uin;
|
||||||
|
@@ -196,6 +196,9 @@ export class NapCatCore {
|
|||||||
this.apis.GroupApi.groupMemberCache.set(groupCode, members);
|
this.apis.GroupApi.groupMemberCache.set(groupCode, members);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.context.session.getGroupService().addKernelGroupListener(
|
||||||
|
new this.context.wrapper.NodeIKernelGroupListener(proxiedListenerOf(groupListener, this.context.logger)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
checkAdminEvent(groupCode: string, memberNew: GroupMember, memberOld: GroupMember | undefined): boolean {
|
checkAdminEvent(groupCode: string, memberNew: GroupMember, memberOld: GroupMember | undefined): boolean {
|
||||||
if (memberNew.role !== memberOld?.role) {
|
if (memberNew.role !== memberOld?.role) {
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
import BaseAction from '../BaseAction';
|
|
||||||
import { ActionName } from '../types';
|
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
|
||||||
|
|
||||||
const SchemaData = {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
nick: { type: 'string' },
|
|
||||||
longNick: { type: 'string' },
|
|
||||||
sex: { type: ['number', 'string'] },//传Sex值?建议传0
|
|
||||||
},
|
|
||||||
required: ['nick', 'longNick', 'sex'],
|
|
||||||
} as const satisfies JSONSchema;
|
|
||||||
|
|
||||||
type Payload = FromSchema<typeof SchemaData>;
|
|
||||||
|
|
||||||
export class SetSelfProfile extends BaseAction<Payload, any | null> {
|
|
||||||
actionName = ActionName.SetSelfProfile;
|
|
||||||
PayloadSchema = SchemaData;
|
|
||||||
|
|
||||||
async _handle(payload: Payload) {
|
|
||||||
const NTQQUserApi = this.CoreContext.apis.UserApi;
|
|
||||||
const ret = await NTQQUserApi.modifySelfProfile({
|
|
||||||
nick: payload.nick,
|
|
||||||
longNick: payload.longNick,
|
|
||||||
sex: parseInt(payload.sex.toString()),
|
|
||||||
birthday: { birthday_year: '', birthday_month: '', birthday_day: '' },
|
|
||||||
location: undefined,
|
|
||||||
});
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -7,18 +7,18 @@ import { checkFileReceived, uri2local } from '@/common/utils/file';
|
|||||||
|
|
||||||
interface Payload {
|
interface Payload {
|
||||||
file: string,
|
file: string,
|
||||||
groupCode: string
|
group_id: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SetGroupHeader extends BaseAction<Payload, any> {
|
export default class SetGroupPortrait extends BaseAction<Payload, any> {
|
||||||
actionName = ActionName.SetGroupHeader;
|
actionName = ActionName.SetGroupPortrait;
|
||||||
|
|
||||||
// 用不着复杂检测
|
// 用不着复杂检测
|
||||||
protected async check(payload: Payload): Promise<BaseCheckResult> {
|
protected async check(payload: Payload): Promise<BaseCheckResult> {
|
||||||
if (!payload.file || typeof payload.file != 'string' || !payload.groupCode || typeof payload.groupCode != 'string') {
|
if (!payload.file || typeof payload.file != 'string' || !payload.group_id || typeof payload.group_id != 'number') {
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: 'file和groupCode字段不能为空或者类型错误',
|
message: 'file和group_id字段不能为空或者类型错误',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -34,7 +34,7 @@ export default class SetGroupHeader extends BaseAction<Payload, any> {
|
|||||||
}
|
}
|
||||||
if (path) {
|
if (path) {
|
||||||
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断
|
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断
|
||||||
const ret = await NTQQGroupApi.setGroupAvatar(payload.groupCode, path);
|
const ret = await NTQQGroupApi.setGroupAvatar(payload.group_id.toString(), path) as any;
|
||||||
if (!isLocal) {
|
if (!isLocal) {
|
||||||
fs.unlink(path, () => {
|
fs.unlink(path, () => {
|
||||||
});
|
});
|
||||||
@@ -43,11 +43,11 @@ export default class SetGroupHeader extends BaseAction<Payload, any> {
|
|||||||
throw `头像${payload.file}设置失败,api无返回`;
|
throw `头像${payload.file}设置失败,api无返回`;
|
||||||
}
|
}
|
||||||
// log(`头像设置返回:${JSON.stringify(ret)}`)
|
// log(`头像设置返回:${JSON.stringify(ret)}`)
|
||||||
// if (ret['result'] == 1004022) {
|
if (ret['result'] == 1004022) {
|
||||||
// throw `头像${payload.file}设置失败,文件可能不是图片格式`;
|
throw `头像${payload.file}设置失败,文件可能不是图片格式或权限不足`;
|
||||||
// } else if (ret['result'] != 0) {
|
} else if (ret['result'] != 0) {
|
||||||
// throw `头像${payload.file}设置失败,未知的错误,${ret['result']}:${ret['errMsg']}`;
|
throw `头像${payload.file}设置失败,未知的错误,${ret['result']}:${ret['errMsg']}`;
|
||||||
// }
|
}
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
if (!isLocal) {
|
if (!isLocal) {
|
34
src/onebot/action/go-cqhttp/SetQQProfile.ts
Normal file
34
src/onebot/action/go-cqhttp/SetQQProfile.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import BaseAction from '../BaseAction';
|
||||||
|
import { ActionName } from '../types';
|
||||||
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
|
|
||||||
|
const SchemaData = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
nickname: { type: 'string' },
|
||||||
|
personal_note: { type: 'string' },
|
||||||
|
sex: { type: ['number', 'string'] },//传Sex值?建议传0
|
||||||
|
},
|
||||||
|
required: ['nickname'],
|
||||||
|
} as const satisfies JSONSchema;
|
||||||
|
|
||||||
|
type Payload = FromSchema<typeof SchemaData>;
|
||||||
|
|
||||||
|
export class SetQQProfile extends BaseAction<Payload, any | null> {
|
||||||
|
actionName = ActionName.SetQQProfile;
|
||||||
|
PayloadSchema = SchemaData;
|
||||||
|
|
||||||
|
async _handle(payload: Payload) {
|
||||||
|
const NTQQUserApi = this.CoreContext.apis.UserApi;
|
||||||
|
const self = this.CoreContext.selfInfo;
|
||||||
|
const OldProfile = await NTQQUserApi.getUserDetailInfo(self.uid);
|
||||||
|
const ret = await NTQQUserApi.modifySelfProfile({
|
||||||
|
nick: payload.nickname,
|
||||||
|
longNick: payload?.personal_note ?? OldProfile?.longNick!,
|
||||||
|
sex: parseInt(payload?.sex ? payload?.sex.toString() : OldProfile?.sex!.toString()),
|
||||||
|
birthday: { birthday_year: OldProfile?.birthday_year!.toString(), birthday_month: OldProfile?.birthday_month!.toString(), birthday_day: OldProfile?.birthday_day!.toString() },
|
||||||
|
location: undefined,
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
@@ -3,6 +3,7 @@ import { OB11Constructor } from '../../helper/data';
|
|||||||
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 { GroupMember } from '@/core';
|
||||||
|
|
||||||
const SchemaData = {
|
const SchemaData = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@@ -23,23 +24,25 @@ class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
|
|||||||
async _handle(payload: Payload) {
|
async _handle(payload: Payload) {
|
||||||
const NTQQUserApi = this.CoreContext.apis.UserApi;
|
const NTQQUserApi = this.CoreContext.apis.UserApi;
|
||||||
const NTQQGroupApi = this.CoreContext.apis.GroupApi;
|
const NTQQGroupApi = this.CoreContext.apis.GroupApi;
|
||||||
const NTQQWebApi = this.CoreContext.apis.WebApi;
|
|
||||||
const isNocache = typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache;
|
const isNocache = typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache;
|
||||||
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
|
||||||
if (!uid) throw (`Uin2Uid Error ${payload.user_id}不存在`);
|
if (!uid) throw (`Uin2Uid Error ${payload.user_id}不存在`);
|
||||||
const member = await NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache);
|
const [member, info] = await Promise.allSettled([
|
||||||
if (!member) throw (`群(${payload.group_id})成员${payload.user_id}不存在`);
|
NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache),
|
||||||
try {
|
NTQQUserApi.getUserDetailInfo(uid),
|
||||||
const info = (await NTQQUserApi.getUserDetailInfo(member.uid));
|
]);
|
||||||
this.CoreContext.context.logger.logDebug('群成员详细信息结果', info);
|
if (member.status !== 'fulfilled') throw (`群(${payload.group_id})成员${payload.user_id}不存在 ${member.reason}`);
|
||||||
Object.assign(member, info);
|
if (info.status === 'fulfilled') {
|
||||||
} catch (e) {
|
this.CoreContext.context.logger.logDebug("群成员详细信息结果", info.value);
|
||||||
this.CoreContext.context.logger.logDebug('获取群成员详细信息失败, 只能返回基础信息', e);
|
Object.assign(member, info.value);
|
||||||
|
} else {
|
||||||
|
this.CoreContext.context.logger.logDebug(`获取群成员详细信息失败, 只能返回基础信息 ${info.reason}`);
|
||||||
}
|
}
|
||||||
const date = Math.round(Date.now() / 1000);
|
const date = Math.round(Date.now() / 1000);
|
||||||
const retMember = OB11Constructor.groupMember(payload.group_id.toString(), member);
|
const retMember = OB11Constructor.groupMember(payload.group_id.toString(), member.value as GroupMember);
|
||||||
retMember.last_sent_time = parseInt((await this.CoreContext.apis.GroupApi.getGroupMember(payload.group_id.toString(), retMember.user_id))?.lastSpeakTime || date.toString());
|
const Member = await this.CoreContext.apis.GroupApi.getGroupMember(payload.group_id.toString(), retMember.user_id);
|
||||||
retMember.join_time = parseInt((await this.CoreContext.apis.GroupApi.getGroupMember(payload.group_id.toString(), retMember.user_id))?.joinTime || date.toString());
|
retMember.last_sent_time = parseInt(Member?.lastSpeakTime || date.toString());
|
||||||
|
retMember.join_time = parseInt(Member?.joinTime || date.toString());
|
||||||
return retMember;
|
return retMember;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -61,7 +61,7 @@ import { TranslateEnWordToZn } from './extends/TranslateEnWordToZn';
|
|||||||
import { SetGroupFileFolder } from './file/SetGroupFileFolder';
|
import { SetGroupFileFolder } from './file/SetGroupFileFolder';
|
||||||
import { DelGroupFile } from './file/DelGroupFile';
|
import { DelGroupFile } from './file/DelGroupFile';
|
||||||
import { DelGroupFileFolder } from './file/DelGroupFileFolder';
|
import { DelGroupFileFolder } from './file/DelGroupFileFolder';
|
||||||
import { SetSelfProfile } from './extends/SetSelfProfile';
|
import { SetQQProfile } from './go-cqhttp/SetQQProfile'
|
||||||
import { ShareGroupEx, SharePeer } from './extends/ShareContact';
|
import { ShareGroupEx, SharePeer } from './extends/ShareContact';
|
||||||
import { CreateCollection } from './extends/CreateCollection';
|
import { CreateCollection } from './extends/CreateCollection';
|
||||||
import { SetLongNick } from './extends/SetLongNick';
|
import { SetLongNick } from './extends/SetLongNick';
|
||||||
@@ -69,7 +69,7 @@ import DelEssenceMsg from './group/DelEssenceMsg';
|
|||||||
import SetEssenceMsg from './group/SetEssenceMsg';
|
import SetEssenceMsg from './group/SetEssenceMsg';
|
||||||
import GetRecentContact from './user/GetRecentContact';
|
import GetRecentContact from './user/GetRecentContact';
|
||||||
import { GetProfileLike } from './extends/GetProfileLike';
|
import { GetProfileLike } from './extends/GetProfileLike';
|
||||||
import SetGroupHeader from './extends/SetGroupHeader';
|
import SetGroupPortrait from './go-cqhttp/SetGroupPortrait';
|
||||||
import { FetchCustomFace } from './extends/FetchCustomFace';
|
import { FetchCustomFace } from './extends/FetchCustomFace';
|
||||||
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivareFile';
|
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivareFile';
|
||||||
import { FetchEmojiLike } from './extends/FetchEmojiLike';
|
import { FetchEmojiLike } from './extends/FetchEmojiLike';
|
||||||
@@ -86,7 +86,7 @@ export function createActionMap(onebotContext: NapCatOneBot11Adapter, coreContex
|
|||||||
const actionHandlers = [
|
const actionHandlers = [
|
||||||
new FetchEmojiLike(onebotContext, coreContext),
|
new FetchEmojiLike(onebotContext, coreContext),
|
||||||
new GetFile(onebotContext, coreContext),
|
new GetFile(onebotContext, coreContext),
|
||||||
new SetSelfProfile(onebotContext, coreContext),
|
new SetQQProfile(onebotContext, coreContext),
|
||||||
new ShareGroupEx(onebotContext, coreContext),
|
new ShareGroupEx(onebotContext, coreContext),
|
||||||
new SharePeer(onebotContext, coreContext),
|
new SharePeer(onebotContext, coreContext),
|
||||||
new CreateCollection(onebotContext, coreContext),
|
new CreateCollection(onebotContext, coreContext),
|
||||||
@@ -161,7 +161,7 @@ export function createActionMap(onebotContext: NapCatOneBot11Adapter, coreContex
|
|||||||
new GetRecentContact(onebotContext, coreContext),
|
new GetRecentContact(onebotContext, coreContext),
|
||||||
new MarkAllMsgAsRead(onebotContext, coreContext),
|
new MarkAllMsgAsRead(onebotContext, coreContext),
|
||||||
new GetProfileLike(onebotContext, coreContext),
|
new GetProfileLike(onebotContext, coreContext),
|
||||||
new SetGroupHeader(onebotContext, coreContext),
|
new SetGroupPortrait(onebotContext, coreContext),
|
||||||
new FetchCustomFace(onebotContext, coreContext),
|
new FetchCustomFace(onebotContext, coreContext),
|
||||||
new GoCQHTTPUploadPrivateFile(onebotContext, coreContext),
|
new GoCQHTTPUploadPrivateFile(onebotContext, coreContext),
|
||||||
new GetGuildProfile(onebotContext, coreContext),
|
new GetGuildProfile(onebotContext, coreContext),
|
||||||
|
@@ -56,7 +56,7 @@ const _handlers: {
|
|||||||
if (atQQ === 'all') return SendMsgElementConstructor.at(coreContext, atQQ, atQQ, AtType.atAll, '全体成员');
|
if (atQQ === 'all') return SendMsgElementConstructor.at(coreContext, atQQ, atQQ, AtType.atAll, '全体成员');
|
||||||
|
|
||||||
// then the qq is a group member
|
// then the qq is a group member
|
||||||
// Mlikiowa V2.0.32 Refactor Todo
|
// Mlikiowa V2.0.35 Refactor Todo
|
||||||
const uid = await coreContext.apis.UserApi.getUidByUinV2(`${atQQ}`);
|
const uid = await coreContext.apis.UserApi.getUidByUinV2(`${atQQ}`);
|
||||||
if (!uid) throw new Error('Get Uid Error');
|
if (!uid) throw new Error('Get Uid Error');
|
||||||
return SendMsgElementConstructor.at(coreContext, atQQ, uid, AtType.atUser, '');
|
return SendMsgElementConstructor.at(coreContext, atQQ, uid, AtType.atUser, '');
|
||||||
@@ -161,7 +161,7 @@ const _handlers: {
|
|||||||
} else {
|
} else {
|
||||||
postData = data;
|
postData = data;
|
||||||
}
|
}
|
||||||
// Mlikiowa V2.0.32 Refactor Todo
|
// Mlikiowa V2.0.35 Refactor Todo
|
||||||
const signUrl = obContext.configLoader.configData.musicSignUrl;
|
const signUrl = obContext.configLoader.configData.musicSignUrl;
|
||||||
if (!signUrl) {
|
if (!signUrl) {
|
||||||
if (data.type === 'qq') {
|
if (data.type === 'qq') {
|
||||||
|
@@ -91,7 +91,7 @@ export enum ActionName {
|
|||||||
GetOnlineClient = 'get_online_clients',
|
GetOnlineClient = 'get_online_clients',
|
||||||
OCRImage = 'ocr_image',
|
OCRImage = 'ocr_image',
|
||||||
IOCRImage = '.ocr_image',
|
IOCRImage = '.ocr_image',
|
||||||
SetSelfProfile = 'set_self_profile',
|
SetQQProfile = 'set_qq_profile',
|
||||||
CreateCollection = 'create_collection',
|
CreateCollection = 'create_collection',
|
||||||
GetCollectionList = 'get_collection_list',
|
GetCollectionList = 'get_collection_list',
|
||||||
SetLongNick = 'set_self_longnick',
|
SetLongNick = 'set_self_longnick',
|
||||||
@@ -100,7 +100,7 @@ export enum ActionName {
|
|||||||
GetRecentContact = 'get_recent_contact',
|
GetRecentContact = 'get_recent_contact',
|
||||||
_MarkAllMsgAsRead = '_mark_all_as_read',
|
_MarkAllMsgAsRead = '_mark_all_as_read',
|
||||||
GetProfileLike = 'get_profile_like',
|
GetProfileLike = 'get_profile_like',
|
||||||
SetGroupHeader = 'set_group_head',
|
SetGroupPortrait = 'set_group_portrait',
|
||||||
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',
|
||||||
|
@@ -30,6 +30,7 @@ import { EventType } from '../event/OB11BaseEvent';
|
|||||||
import { encodeCQCode } from './cqcode';
|
import { encodeCQCode } from './cqcode';
|
||||||
import { OB11GroupIncreaseEvent } from '../event/notice/OB11GroupIncreaseEvent';
|
import { OB11GroupIncreaseEvent } from '../event/notice/OB11GroupIncreaseEvent';
|
||||||
import { OB11GroupBanEvent } from '../event/notice/OB11GroupBanEvent';
|
import { OB11GroupBanEvent } from '../event/notice/OB11GroupBanEvent';
|
||||||
|
import { OB11GroupCardEvent } from '../event/notice/OB11GroupCardEvent';
|
||||||
import { OB11GroupUploadNoticeEvent } from '../event/notice/OB11GroupUploadNoticeEvent';
|
import { OB11GroupUploadNoticeEvent } from '../event/notice/OB11GroupUploadNoticeEvent';
|
||||||
import { OB11GroupNoticeEvent } from '../event/notice/OB11GroupNoticeEvent';
|
import { OB11GroupNoticeEvent } from '../event/notice/OB11GroupNoticeEvent';
|
||||||
import { calcQQLevel, sleep, UUIDConverter } from '@/common/utils/helper';
|
import { calcQQLevel, sleep, UUIDConverter } from '@/common/utils/helper';
|
||||||
@@ -149,7 +150,6 @@ export class OB11Constructor {
|
|||||||
message_data['type'] = OB11MessageDataType.reply;
|
message_data['type'] = OB11MessageDataType.reply;
|
||||||
//log("收到回复消息", element.replyElement);
|
//log("收到回复消息", element.replyElement);
|
||||||
try {
|
try {
|
||||||
let oldMsgFlag = false;
|
|
||||||
const records = msg.records.find(msgRecord => msgRecord.msgId === element?.replyElement?.sourceMsgIdInRecords);
|
const records = msg.records.find(msgRecord => msgRecord.msgId === element?.replyElement?.sourceMsgIdInRecords);
|
||||||
const peer = {
|
const peer = {
|
||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
@@ -164,15 +164,18 @@ export class OB11Constructor {
|
|||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
}, element.replyElement.replayMsgSeq, 1, true, true)).msgList.find(msg => msg.msgRandom === records.msgRandom);
|
}, element.replyElement.replayMsgSeq, 1, true, true)).msgList.find(msg => msg.msgRandom === records.msgRandom);
|
||||||
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
|
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
|
||||||
if (!replyMsg && records.msgRandom === '0') oldMsgFlag = true;
|
|
||||||
replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replyElement.replayMsgSeq)).msgList[0];
|
replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replyElement.replayMsgSeq)).msgList[0];
|
||||||
}
|
}
|
||||||
if (msg.peerUin == '284840486') {
|
if (msg.peerUin == '284840486') {
|
||||||
//合并消息内侧 消息具体定位不到
|
//合并消息内侧 消息具体定位不到
|
||||||
}
|
}
|
||||||
if ((!replyMsg || (records.msgRandom !== replyMsg.msgRandom && !oldMsgFlag || (oldMsgFlag && records.msgSeq !== replyMsg.msgSeq))) && msg.peerUin !== '284840486') {
|
if ((!replyMsg || records.msgRandom !== replyMsg.msgRandom) && msg.peerUin !== '284840486') {
|
||||||
|
const replyMsgList = (await NTQQMsgApi.getMsgExBySeq(peer, records.msgSeq)).msgList;
|
||||||
|
if (replyMsgList.length < 1) {
|
||||||
throw new Error('回复消息消息验证失败');
|
throw new Error('回复消息消息验证失败');
|
||||||
}
|
}
|
||||||
|
replyMsg = replyMsgList.filter(e => e.msgSeq == records.msgSeq).sort((a, b) => parseInt(a.msgTime) - parseInt(b.msgTime))[0];
|
||||||
|
}
|
||||||
message_data['data']['id'] = MessageUnique.createMsg({
|
message_data['data']['id'] = MessageUnique.createMsg({
|
||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
@@ -419,16 +422,15 @@ export class OB11Constructor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//log("group msg", msg);
|
//log("group msg", msg);
|
||||||
// Mlikiowa V2.0.32 Refactor Todo
|
if (msg.senderUin && msg.senderUin !== '0') {
|
||||||
// if (msg.senderUin && msg.senderUin !== '0') {
|
const member = await NTQQGroupApi.getGroupMember(msg.peerUid, msg.senderUin);
|
||||||
// const member = await getGroupMember(msg.peerUid, msg.senderUin);
|
if (member && member.cardName !== msg.sendMemberName) {
|
||||||
// if (member && member.cardName !== msg.sendMemberName) {
|
const newCardName = msg.sendMemberName || '';
|
||||||
// const newCardName = msg.sendMemberName || '';
|
const event = new OB11GroupCardEvent(core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName);
|
||||||
// const event = new OB11GroupCardEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName);
|
member.cardName = newCardName;
|
||||||
// member.cardName = newCardName;
|
return event;
|
||||||
// return event;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
for (const element of msg.elements) {
|
for (const element of msg.elements) {
|
||||||
const grayTipElement = element.grayTipElement;
|
const grayTipElement = element.grayTipElement;
|
||||||
|
@@ -9,6 +9,7 @@ import {
|
|||||||
NapCatCore,
|
NapCatCore,
|
||||||
RawMessage,
|
RawMessage,
|
||||||
SendStatusType,
|
SendStatusType,
|
||||||
|
GroupMemberRole,
|
||||||
} from '@/core';
|
} from '@/core';
|
||||||
import { OB11Config, OB11ConfigLoader } from '@/onebot/helper/config';
|
import { OB11Config, OB11ConfigLoader } from '@/onebot/helper/config';
|
||||||
import { OneBotApiContextType } from '@/onebot/types';
|
import { OneBotApiContextType } from '@/onebot/types';
|
||||||
@@ -413,6 +414,29 @@ export class NapCatOneBot11Adapter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
groupListener.onMemberInfoChange = async (groupCode, changeType, members) => {
|
||||||
|
//this.context.logger.logDebug('收到群成员信息变动通知', groupCode, changeType);
|
||||||
|
if (changeType === 0) {
|
||||||
|
const existMembers = this.core.apis.GroupApi.groupMemberCache.get(groupCode);
|
||||||
|
if (!existMembers) return;
|
||||||
|
members.forEach((member) => {
|
||||||
|
const existMember = existMembers.get(member.uid);
|
||||||
|
if (!existMember?.isChangeRole) return;
|
||||||
|
this.context.logger.logDebug('变动管理员获取成功');
|
||||||
|
const groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent(
|
||||||
|
this.core,
|
||||||
|
parseInt(groupCode),
|
||||||
|
parseInt(member.uin),
|
||||||
|
member.role === GroupMemberRole.admin ? 'set' : 'unset',
|
||||||
|
);
|
||||||
|
this.networkManager.emitEvent(groupAdminNoticeEvent)
|
||||||
|
.catch(e => this.context.logger.logError('处理群管理员变动失败', e));
|
||||||
|
existMember.isChangeRole = false;
|
||||||
|
this.context.logger.logDebug('群管理员变动处理完毕');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.context.session.getGroupService().addKernelGroupListener(
|
this.context.session.getGroupService().addKernelGroupListener(
|
||||||
new this.context.wrapper.NodeIKernelGroupListener(proxiedListenerOf(groupListener, this.context.logger)),
|
new this.context.wrapper.NodeIKernelGroupListener(proxiedListenerOf(groupListener, this.context.logger)),
|
||||||
);
|
);
|
||||||
|
@@ -79,6 +79,12 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
this.connection.on('ping', () => {
|
||||||
|
this.connection?.pong();
|
||||||
|
});
|
||||||
|
this.connection.on('pong', () => {
|
||||||
|
//this.logger.logDebug('[OneBot] [WebSocket Client] 收到pong');
|
||||||
|
});
|
||||||
this.connection.on('open', () => {
|
this.connection.on('open', () => {
|
||||||
try {
|
try {
|
||||||
this.connectEvent(this.coreContext);
|
this.connectEvent(this.coreContext);
|
||||||
|
@@ -50,6 +50,12 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
wsClient.on('message', (message) => {
|
wsClient.on('message', (message) => {
|
||||||
this.handleMessage(wsClient, message).then().catch(this.logger.logError);
|
this.handleMessage(wsClient, message).then().catch(this.logger.logError);
|
||||||
});
|
});
|
||||||
|
wsClient.on('ping', () => {
|
||||||
|
wsClient.pong();
|
||||||
|
});
|
||||||
|
wsClient.on('pong', () => {
|
||||||
|
//this.logger.logDebug('[OneBot] [WebSocket Server] Pong received');
|
||||||
|
});
|
||||||
wsClient.once('close', () => {
|
wsClient.once('close', () => {
|
||||||
this.wsClientsMutex.runExclusive(async () => {
|
this.wsClientsMutex.runExclusive(async () => {
|
||||||
const index = this.wsClients.indexOf(wsClient);
|
const index = this.wsClients.indexOf(wsClient);
|
||||||
|
@@ -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.0.32', 'napcat-update-button', 'secondary'),
|
SettingButton('V2.0.35', 'napcat-update-button', 'secondary'),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
@@ -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.0.32", "napcat-update-button", "secondary")
|
SettingButton("V2.0.35", "napcat-update-button", "secondary")
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
Reference in New Issue
Block a user