mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
03a298a70f | ||
![]() |
2722ca2b0e | ||
![]() |
179c4b800e | ||
![]() |
6bdf14223d | ||
![]() |
1b8252aa4f | ||
![]() |
8219889154 | ||
![]() |
df4ac5dcce | ||
![]() |
738eaf9de9 | ||
![]() |
c483ccbbbc | ||
![]() |
0d65f846ae | ||
![]() |
f47e75c423 | ||
![]() |
c008e58fb8 | ||
![]() |
26e0f17bc5 | ||
![]() |
6543f28bdb | ||
![]() |
a86851b338 | ||
![]() |
3a03e455c6 | ||
![]() |
3d39fd1580 | ||
![]() |
601b0add26 | ||
![]() |
4f974cc913 |
@@ -4,7 +4,7 @@ module.exports = {
|
||||
'es2021': true,
|
||||
'node': true
|
||||
},
|
||||
'ignorePatterns': ['src/proto/'],
|
||||
'ignorePatterns': ['src/core/proto/'],
|
||||
'extends': [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended'
|
||||
|
@@ -4,7 +4,7 @@
|
||||
"name": "NapCatQQ",
|
||||
"slug": "NapCat.Framework",
|
||||
"description": "高性能的 OneBot 11 协议实现",
|
||||
"version": "2.2.16",
|
||||
"version": "2.2.20",
|
||||
"icon": "./logo.png",
|
||||
"authors": [
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "2.2.16",
|
||||
"version": "2.2.20",
|
||||
"scripts": {
|
||||
"build:framework": "vite build --mode framework",
|
||||
"build:shell": "vite build --mode shell",
|
||||
@@ -27,8 +27,8 @@
|
||||
"@types/node": "^22.0.1",
|
||||
"@types/qrcode-terminal": "^0.12.2",
|
||||
"@types/ws": "^8.5.12",
|
||||
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
||||
"@typescript-eslint/parser": "^7.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.3.0",
|
||||
"@typescript-eslint/parser": "^8.3.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import type { NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core/wrapper/wrapper';
|
||||
import type { NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core/wrapper';
|
||||
import EventEmitter from 'node:events';
|
||||
|
||||
export type ListenerClassBase = Record<string, string>;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { NodeIQQNTWrapperSession } from '@/core/wrapper/wrapper';
|
||||
import { NodeIQQNTWrapperSession } from '@/core/wrapper';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { ListenerNamingMapping, ServiceNamingMapping } from '@/core';
|
||||
|
||||
|
@@ -1 +1 @@
|
||||
export const napCatVersion = '2.2.16';
|
||||
export const napCatVersion = '2.2.20';
|
||||
|
@@ -2,6 +2,7 @@ import {
|
||||
ChatType,
|
||||
GeneralCallResult,
|
||||
Group,
|
||||
GroupInfoSource,
|
||||
GroupMember,
|
||||
GroupMemberRole,
|
||||
GroupRequestOperateTypes,
|
||||
@@ -32,7 +33,6 @@ export class NTQQGroupApi {
|
||||
}
|
||||
this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`);
|
||||
}
|
||||
|
||||
async setGroupAvatar(gc: string, filePath: string) {
|
||||
return this.context.session.getGroupService().setHeader(gc, filePath);
|
||||
}
|
||||
@@ -340,7 +340,7 @@ export class NTQQGroupApi {
|
||||
]);
|
||||
if (membersFromFunc.status === 'fulfilled' && membersFromListener.status === 'fulfilled') {
|
||||
return new Map([
|
||||
...membersFromFunc.value.result.infos,
|
||||
...membersFromFunc.value.result.infos,
|
||||
...membersFromListener.value[0].infos
|
||||
]);
|
||||
}
|
||||
@@ -355,7 +355,7 @@ export class NTQQGroupApi {
|
||||
groupService.destroyMemberListScene(sceneId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async getGroupMembers(groupQQ: string, num = 3000): Promise<Map<string, GroupMember>> {
|
||||
const groupService = this.context.session.getGroupService();
|
||||
const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow');
|
||||
|
@@ -200,7 +200,7 @@ export class NTQQMsgApi {
|
||||
msgElements,
|
||||
new Map(),
|
||||
],
|
||||
() => true,
|
||||
(ret) => ret.result === 0,
|
||||
msgRecords => {
|
||||
for (const msgRecord of msgRecords) {
|
||||
if (msgRecord.guildId === msgId && msgRecord.sendStatus === SendStatusType.KSEND_STATUS_SUCCESS) {
|
||||
|
205
src/core/core.ts
205
src/core/core.ts
@@ -1,205 +0,0 @@
|
||||
import { NodeQQNTWrapperUtil, StableNTApiWrapper, WrapperNodeApi } from '@/core/wrapper';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { InstanceContext } from './wrapper';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
import { NodeIKernelGroupListener, NodeIKernelMsgListener, NodeIKernelProfileListener } from './listeners';
|
||||
import { DataSource, GroupMember, SelfInfo } from './entities';
|
||||
import { NTEventWrapper } from '@/common/event';
|
||||
import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from './apis';
|
||||
import os from 'node:os';
|
||||
import { NTQQCollectionApi } from './apis/collection';
|
||||
import { NapCatConfigLoader } from './helper/config';
|
||||
import { LogLevel } from '@/common/log';
|
||||
|
||||
export enum NapCatCoreWorkingEnv {
|
||||
Unknown = 0,
|
||||
Shell = 1,
|
||||
Framework = 2,
|
||||
}
|
||||
|
||||
export function loadQQWrapper(QQVersion: string): WrapperNodeApi {
|
||||
let wrapperNodePath = path.resolve(path.dirname(process.execPath), './resources/app/wrapper.node');
|
||||
if (!fs.existsSync(wrapperNodePath)) {
|
||||
wrapperNodePath = path.join(path.dirname(process.execPath), `resources/app/versions/${QQVersion}/wrapper.node`);
|
||||
}
|
||||
const nativemodule: any = { exports: {} };
|
||||
process.dlopen(nativemodule, wrapperNodePath);
|
||||
return nativemodule.exports;
|
||||
}
|
||||
|
||||
export class NapCatCore {
|
||||
readonly context: InstanceContext;
|
||||
readonly apis: StableNTApiWrapper;
|
||||
readonly eventWrapper: NTEventWrapper;
|
||||
// readonly eventChannel: NTEventChannel;
|
||||
NapCatDataPath: string;
|
||||
NapCatTempPath: string;
|
||||
// runtime info, not readonly
|
||||
selfInfo: SelfInfo;
|
||||
util: NodeQQNTWrapperUtil;
|
||||
configLoader: NapCatConfigLoader;
|
||||
|
||||
// 通过构造器递过去的 runtime info 应该尽量少
|
||||
constructor(context: InstanceContext, selfInfo: SelfInfo) {
|
||||
this.selfInfo = selfInfo;
|
||||
this.context = context;
|
||||
this.util = this.context.wrapper.NodeQQNTWrapperUtil;
|
||||
this.eventWrapper = new NTEventWrapper(context.session);
|
||||
this.apis = {
|
||||
FileApi: new NTQQFileApi(this.context, this),
|
||||
SystemApi: new NTQQSystemApi(this.context, this),
|
||||
CollectionApi: new NTQQCollectionApi(this.context, this),
|
||||
WebApi: new NTQQWebApi(this.context, this),
|
||||
FriendApi: new NTQQFriendApi(this.context, this),
|
||||
MsgApi: new NTQQMsgApi(this.context, this),
|
||||
UserApi: new NTQQUserApi(this.context, this),
|
||||
GroupApi: new NTQQGroupApi(this.context, this),
|
||||
};
|
||||
this.configLoader = new NapCatConfigLoader(this, this.context.pathWrapper.configPath);
|
||||
this.NapCatDataPath = path.join(this.dataPath, 'NapCat');
|
||||
fs.mkdirSync(this.NapCatDataPath, { recursive: true });
|
||||
this.NapCatTempPath = path.join(this.NapCatDataPath, 'temp');
|
||||
// 创建临时目录
|
||||
if (!fs.existsSync(this.NapCatTempPath)) {
|
||||
fs.mkdirSync(this.NapCatTempPath, { recursive: true });
|
||||
}
|
||||
this.initNapCatCoreListeners().then().catch(this.context.logger.logError);
|
||||
|
||||
this.context.logger.setFileLogEnabled(
|
||||
this.configLoader.configData.fileLog,
|
||||
);
|
||||
this.context.logger.setConsoleLogEnabled(
|
||||
this.configLoader.configData.consoleLog,
|
||||
);
|
||||
this.context.logger.setFileAndConsoleLogLevel(
|
||||
this.configLoader.configData.fileLogLevel as LogLevel,
|
||||
this.configLoader.configData.consoleLogLevel as LogLevel,
|
||||
);
|
||||
}
|
||||
|
||||
get dataPath(): string {
|
||||
let result = this.context.wrapper.NodeQQNTWrapperUtil.getNTUserDataInfoConfig();
|
||||
if (!result) {
|
||||
result = path.resolve(os.homedir(), './.config/QQ');
|
||||
fs.mkdirSync(result, { recursive: true });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Renamed from 'InitDataListener'
|
||||
async initNapCatCoreListeners() {
|
||||
const msgListener = new NodeIKernelMsgListener();
|
||||
msgListener.onRecvMsg = (msgs) => {
|
||||
msgs.forEach(msg => this.context.logger.logMessage(msg, this.selfInfo));
|
||||
};
|
||||
msgListener.onAddSendMsg = (msg) => {
|
||||
this.context.logger.logMessage(msg, this.selfInfo);
|
||||
};
|
||||
//await sleep(2500);
|
||||
this.context.session.getMsgService().addKernelMsgListener(
|
||||
proxiedListenerOf(msgListener, this.context.logger) as any,
|
||||
);
|
||||
|
||||
const profileListener = new NodeIKernelProfileListener();
|
||||
profileListener.onProfileDetailInfoChanged = (profile) => {
|
||||
if (profile.uid === this.selfInfo.uid) {
|
||||
Object.assign(this.selfInfo, profile);
|
||||
}
|
||||
};
|
||||
profileListener.onSelfStatusChanged = (/* Info: SelfStatusInfo */) => {
|
||||
// if (Info.status == 20) {
|
||||
// log("账号状态变更为离线")
|
||||
// }
|
||||
};
|
||||
this.context.session.getProfileService().addKernelProfileListener(
|
||||
proxiedListenerOf(profileListener, this.context.logger),
|
||||
);
|
||||
|
||||
// 群相关
|
||||
const groupListener = new NodeIKernelGroupListener();
|
||||
groupListener.onGroupListUpdate = (updateType, groupList) => {
|
||||
// console.log("onGroupListUpdate", updateType, groupList)
|
||||
groupList.map(g => {
|
||||
const existGroup = this.apis.GroupApi.groupCache.get(g.groupCode);
|
||||
//群成员数量变化 应该刷新缓存
|
||||
if (existGroup && g.memberCount === existGroup.memberCount) {
|
||||
Object.assign(existGroup, g);
|
||||
} else {
|
||||
this.apis.GroupApi.groupCache.set(g.groupCode, g);
|
||||
// 获取群成员
|
||||
}
|
||||
const sceneId = this.context.session.getGroupService().createMemberListScene(g.groupCode, 'groupMemberList_MainWindow');
|
||||
this.context.session.getGroupService().getNextMemberList(sceneId, undefined, 3000).then( /* r => {
|
||||
// console.log(`get group ${g.groupCode} members`, r);
|
||||
// r.result.infos.forEach(member => {
|
||||
// });
|
||||
// groupMembers.set(g.groupCode, r.result.infos);
|
||||
} */);
|
||||
this.context.session.getGroupService().destroyMemberListScene(sceneId);
|
||||
});
|
||||
};
|
||||
groupListener.onMemberListChange = (arg) => {
|
||||
// todo: 应该加一个内部自己维护的成员变动callback,用于判断成员变化通知
|
||||
const groupCode = arg.sceneId.split('_')[0];
|
||||
if (this.apis.GroupApi.groupMemberCache.has(groupCode)) {
|
||||
const existMembers = this.apis.GroupApi.groupMemberCache.get(groupCode)!;
|
||||
arg.infos.forEach((member, uid) => {
|
||||
//console.log('onMemberListChange', member);
|
||||
const existMember = existMembers.get(uid);
|
||||
if (existMember) {
|
||||
Object.assign(existMember, member);
|
||||
} else {
|
||||
existMembers!.set(uid, member);
|
||||
}
|
||||
//移除成员
|
||||
if (member.isDelete) {
|
||||
existMembers.delete(uid);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.apis.GroupApi.groupMemberCache.set(groupCode, arg.infos);
|
||||
}
|
||||
};
|
||||
groupListener.onMemberInfoChange = (groupCode, dataSource, members) => {
|
||||
if (dataSource === DataSource.LOCAL && members.get(this.selfInfo.uid)?.isDelete) {
|
||||
// 自身退群或者被踢退群 5s用于Api操作 之后不再出现
|
||||
setTimeout(() => {
|
||||
this.apis.GroupApi.groupCache.delete(groupCode);
|
||||
}, 5000);
|
||||
|
||||
}
|
||||
const existMembers = this.apis.GroupApi.groupMemberCache.get(groupCode);
|
||||
if (existMembers) {
|
||||
members.forEach((member, uid) => {
|
||||
const existMember = existMembers.get(uid);
|
||||
if (existMember) {
|
||||
// 检查管理变动
|
||||
member.isChangeRole = this.checkAdminEvent(groupCode, member, existMember);
|
||||
// 更新成员信息
|
||||
Object.assign(existMember, member);
|
||||
} else {
|
||||
existMembers.set(uid, member);
|
||||
}
|
||||
//移除成员
|
||||
if (member.isDelete) {
|
||||
existMembers.delete(uid);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.apis.GroupApi.groupMemberCache.set(groupCode, members);
|
||||
}
|
||||
};
|
||||
this.context.session.getGroupService().addKernelGroupListener(
|
||||
proxiedListenerOf(groupListener, this.context.logger) as any,
|
||||
);
|
||||
}
|
||||
|
||||
checkAdminEvent(groupCode: string, memberNew: GroupMember, memberOld: GroupMember | undefined): boolean {
|
||||
if (memberNew.role !== memberOld?.role) {
|
||||
this.context.logger.logDebug(`群 ${groupCode} ${memberNew.nick} 角色变更为 ${memberNew.role === 3 ? '管理员' : '群员'}`);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,5 +1,299 @@
|
||||
export * from './core';
|
||||
import {
|
||||
NTQQFileApi,
|
||||
NTQQFriendApi,
|
||||
NTQQGroupApi,
|
||||
NTQQMsgApi,
|
||||
NTQQSystemApi,
|
||||
NTQQUserApi,
|
||||
NTQQWebApi,
|
||||
} from '@/core/apis';
|
||||
import { NTQQCollectionApi } from '@/core/apis/collection';
|
||||
import {
|
||||
NodeIQQNTWrapperSession,
|
||||
NodeQQNTWrapperUtil,
|
||||
PlatformType,
|
||||
VendorType,
|
||||
WrapperNodeApi,
|
||||
WrapperSessionInitConfig,
|
||||
} from '@/core/wrapper';
|
||||
import { LogLevel, LogWrapper } from '@/common/log';
|
||||
import { NodeIKernelLoginService } from '@/core/services';
|
||||
import { QQBasicInfoWrapper } from '@/common/qq-basic-info';
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { getMachineId, hostname, systemName, systemVersion } from '@/common/system';
|
||||
import { NTEventWrapper } from '@/common/event';
|
||||
import { DataSource, GroupMember, SelfInfo } from '@/core/entities';
|
||||
import { NapCatConfigLoader } from '@/core/helper/config';
|
||||
import os from 'node:os';
|
||||
import { NodeIKernelGroupListener, NodeIKernelMsgListener, NodeIKernelProfileListener } from '@/core/listeners';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
|
||||
export * from './wrapper';
|
||||
export * from './entities';
|
||||
export * from './services';
|
||||
export * from './listeners';
|
||||
|
||||
export enum NapCatCoreWorkingEnv {
|
||||
Unknown = 0,
|
||||
Shell = 1,
|
||||
Framework = 2,
|
||||
}
|
||||
|
||||
export function loadQQWrapper(QQVersion: string): WrapperNodeApi {
|
||||
let wrapperNodePath = path.resolve(path.dirname(process.execPath), './resources/app/wrapper.node');
|
||||
if (!fs.existsSync(wrapperNodePath)) {
|
||||
wrapperNodePath = path.join(path.dirname(process.execPath), `resources/app/versions/${QQVersion}/wrapper.node`);
|
||||
}
|
||||
const nativemodule: any = { exports: {} };
|
||||
process.dlopen(nativemodule, wrapperNodePath);
|
||||
return nativemodule.exports;
|
||||
}
|
||||
|
||||
export class NapCatCore {
|
||||
readonly context: InstanceContext;
|
||||
readonly apis: StableNTApiWrapper;
|
||||
readonly eventWrapper: NTEventWrapper;
|
||||
// readonly eventChannel: NTEventChannel;
|
||||
NapCatDataPath: string;
|
||||
NapCatTempPath: string;
|
||||
// runtime info, not readonly
|
||||
selfInfo: SelfInfo;
|
||||
util: NodeQQNTWrapperUtil;
|
||||
configLoader: NapCatConfigLoader;
|
||||
|
||||
// 通过构造器递过去的 runtime info 应该尽量少
|
||||
constructor(context: InstanceContext, selfInfo: SelfInfo) {
|
||||
this.selfInfo = selfInfo;
|
||||
this.context = context;
|
||||
this.util = this.context.wrapper.NodeQQNTWrapperUtil;
|
||||
this.eventWrapper = new NTEventWrapper(context.session);
|
||||
this.apis = {
|
||||
FileApi: new NTQQFileApi(this.context, this),
|
||||
SystemApi: new NTQQSystemApi(this.context, this),
|
||||
CollectionApi: new NTQQCollectionApi(this.context, this),
|
||||
WebApi: new NTQQWebApi(this.context, this),
|
||||
FriendApi: new NTQQFriendApi(this.context, this),
|
||||
MsgApi: new NTQQMsgApi(this.context, this),
|
||||
UserApi: new NTQQUserApi(this.context, this),
|
||||
GroupApi: new NTQQGroupApi(this.context, this),
|
||||
};
|
||||
this.configLoader = new NapCatConfigLoader(this, this.context.pathWrapper.configPath);
|
||||
this.NapCatDataPath = path.join(this.dataPath, 'NapCat');
|
||||
fs.mkdirSync(this.NapCatDataPath, { recursive: true });
|
||||
this.NapCatTempPath = path.join(this.NapCatDataPath, 'temp');
|
||||
// 创建临时目录
|
||||
if (!fs.existsSync(this.NapCatTempPath)) {
|
||||
fs.mkdirSync(this.NapCatTempPath, { recursive: true });
|
||||
}
|
||||
this.initNapCatCoreListeners().then().catch(this.context.logger.logError);
|
||||
|
||||
this.context.logger.setFileLogEnabled(
|
||||
this.configLoader.configData.fileLog,
|
||||
);
|
||||
this.context.logger.setConsoleLogEnabled(
|
||||
this.configLoader.configData.consoleLog,
|
||||
);
|
||||
this.context.logger.setFileAndConsoleLogLevel(
|
||||
this.configLoader.configData.fileLogLevel as LogLevel,
|
||||
this.configLoader.configData.consoleLogLevel as LogLevel,
|
||||
);
|
||||
}
|
||||
|
||||
get dataPath(): string {
|
||||
let result = this.context.wrapper.NodeQQNTWrapperUtil.getNTUserDataInfoConfig();
|
||||
if (!result) {
|
||||
result = path.resolve(os.homedir(), './.config/QQ');
|
||||
fs.mkdirSync(result, { recursive: true });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Renamed from 'InitDataListener'
|
||||
async initNapCatCoreListeners() {
|
||||
const msgListener = new NodeIKernelMsgListener();
|
||||
msgListener.onRecvMsg = (msgs) => {
|
||||
msgs.forEach(msg => this.context.logger.logMessage(msg, this.selfInfo));
|
||||
};
|
||||
msgListener.onAddSendMsg = (msg) => {
|
||||
this.context.logger.logMessage(msg, this.selfInfo);
|
||||
};
|
||||
//await sleep(2500);
|
||||
this.context.session.getMsgService().addKernelMsgListener(
|
||||
proxiedListenerOf(msgListener, this.context.logger) as any,
|
||||
);
|
||||
|
||||
const profileListener = new NodeIKernelProfileListener();
|
||||
profileListener.onProfileDetailInfoChanged = (profile) => {
|
||||
if (profile.uid === this.selfInfo.uid) {
|
||||
Object.assign(this.selfInfo, profile);
|
||||
}
|
||||
};
|
||||
profileListener.onSelfStatusChanged = (/* Info: SelfStatusInfo */) => {
|
||||
// if (Info.status == 20) {
|
||||
// log("账号状态变更为离线")
|
||||
// }
|
||||
};
|
||||
this.context.session.getProfileService().addKernelProfileListener(
|
||||
proxiedListenerOf(profileListener, this.context.logger),
|
||||
);
|
||||
|
||||
// 群相关
|
||||
const groupListener = new NodeIKernelGroupListener();
|
||||
groupListener.onGroupListUpdate = (updateType, groupList) => {
|
||||
// console.log("onGroupListUpdate", updateType, groupList)
|
||||
groupList.map(g => {
|
||||
const existGroup = this.apis.GroupApi.groupCache.get(g.groupCode);
|
||||
//群成员数量变化 应该刷新缓存
|
||||
if (existGroup && g.memberCount === existGroup.memberCount) {
|
||||
Object.assign(existGroup, g);
|
||||
} else {
|
||||
this.apis.GroupApi.groupCache.set(g.groupCode, g);
|
||||
// 获取群成员
|
||||
}
|
||||
const sceneId = this.context.session.getGroupService().createMemberListScene(g.groupCode, 'groupMemberList_MainWindow');
|
||||
this.context.session.getGroupService().getNextMemberList(sceneId, undefined, 3000).then( /* r => {
|
||||
// console.log(`get group ${g.groupCode} members`, r);
|
||||
// r.result.infos.forEach(member => {
|
||||
// });
|
||||
// groupMembers.set(g.groupCode, r.result.infos);
|
||||
} */);
|
||||
this.context.session.getGroupService().destroyMemberListScene(sceneId);
|
||||
});
|
||||
};
|
||||
groupListener.onMemberListChange = (arg) => {
|
||||
// todo: 应该加一个内部自己维护的成员变动callback,用于判断成员变化通知
|
||||
const groupCode = arg.sceneId.split('_')[0];
|
||||
if (this.apis.GroupApi.groupMemberCache.has(groupCode)) {
|
||||
const existMembers = this.apis.GroupApi.groupMemberCache.get(groupCode)!;
|
||||
arg.infos.forEach((member, uid) => {
|
||||
//console.log('onMemberListChange', member);
|
||||
const existMember = existMembers.get(uid);
|
||||
if (existMember) {
|
||||
Object.assign(existMember, member);
|
||||
} else {
|
||||
existMembers!.set(uid, member);
|
||||
}
|
||||
//移除成员
|
||||
if (member.isDelete) {
|
||||
existMembers.delete(uid);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.apis.GroupApi.groupMemberCache.set(groupCode, arg.infos);
|
||||
}
|
||||
};
|
||||
groupListener.onMemberInfoChange = (groupCode, dataSource, members) => {
|
||||
if (dataSource === DataSource.LOCAL && members.get(this.selfInfo.uid)?.isDelete) {
|
||||
// 自身退群或者被踢退群 5s用于Api操作 之后不再出现
|
||||
setTimeout(() => {
|
||||
this.apis.GroupApi.groupCache.delete(groupCode);
|
||||
}, 5000);
|
||||
|
||||
}
|
||||
const existMembers = this.apis.GroupApi.groupMemberCache.get(groupCode);
|
||||
if (existMembers) {
|
||||
members.forEach((member, uid) => {
|
||||
const existMember = existMembers.get(uid);
|
||||
if (existMember) {
|
||||
// 检查管理变动
|
||||
member.isChangeRole = this.checkAdminEvent(groupCode, member, existMember);
|
||||
// 更新成员信息
|
||||
Object.assign(existMember, member);
|
||||
} else {
|
||||
existMembers.set(uid, member);
|
||||
}
|
||||
//移除成员
|
||||
if (member.isDelete) {
|
||||
existMembers.delete(uid);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.apis.GroupApi.groupMemberCache.set(groupCode, members);
|
||||
}
|
||||
};
|
||||
this.context.session.getGroupService().addKernelGroupListener(
|
||||
proxiedListenerOf(groupListener, this.context.logger) as any,
|
||||
);
|
||||
}
|
||||
|
||||
checkAdminEvent(groupCode: string, memberNew: GroupMember, memberOld: GroupMember | undefined): boolean {
|
||||
if (memberNew.role !== memberOld?.role) {
|
||||
this.context.logger.logDebug(`群 ${groupCode} ${memberNew.nick} 角色变更为 ${memberNew.role === 3 ? '管理员' : '群员'}`);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function genSessionConfig(QQVersionAppid: string, QQVersion: string, selfUin: string, selfUid: string, account_path: string): Promise<WrapperSessionInitConfig> {
|
||||
const downloadPath = path.join(account_path, 'NapCat', 'temp');
|
||||
fs.mkdirSync(downloadPath, { recursive: true });
|
||||
const guid: string = await getMachineId();//26702 支持JS获取guid值 在LoginService中获取 TODO mlikiow a
|
||||
return {
|
||||
selfUin,
|
||||
selfUid,
|
||||
desktopPathConfig: {
|
||||
account_path, // 可以通过NodeQQNTWrapperUtil().getNTUserDataInfoConfig()获取
|
||||
},
|
||||
clientVer: QQVersion, // 9.9.8-22355
|
||||
a2: '',
|
||||
d2: '',
|
||||
d2Key: '',
|
||||
machineId: '',
|
||||
platform: PlatformType.KWINDOWS, // 3是Windows?
|
||||
platVer: systemVersion, // 系统版本号, 应该可以固定
|
||||
appid: QQVersionAppid,
|
||||
rdeliveryConfig: {
|
||||
appKey: '',
|
||||
systemId: 0,
|
||||
appId: '',
|
||||
logicEnvironment: '',
|
||||
platform: PlatformType.KWINDOWS,
|
||||
language: '',
|
||||
sdkVersion: '',
|
||||
userId: '',
|
||||
appVersion: '',
|
||||
osVersion: '',
|
||||
bundleId: '',
|
||||
serverUrl: '',
|
||||
fixedAfterHitKeys: [''],
|
||||
},
|
||||
defaultFileDownloadPath: downloadPath,
|
||||
deviceInfo: {
|
||||
guid,
|
||||
buildVer: QQVersion,
|
||||
localId: 2052,
|
||||
devName: hostname,
|
||||
devType: systemName,
|
||||
vendorName: '',
|
||||
osVer: systemVersion,
|
||||
vendorOsName: systemName,
|
||||
setMute: false,
|
||||
vendorType: VendorType.KNOSETONIOS,
|
||||
},
|
||||
deviceConfig: '{"appearance":{"isSplitViewMode":true},"msg":{}}',
|
||||
};
|
||||
}
|
||||
|
||||
export interface InstanceContext {
|
||||
readonly workingEnv: NapCatCoreWorkingEnv;
|
||||
readonly wrapper: WrapperNodeApi;
|
||||
readonly session: NodeIQQNTWrapperSession;
|
||||
readonly logger: LogWrapper;
|
||||
readonly loginService: NodeIKernelLoginService;
|
||||
readonly basicInfoWrapper: QQBasicInfoWrapper;
|
||||
readonly pathWrapper: NapCatPathWrapper;
|
||||
}
|
||||
|
||||
export interface StableNTApiWrapper {
|
||||
FileApi: NTQQFileApi,
|
||||
SystemApi: NTQQSystemApi,
|
||||
CollectionApi: NTQQCollectionApi,
|
||||
WebApi: NTQQWebApi,
|
||||
FriendApi: NTQQFriendApi,
|
||||
MsgApi: NTQQMsgApi,
|
||||
UserApi: NTQQUserApi,
|
||||
GroupApi: NTQQGroupApi
|
||||
}
|
||||
|
24
src/core/proto/EmojiLikeToOthers.proto
Normal file
24
src/core/proto/EmojiLikeToOthers.proto
Normal file
@@ -0,0 +1,24 @@
|
||||
syntax = 'proto3';
|
||||
package SysMessage;
|
||||
|
||||
message EmojiLikeToOthersWrapper1 {
|
||||
EmojiLikeToOthersWrapper2 wrapper = 1;
|
||||
}
|
||||
|
||||
message EmojiLikeToOthersWrapper2 {
|
||||
EmojiLikeToOthersWrapper3 body = 1;
|
||||
}
|
||||
|
||||
message EmojiLikeToOthersWrapper3 {
|
||||
EmojiLikeToOthersMsgSpec msgSpec = 2;
|
||||
EmojiLikeToOthersAttributes attributes = 3;
|
||||
}
|
||||
|
||||
message EmojiLikeToOthersMsgSpec {
|
||||
uint32 msgSeq = 1;
|
||||
}
|
||||
|
||||
message EmojiLikeToOthersAttributes {
|
||||
string emojiId = 1;
|
||||
string senderUid = 4;
|
||||
}
|
312
src/core/proto/EmojiLikeToOthers.ts
Normal file
312
src/core/proto/EmojiLikeToOthers.ts
Normal file
@@ -0,0 +1,312 @@
|
||||
// @generated by protobuf-ts 2.9.4
|
||||
// @generated from protobuf file "EmojiLikeToOthers.proto" (package "SysMessage", syntax proto3)
|
||||
// tslint:disable
|
||||
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
||||
import { WireType } from "@protobuf-ts/runtime";
|
||||
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
||||
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
||||
import type { PartialMessage } from "@protobuf-ts/runtime";
|
||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||
import { MessageType } from "@protobuf-ts/runtime";
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.EmojiLikeToOthersWrapper1
|
||||
*/
|
||||
export interface EmojiLikeToOthersWrapper1 {
|
||||
/**
|
||||
* @generated from protobuf field: SysMessage.EmojiLikeToOthersWrapper2 wrapper = 1;
|
||||
*/
|
||||
wrapper?: EmojiLikeToOthersWrapper2;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.EmojiLikeToOthersWrapper2
|
||||
*/
|
||||
export interface EmojiLikeToOthersWrapper2 {
|
||||
/**
|
||||
* @generated from protobuf field: SysMessage.EmojiLikeToOthersWrapper3 body = 1;
|
||||
*/
|
||||
body?: EmojiLikeToOthersWrapper3;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.EmojiLikeToOthersWrapper3
|
||||
*/
|
||||
export interface EmojiLikeToOthersWrapper3 {
|
||||
/**
|
||||
* @generated from protobuf field: SysMessage.EmojiLikeToOthersMsgSpec msgSpec = 2;
|
||||
*/
|
||||
msgSpec?: EmojiLikeToOthersMsgSpec;
|
||||
/**
|
||||
* @generated from protobuf field: SysMessage.EmojiLikeToOthersAttributes attributes = 3;
|
||||
*/
|
||||
attributes?: EmojiLikeToOthersAttributes;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.EmojiLikeToOthersMsgSpec
|
||||
*/
|
||||
export interface EmojiLikeToOthersMsgSpec {
|
||||
/**
|
||||
* @generated from protobuf field: uint32 msgSeq = 1;
|
||||
*/
|
||||
msgSeq: number;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.EmojiLikeToOthersAttributes
|
||||
*/
|
||||
export interface EmojiLikeToOthersAttributes {
|
||||
/**
|
||||
* @generated from protobuf field: string emojiId = 1;
|
||||
*/
|
||||
emojiId: string;
|
||||
/**
|
||||
* @generated from protobuf field: string senderUid = 4;
|
||||
*/
|
||||
senderUid: string;
|
||||
}
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class EmojiLikeToOthersWrapper1$Type extends MessageType<EmojiLikeToOthersWrapper1> {
|
||||
constructor() {
|
||||
super("SysMessage.EmojiLikeToOthersWrapper1", [
|
||||
{ no: 1, name: "wrapper", kind: "message", T: () => EmojiLikeToOthersWrapper2 }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<EmojiLikeToOthersWrapper1>): EmojiLikeToOthersWrapper1 {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<EmojiLikeToOthersWrapper1>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: EmojiLikeToOthersWrapper1): EmojiLikeToOthersWrapper1 {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* SysMessage.EmojiLikeToOthersWrapper2 wrapper */ 1:
|
||||
message.wrapper = EmojiLikeToOthersWrapper2.internalBinaryRead(reader, reader.uint32(), options, message.wrapper);
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: EmojiLikeToOthersWrapper1, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* SysMessage.EmojiLikeToOthersWrapper2 wrapper = 1; */
|
||||
if (message.wrapper)
|
||||
EmojiLikeToOthersWrapper2.internalBinaryWrite(message.wrapper, writer.tag(1, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.EmojiLikeToOthersWrapper1
|
||||
*/
|
||||
export const EmojiLikeToOthersWrapper1 = new EmojiLikeToOthersWrapper1$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class EmojiLikeToOthersWrapper2$Type extends MessageType<EmojiLikeToOthersWrapper2> {
|
||||
constructor() {
|
||||
super("SysMessage.EmojiLikeToOthersWrapper2", [
|
||||
{ no: 1, name: "body", kind: "message", T: () => EmojiLikeToOthersWrapper3 }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<EmojiLikeToOthersWrapper2>): EmojiLikeToOthersWrapper2 {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<EmojiLikeToOthersWrapper2>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: EmojiLikeToOthersWrapper2): EmojiLikeToOthersWrapper2 {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* SysMessage.EmojiLikeToOthersWrapper3 body */ 1:
|
||||
message.body = EmojiLikeToOthersWrapper3.internalBinaryRead(reader, reader.uint32(), options, message.body);
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: EmojiLikeToOthersWrapper2, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* SysMessage.EmojiLikeToOthersWrapper3 body = 1; */
|
||||
if (message.body)
|
||||
EmojiLikeToOthersWrapper3.internalBinaryWrite(message.body, writer.tag(1, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.EmojiLikeToOthersWrapper2
|
||||
*/
|
||||
export const EmojiLikeToOthersWrapper2 = new EmojiLikeToOthersWrapper2$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class EmojiLikeToOthersWrapper3$Type extends MessageType<EmojiLikeToOthersWrapper3> {
|
||||
constructor() {
|
||||
super("SysMessage.EmojiLikeToOthersWrapper3", [
|
||||
{ no: 2, name: "msgSpec", kind: "message", T: () => EmojiLikeToOthersMsgSpec },
|
||||
{ no: 3, name: "attributes", kind: "message", T: () => EmojiLikeToOthersAttributes }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<EmojiLikeToOthersWrapper3>): EmojiLikeToOthersWrapper3 {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<EmojiLikeToOthersWrapper3>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: EmojiLikeToOthersWrapper3): EmojiLikeToOthersWrapper3 {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* SysMessage.EmojiLikeToOthersMsgSpec msgSpec */ 2:
|
||||
message.msgSpec = EmojiLikeToOthersMsgSpec.internalBinaryRead(reader, reader.uint32(), options, message.msgSpec);
|
||||
break;
|
||||
case /* SysMessage.EmojiLikeToOthersAttributes attributes */ 3:
|
||||
message.attributes = EmojiLikeToOthersAttributes.internalBinaryRead(reader, reader.uint32(), options, message.attributes);
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: EmojiLikeToOthersWrapper3, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* SysMessage.EmojiLikeToOthersMsgSpec msgSpec = 2; */
|
||||
if (message.msgSpec)
|
||||
EmojiLikeToOthersMsgSpec.internalBinaryWrite(message.msgSpec, writer.tag(2, WireType.LengthDelimited).fork(), options).join();
|
||||
/* SysMessage.EmojiLikeToOthersAttributes attributes = 3; */
|
||||
if (message.attributes)
|
||||
EmojiLikeToOthersAttributes.internalBinaryWrite(message.attributes, writer.tag(3, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.EmojiLikeToOthersWrapper3
|
||||
*/
|
||||
export const EmojiLikeToOthersWrapper3 = new EmojiLikeToOthersWrapper3$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class EmojiLikeToOthersMsgSpec$Type extends MessageType<EmojiLikeToOthersMsgSpec> {
|
||||
constructor() {
|
||||
super("SysMessage.EmojiLikeToOthersMsgSpec", [
|
||||
{ no: 1, name: "msgSeq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<EmojiLikeToOthersMsgSpec>): EmojiLikeToOthersMsgSpec {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
message.msgSeq = 0;
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<EmojiLikeToOthersMsgSpec>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: EmojiLikeToOthersMsgSpec): EmojiLikeToOthersMsgSpec {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* uint32 msgSeq */ 1:
|
||||
message.msgSeq = reader.uint32();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: EmojiLikeToOthersMsgSpec, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* uint32 msgSeq = 1; */
|
||||
if (message.msgSeq !== 0)
|
||||
writer.tag(1, WireType.Varint).uint32(message.msgSeq);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.EmojiLikeToOthersMsgSpec
|
||||
*/
|
||||
export const EmojiLikeToOthersMsgSpec = new EmojiLikeToOthersMsgSpec$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class EmojiLikeToOthersAttributes$Type extends MessageType<EmojiLikeToOthersAttributes> {
|
||||
constructor() {
|
||||
super("SysMessage.EmojiLikeToOthersAttributes", [
|
||||
{ no: 1, name: "emojiId", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 4, name: "senderUid", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<EmojiLikeToOthersAttributes>): EmojiLikeToOthersAttributes {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
message.emojiId = "";
|
||||
message.senderUid = "";
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<EmojiLikeToOthersAttributes>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: EmojiLikeToOthersAttributes): EmojiLikeToOthersAttributes {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* string emojiId */ 1:
|
||||
message.emojiId = reader.string();
|
||||
break;
|
||||
case /* string senderUid */ 4:
|
||||
message.senderUid = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: EmojiLikeToOthersAttributes, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* string emojiId = 1; */
|
||||
if (message.emojiId !== "")
|
||||
writer.tag(1, WireType.LengthDelimited).string(message.emojiId);
|
||||
/* string senderUid = 4; */
|
||||
if (message.senderUid !== "")
|
||||
writer.tag(4, WireType.LengthDelimited).string(message.senderUid);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.EmojiLikeToOthersAttributes
|
||||
*/
|
||||
export const EmojiLikeToOthersAttributes = new EmojiLikeToOthersAttributes$Type();
|
9
src/core/proto/GreyTipWrapper.proto
Normal file
9
src/core/proto/GreyTipWrapper.proto
Normal file
@@ -0,0 +1,9 @@
|
||||
syntax = 'proto3';
|
||||
package SysMessage;
|
||||
|
||||
message GreyTipWrapper {
|
||||
uint32 subTypeId = 1;
|
||||
uint32 groupCode = 4;
|
||||
uint32 subTypeIdMinusOne = 13;
|
||||
bytes rest = 44;
|
||||
}
|
104
src/core/proto/GreyTipWrapper.ts
Normal file
104
src/core/proto/GreyTipWrapper.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
// @generated by protobuf-ts 2.9.4
|
||||
// @generated from protobuf file "GreyTipWrapper.proto" (package "SysMessage", syntax proto3)
|
||||
// tslint:disable
|
||||
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
||||
import { WireType } from "@protobuf-ts/runtime";
|
||||
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
||||
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
||||
import type { PartialMessage } from "@protobuf-ts/runtime";
|
||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||
import { MessageType } from "@protobuf-ts/runtime";
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.GreyTipWrapper
|
||||
*/
|
||||
export interface GreyTipWrapper {
|
||||
/**
|
||||
* @generated from protobuf field: uint32 subTypeId = 1;
|
||||
*/
|
||||
subTypeId: number;
|
||||
/**
|
||||
* @generated from protobuf field: uint32 groupCode = 4;
|
||||
*/
|
||||
groupCode: number;
|
||||
/**
|
||||
* @generated from protobuf field: uint32 subTypeIdMinusOne = 13;
|
||||
*/
|
||||
subTypeIdMinusOne: number;
|
||||
/**
|
||||
* @generated from protobuf field: bytes rest = 44;
|
||||
*/
|
||||
rest: Uint8Array;
|
||||
}
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class GreyTipWrapper$Type extends MessageType<GreyTipWrapper> {
|
||||
constructor() {
|
||||
super("SysMessage.GreyTipWrapper", [
|
||||
{ no: 1, name: "subTypeId", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 4, name: "groupCode", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 13, name: "subTypeIdMinusOne", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 44, name: "rest", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<GreyTipWrapper>): GreyTipWrapper {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
message.subTypeId = 0;
|
||||
message.groupCode = 0;
|
||||
message.subTypeIdMinusOne = 0;
|
||||
message.rest = new Uint8Array(0);
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<GreyTipWrapper>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: GreyTipWrapper): GreyTipWrapper {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* uint32 subTypeId */ 1:
|
||||
message.subTypeId = reader.uint32();
|
||||
break;
|
||||
case /* uint32 groupCode */ 4:
|
||||
message.groupCode = reader.uint32();
|
||||
break;
|
||||
case /* uint32 subTypeIdMinusOne */ 13:
|
||||
message.subTypeIdMinusOne = reader.uint32();
|
||||
break;
|
||||
case /* bytes rest */ 44:
|
||||
message.rest = reader.bytes();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: GreyTipWrapper, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* uint32 subTypeId = 1; */
|
||||
if (message.subTypeId !== 0)
|
||||
writer.tag(1, WireType.Varint).uint32(message.subTypeId);
|
||||
/* uint32 groupCode = 4; */
|
||||
if (message.groupCode !== 0)
|
||||
writer.tag(4, WireType.Varint).uint32(message.groupCode);
|
||||
/* uint32 subTypeIdMinusOne = 13; */
|
||||
if (message.subTypeIdMinusOne !== 0)
|
||||
writer.tag(13, WireType.Varint).uint32(message.subTypeIdMinusOne);
|
||||
/* bytes rest = 44; */
|
||||
if (message.rest.length)
|
||||
writer.tag(44, WireType.LengthDelimited).bytes(message.rest);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.GreyTipWrapper
|
||||
*/
|
||||
export const GreyTipWrapper = new GreyTipWrapper$Type();
|
36
src/core/proto/SysMessage.proto
Normal file
36
src/core/proto/SysMessage.proto
Normal file
@@ -0,0 +1,36 @@
|
||||
syntax = 'proto3';
|
||||
package SysMessage;
|
||||
|
||||
message SysMessage {
|
||||
repeated SysMessageHeader header = 1;
|
||||
repeated SysMessageMsgSpec msgSpec = 2;
|
||||
SysMessageBodyWrapper bodyWrapper = 3;
|
||||
}
|
||||
|
||||
message SysMessageHeader {
|
||||
uint32 PeerNumber = 1;
|
||||
string PeerString = 2;
|
||||
uint32 Uin = 5;
|
||||
optional string Uid = 6;
|
||||
}
|
||||
|
||||
message SysMessageMsgSpec {
|
||||
uint32 msgType = 1;
|
||||
uint32 subType = 2;
|
||||
uint32 subSubType = 3;
|
||||
uint32 msgSeq = 5;
|
||||
uint32 time = 6;
|
||||
uint64 msgId = 12;
|
||||
uint32 other = 13;
|
||||
}
|
||||
|
||||
message SysMessageBodyWrapper {
|
||||
bytes wrappedBody = 2;
|
||||
// Find the first [08], or ignore the first 7 bytes?
|
||||
// And it becomes another ProtoBuf message.
|
||||
}
|
||||
|
||||
message KeyValuePair {
|
||||
string key = 1;
|
||||
string value = 2;
|
||||
}
|
435
src/core/proto/SysMessage.ts
Normal file
435
src/core/proto/SysMessage.ts
Normal file
@@ -0,0 +1,435 @@
|
||||
// @generated by protobuf-ts 2.9.4
|
||||
// @generated from protobuf file "SysMessage.proto" (package "SysMessage", syntax proto3)
|
||||
// tslint:disable
|
||||
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
||||
import { WireType } from "@protobuf-ts/runtime";
|
||||
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
||||
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
||||
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
||||
import type { PartialMessage } from "@protobuf-ts/runtime";
|
||||
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
||||
import { MessageType } from "@protobuf-ts/runtime";
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.SysMessage
|
||||
*/
|
||||
export interface SysMessage {
|
||||
/**
|
||||
* @generated from protobuf field: repeated SysMessage.SysMessageHeader header = 1;
|
||||
*/
|
||||
header: SysMessageHeader[];
|
||||
/**
|
||||
* @generated from protobuf field: repeated SysMessage.SysMessageMsgSpec msgSpec = 2;
|
||||
*/
|
||||
msgSpec: SysMessageMsgSpec[];
|
||||
/**
|
||||
* @generated from protobuf field: SysMessage.SysMessageBodyWrapper bodyWrapper = 3;
|
||||
*/
|
||||
bodyWrapper?: SysMessageBodyWrapper;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.SysMessageHeader
|
||||
*/
|
||||
export interface SysMessageHeader {
|
||||
/**
|
||||
* @generated from protobuf field: uint32 PeerNumber = 1 [json_name = "PeerNumber"];
|
||||
*/
|
||||
peerNumber: number;
|
||||
/**
|
||||
* @generated from protobuf field: string PeerString = 2 [json_name = "PeerString"];
|
||||
*/
|
||||
peerString: string;
|
||||
/**
|
||||
* @generated from protobuf field: uint32 Uin = 5 [json_name = "Uin"];
|
||||
*/
|
||||
uin: number;
|
||||
/**
|
||||
* @generated from protobuf field: optional string Uid = 6 [json_name = "Uid"];
|
||||
*/
|
||||
uid?: string;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.SysMessageMsgSpec
|
||||
*/
|
||||
export interface SysMessageMsgSpec {
|
||||
/**
|
||||
* @generated from protobuf field: uint32 msgType = 1;
|
||||
*/
|
||||
msgType: number;
|
||||
/**
|
||||
* @generated from protobuf field: uint32 subType = 2;
|
||||
*/
|
||||
subType: number;
|
||||
/**
|
||||
* @generated from protobuf field: uint32 subSubType = 3;
|
||||
*/
|
||||
subSubType: number;
|
||||
/**
|
||||
* @generated from protobuf field: uint32 msgSeq = 5;
|
||||
*/
|
||||
msgSeq: number;
|
||||
/**
|
||||
* @generated from protobuf field: uint32 time = 6;
|
||||
*/
|
||||
time: number;
|
||||
/**
|
||||
* @generated from protobuf field: uint64 msgId = 12;
|
||||
*/
|
||||
msgId: bigint;
|
||||
/**
|
||||
* @generated from protobuf field: uint32 other = 13;
|
||||
*/
|
||||
other: number;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.SysMessageBodyWrapper
|
||||
*/
|
||||
export interface SysMessageBodyWrapper {
|
||||
/**
|
||||
* @generated from protobuf field: bytes wrappedBody = 2;
|
||||
*/
|
||||
wrappedBody: Uint8Array; // Find the first [08], or ignore the first 7 bytes?
|
||||
// And it becomes another ProtoBuf message.
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf message SysMessage.KeyValuePair
|
||||
*/
|
||||
export interface KeyValuePair {
|
||||
/**
|
||||
* @generated from protobuf field: string key = 1;
|
||||
*/
|
||||
key: string;
|
||||
/**
|
||||
* @generated from protobuf field: string value = 2;
|
||||
*/
|
||||
value: string;
|
||||
}
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class SysMessage$Type extends MessageType<SysMessage> {
|
||||
constructor() {
|
||||
super("SysMessage.SysMessage", [
|
||||
{ no: 1, name: "header", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => SysMessageHeader },
|
||||
{ no: 2, name: "msgSpec", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => SysMessageMsgSpec },
|
||||
{ no: 3, name: "bodyWrapper", kind: "message", T: () => SysMessageBodyWrapper }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<SysMessage>): SysMessage {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
message.header = [];
|
||||
message.msgSpec = [];
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<SysMessage>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SysMessage): SysMessage {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* repeated SysMessage.SysMessageHeader header */ 1:
|
||||
message.header.push(SysMessageHeader.internalBinaryRead(reader, reader.uint32(), options));
|
||||
break;
|
||||
case /* repeated SysMessage.SysMessageMsgSpec msgSpec */ 2:
|
||||
message.msgSpec.push(SysMessageMsgSpec.internalBinaryRead(reader, reader.uint32(), options));
|
||||
break;
|
||||
case /* SysMessage.SysMessageBodyWrapper bodyWrapper */ 3:
|
||||
message.bodyWrapper = SysMessageBodyWrapper.internalBinaryRead(reader, reader.uint32(), options, message.bodyWrapper);
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: SysMessage, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* repeated SysMessage.SysMessageHeader header = 1; */
|
||||
for (let i = 0; i < message.header.length; i++)
|
||||
SysMessageHeader.internalBinaryWrite(message.header[i], writer.tag(1, WireType.LengthDelimited).fork(), options).join();
|
||||
/* repeated SysMessage.SysMessageMsgSpec msgSpec = 2; */
|
||||
for (let i = 0; i < message.msgSpec.length; i++)
|
||||
SysMessageMsgSpec.internalBinaryWrite(message.msgSpec[i], writer.tag(2, WireType.LengthDelimited).fork(), options).join();
|
||||
/* SysMessage.SysMessageBodyWrapper bodyWrapper = 3; */
|
||||
if (message.bodyWrapper)
|
||||
SysMessageBodyWrapper.internalBinaryWrite(message.bodyWrapper, writer.tag(3, WireType.LengthDelimited).fork(), options).join();
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.SysMessage
|
||||
*/
|
||||
export const SysMessage = new SysMessage$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class SysMessageHeader$Type extends MessageType<SysMessageHeader> {
|
||||
constructor() {
|
||||
super("SysMessage.SysMessageHeader", [
|
||||
{ no: 1, name: "PeerNumber", kind: "scalar", jsonName: "PeerNumber", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 2, name: "PeerString", kind: "scalar", jsonName: "PeerString", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 5, name: "Uin", kind: "scalar", jsonName: "Uin", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 6, name: "Uid", kind: "scalar", jsonName: "Uid", opt: true, T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<SysMessageHeader>): SysMessageHeader {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
message.peerNumber = 0;
|
||||
message.peerString = "";
|
||||
message.uin = 0;
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<SysMessageHeader>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SysMessageHeader): SysMessageHeader {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* uint32 PeerNumber = 1 [json_name = "PeerNumber"];*/ 1:
|
||||
message.peerNumber = reader.uint32();
|
||||
break;
|
||||
case /* string PeerString = 2 [json_name = "PeerString"];*/ 2:
|
||||
message.peerString = reader.string();
|
||||
break;
|
||||
case /* uint32 Uin = 5 [json_name = "Uin"];*/ 5:
|
||||
message.uin = reader.uint32();
|
||||
break;
|
||||
case /* optional string Uid = 6 [json_name = "Uid"];*/ 6:
|
||||
message.uid = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: SysMessageHeader, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* uint32 PeerNumber = 1 [json_name = "PeerNumber"]; */
|
||||
if (message.peerNumber !== 0)
|
||||
writer.tag(1, WireType.Varint).uint32(message.peerNumber);
|
||||
/* string PeerString = 2 [json_name = "PeerString"]; */
|
||||
if (message.peerString !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.peerString);
|
||||
/* uint32 Uin = 5 [json_name = "Uin"]; */
|
||||
if (message.uin !== 0)
|
||||
writer.tag(5, WireType.Varint).uint32(message.uin);
|
||||
/* optional string Uid = 6 [json_name = "Uid"]; */
|
||||
if (message.uid !== undefined)
|
||||
writer.tag(6, WireType.LengthDelimited).string(message.uid);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.SysMessageHeader
|
||||
*/
|
||||
export const SysMessageHeader = new SysMessageHeader$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class SysMessageMsgSpec$Type extends MessageType<SysMessageMsgSpec> {
|
||||
constructor() {
|
||||
super("SysMessage.SysMessageMsgSpec", [
|
||||
{ no: 1, name: "msgType", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 2, name: "subType", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 3, name: "subSubType", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 5, name: "msgSeq", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 6, name: "time", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
|
||||
{ no: 12, name: "msgId", kind: "scalar", T: 4 /*ScalarType.UINT64*/, L: 0 /*LongType.BIGINT*/ },
|
||||
{ no: 13, name: "other", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<SysMessageMsgSpec>): SysMessageMsgSpec {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
message.msgType = 0;
|
||||
message.subType = 0;
|
||||
message.subSubType = 0;
|
||||
message.msgSeq = 0;
|
||||
message.time = 0;
|
||||
message.msgId = 0n;
|
||||
message.other = 0;
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<SysMessageMsgSpec>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SysMessageMsgSpec): SysMessageMsgSpec {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* uint32 msgType */ 1:
|
||||
message.msgType = reader.uint32();
|
||||
break;
|
||||
case /* uint32 subType */ 2:
|
||||
message.subType = reader.uint32();
|
||||
break;
|
||||
case /* uint32 subSubType */ 3:
|
||||
message.subSubType = reader.uint32();
|
||||
break;
|
||||
case /* uint32 msgSeq */ 5:
|
||||
message.msgSeq = reader.uint32();
|
||||
break;
|
||||
case /* uint32 time */ 6:
|
||||
message.time = reader.uint32();
|
||||
break;
|
||||
case /* uint64 msgId */ 12:
|
||||
message.msgId = reader.uint64().toBigInt();
|
||||
break;
|
||||
case /* uint32 other */ 13:
|
||||
message.other = reader.uint32();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: SysMessageMsgSpec, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* uint32 msgType = 1; */
|
||||
if (message.msgType !== 0)
|
||||
writer.tag(1, WireType.Varint).uint32(message.msgType);
|
||||
/* uint32 subType = 2; */
|
||||
if (message.subType !== 0)
|
||||
writer.tag(2, WireType.Varint).uint32(message.subType);
|
||||
/* uint32 subSubType = 3; */
|
||||
if (message.subSubType !== 0)
|
||||
writer.tag(3, WireType.Varint).uint32(message.subSubType);
|
||||
/* uint32 msgSeq = 5; */
|
||||
if (message.msgSeq !== 0)
|
||||
writer.tag(5, WireType.Varint).uint32(message.msgSeq);
|
||||
/* uint32 time = 6; */
|
||||
if (message.time !== 0)
|
||||
writer.tag(6, WireType.Varint).uint32(message.time);
|
||||
/* uint64 msgId = 12; */
|
||||
if (message.msgId !== 0n)
|
||||
writer.tag(12, WireType.Varint).uint64(message.msgId);
|
||||
/* uint32 other = 13; */
|
||||
if (message.other !== 0)
|
||||
writer.tag(13, WireType.Varint).uint32(message.other);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.SysMessageMsgSpec
|
||||
*/
|
||||
export const SysMessageMsgSpec = new SysMessageMsgSpec$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class SysMessageBodyWrapper$Type extends MessageType<SysMessageBodyWrapper> {
|
||||
constructor() {
|
||||
super("SysMessage.SysMessageBodyWrapper", [
|
||||
{ no: 2, name: "wrappedBody", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<SysMessageBodyWrapper>): SysMessageBodyWrapper {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
message.wrappedBody = new Uint8Array(0);
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<SysMessageBodyWrapper>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SysMessageBodyWrapper): SysMessageBodyWrapper {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* bytes wrappedBody */ 2:
|
||||
message.wrappedBody = reader.bytes();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: SysMessageBodyWrapper, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* bytes wrappedBody = 2; */
|
||||
if (message.wrappedBody.length)
|
||||
writer.tag(2, WireType.LengthDelimited).bytes(message.wrappedBody);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.SysMessageBodyWrapper
|
||||
*/
|
||||
export const SysMessageBodyWrapper = new SysMessageBodyWrapper$Type();
|
||||
// @generated message type with reflection information, may provide speed optimized methods
|
||||
class KeyValuePair$Type extends MessageType<KeyValuePair> {
|
||||
constructor() {
|
||||
super("SysMessage.KeyValuePair", [
|
||||
{ no: 1, name: "key", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
|
||||
{ no: 2, name: "value", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<KeyValuePair>): KeyValuePair {
|
||||
const message = globalThis.Object.create((this.messagePrototype!));
|
||||
message.key = "";
|
||||
message.value = "";
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<KeyValuePair>(this, message, value);
|
||||
return message;
|
||||
}
|
||||
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: KeyValuePair): KeyValuePair {
|
||||
let message = target ?? this.create(), end = reader.pos + length;
|
||||
while (reader.pos < end) {
|
||||
let [fieldNo, wireType] = reader.tag();
|
||||
switch (fieldNo) {
|
||||
case /* string key */ 1:
|
||||
message.key = reader.string();
|
||||
break;
|
||||
case /* string value */ 2:
|
||||
message.value = reader.string();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
||||
let d = reader.skip(wireType);
|
||||
if (u !== false)
|
||||
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
internalBinaryWrite(message: KeyValuePair, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
||||
/* string key = 1; */
|
||||
if (message.key !== "")
|
||||
writer.tag(1, WireType.LengthDelimited).string(message.key);
|
||||
/* string value = 2; */
|
||||
if (message.value !== "")
|
||||
writer.tag(2, WireType.LengthDelimited).string(message.value);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @generated MessageType for protobuf message SysMessage.KeyValuePair
|
||||
*/
|
||||
export const KeyValuePair = new KeyValuePair$Type();
|
@@ -2,6 +2,7 @@ import { NodeIKernelGroupListener } from '@/core/listeners/NodeIKernelGroupListe
|
||||
import {
|
||||
GroupExt0xEF0InfoFilter,
|
||||
GroupExtParam,
|
||||
GroupInfoSource,
|
||||
GroupMember,
|
||||
GroupMemberRole,
|
||||
GroupNotifyMsgType,
|
||||
@@ -13,9 +14,9 @@ import { GeneralCallResult } from '@/core/services/common';
|
||||
//高版本的接口不应该随意使用 使用应该严格进行pr审核 同时部分ipc中未出现的接口不要过于依赖 应该做好数据兜底
|
||||
|
||||
export interface NodeIKernelGroupService {
|
||||
//getGroupExt0xEF0Info(this.$enableGroupCodes, this.$bannedGroupCodes, this.$filter, this.$forceFetch
|
||||
getGroupExt0xEF0Info(enableGroupCodes: string[], bannedGroupCodes: string[], filter: GroupExt0xEF0InfoFilter, forceFetch: boolean):
|
||||
Promise<GeneralCallResult & { result: { groupExtInfos: Map<string, any> }}>;
|
||||
Promise<GeneralCallResult & { result: { groupExtInfos: Map<string, any> } }>;
|
||||
|
||||
kickMemberV2(param: KickMemberV2Req): Promise<GeneralCallResult>;
|
||||
|
||||
quitGroupV2(param: { groupCode: string; needDeleteLocalMsg: boolean; }): Promise<GeneralCallResult>;
|
||||
@@ -39,11 +40,11 @@ export interface NodeIKernelGroupService {
|
||||
realSpecialTitleFlag: number
|
||||
}): Promise<unknown>;
|
||||
|
||||
//26702
|
||||
getGroupMemberLevelInfo(groupCode: string): Promise<unknown>;
|
||||
|
||||
//26702
|
||||
getGroupHonorList(groupCodes: Array<string>): unknown;
|
||||
getGroupInfoForJoinGroup(groupCode: string, needPrivilegeFlag: boolean, serviceType: number): Promise<unknown>;
|
||||
|
||||
getGroupHonorList(req: { groupCodes: Array<string> }): Promise<unknown>;
|
||||
|
||||
getUinByUids(uins: string[]): Promise<{
|
||||
errCode: number,
|
||||
@@ -57,13 +58,10 @@ export interface NodeIKernelGroupService {
|
||||
uids: Map<string, string>
|
||||
}>;
|
||||
|
||||
//26702(其实更早 但是我不知道)
|
||||
checkGroupMemberCache(arrayList: Array<string>): Promise<unknown>;
|
||||
|
||||
//26702(其实更早 但是我不知道)
|
||||
getGroupLatestEssenceList(groupCode: string): Promise<unknown>;
|
||||
|
||||
//26702(其实更早 但是我不知道)
|
||||
shareDigest(Req: {
|
||||
appId: string,
|
||||
appType: number,
|
||||
@@ -83,20 +81,17 @@ export interface NodeIKernelGroupService {
|
||||
}
|
||||
}): Promise<unknown>;
|
||||
|
||||
//26702(其实更早 但是我不知道)
|
||||
|
||||
isEssenceMsg(Req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>;
|
||||
|
||||
//26702(其实更早 但是我不知道)
|
||||
queryCachedEssenceMsg(Req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>;
|
||||
|
||||
//26702(其实更早 但是我不知道)
|
||||
fetchGroupEssenceList(Req: {
|
||||
groupCode: string,
|
||||
pageStart: number,
|
||||
pageLimit: number
|
||||
}, Arg: unknown): Promise<unknown>;
|
||||
|
||||
//26702
|
||||
getAllMemberList(groupCode: string, forceFetch: boolean): Promise<{
|
||||
errCode: number,
|
||||
errMsg: string,
|
||||
@@ -135,8 +130,6 @@ export interface NodeIKernelGroupService {
|
||||
|
||||
getMemberInfo(group_id: string, uids: string[], forceFetch: boolean): Promise<GeneralCallResult>;
|
||||
|
||||
//getMemberInfo [ '56729xxxx', [ 'u_4Nj08cwW5Hxxxxx' ], true ]
|
||||
|
||||
kickMember(groupCode: string, memberUids: string[], refuseForever: boolean, kickReason: string): Promise<void>;
|
||||
|
||||
modifyMemberRole(groupCode: string, uid: string, role: GroupMemberRole): void;
|
||||
@@ -151,7 +144,7 @@ export interface NodeIKernelGroupService {
|
||||
|
||||
getGroupExtList(force: boolean): Promise<GeneralCallResult>;
|
||||
|
||||
getGroupDetailInfo(groupCode: string): unknown;
|
||||
getGroupDetailInfo(groupCode: string, groupInfoSource: GroupInfoSource): Promise<unknown>;
|
||||
|
||||
getMemberExtInfo(param: GroupExtParam): Promise<unknown>;//req
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { NodeIDependsAdapter, NodeIDispatcherAdapter, NodeIGlobalAdapter } from '../adapters';
|
||||
import { NodeIDependsAdapter, NodeIDispatcherAdapter, NodeIGlobalAdapter } from './adapters';
|
||||
import {
|
||||
NodeIKernelAvatarService,
|
||||
NodeIKernelBuddyService,
|
||||
@@ -13,19 +13,19 @@ import {
|
||||
NodeIKernelStorageCleanService,
|
||||
NodeIKernelTicketService,
|
||||
NodeIKernelTipOffService,
|
||||
} from '@/core';
|
||||
import { NodeIKernelNodeMiscService } from '../services/NodeIKernelNodeMiscService';
|
||||
import { NodeIKernelUixConvertService } from '../services/NodeIKernelUixConvertService';
|
||||
import { NodeIKernelMsgBackupService } from '../services/NodeIKernelMsgBackupService';
|
||||
import { NodeIKernelAlbumService } from '../services/NodeIKernelAlbumService';
|
||||
import { NodeIKernelTianShuService } from '../services/NodeIKernelTianShuService';
|
||||
import { NodeIKernelUnitedConfigService } from '../services/NodeIKernelUnitedConfigService';
|
||||
import { NodeIKernelSearchService } from '../services/NodeIKernelSearchService';
|
||||
import { NodeIKernelCollectionService } from '../services/NodeIKernelCollectionService';
|
||||
import { NodeIKernelRecentContactService } from '../services/NodeIKernelRecentContactService';
|
||||
import { NodeIKernelMSFService } from '../services/NodeIKernelMSFService';
|
||||
import { NodeIkernelTestPerformanceService } from '../services/NodeIkernelTestPerformanceService';
|
||||
import { NodeIKernelECDHService } from '../services/NodeIKernelECDHService';
|
||||
} from '@/core/index';
|
||||
import { NodeIKernelNodeMiscService } from './services/NodeIKernelNodeMiscService';
|
||||
import { NodeIKernelUixConvertService } from './services/NodeIKernelUixConvertService';
|
||||
import { NodeIKernelMsgBackupService } from './services/NodeIKernelMsgBackupService';
|
||||
import { NodeIKernelAlbumService } from './services/NodeIKernelAlbumService';
|
||||
import { NodeIKernelTianShuService } from './services/NodeIKernelTianShuService';
|
||||
import { NodeIKernelUnitedConfigService } from './services/NodeIKernelUnitedConfigService';
|
||||
import { NodeIKernelSearchService } from './services/NodeIKernelSearchService';
|
||||
import { NodeIKernelCollectionService } from './services/NodeIKernelCollectionService';
|
||||
import { NodeIKernelRecentContactService } from './services/NodeIKernelRecentContactService';
|
||||
import { NodeIKernelMSFService } from './services/NodeIKernelMSFService';
|
||||
import { NodeIkernelTestPerformanceService } from './services/NodeIkernelTestPerformanceService';
|
||||
import { NodeIKernelECDHService } from './services/NodeIKernelECDHService';
|
||||
|
||||
export interface NodeQQNTWrapperUtil {
|
||||
get(): unknown;
|
@@ -1,27 +0,0 @@
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { QQBasicInfoWrapper } from '@/common/qq-basic-info';
|
||||
import { NapCatCoreWorkingEnv, NodeIKernelLoginService, NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core';
|
||||
import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from '../apis';
|
||||
import { NTQQCollectionApi } from '../apis/collection';
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
|
||||
export interface InstanceContext {
|
||||
readonly workingEnv: NapCatCoreWorkingEnv;
|
||||
readonly wrapper: WrapperNodeApi;
|
||||
readonly session: NodeIQQNTWrapperSession;
|
||||
readonly logger: LogWrapper;
|
||||
readonly loginService: NodeIKernelLoginService;
|
||||
readonly basicInfoWrapper: QQBasicInfoWrapper;
|
||||
readonly pathWrapper: NapCatPathWrapper;
|
||||
}
|
||||
|
||||
export interface StableNTApiWrapper {
|
||||
FileApi: NTQQFileApi,
|
||||
SystemApi: NTQQSystemApi,
|
||||
CollectionApi: NTQQCollectionApi,
|
||||
WebApi: NTQQWebApi,
|
||||
FriendApi: NTQQFriendApi,
|
||||
MsgApi: NTQQMsgApi,
|
||||
UserApi: NTQQUserApi,
|
||||
GroupApi: NTQQGroupApi
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { PlatformType, VendorType, WrapperSessionInitConfig } from './wrapper';
|
||||
import { getMachineId, hostname, systemName, systemVersion } from '@/common/system';
|
||||
|
||||
export async function genSessionConfig(QQVersionAppid: string, QQVersion: string, selfUin: string, selfUid: string, account_path: string): Promise<WrapperSessionInitConfig> {
|
||||
const downloadPath = path.join(account_path, 'NapCat', 'temp');
|
||||
fs.mkdirSync(downloadPath, { recursive: true });
|
||||
const guid: string = await getMachineId();//26702 支持JS获取guid值 在LoginService中获取 TODO mlikiow a
|
||||
const config: WrapperSessionInitConfig = {
|
||||
selfUin,
|
||||
selfUid,
|
||||
desktopPathConfig: {
|
||||
account_path, // 可以通过NodeQQNTWrapperUtil().getNTUserDataInfoConfig()获取
|
||||
},
|
||||
clientVer: QQVersion, // 9.9.8-22355
|
||||
a2: '',
|
||||
d2: '',
|
||||
d2Key: '',
|
||||
machineId: '',
|
||||
platform: PlatformType.KWINDOWS, // 3是Windows?
|
||||
platVer: systemVersion, // 系统版本号, 应该可以固定
|
||||
appid: QQVersionAppid,
|
||||
rdeliveryConfig: {
|
||||
appKey: '',
|
||||
systemId: 0,
|
||||
appId: '',
|
||||
logicEnvironment: '',
|
||||
platform: PlatformType.KWINDOWS,
|
||||
language: '',
|
||||
sdkVersion: '',
|
||||
userId: '',
|
||||
appVersion: '',
|
||||
osVersion: '',
|
||||
bundleId: '',
|
||||
serverUrl: '',
|
||||
fixedAfterHitKeys: [''],
|
||||
},
|
||||
defaultFileDownloadPath: downloadPath,
|
||||
deviceInfo: {
|
||||
guid,
|
||||
buildVer: QQVersion,
|
||||
localId: 2052,
|
||||
devName: hostname,
|
||||
devType: systemName,
|
||||
vendorName: '',
|
||||
osVer: systemVersion,
|
||||
vendorOsName: systemName,
|
||||
setMute: false,
|
||||
vendorType: VendorType.KNOSETONIOS,
|
||||
},
|
||||
deviceConfig: '{"appearance":{"isSplitViewMode":true},"msg":{}}',
|
||||
};
|
||||
return config;
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
export * from './wrapper';
|
||||
export * from './helper';
|
||||
export * from './context';
|
@@ -2,12 +2,12 @@ import { NapCatPathWrapper } from '@/common/path';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
import { QQBasicInfoWrapper } from '@/common/qq-basic-info';
|
||||
import { loadQQWrapper, NapCatCore, NapCatCoreWorkingEnv } from '@/core/core';
|
||||
import { loadQQWrapper, NapCatCore, NapCatCoreWorkingEnv } from '@/core';
|
||||
import { InstanceContext } from '@/core';
|
||||
import { SelfInfo } from '@/core/entities';
|
||||
import { NodeIKernelLoginListener } from '@/core/listeners';
|
||||
import { NodeIKernelLoginService } from '@/core/services';
|
||||
import { NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core/wrapper/wrapper';
|
||||
import { NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core/wrapper';
|
||||
import { InitWebUi, WebUiConfig } from '@/webui';
|
||||
import { NapCatOneBot11Adapter } from '@/onebot';
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
|
||||
|
24
src/onebot/action/extends/GetGroupInfoEx.ts
Normal file
24
src/onebot/action/extends/GetGroupInfoEx.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
group_id: { type: ['number', 'string'] },
|
||||
},
|
||||
required: ['group_id'],
|
||||
} as const satisfies JSONSchema;
|
||||
|
||||
type Payload = FromSchema<typeof SchemaData>;
|
||||
|
||||
export class GetGroupInfoEx extends BaseAction<Payload, any> {
|
||||
actionName = ActionName.GetGroupInfoEx;
|
||||
payloadSchema = SchemaData;
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
const groupInfoEx = (await NTQQGroupApi.getGroupExtFE0Info([payload.group_id.toString()])).result.groupExtInfos.get(payload.group_id.toString());
|
||||
return groupInfoEx;
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { OB11User, OB11UserSex } from '@/onebot';
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { calcQQLevel } from '@/common/helper';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { OB11Group } from '@/onebot';
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { OB11Group } from '@/onebot';
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { Group } from '@/core/entities';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { OB11GroupMember } from '@/onebot';
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { OB11GroupMember } from '@/onebot';
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
@@ -81,11 +81,13 @@ import SetModelShow from './go-cqhttp/SetModelShow';
|
||||
import { SetInputStatus } from './extends/SetInputStatus';
|
||||
import { GetCSRF } from './system/GetCSRF';
|
||||
import { DelGroupNotice } from './group/DelGroupNotice';
|
||||
import { GetGroupInfoEx } from './extends/GetGroupInfoEx';
|
||||
|
||||
export type ActionMap = Map<string, BaseAction<any, any>>;
|
||||
|
||||
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore): ActionMap {
|
||||
const actionHandlers = [
|
||||
new GetGroupInfoEx(obContext, core),
|
||||
new FetchEmojiLike(obContext, core),
|
||||
new GetFile(obContext, core),
|
||||
new SetQQProfile(obContext, core),
|
||||
|
@@ -6,7 +6,7 @@ import {
|
||||
OB11PostSendMsg,
|
||||
} from '@/onebot/types';
|
||||
import { ActionName, BaseCheckResult } from '@/onebot/action/types';
|
||||
import { decodeCQCode } from '@/onebot/helper/cqcode';
|
||||
import { decodeCQCode } from '@/onebot/cqcode';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
import { ChatType, ElementType, NapCatCore, Peer, RawMessage, SendMessageElement } from '@/core';
|
||||
import BaseAction from '../BaseAction';
|
||||
@@ -98,11 +98,6 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
message: '转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素',
|
||||
};
|
||||
}
|
||||
if (payload.user_id && payload.message_type !== 'group') {
|
||||
// const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
|
||||
// const isBuddy = await NTQQFriendApi.isBuddy(uid!);
|
||||
// if (!isBuddy) { }
|
||||
}
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { OB11User } from '@/onebot';
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
|
||||
|
@@ -110,4 +110,5 @@ export enum ActionName {
|
||||
SetInputStatus = 'set_input_status',
|
||||
GetCSRF = 'get_csrf_token',
|
||||
DelGroupNotice = '_del_group_notice',
|
||||
GetGroupInfoEx = "get_group_info_ex"
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { OB11User } from '@/onebot';
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
@@ -1,4 +1,11 @@
|
||||
import { ChatType, GrayTipElement, NapCatCore } from '@/core';
|
||||
import {
|
||||
ChatType,
|
||||
GrayTipElement,
|
||||
NapCatCore,
|
||||
NTGrayTipElementSubTypeV2,
|
||||
RawMessage,
|
||||
TipGroupElementType,
|
||||
} from '@/core';
|
||||
import { NapCatOneBot11Adapter } from '@/onebot';
|
||||
import { OB11GroupBanEvent } from '../event/notice/OB11GroupBanEvent';
|
||||
import { OB11GroupIncreaseEvent } from '../event/notice/OB11GroupIncreaseEvent';
|
||||
@@ -6,6 +13,11 @@ import { OB11GroupDecreaseEvent } from '../event/notice/OB11GroupDecreaseEvent';
|
||||
import fastXmlParser from 'fast-xml-parser';
|
||||
import { OB11GroupMsgEmojiLikeEvent } from '../event/notice/OB11MsgEmojiLikeEvent';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
import { OB11GroupCardEvent } from '@/onebot/event/notice/OB11GroupCardEvent';
|
||||
import { OB11GroupUploadNoticeEvent } from '@/onebot/event/notice/OB11GroupUploadNoticeEvent';
|
||||
import { OB11GroupPokeEvent } from '@/onebot/event/notice/OB11PokeEvent';
|
||||
import { OB11GroupEssenceEvent } from '@/onebot/event/notice/OB11GroupEssenceEvent';
|
||||
import { OB11GroupTitleEvent } from '@/onebot/event/notice/OB11GroupTitleEvent';
|
||||
|
||||
export class OneBotGroupApi {
|
||||
obContext: NapCatOneBot11Adapter;
|
||||
@@ -16,6 +28,126 @@ export class OneBotGroupApi {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
async parseGroupEvent(msg: RawMessage) {
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
const NTQQUserApi = this.core.apis.UserApi;
|
||||
const NTQQMsgApi = this.core.apis.MsgApi;
|
||||
const logger = this.core.context.logger;
|
||||
if (msg.chatType !== ChatType.KCHATTYPEGROUP) {
|
||||
return;
|
||||
}
|
||||
//log("group msg", msg);
|
||||
if (msg.senderUin && msg.senderUin !== '0') {
|
||||
const member = await NTQQGroupApi.getGroupMember(msg.peerUid, msg.senderUin);
|
||||
if (member && member.cardName !== msg.sendMemberName) {
|
||||
const newCardName = msg.sendMemberName || '';
|
||||
const event = new OB11GroupCardEvent(this.core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName);
|
||||
member.cardName = newCardName;
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
for (const element of msg.elements) {
|
||||
if (element.grayTipElement && element.grayTipElement.groupElement) {
|
||||
const groupElement = element.grayTipElement.groupElement;
|
||||
if (groupElement.type == TipGroupElementType.memberIncrease) {
|
||||
const MemberIncreaseEvent = await this.obContext.apis.GroupApi.parseGroupMemberIncreaseEvent(msg.peerUid, element.grayTipElement);
|
||||
if (MemberIncreaseEvent) return MemberIncreaseEvent;
|
||||
} else if (groupElement.type === TipGroupElementType.ban) {
|
||||
const BanEvent = await this.obContext.apis.GroupApi.parseGroupBanEvent(msg.peerUid, element.grayTipElement);
|
||||
if (BanEvent) return BanEvent;
|
||||
} else if (groupElement.type == TipGroupElementType.kicked) {
|
||||
NTQQGroupApi.quitGroup(msg.peerUid).then();
|
||||
try {
|
||||
const KickEvent = await this.obContext.apis.GroupApi.parseGroupKickEvent(msg.peerUid, element.grayTipElement);
|
||||
if (KickEvent) return KickEvent;
|
||||
} catch (e) {
|
||||
return new OB11GroupDecreaseEvent(
|
||||
this.core,
|
||||
parseInt(msg.peerUid),
|
||||
parseInt(this.core.selfInfo.uin),
|
||||
0,
|
||||
'leave',
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (element.fileElement) {
|
||||
return new OB11GroupUploadNoticeEvent(
|
||||
this.core,
|
||||
parseInt(msg.peerUid), parseInt(msg.senderUin || ''),
|
||||
{
|
||||
id: element.fileElement.fileUuid!,
|
||||
name: element.fileElement.fileName,
|
||||
size: parseInt(element.fileElement.fileSize),
|
||||
busid: element.fileElement.fileBizId || 0,
|
||||
},
|
||||
);
|
||||
}
|
||||
if (element.grayTipElement) {
|
||||
if (element.grayTipElement.xmlElement?.templId === '10382') {
|
||||
const emojiLikeEvent = await this.obContext.apis.GroupApi.parseGroupEmojiLikeEventByGrayTip(msg.peerUid, element.grayTipElement);
|
||||
if (emojiLikeEvent) return emojiLikeEvent;
|
||||
}
|
||||
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
|
||||
const GroupIncreaseEvent = await this.obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, element.grayTipElement);
|
||||
if (GroupIncreaseEvent) return GroupIncreaseEvent;
|
||||
}
|
||||
|
||||
//代码歧义 GrayTipElementSubType.MEMBER_NEW_TITLE
|
||||
else if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
|
||||
const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr);
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
|
||||
//判断业务类型
|
||||
//Poke事件
|
||||
const pokedetail: any[] = json.items;
|
||||
//筛选item带有uid的元素
|
||||
const poke_uid = pokedetail.filter(item => item.uid);
|
||||
if (poke_uid.length == 2) {
|
||||
return new OB11GroupPokeEvent(
|
||||
this.core,
|
||||
parseInt(msg.peerUid),
|
||||
parseInt((await NTQQUserApi.getUinByUidV2(poke_uid[0].uid))!),
|
||||
parseInt((await NTQQUserApi.getUinByUidV2(poke_uid[1].uid))!),
|
||||
pokedetail,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 2401) {
|
||||
const searchParams = new URL(json.items[0].jp).searchParams;
|
||||
const msgSeq = searchParams.get('msgSeq')!;
|
||||
const Group = searchParams.get('groupCode');
|
||||
// const businessId = searchParams.get('businessid');
|
||||
const Peer = {
|
||||
guildId: '',
|
||||
chatType: ChatType.KCHATTYPEGROUP,
|
||||
peerUid: Group!,
|
||||
};
|
||||
const msgData = await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true);
|
||||
return new OB11GroupEssenceEvent(
|
||||
this.core,
|
||||
parseInt(msg.peerUid),
|
||||
MessageUnique.getShortIdByMsgId(msgData.msgList[0].msgId)!,
|
||||
parseInt(msgData.msgList[0].senderUin),
|
||||
);
|
||||
// 获取MsgSeq+Peer可获取具体消息
|
||||
}
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 2407) {
|
||||
//下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE
|
||||
const memberUin = json.items[1].param[0];
|
||||
const title = json.items[3].txt;
|
||||
logger.logDebug('收到群成员新头衔消息', json);
|
||||
return new OB11GroupTitleEvent(
|
||||
this.core,
|
||||
parseInt(msg.peerUid),
|
||||
parseInt(memberUin),
|
||||
title,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async parseGroupBanEvent(GroupCode: string, grayTipElement: GrayTipElement) {
|
||||
const groupElement = grayTipElement?.groupElement;
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
@@ -112,8 +244,10 @@ export class OneBotGroupApi {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async parseGroupEmjioLikeEvent(GroupCode: string, grayTipElement: GrayTipElement) {
|
||||
const NTQQMsgApi = this.core.apis.MsgApi;
|
||||
async parseGroupEmojiLikeEventByGrayTip(
|
||||
groupCode: string,
|
||||
grayTipElement: GrayTipElement
|
||||
) {
|
||||
const emojiLikeData = new fastXmlParser.XMLParser({
|
||||
ignoreAttributes: false,
|
||||
attributeNamePrefix: '',
|
||||
@@ -122,16 +256,27 @@ export class OneBotGroupApi {
|
||||
const senderUin = emojiLikeData.gtip.qq.jp;
|
||||
const msgSeq = emojiLikeData.gtip.url.msgseq;
|
||||
const emojiId = emojiLikeData.gtip.face.id;
|
||||
return await this.createGroupEmojiLikeEvent(groupCode, senderUin, msgSeq, emojiId);
|
||||
}
|
||||
|
||||
async createGroupEmojiLikeEvent(
|
||||
groupCode: string,
|
||||
senderUin: string,
|
||||
msgSeq: string,
|
||||
emojiId: string,
|
||||
) {
|
||||
const peer = {
|
||||
chatType: ChatType.KCHATTYPEGROUP,
|
||||
guildId: '',
|
||||
peerUid: GroupCode,
|
||||
peerUid: groupCode,
|
||||
};
|
||||
const replyMsgList = (await NTQQMsgApi.getMsgExBySeq(peer, msgSeq)).msgList;
|
||||
const replyMsgList = (await this.core.apis.MsgApi.getMsgExBySeq(peer, msgSeq)).msgList;
|
||||
if (replyMsgList.length < 1) {
|
||||
return;
|
||||
}
|
||||
const replyMsg = replyMsgList.filter(e => e.msgSeq == msgSeq).sort((a, b) => parseInt(a.msgTime) - parseInt(b.msgTime))[0];
|
||||
const replyMsg = replyMsgList
|
||||
.filter(e => e.msgSeq == msgSeq)
|
||||
.sort((a, b) => parseInt(a.msgTime) - parseInt(b.msgTime))[0];
|
||||
//console.log("表情回应消息长度检测", msgSeq, replyMsg.elements);
|
||||
if (!replyMsg) {
|
||||
this.core.context.logger.logError('解析表情回应消息失败: 未找到回应消息');
|
||||
@@ -139,7 +284,7 @@ export class OneBotGroupApi {
|
||||
}
|
||||
return new OB11GroupMsgEmojiLikeEvent(
|
||||
this.core,
|
||||
parseInt(GroupCode),
|
||||
parseInt(groupCode),
|
||||
parseInt(senderUin),
|
||||
MessageUnique.getShortIdByMsgId(replyMsg.msgId)!,
|
||||
[{
|
||||
|
@@ -9,7 +9,7 @@ import {
|
||||
FaceType,
|
||||
IdMusicSignPostData,
|
||||
MessageElement,
|
||||
NapCatCore,
|
||||
NapCatCore, NTGrayTipElementSubTypeV2,
|
||||
Peer,
|
||||
RawMessage,
|
||||
SendMessageElement,
|
||||
@@ -24,13 +24,14 @@ import {
|
||||
OB11MessageFileBase,
|
||||
OB11MessageForward,
|
||||
} from '@/onebot';
|
||||
import { OB11Entities } from '../helper';
|
||||
import { OB11Entities } from '@/onebot/entities';
|
||||
import { EventType } from '@/onebot/event/OB11BaseEvent';
|
||||
import { encodeCQCode } from '@/onebot/helper/cqcode';
|
||||
import { encodeCQCode } from '@/onebot/cqcode';
|
||||
import { uri2local } from '@/common/file';
|
||||
import { RequestUtil } from '@/common/request';
|
||||
import fs from 'node:fs';
|
||||
import fsPromise from 'node:fs/promises';
|
||||
import { OB11FriendAddNoticeEvent } from '@/onebot/event/notice/OB11FriendAddNoticeEvent';
|
||||
|
||||
type RawToOb11Converters = {
|
||||
[Key in keyof MessageElement as Key extends `${string}Element` ? Key : never]: (
|
||||
@@ -656,6 +657,28 @@ export class OneBotMsgApi {
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
async parsePrivateMsgEvent(msg: RawMessage) {
|
||||
if (msg.chatType !== ChatType.KCHATTYPEC2C) {
|
||||
return;
|
||||
}
|
||||
for (const element of msg.elements) {
|
||||
if (element.grayTipElement) {
|
||||
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
|
||||
const PokeEvent = await this.obContext.apis.FriendApi.parsePrivatePokeEvent(element.grayTipElement);
|
||||
if (PokeEvent) return PokeEvent;
|
||||
}
|
||||
}
|
||||
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
|
||||
//好友添加成功事件
|
||||
if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') {
|
||||
return new OB11FriendAddNoticeEvent(this.core, parseInt(msg.peerUin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async parseMessage(
|
||||
msg: RawMessage,
|
||||
messagePostFormat: string = this.obContext.configLoader.configData.messagePostFormat,
|
||||
@@ -799,16 +822,12 @@ export class OneBotMsgApi {
|
||||
this.core.context.logger.logError('发送消息计算预计时间异常', e);
|
||||
}
|
||||
const returnMsg = await this.core.apis.MsgApi.sendMsg(peer, sendElements, waitComplete, timeout);
|
||||
try {
|
||||
returnMsg!.id = MessageUnique.createMsg({
|
||||
chatType: peer.chatType,
|
||||
guildId: '',
|
||||
peerUid: peer.peerUid,
|
||||
}, returnMsg!.msgId);
|
||||
} catch (e: any) {
|
||||
this.core.context.logger.logDebug('发送消息id获取失败', e);
|
||||
returnMsg!.id = 0;
|
||||
}
|
||||
if (!returnMsg) throw new Error('发送消息失败');
|
||||
returnMsg.id = MessageUnique.createMsg({
|
||||
chatType: peer.chatType,
|
||||
guildId: '',
|
||||
peerUid: peer.peerUid,
|
||||
}, returnMsg.msgId);
|
||||
deleteAfterSentFiles.forEach(file => {
|
||||
fsPromise.unlink(file).then().catch(e => this.core.context.logger.logError('发送消息删除文件失败', e));
|
||||
});
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { ConfigBase } from '@/common/config-base';
|
||||
import ob11DefaultConfig from '@/onebot/external/onebot11.json';
|
||||
import ob11DefaultConfig from './onebot11.json';
|
||||
import { NapCatCore } from '@/core';
|
||||
|
||||
export type OB11Config = typeof ob11DefaultConfig;
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"http": {
|
||||
"enable": true,
|
||||
"enable": false,
|
||||
"host": "",
|
||||
"port": 3000,
|
||||
"secret": "",
|
@@ -1,4 +1,4 @@
|
||||
import { OB11MessageData } from '../types';
|
||||
import { OB11MessageData } from './types';
|
||||
|
||||
const pattern = /\[CQ:(\w+)((,\w+=[^,\]]*)*)]/;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { calcQQLevel } from '@/common/helper';
|
||||
import { Friend, FriendV2, Group, GroupMember, SelfInfo, Sex, User } from '@/core';
|
||||
import { OB11Group, OB11GroupMember, OB11GroupMemberRole, OB11User, OB11UserSex } from '../types';
|
||||
import { OB11Group, OB11GroupMember, OB11GroupMemberRole, OB11User, OB11UserSex } from './types';
|
||||
|
||||
export class OB11Entities {
|
||||
static selfInfo(selfInfo: SelfInfo): OB11User {
|
@@ -1,154 +0,0 @@
|
||||
import { NapCatOneBot11Adapter } from '..';
|
||||
import { OB11BaseNoticeEvent } from '../event/notice/OB11BaseNoticeEvent';
|
||||
import { OB11FriendAddNoticeEvent } from '../event/notice/OB11FriendAddNoticeEvent';
|
||||
import { OB11GroupNoticeEvent } from '../event/notice/OB11GroupNoticeEvent';
|
||||
import { OB11GroupCardEvent } from '../event/notice/OB11GroupCardEvent';
|
||||
import { OB11GroupDecreaseEvent } from '../event/notice/OB11GroupDecreaseEvent';
|
||||
import { OB11GroupUploadNoticeEvent } from '../event/notice/OB11GroupUploadNoticeEvent';
|
||||
import { OB11GroupPokeEvent } from '../event/notice/OB11PokeEvent';
|
||||
import { OB11GroupEssenceEvent } from '../event/notice/OB11GroupEssenceEvent';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
import { OB11GroupTitleEvent } from '../event/notice/OB11GroupTitleEvent';
|
||||
import { ChatType, NapCatCore, NTGrayTipElementSubTypeV2, Peer, RawMessage, TipGroupElementType } from '@/core';
|
||||
|
||||
export async function NT2PrivateEvent(core: NapCatCore, obContext: NapCatOneBot11Adapter, msg: RawMessage): Promise<OB11BaseNoticeEvent | undefined> {
|
||||
if (msg.chatType !== ChatType.KCHATTYPEC2C) {
|
||||
return;
|
||||
}
|
||||
for (const element of msg.elements) {
|
||||
if (element.grayTipElement) {
|
||||
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
|
||||
const PokeEvent = await obContext.apis.FriendApi.parsePrivatePokeEvent(element.grayTipElement);
|
||||
if (PokeEvent) return PokeEvent;
|
||||
}
|
||||
}
|
||||
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
|
||||
//好友添加成功事件
|
||||
if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') {
|
||||
return new OB11FriendAddNoticeEvent(core, parseInt(msg.peerUin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function NT2GroupEvent(core: NapCatCore, obContext: NapCatOneBot11Adapter, msg: RawMessage): Promise<OB11GroupNoticeEvent | undefined> {
|
||||
const NTQQGroupApi = core.apis.GroupApi;
|
||||
const NTQQUserApi = core.apis.UserApi;
|
||||
const NTQQMsgApi = core.apis.MsgApi;
|
||||
const logger = core.context.logger;
|
||||
if (msg.chatType !== ChatType.KCHATTYPEGROUP) {
|
||||
return;
|
||||
}
|
||||
//log("group msg", msg);
|
||||
if (msg.senderUin && msg.senderUin !== '0') {
|
||||
const member = await NTQQGroupApi.getGroupMember(msg.peerUid, msg.senderUin);
|
||||
if (member && member.cardName !== msg.sendMemberName) {
|
||||
const newCardName = msg.sendMemberName || '';
|
||||
const event = new OB11GroupCardEvent(core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName);
|
||||
member.cardName = newCardName;
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
for (const element of msg.elements) {
|
||||
if (element.grayTipElement && element.grayTipElement.groupElement) {
|
||||
const groupElement = element.grayTipElement.groupElement;
|
||||
if (groupElement.type == TipGroupElementType.memberIncrease) {
|
||||
const MemberIncreaseEvent = await obContext.apis.GroupApi.parseGroupMemberIncreaseEvent(msg.peerUid, element.grayTipElement);
|
||||
if (MemberIncreaseEvent) return MemberIncreaseEvent;
|
||||
} else if (groupElement.type === TipGroupElementType.ban) {
|
||||
const BanEvent = await obContext.apis.GroupApi.parseGroupBanEvent(msg.peerUid, element.grayTipElement);
|
||||
if (BanEvent) return BanEvent;
|
||||
} else if (groupElement.type == TipGroupElementType.kicked) {
|
||||
NTQQGroupApi.quitGroup(msg.peerUid).then();
|
||||
try {
|
||||
const KickEvent = await obContext.apis.GroupApi.parseGroupKickEvent(msg.peerUid, element.grayTipElement);
|
||||
if (KickEvent) return KickEvent;
|
||||
} catch (e) {
|
||||
return new OB11GroupDecreaseEvent(
|
||||
core,
|
||||
parseInt(msg.peerUid),
|
||||
parseInt(core.selfInfo.uin),
|
||||
0,
|
||||
'leave',
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (element.fileElement) {
|
||||
return new OB11GroupUploadNoticeEvent(
|
||||
core,
|
||||
parseInt(msg.peerUid), parseInt(msg.senderUin || ''),
|
||||
{
|
||||
id: element.fileElement.fileUuid!,
|
||||
name: element.fileElement.fileName,
|
||||
size: parseInt(element.fileElement.fileSize),
|
||||
busid: element.fileElement.fileBizId || 0,
|
||||
},
|
||||
);
|
||||
}
|
||||
if (element.grayTipElement) {
|
||||
if (element.grayTipElement.xmlElement?.templId === '10382') {
|
||||
const emojiLikeEvent = await obContext.apis.GroupApi.parseGroupEmjioLikeEvent(msg.peerUid, element.grayTipElement);
|
||||
if (emojiLikeEvent) return emojiLikeEvent;
|
||||
}
|
||||
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
|
||||
const GroupIncreaseEvent = await obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, element.grayTipElement);
|
||||
if (GroupIncreaseEvent) return GroupIncreaseEvent;
|
||||
}
|
||||
|
||||
//代码歧义 GrayTipElementSubType.MEMBER_NEW_TITLE
|
||||
else if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
|
||||
const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr);
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
|
||||
//判断业务类型
|
||||
//Poke事件
|
||||
const pokedetail: any[] = json.items;
|
||||
//筛选item带有uid的元素
|
||||
const poke_uid = pokedetail.filter(item => item.uid);
|
||||
if (poke_uid.length == 2) {
|
||||
return new OB11GroupPokeEvent(
|
||||
core,
|
||||
parseInt(msg.peerUid),
|
||||
parseInt((await NTQQUserApi.getUinByUidV2(poke_uid[0].uid))!),
|
||||
parseInt((await NTQQUserApi.getUinByUidV2(poke_uid[1].uid))!),
|
||||
pokedetail,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 2401) {
|
||||
const searchParams = new URL(json.items[0].jp).searchParams;
|
||||
const msgSeq = searchParams.get('msgSeq')!;
|
||||
const Group = searchParams.get('groupCode');
|
||||
// const businessId = searchParams.get('businessid');
|
||||
const Peer: Peer = {
|
||||
guildId: '',
|
||||
chatType: ChatType.KCHATTYPEGROUP,
|
||||
peerUid: Group!,
|
||||
};
|
||||
const msgData = await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true);
|
||||
return new OB11GroupEssenceEvent(
|
||||
core,
|
||||
parseInt(msg.peerUid),
|
||||
MessageUnique.getShortIdByMsgId(msgData.msgList[0].msgId)!,
|
||||
parseInt(msgData.msgList[0].senderUin),
|
||||
);
|
||||
// 获取MsgSeq+Peer可获取具体消息
|
||||
}
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 2407) {
|
||||
//下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE
|
||||
const memberUin = json.items[1].param[0];
|
||||
const title = json.items[3].txt;
|
||||
logger.logDebug('收到群成员新头衔消息', json);
|
||||
return new OB11GroupTitleEvent(
|
||||
core,
|
||||
parseInt(msg.peerUid),
|
||||
parseInt(memberUin),
|
||||
title,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +0,0 @@
|
||||
export * from './config';
|
||||
export * from './entities';
|
||||
export * from './event';
|
@@ -13,7 +13,7 @@ import {
|
||||
RawMessage,
|
||||
SendStatusType,
|
||||
} from '@/core';
|
||||
import { OB11Config, OB11ConfigLoader } from '@/onebot/helper/config';
|
||||
import { OB11Config, OB11ConfigLoader } from '@/onebot/config';
|
||||
import {
|
||||
OB11ActiveHttpAdapter,
|
||||
OB11ActiveWebSocketAdapter,
|
||||
@@ -42,8 +42,10 @@ import { OB11GroupRequestEvent } from '@/onebot/event/request/OB11GroupRequest';
|
||||
import { OB11FriendRecallNoticeEvent } from '@/onebot/event/notice/OB11FriendRecallNoticeEvent';
|
||||
import { OB11GroupRecallNoticeEvent } from '@/onebot/event/notice/OB11GroupRecallNoticeEvent';
|
||||
import { LRUCache } from '@/common/lru-cache';
|
||||
import { NT2GroupEvent, NT2PrivateEvent } from './helper';
|
||||
import { NodeIKernelRecentContactListener } from '@/core/listeners/NodeIKernelRecentContactListener';
|
||||
import { SysMessage } from '@/core/proto/SysMessage';
|
||||
import { GreyTipWrapper } from '@/core/proto/GreyTipWrapper';
|
||||
import { EmojiLikeToOthersWrapper1 } from '@/core/proto/EmojiLikeToOthers';
|
||||
|
||||
//OneBot实现类
|
||||
export class NapCatOneBot11Adapter {
|
||||
@@ -239,9 +241,31 @@ export class NapCatOneBot11Adapter {
|
||||
|
||||
private initMsgListener() {
|
||||
const msgListener = new NodeIKernelMsgListener();
|
||||
/* msgListener.onRecvSysMsg = msg => {
|
||||
//console.log('onRecvSysMsg', Buffer.from(msg).toString('hex'));
|
||||
}; */
|
||||
|
||||
msgListener.onRecvSysMsg = async msg => {
|
||||
const sysMsg = SysMessage.fromBinary(Uint8Array.from(msg));
|
||||
if (sysMsg.msgSpec.length === 0) {
|
||||
return;
|
||||
}
|
||||
const { msgType, subType, subSubType } = sysMsg.msgSpec[0];
|
||||
if (msgType === 732 && subType === 16 && subSubType === 16 ) {
|
||||
const greyTip = GreyTipWrapper.fromBinary(Uint8Array.from(sysMsg.bodyWrapper!.wrappedBody.slice(7)));
|
||||
if (greyTip.subTypeId === 36) {
|
||||
const emojiLikeToOthers = EmojiLikeToOthersWrapper1
|
||||
.fromBinary(greyTip.rest)
|
||||
.wrapper!
|
||||
.body!;
|
||||
const eventOrEmpty = await this.apis.GroupApi.createGroupEmojiLikeEvent(
|
||||
greyTip.groupCode.toString(),
|
||||
await this.core.apis.UserApi.getUinByUidV2(emojiLikeToOthers.attributes!.senderUid),
|
||||
emojiLikeToOthers.msgSpec!.msgSeq.toString(),
|
||||
emojiLikeToOthers.attributes!.emojiId,
|
||||
);
|
||||
eventOrEmpty && await this.networkManager.emitEvent(eventOrEmpty);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
msgListener.onInputStatusPush = async data => {
|
||||
const uin = await this.core.apis.UserApi.getUinByUidV2(data.fromUin);
|
||||
this.context.logger.log(`[Notice] [输入状态] ${uin} ${data.statusText}`);
|
||||
@@ -271,6 +295,7 @@ export class NapCatOneBot11Adapter {
|
||||
.catch(e => this.context.logger.logError('处理消息失败', e));
|
||||
}
|
||||
};
|
||||
|
||||
const msgIdSend = new LRUCache<string, boolean>(100);
|
||||
const recallMsgs = new LRUCache<string, boolean>(100);
|
||||
msgListener.onMsgInfoListUpdate = async msgList => {
|
||||
@@ -501,14 +526,14 @@ export class NapCatOneBot11Adapter {
|
||||
this.networkManager.emitEvent(ob11Msg);
|
||||
}).catch(e => this.context.logger.logError('constructMessage error: ', e));
|
||||
|
||||
NT2GroupEvent(this.core, this, message).then(groupEvent => {
|
||||
this.apis.GroupApi.parseGroupEvent(message).then(groupEvent => {
|
||||
if (groupEvent) {
|
||||
// log("post group event", groupEvent);
|
||||
this.networkManager.emitEvent(groupEvent);
|
||||
}
|
||||
}).catch(e => this.context.logger.logError('constructGroupEvent error: ', e));
|
||||
|
||||
NT2PrivateEvent(this.core, this, message).then(privateEvent => {
|
||||
this.apis.MsgApi.parsePrivateMsgEvent(message).then(privateEvent => {
|
||||
if (privateEvent) {
|
||||
// log("post private event", privateEvent);
|
||||
this.networkManager.emitEvent(privateEvent);
|
||||
|
@@ -6,6 +6,7 @@ import { NodeIDependsAdapter, NodeIDispatcherAdapter, NodeIGlobalAdapter } from
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
import {
|
||||
InstanceContext,
|
||||
genSessionConfig,
|
||||
loadQQWrapper,
|
||||
NapCatCore,
|
||||
NapCatCoreWorkingEnv,
|
||||
@@ -14,7 +15,6 @@ import {
|
||||
} from '@/core';
|
||||
import { QQBasicInfoWrapper } from '@/common/qq-basic-info';
|
||||
import { hostname, systemVersion } from '@/common/system';
|
||||
import { genSessionConfig } from '@/core/wrapper/helper';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
|
||||
import path from 'path';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { OB11Config } from '@/onebot/helper/config';
|
||||
import { OB11Config } from '@/onebot/config';
|
||||
|
||||
interface LoginRuntimeType {
|
||||
LoginCurrentTime: number;
|
||||
|
@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
undefined,
|
||||
SettingButton('V2.2.16', 'napcat-update-button', 'secondary'),
|
||||
SettingButton('V2.2.20', 'napcat-update-button', 'secondary'),
|
||||
),
|
||||
]),
|
||||
SettingList([
|
||||
|
@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
void 0,
|
||||
SettingButton("V2.2.16", "napcat-update-button", "secondary")
|
||||
SettingButton("V2.2.20", "napcat-update-button", "secondary")
|
||||
)
|
||||
]),
|
||||
SettingList([
|
||||
|
@@ -46,7 +46,7 @@ const FrameworkBaseConfigPlugin: PluginOption[] = [
|
||||
{ src: './manifest.json', dest: 'dist' },
|
||||
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
||||
{ src: './static/', dest: 'dist/static/', flatten: false },
|
||||
{ src: './src/onebot/external/onebot11.json', dest: 'dist/config/' },
|
||||
{ src: './src/onebot/config/onebot11.json', dest: 'dist/config/' },
|
||||
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
|
||||
{ src: './src/framework/napcat.cjs', dest: 'dist' },
|
||||
{ src: './src/framework/preload.cjs', dest: 'dist' },
|
||||
@@ -80,7 +80,7 @@ const ShellBaseConfigPlugin: PluginOption[] = [
|
||||
{ src: './static/', dest: 'dist/static/', flatten: false },
|
||||
// { src: './src/onebot11/onebot11.json', dest: 'dist/config/' },
|
||||
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
||||
{ src: './src/onebot/external/onebot11.json', dest: 'dist/config/' },
|
||||
{ src: './src/onebot/config/onebot11.json', dest: 'dist/config/' },
|
||||
{ src: './package.json', dest: 'dist' },
|
||||
// { src: './README.md', dest: 'dist' },
|
||||
// { src: './logo.png', dest: 'dist/logs' },
|
||||
|
Reference in New Issue
Block a user