mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
95b003802c | ||
![]() |
95c9eae4ed | ||
![]() |
e3814403e4 | ||
![]() |
3d16d52dd8 | ||
![]() |
1ae47fffb4 | ||
![]() |
4e7096b9e2 | ||
![]() |
8cc9b7f6a7 |
@@ -4,7 +4,7 @@
|
||||
"name": "NapCatQQ",
|
||||
"slug": "NapCat.Framework",
|
||||
"description": "高性能的 OneBot 11 协议实现",
|
||||
"version": "4.2.66",
|
||||
"version": "4.3.2",
|
||||
"icon": "./logo.png",
|
||||
"authors": [
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "4.2.66",
|
||||
"version": "4.3.2",
|
||||
"scripts": {
|
||||
"build:universal": "npm run build:webui && vite build --mode universal || exit 1",
|
||||
"build:framework": "npm run build:webui && vite build --mode framework || exit 1",
|
||||
|
@@ -20,19 +20,19 @@ export class Fallback<T> {
|
||||
for (const handler of this.handlers) {
|
||||
try {
|
||||
const result = await handler();
|
||||
try {
|
||||
return await this.checker(result);
|
||||
} catch (checkerError) {
|
||||
errors.push(checkerError instanceof Error ? checkerError : new Error(String(checkerError)));
|
||||
let data = await this.checker(result);
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
errors.push(error instanceof Error ? error : new Error(String(error)));
|
||||
}
|
||||
}
|
||||
throw new AggregateError(errors, 'All handlers failed');
|
||||
}
|
||||
}
|
||||
export class FallbackUtil{
|
||||
export class FallbackUtil {
|
||||
static boolchecker<T>(value: T, condition: boolean): T {
|
||||
if (condition) {
|
||||
return value;
|
||||
|
@@ -1 +1 @@
|
||||
export const napCatVersion = '4.2.66';
|
||||
export const napCatVersion = '4.3.2';
|
||||
|
@@ -18,6 +18,7 @@ export class NTQQGroupApi {
|
||||
context: InstanceContext;
|
||||
core: NapCatCore;
|
||||
groupMemberCache: Map<string, Map<string, GroupMember>> = new Map<string, Map<string, GroupMember>>();
|
||||
groupMemberCacheEvent: Map<string, boolean> = new Map<string, boolean>();
|
||||
essenceLRU = new LimitedHashTable<number, string>(1000);
|
||||
|
||||
constructor(context: InstanceContext, core: NapCatCore) {
|
||||
@@ -44,7 +45,7 @@ export class NTQQGroupApi {
|
||||
|
||||
async initCache() {
|
||||
for (const group of await this.getGroups(true)) {
|
||||
this.refreshGroupMemberCache(group.groupCode).then().catch();
|
||||
this.refreshGroupMemberCache(group.groupCode, false).then().catch(e => this.context.logger.logError(e));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,14 +127,26 @@ export class NTQQGroupApi {
|
||||
return this.context.session.getGroupService().getAllMemberList(groupCode, forced);
|
||||
}
|
||||
|
||||
async refreshGroupMemberCache(groupCode: string) {
|
||||
try {
|
||||
const members = await this.getGroupMemberAll(groupCode, true);
|
||||
this.groupMemberCache.set(groupCode, members.result.infos);
|
||||
} catch (e) {
|
||||
this.context.logger.logError(`刷新群成员缓存失败, 群号: ${groupCode}, 错误: ${e}`);
|
||||
async refreshGroupMemberCache(groupCode: string, isWait = true) {
|
||||
this.groupMemberCacheEvent.set(groupCode, true);
|
||||
const updateCache = async () => {
|
||||
try {
|
||||
const members = await this.getGroupMemberAll(groupCode, true);
|
||||
this.groupMemberCache.set(groupCode, members.result.infos);
|
||||
} catch (e) {
|
||||
this.context.logger.logError(`刷新群成员缓存失败, 群号: ${groupCode}, 错误: ${e}`);
|
||||
} finally {
|
||||
this.groupMemberCacheEvent.set(groupCode, false);
|
||||
}
|
||||
};
|
||||
|
||||
if (isWait) {
|
||||
await updateCache();
|
||||
} else {
|
||||
updateCache();
|
||||
}
|
||||
return this.groupMemberCache;
|
||||
|
||||
return this.groupMemberCache.get(groupCode);
|
||||
}
|
||||
|
||||
async getGroupMember(groupCode: string | number, memberUinOrUid: string | number) {
|
||||
@@ -143,7 +156,7 @@ export class NTQQGroupApi {
|
||||
// 获取群成员缓存
|
||||
let members = this.groupMemberCache.get(groupCodeStr);
|
||||
if (!members) {
|
||||
members = (await this.refreshGroupMemberCache(groupCodeStr)).get(groupCodeStr);
|
||||
members = (await this.refreshGroupMemberCache(groupCodeStr, true));
|
||||
}
|
||||
|
||||
const getMember = () => {
|
||||
@@ -157,7 +170,7 @@ export class NTQQGroupApi {
|
||||
let member = getMember();
|
||||
// 如果缓存中不存在该成员,尝试刷新缓存
|
||||
if (!member) {
|
||||
members = (await this.refreshGroupMemberCache(groupCodeStr)).get(groupCodeStr);
|
||||
members = (await this.refreshGroupMemberCache(groupCodeStr, true));
|
||||
member = getMember();
|
||||
}
|
||||
return member;
|
||||
|
@@ -193,7 +193,7 @@ export class NTQQUserApi {
|
||||
.add(() => this.context.session.getGroupService().getUidByUins([uin]).then((data) => data.uids.get(uin)))
|
||||
.add(() => this.getUserDetailInfoByUin(uin).then((data) => data.detail.uid));
|
||||
|
||||
const uid = await fallback.run().catch(() => '0');
|
||||
const uid = await fallback.run().catch(() => '');
|
||||
return uid ?? '';
|
||||
}
|
||||
|
||||
|
8
src/core/external/appid.json
vendored
8
src/core/external/appid.json
vendored
@@ -158,5 +158,13 @@
|
||||
"6.9.63-30899": {
|
||||
"appid": 537263820,
|
||||
"qua": "V1_MAC_NQ_6.9.63_30899_GW_B"
|
||||
},
|
||||
"9.9.17-31219": {
|
||||
"appid": 537266450,
|
||||
"qua": "V1_WIN_NQ_9.9.17_31219_GW_B"
|
||||
},
|
||||
"9.9.17-31245": {
|
||||
"appid": 537266450,
|
||||
"qua": "V1_WIN_NQ_9.9.17_31245_GW_B"
|
||||
}
|
||||
}
|
8
src/core/external/offset.json
vendored
8
src/core/external/offset.json
vendored
@@ -202,5 +202,13 @@
|
||||
"6.9.63-30899-arm64": {
|
||||
"send": "41DCBD8",
|
||||
"recv": "41DF3F0"
|
||||
},
|
||||
"9.9.17-31219-x64": {
|
||||
"send": "39C1350",
|
||||
"recv": "39C5784"
|
||||
},
|
||||
"9.9.17-31245-x64": {
|
||||
"send": "39C1350",
|
||||
"recv": "39C5784"
|
||||
}
|
||||
}
|
@@ -13,12 +13,13 @@ type Payload = Static<typeof SchemaData>;
|
||||
|
||||
export default class GoCQHTTPGetStrangerInfo extends OneBotAction<Payload, OB11User> {
|
||||
actionName = ActionName.GoCQHTTP_GetStrangerInfo;
|
||||
|
||||
payloadSchema = SchemaData;
|
||||
async _handle(payload: Payload): Promise<OB11User> {
|
||||
const user_id = payload.user_id.toString();
|
||||
const extendData = await this.core.apis.UserApi.getUserDetailInfoByUin(user_id);
|
||||
let uid = (await this.core.apis.UserApi.getUidByUinV2(user_id));
|
||||
if (!uid) uid = extendData.detail.uid;
|
||||
console.log(uid);
|
||||
const info = (await this.core.apis.UserApi.getUserDetailInfo(uid));
|
||||
return {
|
||||
...extendData.detail.simpleInfo.coreInfo,
|
||||
|
@@ -26,20 +26,35 @@ class GetGroupMemberInfo extends OneBotAction<Payload, OB11GroupMember> {
|
||||
return uid;
|
||||
}
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
const isNocache = this.parseBoolean(payload.no_cache ?? true);
|
||||
const uid = await this.getUid(payload.user_id);
|
||||
const groupMember = this.core.apis.GroupApi.groupMemberCache.get(payload.group_id.toString())?.get(uid);
|
||||
let [member, info] = await Promise.all([
|
||||
private async getGroupMemberInfo(payload: Payload, uid: string, isNocache: boolean) {
|
||||
const groupMemberCache = this.core.apis.GroupApi.groupMemberCache.get(payload.group_id.toString());
|
||||
let groupMember = groupMemberCache?.get(uid);
|
||||
|
||||
const [member, info] = await Promise.all([
|
||||
this.core.apis.GroupApi.getGroupMemberEx(payload.group_id.toString(), uid, isNocache),
|
||||
this.core.apis.UserApi.getUserDetailInfo(uid),
|
||||
]);
|
||||
if (!member || !groupMember) throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在`);
|
||||
if (info) {
|
||||
member = { ...groupMember, ...member, ...info };
|
||||
} else {
|
||||
|
||||
if (!member) throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在`);
|
||||
|
||||
if (!groupMember && this.core.apis.GroupApi.groupMemberCacheEvent.get(payload.group_id.toString())) {
|
||||
groupMember = (await this.core.apis.GroupApi.refreshGroupMemberCache(payload.group_id.toString(), true))?.get(uid);
|
||||
}
|
||||
|
||||
if (!groupMember) throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在`);
|
||||
|
||||
return info ? { ...groupMember, ...member, ...info } : member;
|
||||
}
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
const isNocache = this.parseBoolean(payload.no_cache ?? true);
|
||||
const uid = await this.getUid(payload.user_id);
|
||||
const member = await this.getGroupMemberInfo(payload, uid, isNocache);
|
||||
|
||||
if (!member) {
|
||||
this.core.context.logger.logDebug(`获取群成员详细信息失败, 只能返回基础信息`);
|
||||
}
|
||||
|
||||
return OB11Construct.groupMember(payload.group_id.toString(), member);
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ import { OB11Construct } from '@/onebot/helper/data';
|
||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/onebot/action/router';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { GroupMember } from '@/core';
|
||||
|
||||
const SchemaData = Type.Object({
|
||||
group_id: Type.Union([Type.Number(), Type.String()]),
|
||||
@@ -17,25 +18,32 @@ export class GetGroupMemberList extends OneBotAction<Payload, OB11GroupMember[]>
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
const groupIdStr = payload.group_id.toString();
|
||||
const noCache = payload.no_cache ? this.stringToBoolean(payload.no_cache) : false;
|
||||
const noCache = this.parseBoolean(payload.no_cache ?? false);
|
||||
const groupMembers = await this.getGroupMembers(groupIdStr, noCache);
|
||||
const _groupMembers = await Promise.all(
|
||||
Array.from(groupMembers.values()).map(item =>
|
||||
OB11Construct.groupMember(groupIdStr, item)
|
||||
)
|
||||
);
|
||||
return Array.from(new Map(_groupMembers.map(member => [member.user_id, member])).values());
|
||||
}
|
||||
|
||||
private parseBoolean(value: boolean | string): boolean {
|
||||
return typeof value === 'string' ? value === 'true' : value;
|
||||
}
|
||||
|
||||
private async getGroupMembers(groupIdStr: string, noCache: boolean): Promise<Map<string, GroupMember>> {
|
||||
const memberCache = this.core.apis.GroupApi.groupMemberCache;
|
||||
let groupMembers = memberCache.get(groupIdStr);
|
||||
|
||||
if (noCache || !groupMembers) {
|
||||
this.core.apis.GroupApi.refreshGroupMemberCache(groupIdStr).then().catch();
|
||||
//下次刷新
|
||||
groupMembers = memberCache.get(groupIdStr);
|
||||
const data = this.core.apis.GroupApi.refreshGroupMemberCache(groupIdStr, true).then().catch();
|
||||
groupMembers = memberCache.get(groupIdStr) || (await data);
|
||||
if (!groupMembers) {
|
||||
throw new Error(`Failed to get group member list for group ${groupIdStr}`);
|
||||
}
|
||||
}
|
||||
const memberPromises = Array.from(groupMembers.values()).map(item =>
|
||||
OB11Construct.groupMember(groupIdStr, item)
|
||||
);
|
||||
const _groupMembers = await Promise.all(memberPromises);
|
||||
const MemberMap = new Map(_groupMembers.map(member => [member.user_id, member]));
|
||||
return Array.from(MemberMap.values());
|
||||
|
||||
return groupMembers;
|
||||
}
|
||||
stringToBoolean(str: string | boolean): boolean {
|
||||
return typeof str === 'boolean' ? str : str.toLowerCase() === "true";
|
||||
}
|
||||
}
|
||||
}
|
@@ -223,7 +223,7 @@ export class OneBotGroupApi {
|
||||
} else if (element.type === TipGroupElementType.KMEMBERADD) {
|
||||
// 自己的通知 协议推送为type->85 在这里实现为了避免邀请出现问题
|
||||
if (element.memberUid == this.core.selfInfo.uid) {
|
||||
this.core.apis.GroupApi.refreshGroupMemberCache(msg.peerUid).then().catch();
|
||||
await this.core.apis.GroupApi.refreshGroupMemberCache(msg.peerUid, false);
|
||||
return new OB11GroupIncreaseEvent(
|
||||
this.core,
|
||||
parseInt(msg.peerUid),
|
||||
|
@@ -1022,7 +1022,7 @@ export class OneBotMsgApi {
|
||||
// 邀请需要解grayTipElement
|
||||
if (SysMessage.contentHead.type == 33 && SysMessage.body?.msgContent) {
|
||||
const groupChange = new NapProtoMsg(GroupChange).decode(SysMessage.body.msgContent);
|
||||
this.core.apis.GroupApi.refreshGroupMemberCache(groupChange.groupUin.toString()).then().catch();
|
||||
await this.core.apis.GroupApi.refreshGroupMemberCache(groupChange.groupUin.toString(), false);
|
||||
let operatorUid = await this.waitGroupNotify(
|
||||
groupChange.groupUin.toString(),
|
||||
groupChange.memberUid,
|
||||
@@ -1052,7 +1052,7 @@ export class OneBotMsgApi {
|
||||
}, 5000);
|
||||
// 自己被踢了 5S后回收
|
||||
} else {
|
||||
this.core.apis.GroupApi.refreshGroupMemberCache(groupChange.groupUin.toString()).then().catch();
|
||||
await this.core.apis.GroupApi.refreshGroupMemberCache(groupChange.groupUin.toString(), false);
|
||||
}
|
||||
return new OB11GroupDecreaseEvent(
|
||||
this.core,
|
||||
@@ -1063,7 +1063,7 @@ export class OneBotMsgApi {
|
||||
);
|
||||
} else if (SysMessage.contentHead.type == 44 && SysMessage.body?.msgContent) {
|
||||
const groupAmin = new NapProtoMsg(GroupAdmin).decode(SysMessage.body.msgContent);
|
||||
this.core.apis.GroupApi.refreshGroupMemberCache(groupAmin.groupUin.toString()).then().catch();
|
||||
await this.core.apis.GroupApi.refreshGroupMemberCache(groupAmin.groupUin.toString(), false);
|
||||
let enabled = false;
|
||||
let uid = '';
|
||||
if (groupAmin.body.extraEnable != null) {
|
||||
|
Reference in New Issue
Block a user