mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3de5438139 | ||
![]() |
c4b5f34271 | ||
![]() |
22d3ac33a2 | ||
![]() |
2e5dd6535a | ||
![]() |
eac58a2a50 | ||
![]() |
e939ec0e52 | ||
![]() |
5b17a14a2a | ||
![]() |
8fb8c888f5 | ||
![]() |
4a2884509e |
@@ -4,7 +4,7 @@
|
||||
"name": "NapCatQQ",
|
||||
"slug": "NapCat.Framework",
|
||||
"description": "高性能的 OneBot 11 协议实现",
|
||||
"version": "4.2.19",
|
||||
"version": "4.2.22",
|
||||
"icon": "./logo.png",
|
||||
"authors": [
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "4.2.19",
|
||||
"version": "4.2.22",
|
||||
"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",
|
||||
|
@@ -1 +1 @@
|
||||
export const napCatVersion = '4.2.19';
|
||||
export const napCatVersion = '4.2.22';
|
||||
|
@@ -8,14 +8,10 @@ import { LRUCache } from '@/common/lru-cache';
|
||||
export class NTQQUserApi {
|
||||
context: InstanceContext;
|
||||
core: NapCatCore;
|
||||
private uidCache: LRUCache<string, string>;
|
||||
private uinCache: LRUCache<string, string>;
|
||||
|
||||
constructor(context: InstanceContext, core: NapCatCore) {
|
||||
this.context = context;
|
||||
this.core = core;
|
||||
this.uidCache = new LRUCache(1000);
|
||||
this.uinCache = new LRUCache(1000);
|
||||
}
|
||||
|
||||
async getCoreAndBaseInfo(uids: string[]) {
|
||||
@@ -174,8 +170,8 @@ export class NTQQUserApi {
|
||||
}
|
||||
|
||||
async getUidByUinV2(Uin: string) {
|
||||
if (this.uidCache.get(Uin)) {
|
||||
return this.uidCache.get(Uin);
|
||||
if (!Uin) {
|
||||
return '';
|
||||
}
|
||||
const services = [
|
||||
() => this.context.session.getUixConvertService().getUid([Uin]).then((data) => data.uidInfo.get(Uin)).catch(() => undefined),
|
||||
@@ -188,16 +184,15 @@ export class NTQQUserApi {
|
||||
for (const service of services) {
|
||||
uid = await service();
|
||||
if (uid && uid.indexOf('*') == -1 && uid !== '') {
|
||||
this.uidCache.put(Uin, uid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return uid;
|
||||
return uid ?? '';
|
||||
}
|
||||
|
||||
async getUinByUidV2(Uid: string) {
|
||||
if (this.uinCache.get(Uid)) {
|
||||
return this.uinCache.get(Uid);
|
||||
if (!Uid) {
|
||||
return '0';
|
||||
}
|
||||
const services = [
|
||||
() => this.context.session.getUixConvertService().getUin([Uid]).then((data) => data.uinInfo.get(Uid)).catch(() => undefined),
|
||||
@@ -211,11 +206,10 @@ export class NTQQUserApi {
|
||||
for (const service of services) {
|
||||
uin = await service();
|
||||
if (uin && uin !== '0' && uin !== '') {
|
||||
this.uinCache.put(Uid, uin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return uin;
|
||||
return uin ?? '0';
|
||||
}
|
||||
|
||||
async getRecentContactListSnapShot(count: number) {
|
||||
|
6
src/core/external/appid.json
vendored
6
src/core/external/appid.json
vendored
@@ -98,5 +98,9 @@
|
||||
"6.9.61-29927": {
|
||||
"appid": 537255836,
|
||||
"qua": "V1_MAC_NQ_6.9.61_29927_GW_B"
|
||||
},
|
||||
"9.9.17-30366": {
|
||||
"appid": 537258389,
|
||||
"qua": "V1_WIN_NQ_9.9.17_30366_GW_B"
|
||||
}
|
||||
}
|
||||
}
|
6
src/core/external/offset.json
vendored
6
src/core/external/offset.json
vendored
@@ -102,5 +102,9 @@
|
||||
"6.9.61-29927-arm64": {
|
||||
"send": "4038740",
|
||||
"recv": "403AF58"
|
||||
},
|
||||
"9.9.17-30366-x64": {
|
||||
"send": "39AB0B0",
|
||||
"recv": "39AF4E4"
|
||||
}
|
||||
}
|
||||
}
|
@@ -187,11 +187,11 @@ export interface NodeIKernelGroupService {
|
||||
|
||||
destroyGroup(groupCode: string): void;
|
||||
|
||||
getSingleScreenNotifies(doubted: boolean, start_seq: string, num: number): Promise<GeneralCallResult>;
|
||||
getSingleScreenNotifies(doubt: boolean, startSeq: string, count: number): Promise<GeneralCallResult>;
|
||||
|
||||
clearGroupNotifies(groupCode: string): void;
|
||||
|
||||
getGroupNotifiesUnreadCount(unknown: boolean): Promise<GeneralCallResult>;
|
||||
getGroupNotifiesUnreadCount(doubt: boolean): Promise<GeneralCallResult>;
|
||||
|
||||
clearGroupNotifiesUnreadCount(doubt: boolean): void;
|
||||
|
||||
|
@@ -29,6 +29,7 @@ export interface TextElement {
|
||||
}
|
||||
|
||||
export interface FaceElement {
|
||||
pokeType?: number;
|
||||
faceIndex: number;
|
||||
faceType: FaceType;
|
||||
faceText?: string;
|
||||
|
@@ -2,32 +2,44 @@ import { GroupNotifyMsgStatus } from '@/core';
|
||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/onebot/action/router';
|
||||
|
||||
interface OB11GroupRequestNotify {
|
||||
group_id: number,
|
||||
user_id: number,
|
||||
flag: string
|
||||
interface Notify {
|
||||
request_id: string;
|
||||
invitor_uin: number;
|
||||
invitor_nick?: string;
|
||||
group_id?: number;
|
||||
group_name?: string;
|
||||
checked: boolean;
|
||||
requester_nick?: string;
|
||||
actor: number;
|
||||
}
|
||||
|
||||
export default class GetGroupAddRequest extends OneBotAction<null, OB11GroupRequestNotify[] | null> {
|
||||
export default class GetGroupAddRequest extends OneBotAction<null, Notify[] | null> {
|
||||
actionName = ActionName.GetGroupIgnoreAddRequest;
|
||||
|
||||
async _handle(payload: null): Promise<OB11GroupRequestNotify[] | null> {
|
||||
const ignoredNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(true, 10);
|
||||
const retData: any = {
|
||||
join_requests: await Promise.all(
|
||||
ignoredNotifies
|
||||
.filter(notify => notify.type === 7)
|
||||
.map(async SSNotify => ({
|
||||
request_id: SSNotify.group.groupCode + '|' + SSNotify.seq + '|' + SSNotify.type,
|
||||
requester_uin: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1?.uid),
|
||||
requester_nick: SSNotify.user1?.nickName,
|
||||
group_id: SSNotify.group?.groupCode,
|
||||
group_name: SSNotify.group?.groupName,
|
||||
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||
actor: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
||||
}))),
|
||||
};
|
||||
async _handle(payload: null): Promise<Notify[] | null> {
|
||||
const NTQQUserApi = this.core.apis.UserApi;
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
const ignoredNotifies = await NTQQGroupApi.getSingleScreenNotifies(true, 10);
|
||||
const retData: Notify[] = [];
|
||||
|
||||
const notifyPromises = ignoredNotifies
|
||||
.filter(notify => notify.type === 7)
|
||||
.map(async SSNotify => {
|
||||
const invitorUin = SSNotify.user1?.uid ? +await NTQQUserApi.getUinByUidV2(SSNotify.user1.uid) : 0;
|
||||
const actorUin = SSNotify.user2?.uid ? +await NTQQUserApi.getUinByUidV2(SSNotify.user2.uid) : 0;
|
||||
retData.push({
|
||||
request_id: `${SSNotify.group.groupCode}|${SSNotify.seq}|${SSNotify.type}`,
|
||||
invitor_uin: invitorUin,
|
||||
requester_nick: SSNotify.user1?.nickName,
|
||||
group_id: +SSNotify.group?.groupCode,
|
||||
group_name: SSNotify.group?.groupName,
|
||||
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||
actor: actorUin,
|
||||
});
|
||||
});
|
||||
|
||||
await Promise.all(notifyPromises);
|
||||
|
||||
return retData;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,26 +1,55 @@
|
||||
import { GroupNotifyMsgStatus } from '@/core';
|
||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/onebot/action/router';
|
||||
export class GetGroupIgnoredNotifies extends OneBotAction<void, any> {
|
||||
actionName = ActionName.GetGroupIgnoredNotifies;
|
||||
|
||||
async _handle(payload: void) {
|
||||
const ignoredNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(true, 10);
|
||||
const retData: any = {
|
||||
join_requests: await Promise.all(
|
||||
ignoredNotifies
|
||||
.filter(notify => notify.type === 7)
|
||||
.map(async SSNotify => ({
|
||||
request_id: SSNotify.group.groupCode + '|' + SSNotify.seq + '|' + SSNotify.type,
|
||||
requester_uin: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1?.uid),
|
||||
requester_nick: SSNotify.user1?.nickName,
|
||||
group_id: SSNotify.group?.groupCode,
|
||||
group_name: SSNotify.group?.groupName,
|
||||
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||
actor: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
||||
}))),
|
||||
};
|
||||
interface Notify {
|
||||
request_id: string;
|
||||
invitor_uin: number;
|
||||
invitor_nick?: string;
|
||||
group_id?: number;
|
||||
group_name?: string;
|
||||
checked: boolean;
|
||||
requester_nick?: string;
|
||||
actor: number;
|
||||
}
|
||||
interface RetData {
|
||||
InvitedRequest: Notify[];
|
||||
join_requests: Notify[];
|
||||
}
|
||||
|
||||
export class GetGroupIgnoredNotifies extends OneBotAction<void, RetData> {
|
||||
actionName = ActionName.GetGroupSystemMsg;
|
||||
|
||||
async _handle(): Promise<RetData> {
|
||||
const NTQQUserApi = this.core.apis.UserApi;
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
const SingleScreenNotifies = await NTQQGroupApi.getSingleScreenNotifies(false, 50);
|
||||
const retData: RetData = { InvitedRequest: [], join_requests: [] };
|
||||
|
||||
const notifyPromises = SingleScreenNotifies.map(async (SSNotify) => {
|
||||
const invitorUin = SSNotify.user1?.uid ? +await NTQQUserApi.getUinByUidV2(SSNotify.user1.uid) : 0;
|
||||
const actorUin = SSNotify.user2?.uid ? +await NTQQUserApi.getUinByUidV2(SSNotify.user2.uid) : 0;
|
||||
|
||||
const commonData = {
|
||||
request_id: `${SSNotify.group.groupCode}|${SSNotify.seq}|${SSNotify.type}`,
|
||||
invitor_uin: invitorUin,
|
||||
invitor_nick: SSNotify.user1?.nickName,
|
||||
group_id: +SSNotify.group?.groupCode,
|
||||
group_name: SSNotify.group?.groupName,
|
||||
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||
actor: actorUin,
|
||||
requester_nick: SSNotify.user1?.nickName,
|
||||
};
|
||||
|
||||
if (SSNotify.type === 1) {
|
||||
retData.InvitedRequest.push(commonData);
|
||||
} else if (SSNotify.type === 7) {
|
||||
retData.join_requests.push(commonData);
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(notifyPromises);
|
||||
|
||||
return retData;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,38 +1,63 @@
|
||||
import { GroupNotifyMsgStatus } from '@/core';
|
||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/onebot/action/router';
|
||||
export class GetGroupSystemMsg extends OneBotAction<void, any> {
|
||||
|
||||
interface Notify {
|
||||
request_id: string;
|
||||
invitor_uin: number;
|
||||
invitor_nick?: string;
|
||||
group_id?: number;
|
||||
group_name?: string;
|
||||
checked: boolean;
|
||||
actor: number;
|
||||
}
|
||||
|
||||
interface JoinRequest extends Notify {
|
||||
requester_nick?: string;
|
||||
}
|
||||
|
||||
interface RetData {
|
||||
InvitedRequest: Notify[];
|
||||
join_requests: JoinRequest[];
|
||||
}
|
||||
|
||||
export class GetGroupSystemMsg extends OneBotAction<void, RetData> {
|
||||
actionName = ActionName.GetGroupSystemMsg;
|
||||
|
||||
async _handle() {
|
||||
async _handle(): Promise<RetData> {
|
||||
const NTQQUserApi = this.core.apis.UserApi;
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
// 默认10条 该api未完整实现 包括响应数据规范化 类型规范化
|
||||
const SingleScreenNotifies = await NTQQGroupApi.getSingleScreenNotifies(false, 10);
|
||||
const retData: any = { InvitedRequest: [], join_requests: [] };
|
||||
for (const SSNotify of SingleScreenNotifies) {
|
||||
if (SSNotify.type == 1) {
|
||||
const SingleScreenNotifies = await NTQQGroupApi.getSingleScreenNotifies(false, 50);
|
||||
const retData: RetData = { InvitedRequest: [], join_requests: [] };
|
||||
|
||||
const notifyPromises = SingleScreenNotifies.map(async (SSNotify) => {
|
||||
const invitorUin = SSNotify.user1?.uid ? +await NTQQUserApi.getUinByUidV2(SSNotify.user1.uid) : 0;
|
||||
const actorUin = SSNotify.user2?.uid ? +await NTQQUserApi.getUinByUidV2(SSNotify.user2.uid) : 0;
|
||||
|
||||
if (SSNotify.type === 1) {
|
||||
retData.InvitedRequest.push({
|
||||
request_id: SSNotify.group.groupCode + '|' + SSNotify.seq + '|' + SSNotify.type,
|
||||
invitor_uin: await NTQQUserApi.getUinByUidV2(SSNotify.user1?.uid),
|
||||
request_id: `${SSNotify.group.groupCode}|${SSNotify.seq}|${SSNotify.type}`,
|
||||
invitor_uin: invitorUin,
|
||||
invitor_nick: SSNotify.user1?.nickName,
|
||||
group_id: SSNotify.group?.groupCode,
|
||||
group_id: +SSNotify.group?.groupCode,
|
||||
group_name: SSNotify.group?.groupName,
|
||||
checked: SSNotify.status === GroupNotifyMsgStatus.KUNHANDLE ? false : true,
|
||||
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
||||
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||
actor: actorUin,
|
||||
});
|
||||
} else if (SSNotify.type == 7) {
|
||||
} else if (SSNotify.type === 7) {
|
||||
retData.join_requests.push({
|
||||
request_id: SSNotify.group.groupCode + '|' + SSNotify.seq + '|' + SSNotify.type,
|
||||
requester_uin: await NTQQUserApi.getUinByUidV2(SSNotify.user1?.uid),
|
||||
request_id: `${SSNotify.group.groupCode}|${SSNotify.seq}|${SSNotify.type}`,
|
||||
invitor_uin: invitorUin,
|
||||
requester_nick: SSNotify.user1?.nickName,
|
||||
group_id: SSNotify.group?.groupCode,
|
||||
group_id: +SSNotify.group?.groupCode,
|
||||
group_name: SSNotify.group?.groupName,
|
||||
checked: SSNotify.status === GroupNotifyMsgStatus.KUNHANDLE ? false : true,
|
||||
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
|
||||
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
|
||||
actor: actorUin,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(notifyPromises);
|
||||
|
||||
return retData;
|
||||
}
|
||||
|
@@ -153,6 +153,17 @@ export class OneBotMsgApi {
|
||||
|
||||
faceElement: async element => {
|
||||
const faceIndex = element.faceIndex;
|
||||
if (element.faceType == FaceType.Poke) {
|
||||
return {
|
||||
type: OB11MessageDataType.poke,
|
||||
data: {
|
||||
type: element?.pokeType?.toString() ?? '0',
|
||||
id: faceIndex.toString(),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (faceIndex === FaceIndex.DICE) {
|
||||
return {
|
||||
type: OB11MessageDataType.dice,
|
||||
|
@@ -405,8 +405,8 @@ export class NapCatOneBot11Adapter {
|
||||
this.context.logger.logDebug(`收到邀请我加群通知:${notify}`);
|
||||
const groupInviteEvent = new OB11GroupRequestEvent(
|
||||
this.core,
|
||||
parseInt(notify.group.groupCode),
|
||||
parseInt(await this.core.apis.UserApi.getUinByUidV2(notify.user2.uid)),
|
||||
+notify.group.groupCode,
|
||||
+await this.core.apis.UserApi.getUinByUidV2(notify.user2.uid),
|
||||
'invite',
|
||||
notify.postscript,
|
||||
flag
|
||||
@@ -423,8 +423,8 @@ export class NapCatOneBot11Adapter {
|
||||
this.context.logger.logDebug(`收到群员邀请加群通知:${notify}`);
|
||||
const groupInviteEvent = new OB11GroupRequestEvent(
|
||||
this.core,
|
||||
parseInt(notify.group.groupCode),
|
||||
parseInt(await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid)),
|
||||
+notify.group.groupCode,
|
||||
+await this.core.apis.UserApi.getUinByUidV2(notify.user1.uid),
|
||||
'add',
|
||||
notify.postscript,
|
||||
flag
|
||||
@@ -571,6 +571,8 @@ export class NapCatOneBot11Adapter {
|
||||
}
|
||||
|
||||
private async emitFriendRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) {
|
||||
const operatorUid = element.grayTipElement?.revokeElement.operatorUid;
|
||||
if (!operatorUid) return undefined;
|
||||
return new OB11FriendRecallNoticeEvent(
|
||||
this.core,
|
||||
+message.senderUin,
|
||||
@@ -581,7 +583,7 @@ export class NapCatOneBot11Adapter {
|
||||
private async emitGroupRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) {
|
||||
const operatorUid = element.grayTipElement?.revokeElement.operatorUid;
|
||||
if (!operatorUid) return undefined;
|
||||
const operatorId = message.senderUin ?? await this.core.apis.UserApi.getUinByUidV2(operatorUid);
|
||||
const operatorId = await this.core.apis.UserApi.getUinByUidV2(operatorUid);
|
||||
return new OB11GroupRecallNoticeEvent(
|
||||
this.core,
|
||||
+message.peerUin,
|
||||
|
@@ -71,6 +71,14 @@ export enum OB11MessageDataType {
|
||||
location = 'location'
|
||||
}
|
||||
|
||||
export interface OB11MessagePoke {
|
||||
type: OB11MessageDataType.poke;
|
||||
data: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 商城表情消息接口定义
|
||||
export interface OB11MessageMFace {
|
||||
type: OB11MessageDataType.mface;
|
||||
@@ -247,7 +255,7 @@ export type OB11MessageData =
|
||||
OB11MessageAt | OB11MessageReply |
|
||||
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
||||
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
|
||||
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext;
|
||||
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext | OB11MessagePoke;
|
||||
|
||||
// 发送消息接口定义
|
||||
export interface OB11PostSendMsg {
|
||||
|
Reference in New Issue
Block a user