mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ac2b0118a6 | ||
![]() |
3eb8fd4abe | ||
![]() |
48b389ebe3 | ||
![]() |
065adeb2cd | ||
![]() |
269d0a06fe | ||
![]() |
8eca26b1a5 | ||
![]() |
3019ef7de4 | ||
![]() |
522311b547 | ||
![]() |
21061561ec | ||
![]() |
b83c41ad56 | ||
![]() |
e80a1cc64a |
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -10,6 +10,7 @@ body:
|
|||||||
在提交新的 Bug 反馈前,请确保您:
|
在提交新的 Bug 反馈前,请确保您:
|
||||||
* 已经搜索了现有的 issues,并且没有找到可以解决您问题的方法
|
* 已经搜索了现有的 issues,并且没有找到可以解决您问题的方法
|
||||||
* 不与现有的某一 issue 重复
|
* 不与现有的某一 issue 重复
|
||||||
|
* 不涉及[已经停止维护的特性](https://github.com/NapNeko/NapCatQQ?tab=readme-ov-file#挥别昨日),例如 CQ 码
|
||||||
- type: input
|
- type: input
|
||||||
id: system-version
|
id: system-version
|
||||||
attributes:
|
attributes:
|
||||||
|
@@ -9,7 +9,7 @@ NapCatQQ (aka 猫猫框架) 是现代化的基于 NTQQ 的 Bot 协议端实现
|
|||||||
## 猫猫技能
|
## 猫猫技能
|
||||||
- [x] **高性能**:1K+ 群聊数目、20 线程并行发送消息毫无压力
|
- [x] **高性能**:1K+ 群聊数目、20 线程并行发送消息毫无压力
|
||||||
- [x] **多种启动方式**:支持以无头、LiteLoader 插件、仅 QQ GUI 三种方式启动
|
- [x] **多种启动方式**:支持以无头、LiteLoader 插件、仅 QQ GUI 三种方式启动
|
||||||
- [x] **多平台支持**: 支持Windows/Linux(可选Docker)/Android Termux/MacOs覆盖全平台
|
- [x] **多平台支持**: 覆盖 Windows / Linux (可选 Docker) / Android Termux / MacOS
|
||||||
- [x] **安装简单**: 支持一键脚本/程序自动部署/镜像部署等多种覆盖范围
|
- [x] **安装简单**: 支持一键脚本/程序自动部署/镜像部署等多种覆盖范围
|
||||||
- [x] **低占用**:无头模式占用资源极低,适合在服务器上运行
|
- [x] **低占用**:无头模式占用资源极低,适合在服务器上运行
|
||||||
- [x] **超多接口**:实现大部分 OneBot 和 go-cqhttp 接口,超多扩展 API
|
- [x] **超多接口**:实现大部分 OneBot 和 go-cqhttp 接口,超多扩展 API
|
||||||
|
Binary file not shown.
Binary file not shown.
@@ -36,3 +36,5 @@ set NAPCAT_MAIN_PATH=%NAPCAT_MAIN_PATH:\=/%
|
|||||||
echo (async () =^> {await import("file:///%NAPCAT_MAIN_PATH%")})() > %NAPCAT_LOAD_PATH%
|
echo (async () =^> {await import("file:///%NAPCAT_MAIN_PATH%")})() > %NAPCAT_LOAD_PATH%
|
||||||
|
|
||||||
"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%"
|
"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%"
|
||||||
|
|
||||||
|
REM "%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%" 123456
|
@@ -37,3 +37,5 @@ set NAPCAT_MAIN_PATH=%NAPCAT_MAIN_PATH:\=/%
|
|||||||
echo (async () =^> {await import("file:///%NAPCAT_MAIN_PATH%")})() > %NAPCAT_LOAD_PATH%
|
echo (async () =^> {await import("file:///%NAPCAT_MAIN_PATH%")})() > %NAPCAT_LOAD_PATH%
|
||||||
|
|
||||||
"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%"
|
"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%"
|
||||||
|
|
||||||
|
REM "%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%" 123456
|
@@ -4,7 +4,7 @@
|
|||||||
"name": "NapCatQQ",
|
"name": "NapCatQQ",
|
||||||
"slug": "NapCat.Framework",
|
"slug": "NapCat.Framework",
|
||||||
"description": "高性能的 OneBot 11 协议实现",
|
"description": "高性能的 OneBot 11 协议实现",
|
||||||
"version": "2.3.0",
|
"version": "2.3.5",
|
||||||
"icon": "./logo.png",
|
"icon": "./logo.png",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"name": "napcat",
|
"name": "napcat",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.3.0",
|
"version": "2.3.5",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:framework": "vite build --mode framework",
|
"build:framework": "vite build --mode framework",
|
||||||
"build:shell": "vite build --mode shell",
|
"build:shell": "vite build --mode shell",
|
||||||
|
@@ -1 +1 @@
|
|||||||
export const napCatVersion = '2.3.0';
|
export const napCatVersion = '2.3.5';
|
||||||
|
@@ -298,65 +298,6 @@ export class NTQQFileApi {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async addFileCache(peer: Peer, msgId: string, msgSeq: string, senderUid: string, elemId: string, elemType: string, fileSize: string, fileName: string) {
|
|
||||||
let GroupData;
|
|
||||||
let BuddyData;
|
|
||||||
if (peer.chatType === ChatType.KCHATTYPEGROUP) {
|
|
||||||
GroupData =
|
|
||||||
[{
|
|
||||||
groupCode: peer.peerUid,
|
|
||||||
isConf: false,
|
|
||||||
hasModifyConfGroupFace: true,
|
|
||||||
hasModifyConfGroupName: true,
|
|
||||||
groupName: 'NapCat.Cached',
|
|
||||||
remark: 'NapCat.Cached',
|
|
||||||
}];
|
|
||||||
} else if (peer.chatType === ChatType.KCHATTYPEC2C) {
|
|
||||||
BuddyData = [{
|
|
||||||
category_name: 'NapCat.Cached',
|
|
||||||
peerUid: peer.peerUid,
|
|
||||||
peerUin: peer.peerUid,
|
|
||||||
remark: 'NapCat.Cached',
|
|
||||||
}];
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.context.session.getSearchService().addSearchHistory({
|
|
||||||
type: 4,
|
|
||||||
contactList: [],
|
|
||||||
id: -1,
|
|
||||||
groupInfos: [],
|
|
||||||
msgs: [],
|
|
||||||
fileInfos: [
|
|
||||||
{
|
|
||||||
chatType: peer.chatType,
|
|
||||||
buddyChatInfo: BuddyData || [],
|
|
||||||
discussChatInfo: [],
|
|
||||||
groupChatInfo: GroupData || [],
|
|
||||||
dataLineChatInfo: [],
|
|
||||||
tmpChatInfo: [],
|
|
||||||
msgId: msgId,
|
|
||||||
msgSeq: msgSeq,
|
|
||||||
msgTime: Math.floor(Date.now() / 1000).toString(),
|
|
||||||
senderUid: senderUid,
|
|
||||||
senderNick: 'NapCat.Cached',
|
|
||||||
senderRemark: 'NapCat.Cached',
|
|
||||||
senderCard: 'NapCat.Cached',
|
|
||||||
elemId: elemId,
|
|
||||||
elemType: elemType,
|
|
||||||
fileSize: fileSize,
|
|
||||||
filePath: '',
|
|
||||||
fileName: fileName,
|
|
||||||
hits: [{
|
|
||||||
start: 12,
|
|
||||||
end: 14,
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async searchForFile(keys: string[]): Promise<SearchResultItem | undefined> {
|
async searchForFile(keys: string[]): Promise<SearchResultItem | undefined> {
|
||||||
const randomResultId = 100000 + Math.floor(Math.random() * 10000);
|
const randomResultId = 100000 + Math.floor(Math.random() * 10000);
|
||||||
let searchId = 0;
|
let searchId = 0;
|
||||||
|
@@ -115,6 +115,7 @@ export class OneBotMsgApi {
|
|||||||
file_id: encodedFileId,
|
file_id: encodedFileId,
|
||||||
url: await this.core.apis.FileApi.getImageUrl(element),
|
url: await this.core.apis.FileApi.getImageUrl(element),
|
||||||
file_size: element.fileSize,
|
file_size: element.fileSize,
|
||||||
|
file_unique: element.fileName
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@@ -129,20 +130,6 @@ export class OneBotMsgApi {
|
|||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
};
|
};
|
||||||
await this.core.apis.FileApi.addFileCache(
|
|
||||||
{
|
|
||||||
peerUid: msg.peerUid,
|
|
||||||
chatType: msg.chatType,
|
|
||||||
guildId: '',
|
|
||||||
},
|
|
||||||
msg.msgId,
|
|
||||||
msg.msgSeq,
|
|
||||||
msg.senderUid,
|
|
||||||
elementWrapper.elementId,
|
|
||||||
elementWrapper.elementType.toString(),
|
|
||||||
element.fileSize,
|
|
||||||
element.fileName,
|
|
||||||
);
|
|
||||||
return {
|
return {
|
||||||
type: OB11MessageDataType.file,
|
type: OB11MessageDataType.file,
|
||||||
data: {
|
data: {
|
||||||
@@ -151,6 +138,7 @@ export class OneBotMsgApi {
|
|||||||
url: element.filePath,
|
url: element.filePath,
|
||||||
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
||||||
file_size: element.fileSize,
|
file_size: element.fileSize,
|
||||||
|
file_unique: element.fileName,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -182,20 +170,6 @@ export class OneBotMsgApi {
|
|||||||
},
|
},
|
||||||
|
|
||||||
marketFaceElement: async (_, msg, elementWrapper) => {
|
marketFaceElement: async (_, msg, elementWrapper) => {
|
||||||
await this.core.apis.FileApi.addFileCache(
|
|
||||||
{
|
|
||||||
peerUid: msg.peerUid,
|
|
||||||
chatType: msg.chatType,
|
|
||||||
guildId: '',
|
|
||||||
},
|
|
||||||
msg.msgId,
|
|
||||||
msg.msgSeq,
|
|
||||||
msg.senderUid,
|
|
||||||
elementWrapper.elementId,
|
|
||||||
elementWrapper.elementType.toString(),
|
|
||||||
'0',
|
|
||||||
'marketface',
|
|
||||||
);
|
|
||||||
const peer = {
|
const peer = {
|
||||||
chatType: msg.chatType,
|
chatType: msg.chatType,
|
||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
@@ -208,6 +182,7 @@ export class OneBotMsgApi {
|
|||||||
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
||||||
path: elementWrapper.elementId,
|
path: elementWrapper.elementId,
|
||||||
url: elementWrapper.elementId,
|
url: elementWrapper.elementId,
|
||||||
|
file_unique: _.key
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -283,21 +258,6 @@ export class OneBotMsgApi {
|
|||||||
videoDownUrl = element.filePath;
|
videoDownUrl = element.filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.core.apis.FileApi.addFileCache(
|
|
||||||
{
|
|
||||||
peerUid: msg.peerUid,
|
|
||||||
chatType: msg.chatType,
|
|
||||||
guildId: '',
|
|
||||||
},
|
|
||||||
msg.msgId,
|
|
||||||
msg.msgSeq,
|
|
||||||
msg.senderUid,
|
|
||||||
elementWrapper.elementId,
|
|
||||||
elementWrapper.elementType.toString(),
|
|
||||||
element.fileSize ?? '0',
|
|
||||||
element.fileName,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: OB11MessageDataType.video,
|
type: OB11MessageDataType.video,
|
||||||
data: {
|
data: {
|
||||||
@@ -306,6 +266,7 @@ export class OneBotMsgApi {
|
|||||||
url: videoDownUrl,
|
url: videoDownUrl,
|
||||||
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId),
|
||||||
file_size: element.fileSize,
|
file_size: element.fileSize,
|
||||||
|
file_unique: element.fileName,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -316,20 +277,6 @@ export class OneBotMsgApi {
|
|||||||
peerUid: msg.peerUid,
|
peerUid: msg.peerUid,
|
||||||
guildId: '',
|
guildId: '',
|
||||||
};
|
};
|
||||||
await this.core.apis.FileApi.addFileCache(
|
|
||||||
{
|
|
||||||
peerUid: msg.peerUid,
|
|
||||||
chatType: msg.chatType,
|
|
||||||
guildId: '',
|
|
||||||
},
|
|
||||||
msg.msgId,
|
|
||||||
msg.msgSeq,
|
|
||||||
msg.senderUid,
|
|
||||||
elementWrapper.elementId,
|
|
||||||
elementWrapper.elementType.toString(),
|
|
||||||
element.fileSize || '0',
|
|
||||||
element.fileUuid || '',
|
|
||||||
);
|
|
||||||
return {
|
return {
|
||||||
type: OB11MessageDataType.voice,
|
type: OB11MessageDataType.voice,
|
||||||
data: {
|
data: {
|
||||||
@@ -730,8 +677,10 @@ export class OneBotMsgApi {
|
|||||||
if (ret.result === 0) {
|
if (ret.result === 0) {
|
||||||
resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode);
|
resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode);
|
||||||
resMsg.sender.nickname = ret.tmpChatInfo!.fromNick;
|
resMsg.sender.nickname = ret.tmpChatInfo!.fromNick;
|
||||||
|
resMsg.temp_source = resMsg.group_id;
|
||||||
} else {
|
} else {
|
||||||
resMsg.group_id = 284840486; //兜底数据
|
resMsg.group_id = 284840486; //兜底数据
|
||||||
|
resMsg.temp_source = resMsg.group_id;
|
||||||
resMsg.sender.nickname = '临时会话';
|
resMsg.sender.nickname = '临时会话';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -66,10 +66,7 @@ export function encodeCQCode(data: OB11MessageData) {
|
|||||||
|
|
||||||
let result = '[CQ:' + data.type;
|
let result = '[CQ:' + data.type;
|
||||||
for (const name in data.data) {
|
for (const name in data.data) {
|
||||||
const value =
|
const value = (data.data as any)[name];
|
||||||
// eslint-disable-next-line
|
|
||||||
// @ts-ignore
|
|
||||||
data.data[name];
|
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -98,7 +98,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
if (ob11Config.http.enablePost) {
|
if (ob11Config.http.enablePost) {
|
||||||
ob11Config.http.postUrls.forEach(url => {
|
ob11Config.http.postUrls.forEach(url => {
|
||||||
this.networkManager.registerAdapter(new OB11ActiveHttpAdapter(
|
this.networkManager.registerAdapter(new OB11ActiveHttpAdapter(
|
||||||
url, ob11Config.token, this.core, this,
|
url, ob11Config.http.secret, this.core, this,
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
if (now.http.enablePost) {
|
if (now.http.enablePost) {
|
||||||
now.http.postUrls.forEach(url => {
|
now.http.postUrls.forEach(url => {
|
||||||
this.networkManager.registerAdapterAndOpen(new OB11ActiveHttpAdapter(
|
this.networkManager.registerAdapterAndOpen(new OB11ActiveHttpAdapter(
|
||||||
url, now.token, this.core, this,
|
url, now.http.secret, this.core, this,
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -182,7 +182,7 @@ export class NapCatOneBot11Adapter {
|
|||||||
);
|
);
|
||||||
for (const url of added) {
|
for (const url of added) {
|
||||||
await this.networkManager.registerAdapterAndOpen(new OB11ActiveHttpAdapter(
|
await this.networkManager.registerAdapterAndOpen(new OB11ActiveHttpAdapter(
|
||||||
url, now.token, this.core, this,
|
url, now.http.secret, this.core, this,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ export enum OB11MessageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface OB11Message {
|
export interface OB11Message {
|
||||||
|
temp_source?: number;
|
||||||
message_sent_type?: string;
|
message_sent_type?: string;
|
||||||
target_id?: number; // 自己发送的消息才有此字段
|
target_id?: number; // 自己发送的消息才有此字段
|
||||||
self_id?: number,
|
self_id?: number,
|
||||||
|
@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
|
|||||||
SettingItem(
|
SettingItem(
|
||||||
'<span id="napcat-update-title">Napcat</span>',
|
'<span id="napcat-update-title">Napcat</span>',
|
||||||
undefined,
|
undefined,
|
||||||
SettingButton('V2.3.0', 'napcat-update-button', 'secondary'),
|
SettingButton('V2.3.5', 'napcat-update-button', 'secondary'),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
|
|||||||
SettingItem(
|
SettingItem(
|
||||||
'<span id="napcat-update-title">Napcat</span>',
|
'<span id="napcat-update-title">Napcat</span>',
|
||||||
void 0,
|
void 0,
|
||||||
SettingButton("V2.3.0", "napcat-update-button", "secondary")
|
SettingButton("V2.3.5", "napcat-update-button", "secondary")
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
Reference in New Issue
Block a user