Merge branch 'main' into upmain

This commit is contained in:
Alen 2024-10-23 01:08:56 +08:00
commit 0081000ef0
15 changed files with 100 additions and 79 deletions

View File

@ -4,7 +4,7 @@
"name": "NapCatQQ",
"slug": "NapCat.Framework",
"description": "高性能的 OneBot 11 协议实现",
"version": "3.1.0",
"version": "3.1.3",
"icon": "./logo.png",
"authors": [
{

View File

@ -2,7 +2,7 @@
"name": "napcat",
"private": true,
"type": "module",
"version": "3.1.0",
"version": "3.1.3",
"scripts": {
"build:framework": "vite build --mode framework",
"build:shell": "vite build --mode shell",
@ -37,7 +37,7 @@
"commander": "^12.1.0",
"async-mutex": "^0.5.0",
"file-type": "^19.0.0",
"json-schema-to-ts": "^3.1.0",
"json-schema-to-ts": "^3.1.1",
"image-size": "^1.1.1",
"cors": "^2.8.5"
},

View File

@ -1 +1 @@
export const napCatVersion = '3.1.0';
export const napCatVersion = '3.1.3';

View File

@ -30,7 +30,7 @@ export class NTQQFileApi {
context: InstanceContext;
core: NapCatCore;
rkeyManager: RkeyManager;
packetRkey: Array<{ rkey: string; time: number; type: number; }> | undefined;
packetRkey: Array<{ rkey: string; time: number; type: number; ttl: bigint }> | undefined;
constructor(context: InstanceContext, core: NapCatCore) {
this.context = context;
@ -378,10 +378,12 @@ export class NTQQFileApi {
};
try {
if (this.core.apis.PacketApi.available) {
if ((!this.packetRkey || this.packetRkey[0].time > Date.now() / 1000)) {
let rkey_expired_private = !this.packetRkey || this.packetRkey[0].time + Number(this.packetRkey[0].ttl) < Date.now() / 1000;
let rkey_expired_group = !this.packetRkey || this.packetRkey[0].time + Number(this.packetRkey[0].ttl) < Date.now() / 1000;
if (rkey_expired_private || rkey_expired_group) {
this.packetRkey = await this.core.apis.PacketApi.sendRkeyPacket();
}
if (this.packetRkey.length > 0) {
if (this.packetRkey && this.packetRkey.length > 0) {
rkeyData.group_rkey = this.packetRkey[1].rkey.slice(6);
rkeyData.private_rkey = this.packetRkey[0].rkey.slice(6);
rkeyData.online_rkey = true;

View File

@ -338,4 +338,12 @@ export class NTQQWebApi {
}
return (hash & 0x7FFFFFFF).toString();
}
public getBknFromSKey(sKey: string) {
let hash = 5381;
for (let i = 0; i < sKey.length; i++) {
const code = sKey.charCodeAt(i);
hash = hash + (hash << 5) + code;
}
return (hash & 0x7FFFFFFF).toString();
}
}

View File

@ -14,6 +14,7 @@ export const OidbSvcTrpcTcp0X9067_202Key = {
//Rsp
export const OidbSvcTrpcTcp0X9067_202_RkeyList = {
rkey: ProtoField(1, ScalarType.STRING),
ttl: ProtoField(2, ScalarType.UINT64),
time: ProtoField(4, ScalarType.UINT32),
type: ProtoField(5, ScalarType.UINT32),

View File

@ -1,3 +1,4 @@
import { GroupNotifyMsgStatus } from '@/core';
import BaseAction from '../BaseAction';
import { ActionName } from '../types';
@ -11,18 +12,22 @@ export default class GetGroupAddRequest extends BaseAction<null, OB11GroupReques
actionName = ActionName.GetGroupIgnoreAddRequest;
async _handle(payload: null): Promise<OB11GroupRequestNotify[] | null> {
// const data = await this.core.apis.GroupApi.getGroupIgnoreNotifies();
// log(data);
// const notifies: GroupNotify[] = data.notifies.filter(notify => notify.status === GroupNotifyStatus.WAIT_HANDLE);
// const returnData: OB11GroupRequestNotify[] = [];
// for (const notify of notifies) {
// const uin = || (await NTQQUserApi.getUserDetailInfo(notify.user1.uid))?.uin;
// returnData.push({
// group_id: parseInt(notify.group.groupCode),
// user_id: parseInt(uin),
// flag: notify.seq
// });
// }
return null;
const ignoredNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(true, 10);
const retData: any = {
join_requests: await Promise.all(
ignoredNotifies
.filter(notify => notify.type === 7)
.map(async SSNotify => ({
request_id: SSNotify.seq,
requester_uin: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1?.uid),
requester_nick: SSNotify.user1?.nickName,
group_id: SSNotify.group?.groupCode,
group_name: SSNotify.group?.groupName,
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
actor: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
}))),
};
return retData;
}
}

View File

@ -5,9 +5,9 @@ import { ActionName } from '../types';
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { OB11MessageImage, OB11MessageVideo } from '@/onebot/types';
export interface GetFilePayload {
file: string; // 文件名或者fileUuid
}
// interface GetFilePayload {
// file: string; // 文件名或者fileUuid
// }
export interface GetFileResponse {
file?: string; // path
@ -16,19 +16,25 @@ export interface GetFileResponse {
file_name?: string;
base64?: string;
}
const GetFileBase_PayloadSchema = {
type: 'object',
properties: {
file: { type: 'string' },
file_id: { type: 'string' }
},
required: ['file'],
oneOf: [
{ required: ['file'] },
{ required: ['file_id'] }
]
} as const satisfies JSONSchema;
export type GetFilePayload = FromSchema<typeof GetFileBase_PayloadSchema>;
export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
payloadSchema: any = GetFileBase_PayloadSchema;
payloadSchema = GetFileBase_PayloadSchema;
async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
payload.file ||= payload.file_id || '';
//接收消息标记模式
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file);
if (contextMsgFile) {
@ -115,27 +121,6 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
}
}
const GetFile_PayloadSchema = {
type: 'object',
properties: {
file_id: { type: 'string' },
file: { type: 'string' },
},
required: ['file_id'],
} as const satisfies JSONSchema;
type GetFile_Payload_Internal = FromSchema<typeof GetFile_PayloadSchema>;
interface GetFile_Payload extends GetFile_Payload_Internal {
file: string;
}
export default class GetFile extends GetFileBase {
actionName = ActionName.GetFile;
payloadSchema = GetFile_PayloadSchema;
async _handle(payload: GetFile_Payload): Promise<GetFileResponse> {
payload.file = payload.file_id;
return super._handle(payload);
}
}

View File

@ -92,6 +92,7 @@ import { GetGroupMemberList } from './group/GetGroupMemberList';
import { GetGroupFileUrl } from "@/onebot/action/file/GetGroupFileUrl";
import { GetPacketStatus } from "@/onebot/action/packet/GetPacketStatus";
import { FriendPoke } from "@/onebot/action/user/FriendPoke";
import { GetCredentials } from './system/GetCredentials';
export type ActionMap = Map<string, BaseAction<any, any>>;
@ -180,6 +181,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo
new SetModelShow(obContext, core),
new SetInputStatus(obContext, core),
new GetCSRF(obContext, core),
new GetCredentials(obContext, core),
new DelGroupNotice(obContext, core),
new DeleteGroupFile(obContext, core),
new CreateGroupFileFolder(obContext, core),

View File

@ -1,7 +1,7 @@
import { ChatType, Peer } from '@/core/entities';
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import BaseAction from '../BaseAction';
import { ActionName } from '../types';
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
const SchemaData = {
type: 'object',
@ -49,23 +49,14 @@ export class MarkGroupMsgAsRead extends MarkMsgAsRead {
actionName = ActionName.MarkGroupMsgAsRead;
}
interface Payload {
message_id: number;
}
export class GoCQHTTPMarkMsgAsRead extends BaseAction<Payload, null> {
export class GoCQHTTPMarkMsgAsRead extends MarkMsgAsRead {
actionName = ActionName.GoCQHTTP_MarkMsgAsRead;
async _handle(payload: Payload): Promise<null> {
return null;
}
}
export class MarkAllMsgAsRead extends BaseAction<Payload, null> {
export class MarkAllMsgAsRead extends BaseAction<any, null> {
actionName = ActionName._MarkAllMsgAsRead;
async _handle(payload: Payload): Promise<null> {
async _handle(): Promise<null> {
await this.core.apis.MsgApi.markAllMsgAsRead();
return null;
}

View File

@ -5,8 +5,12 @@ export class GetCSRF extends BaseAction<any, any> {
actionName = ActionName.GetCSRF;
async _handle(payload: any) {
const sKey = await this.core.apis.UserApi.getSKey();
if (!sKey) {
throw new Error('SKey is undefined');
}
return {
token: '',
token: +this.core.apis.WebApi.getBknFromSKey(sKey),
};
}
}

View File

@ -0,0 +1,31 @@
import BaseAction from '../BaseAction';
import { ActionName } from '../types';
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
interface Response {
cookies: string,
token: number
}
const SchemaData = {
type: 'object',
properties: {
domain: { type: 'string' },
},
required: ['domain'],
} as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>;
export class GetCredentials extends BaseAction<Payload, Response> {
actionName = ActionName.GetCredentials;
payloadSchema = SchemaData;
async _handle(payload: Payload) {
const cookiesObject = await this.core.apis.UserApi.getCookies(payload.domain);
//把获取到的cookiesObject转换成 k=v; 格式字符串拼接在一起
const cookies = Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const bkn = cookiesObject?.skey ? this.core.apis.WebApi.getBknFromCookie(cookiesObject) : '';
return { cookies: cookies, token: +bkn };
}
}

View File

@ -43,8 +43,8 @@ export enum ActionName {
GetGroupMemberList = 'get_group_member_list',
GetGroupHonorInfo = 'get_group_honor_info',
GetCookies = 'get_cookies',
// GetCSRF = 'get_csrf_token',
// GetCredentials = 'get_credentials',
GetCSRF = 'get_csrf_token',
GetCredentials = 'get_credentials',
GetRecord = 'get_record',
GetImage = 'get_image',
CanSendImage = 'can_send_image',
@ -59,7 +59,7 @@ export enum ActionName {
// QidianGetAccountInfo = 'qidian_get_account_info',
// GetModelShow = '_get_model_show',
// SetModelShow = '_set_model_show',
// GetOnlineClient = 'get_online_clients',
GetOnlineClient = 'get_online_clients',
// GetUnidirectionalFriendList = 'get_unidirectional_friend_list',
// DeleteFriend = 'delete_friend',
// DeleteUnidirectionalFriendList = 'delete_unidirectional_friend',
@ -105,11 +105,6 @@ export enum ActionName {
ForwardFriendSingleMsg = 'forward_friend_single_msg',
ForwardGroupSingleMsg = 'forward_group_single_msg',
TranslateEnWordToZn = 'translate_en2zh',
GetGroupFileCount = 'get_group_file_count',
GetGroupFileList = 'get_group_file_list',
SetGroupFileFolder = 'set_group_file_folder',
DelGroupFile = 'del_group_file',
DelGroupFileFolder = 'del_group_file_folder',
SetMsgEmojiLike = 'set_msg_emoji_like',
GoCQHTTP_SendForwardMsg = 'send_forward_msg',
MarkPrivateMsgAsRead = 'mark_private_msg_as_read',
@ -125,7 +120,7 @@ export enum ActionName {
FetchEmojiLike = 'fetch_emoji_like',
SetInputStatus = 'set_input_status',
GetGroupInfoEx = 'get_group_info_ex',
GetGroupIgnoredNotifies = 'get_group_ignored_notifies',
GetGroupIgnoreAddRequest = 'get_group_ignore_add_request',
DelGroupNotice = '_del_group_notice',
FetchUserProfileLike = 'fetch_user_profile_like',
FriendPoke = 'friend_poke',
@ -135,12 +130,9 @@ export enum ActionName {
GetRkey = 'nc_get_rkey',
GetGroupShutList = 'get_group_shut_list',
// GetGroupIgnoreAddRequest = 'get_group_ignore_add_request',
// GetConfig = 'get_config',
// SetConfig = 'set_config',
// Debug = 'debug',
// GetGuildList = 'get_guild_list',
// TestApi01 = 'test_api_01',
// GetGuildProfile = 'get_guild_service_profile',
GetGuildList = 'get_guild_list',
GetGuildProfile = 'get_guild_service_profile',
GetGroupIgnoredNotifies = 'get_group_ignored_notifies',
// UploadForwardMsg = "upload_forward_msg",
}

View File

@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
SettingItem(
'<span id="napcat-update-title">Napcat</span>',
undefined,
SettingButton('V3.1.0', 'napcat-update-button', 'secondary'),
SettingButton('V3.1.3', 'napcat-update-button', 'secondary'),
),
]),
SettingList([

View File

@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
SettingItem(
'<span id="napcat-update-title">Napcat</span>',
void 0,
SettingButton("V3.1.0", "napcat-update-button", "secondary")
SettingButton("V3.1.3", "napcat-update-button", "secondary")
)
]),
SettingList([