mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1070278eaf | ||
![]() |
16b1a6b153 | ||
![]() |
096a7534e0 | ||
![]() |
b0897187d2 | ||
![]() |
885d94882d | ||
![]() |
11a3341e13 | ||
![]() |
231890f78a |
@@ -1,12 +0,0 @@
|
||||
# v1.7.8
|
||||
|
||||
QQ Version: Windows 9.9.15-26702 / Linux 3.2.12-26702
|
||||
|
||||
## 启动的方式
|
||||
Way03/Way05
|
||||
|
||||
## 新增与调整
|
||||
1. 彻底支持发言时间与入群时间 For 26702
|
||||
2. 修复转发接口异常问题
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
21
docs/changelogs/CHANGELOG.v1.7.9.md
Normal file
21
docs/changelogs/CHANGELOG.v1.7.9.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# v1.8.0
|
||||
|
||||
QQ Version: Windows 9.9.15-26702 / Linux 3.2.12-26702
|
||||
|
||||
## 启动的方式
|
||||
Way03/Way05
|
||||
|
||||
## 新增与调整
|
||||
1. 消息ID映射到UINT32空间
|
||||
2. 回复ID验证与修复
|
||||
3. 新API /fetch_emoji_like
|
||||
|
||||
```json5
|
||||
{
|
||||
"message_id": 1557274996,//消息ID
|
||||
"emojiType": "1",//可以从event事件获取 一般为1或者2
|
||||
"emojiId": "76"//可以从event事件获取 一个表情对应一个ID
|
||||
}
|
||||
```
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
@@ -2,7 +2,7 @@
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "1.7.8",
|
||||
"version": "1.8.0",
|
||||
"scripts": {
|
||||
"watch:dev": "vite --mode development",
|
||||
"watch:prod": "vite --mode production",
|
||||
|
@@ -99,8 +99,10 @@ class MessageUniqueWrapper {
|
||||
}
|
||||
createMsg(peer: Peer, msgId: string): number | undefined {
|
||||
const key = `${msgId}|${peer.chatType}|${peer.peerUid}`;
|
||||
const hash = crypto.createHash('md5').update(key);
|
||||
const shortId = hash.digest().readInt32BE(0);
|
||||
const hash = crypto.createHash('md5').update(key).digest();
|
||||
//设置第一个bit为0 保证shortId为正数
|
||||
hash[0] &= 0x7f;
|
||||
const shortId = hash.readInt32BE(0);
|
||||
//减少性能损耗
|
||||
// const isExist = this.msgIdMap.getKey(shortId);
|
||||
// if (isExist && isExist === msgId) {
|
||||
|
@@ -67,6 +67,10 @@ setTimeout(() => {
|
||||
// }, 25000)
|
||||
|
||||
export class NTQQMsgApi {
|
||||
static async getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, count: number = 20) {
|
||||
//console.log(peer, msgSeq, emojiId, emojiType, count);
|
||||
return napCatCore.session.getMsgService().getMsgEmojiLikesList(peer, msgSeq, emojiId, emojiType, "", false, 20)
|
||||
}
|
||||
// static napCatCore: NapCatCore | null = null;
|
||||
// enum BaseEmojiType {
|
||||
// NORMAL_EMOJI,
|
||||
|
@@ -477,7 +477,19 @@ export interface NodeIKernelMsgService {
|
||||
|
||||
setMsgEmojiLikes(...args: unknown[]): unknown;
|
||||
|
||||
getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, cookie: string, bForward: boolean, number: number): Promise<unknown>;
|
||||
getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, cookie: string, bForward: boolean, number: number): Promise<{
|
||||
result: number,
|
||||
errMsg: string,
|
||||
emojiLikesList:
|
||||
Array<{
|
||||
tinyId: string,
|
||||
nickName: string,
|
||||
headUrl: string
|
||||
}>,
|
||||
cookie: string,
|
||||
isLastPage: boolean,
|
||||
isFirstPage: boolean
|
||||
}>;
|
||||
|
||||
setMsgEmojiLikesForRole(...args: unknown[]): unknown;
|
||||
|
||||
@@ -592,7 +604,7 @@ export interface NodeIKernelMsgService {
|
||||
// this.selfPhone = str5;
|
||||
// this.gameSession = tempChatGameSession;
|
||||
prepareTempChat(args: unknown): unknown;//主动临时消息 不做
|
||||
|
||||
|
||||
sendSsoCmdReqByContend(cmd: string, param: string): Promise<unknown>;
|
||||
|
||||
//chattype,uid->Promise<any>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Peer } from "../entities";
|
||||
import { ChatType, Peer } from "../entities";
|
||||
import { NodeIKernelRecentContactListener } from "../listeners/NodeIKernelRecentContactListener";
|
||||
import { GeneralCallResult } from "./common";
|
||||
export interface FSABRecentContactParams {
|
||||
@@ -39,7 +39,13 @@ export interface NodeIKernelRecentContactService {
|
||||
errCode: number,
|
||||
errMsg: string,
|
||||
sortedContactList: Array<number>,
|
||||
changedList: Array<any>
|
||||
changedList: Array<{
|
||||
remark: any;
|
||||
peerName: any;
|
||||
sendMemberName: any;
|
||||
sendNickName: any;
|
||||
peerUid: string; peerUin: string, msgTime: string, chatType: ChatType, msgId: string
|
||||
}>
|
||||
}
|
||||
}>; // 1 arguments
|
||||
|
||||
|
32
src/onebot11/action/extends/FetchEmojioLike.ts
Normal file
32
src/onebot11/action/extends/FetchEmojioLike.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
//getMsgEmojiLikesList
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { NTQQMsgApi } from '@/core/apis';
|
||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
user_id: { type: 'string' },
|
||||
group_id: { type: 'string' },
|
||||
emojiId: { type: 'string' },
|
||||
emojiType: { type: 'string' },
|
||||
message_id: { type: ['string', 'number'] },
|
||||
count: { type: 'number' }
|
||||
},
|
||||
required: ['emojiId', 'emojiType', 'message_id']
|
||||
} as const satisfies JSONSchema;
|
||||
|
||||
type Payload = FromSchema<typeof SchemaData>;
|
||||
|
||||
export class FetchEmojioLike extends BaseAction<Payload, any> {
|
||||
actionName = ActionName.FetchEmojioLike;
|
||||
PayloadSchema = SchemaData;
|
||||
protected async _handle(payload: Payload) {
|
||||
let msgIdPeer = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
|
||||
if(!msgIdPeer) throw new Error('消息不存在');
|
||||
let msg = (await NTQQMsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0];
|
||||
const ret = await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer,msg.msgSeq,payload.emojiId,payload.emojiType,payload.count);
|
||||
return ret;
|
||||
}
|
||||
}
|
@@ -78,8 +78,10 @@ import SetGroupHeader from './extends/SetGroupHeader';
|
||||
import { FetchCustomFace } from './extends/FetchCustomFace';
|
||||
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivareFile';
|
||||
import TestApi01 from './extends/TestApi01';
|
||||
import { FetchEmojioLike } from './extends/FetchEmojioLike';
|
||||
|
||||
export const actionHandlers = [
|
||||
new FetchEmojioLike(),
|
||||
new RebootNormal(),
|
||||
new GetFile(),
|
||||
new Debug(),
|
||||
|
@@ -102,5 +102,6 @@ export enum ActionName {
|
||||
SetGroupHeader = 'set_group_head',
|
||||
FetchCustomFace = 'fetch_custom_face',
|
||||
GOCQHTTP_UploadPrivateFile = 'upload_private_file',
|
||||
TestApi01 = 'test_api_01'
|
||||
TestApi01 = 'test_api_01',
|
||||
FetchEmojioLike = "fetch_emoji_like"
|
||||
}
|
||||
|
@@ -1,12 +1,52 @@
|
||||
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { NTQQUserApi } from '@/core';
|
||||
import { NTQQMsgApi, NTQQUserApi } from '@/core';
|
||||
import { OB11Constructor } from '@/onebot11/constructor';
|
||||
|
||||
export default class GetRecentContact extends BaseAction<void, any> {
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
count: { type: ['number', 'string'] }
|
||||
}
|
||||
} as const satisfies JSONSchema;
|
||||
|
||||
type Payload = FromSchema<typeof SchemaData>;
|
||||
|
||||
export default class GetRecentContact extends BaseAction<Payload, any> {
|
||||
actionName = ActionName.GetRecentContact;
|
||||
protected async _handle(payload: void) {
|
||||
//没有效果
|
||||
return await NTQQUserApi.getRecentContactListSnapShot(10);
|
||||
PayloadSchema = SchemaData;
|
||||
protected async _handle(payload: Payload) {
|
||||
let ret = await NTQQUserApi.getRecentContactListSnapShot(parseInt((payload.count || 10).toString()));
|
||||
let data = await Promise.all(ret.info.changedList.map(async (t) => {
|
||||
let FastMsg = await NTQQMsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]);
|
||||
if (FastMsg.msgList.length > 0) {
|
||||
//扩展ret.info.changedList
|
||||
let lastestMsg = await OB11Constructor.message(FastMsg.msgList[0]);
|
||||
return {
|
||||
lastestMsg: lastestMsg,
|
||||
peerUin: t.peerUin,
|
||||
remark: t.remark,
|
||||
msgTime: t.msgTime,
|
||||
chatType: t.chatType,
|
||||
msgId: t.msgId,
|
||||
sendNickName: t.sendNickName,
|
||||
sendMemberName: t.sendMemberName,
|
||||
peerName: t.peerName
|
||||
};
|
||||
}
|
||||
return {
|
||||
peerUin: t.peerUin,
|
||||
remark: t.remark,
|
||||
msgTime: t.msgTime,
|
||||
chatType: t.chatType,
|
||||
msgId: t.msgId,
|
||||
sendNickName: t.sendNickName,
|
||||
sendMemberName: t.sendMemberName,
|
||||
peerName: t.peerName
|
||||
};
|
||||
}));
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@@ -153,21 +153,20 @@ export class OB11Constructor {
|
||||
message_data['type'] = OB11MessageDataType.reply;
|
||||
//log("收到回复消息", element.replyElement);
|
||||
try {
|
||||
//做这么多都是因为NC速度太快 可能nt还没有写入数据库
|
||||
//const records = msg.records.find(msgRecord => msgRecord.msgId === element.replyElement.sourceMsgIdInRecords);
|
||||
const records = msg.records.find(msgRecord => msgRecord.msgId === element.replyElement.sourceMsgIdInRecords);
|
||||
const peer = {
|
||||
chatType: msg.chatType,
|
||||
peerUid: msg.peerUid,
|
||||
guildId: '',
|
||||
};
|
||||
let replyMsg: RawMessage | undefined;
|
||||
|
||||
if (!records) throw new Error('找不到回复消息');
|
||||
replyMsg = (await NTQQMsgApi.getMsgsBySeqAndCount({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, element.replyElement.replayMsgSeq, 1, true, true)).msgList[0];
|
||||
if (!replyMsg || element.replyElement.replayMsgSeq !== replyMsg.msgSeq) {
|
||||
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
|
||||
replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replyElement.replayMsgSeq)).msgList[0];
|
||||
}
|
||||
|
||||
if (!replyMsg || element.replyElement.replayMsgSeq !== replyMsg.msgSeq) {
|
||||
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
|
||||
throw new Error('回复消息消息验证失败');
|
||||
}
|
||||
message_data['data']['id'] = MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType }, replyMsg.msgId)?.toString();
|
||||
@@ -459,6 +458,7 @@ export class OB11Constructor {
|
||||
});
|
||||
}
|
||||
if (grayTipElement) {
|
||||
//console.log('收到群提示消息', grayTipElement);
|
||||
if (grayTipElement.xmlElement?.templId === '10382') {
|
||||
const emojiLikeData = new fastXmlParser.XMLParser({
|
||||
ignoreAttributes: false,
|
||||
|
@@ -98,6 +98,8 @@ export class NapCatOnebot11 {
|
||||
// .map(x => x.toString(16).padStart(2, '0'))
|
||||
// .join('');
|
||||
// }
|
||||
// const hex = buf2hex(Buffer.from(protobufData));
|
||||
// console.log(hex);
|
||||
// // let Data: Data = {
|
||||
// // header: {
|
||||
// // GroupNumber: 0,
|
||||
@@ -192,6 +194,7 @@ export class NapCatOnebot11 {
|
||||
// // 732 17 GroupRecall
|
||||
// // 732 20 GroupCommonTips
|
||||
// // 732 21 EssenceMessage
|
||||
// // 732 16 16 GrayTips ->Busi->GroupEmjioLike
|
||||
// } catch (e) {
|
||||
// log('解析SysMsg异常', e);
|
||||
// // console.log(e);
|
||||
@@ -209,7 +212,7 @@ export class NapCatOnebot11 {
|
||||
// 临时会话更新 tempGroupCodeMap uid -> source/GroupCode
|
||||
};
|
||||
msgListener.onRecvMsg = async (msg) => {
|
||||
|
||||
|
||||
//console.log('ob11 onRecvMsg', JSON.stringify(msg, null, 2));
|
||||
// logDebug('收到消息', msg);
|
||||
for (const m of msg) {
|
||||
@@ -291,7 +294,7 @@ export class NapCatOnebot11 {
|
||||
}
|
||||
};
|
||||
groupListener.onMemberInfoChange = async (groupCode: string, changeType: number, members: Map<string, GroupMember>) => {
|
||||
// console.log("ob11 onMemberInfoChange", groupCode, changeType, members)
|
||||
// console.log("ob11 onMemberInfoChange", groupCode, changeType, members)
|
||||
if (changeType === 1) {
|
||||
let member;
|
||||
for (const [key, value] of members) {
|
||||
|
@@ -1 +1 @@
|
||||
export const version = '1.7.8';
|
||||
export const version = '1.8.0';
|
||||
|
@@ -29,7 +29,7 @@ async function onSettingWindowCreated(view: Element) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
undefined,
|
||||
SettingButton('V1.7.8', 'napcat-update-button', 'secondary')
|
||||
SettingButton('V1.8.0', 'napcat-update-button', 'secondary')
|
||||
),
|
||||
]),
|
||||
SettingList([
|
||||
|
@@ -163,7 +163,7 @@ async function onSettingWindowCreated(view) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
void 0,
|
||||
SettingButton("V1.7.8", "napcat-update-button", "secondary")
|
||||
SettingButton("V1.8.0", "napcat-update-button", "secondary")
|
||||
)
|
||||
]),
|
||||
SettingList([
|
||||
|
Reference in New Issue
Block a user