Compare commits

..

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
e431471c4c Revert formatting-only changes, keep only bug fixes
Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-10-02 01:48:08 +00:00
copilot-swe-agent[bot]
e6c694c2b7 Fix group file API fileUUID handling to fallback to fileId
Co-authored-by: sj817 <74231782+sj817@users.noreply.github.com>
2025-10-02 01:30:39 +00:00
copilot-swe-agent[bot]
65bd37fdb5 Initial plan 2025-10-02 01:22:48 +00:00
27 changed files with 34 additions and 168 deletions

View File

@@ -7,7 +7,7 @@ set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe
set NAPCAT_MAIN_PATH=%cd%\napcat.mjs
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%~b"
set RetString=%%b
goto :napcat_boot
)
@@ -16,7 +16,7 @@ for %%a in ("%RetString%") do (
set "pathWithoutUninstall=%%~dpa"
)
set "QQPath=%pathWithoutUninstall%QQ.exe"
SET QQPath=%pathWithoutUninstall%QQ.exe
if not exist "%QQpath%" (
echo provided QQ path is invalid

View File

@@ -7,7 +7,7 @@ set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe
set NAPCAT_MAIN_PATH=%cd%\napcat.mjs
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%~b"
set RetString=%%b
goto :napcat_boot
)
@@ -16,7 +16,7 @@ for %%a in ("%RetString%") do (
set "pathWithoutUninstall=%%~dpa"
)
set "QQPath=%pathWithoutUninstall%QQ.exe"
SET QQPath=%pathWithoutUninstall%QQ.exe
if not exist "%QQpath%" (
echo provided QQ path is invalid

View File

@@ -16,7 +16,7 @@ set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe
set NAPCAT_MAIN_PATH=%cd%\napcat.mjs
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%~b"
set RetString=%%b
goto :napcat_boot
)
@@ -25,7 +25,7 @@ for %%a in ("%RetString%") do (
set "pathWithoutUninstall=%%~dpa"
)
set "QQPath=%pathWithoutUninstall%QQ.exe"
SET QQPath=%pathWithoutUninstall%QQ.exe
if not exist "%QQPath%" (
echo provided QQ path is invalid

View File

@@ -16,7 +16,7 @@ set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe
set NAPCAT_MAIN_PATH=%cd%\napcat.mjs
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%~b"
set RetString=%%b
goto :napcat_boot
)
@@ -25,7 +25,7 @@ for %%a in ("%RetString%") do (
set "pathWithoutUninstall=%%~dpa"
)
set "QQPath=%pathWithoutUninstall%QQ.exe"
SET QQPath=%pathWithoutUninstall%QQ.exe
if not exist "%QQPath%" (
echo provided QQ path is invalid

View File

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

View File

@@ -93,7 +93,6 @@
"@types/node": "^22.12.0",
"@types/path-browserify": "^1.0.3",
"@types/react": "^19.0.8",
"@types/react-color": "^3.0.13",
"@types/react-dom": "^19.0.3",
"@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "^8.22.0",
@@ -8153,19 +8152,6 @@
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-color": {
"version": "3.0.13",
"resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.13.tgz",
"integrity": "sha512-2c/9FZ4ixC5T3JzN0LP5Cke2Mf0MKOP2Eh0NPDPWmuVH3NjPyhEjqNMQpN1Phr5m74egAy+p2lYNAFrX1z9Yrg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/reactcss": "*"
},
"peerDependencies": {
"@types/react": "*"
}
},
"node_modules/@types/react-dom": {
"version": "19.1.6",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz",
@@ -8186,16 +8172,6 @@
"@types/react": "*"
}
},
"node_modules/@types/reactcss": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.13.tgz",
"integrity": "sha512-gi3S+aUi6kpkF5vdhUsnkwbiSEIU/BEJyD7kBy2SudWBUuKmJk8AQKE0OVcQQeEy40Azh0lV6uynxlikYIJuwg==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"@types/react": "*"
}
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",

View File

@@ -95,7 +95,6 @@
"@types/node": "^22.12.0",
"@types/path-browserify": "^1.0.3",
"@types/react": "^19.0.8",
"@types/react-color": "^3.0.13",
"@types/react-dom": "^19.0.3",
"@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "^8.22.0",

View File

@@ -82,7 +82,6 @@ export default function FileTable({
setPreviewImages([])
setPreviewIndex(0)
setShowImage(false)
setPage(1)
}, [currentPath])
const onPreviewImage = (name: string, images: PreviewImage[]) => {

View File

@@ -171,8 +171,7 @@ const GenericForm = <T extends keyof NetworkConfigType>({
export default GenericForm
export function random_token(length: number) {
const chars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%^&*()-_=+[]{}|;:,.<>?'
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%^&*()-_=+[]{}|;:,.<>?'
let result = ''
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length))

View File

@@ -1,10 +1,9 @@
import CryptoJS from 'crypto-js'
import { EventSourcePolyfill } from 'event-source-polyfill'
import { LogLevel } from '@/const/enum'
import { serverRequest } from '@/utils/request'
import CryptoJS from "crypto-js";
export interface Log {
level: LogLevel
message: string
@@ -18,7 +17,7 @@ export default class WebUIManager {
}
public static async loginWithToken(token: string) {
const sha256 = CryptoJS.SHA256(token + '.napcat').toString()
const sha256 = CryptoJS.SHA256(token + '.napcat').toString();
const { data } = await serverRequest.post<ServerResponse<AuthResponse>>(
'/auth/login',
{ hash: sha256 }
@@ -197,13 +196,4 @@ export default class WebUIManager {
)
return data.data
}
// 清理缓存
public static async cleanCache() {
const { data } =
await serverRequest.post<
ServerResponse<{ result: boolean; message: string }>
>('/base/CleanCache')
return data.data
}
}

View File

@@ -1,22 +1,16 @@
import { Button } from '@heroui/button'
import { Input } from '@heroui/input'
import { Switch } from '@heroui/switch'
import { useRequest } from 'ahooks'
import { useEffect, useState } from 'react'
import { useEffect } from 'react'
import { Controller, useForm } from 'react-hook-form'
import toast from 'react-hot-toast'
import { MdDeleteSweep } from 'react-icons/md'
import SaveButtons from '@/components/button/save_buttons'
import PageLoading from '@/components/page_loading'
import useDialog from '@/hooks/use-dialog'
import WebUIManager from '@/controllers/webui_manager'
const ServerConfigCard = () => {
const dialog = useDialog()
const [isCleaningCache, setIsCleaningCache] = useState(false)
const {
data: configData,
loading: configLoading,
@@ -75,42 +69,6 @@ const ServerConfigCard = () => {
}
}
const handleCleanCache = () => {
dialog.confirm({
title: '清理缓存',
content: (
<div className="space-y-2">
<p></p>
<ul className="list-disc list-inside text-sm text-default-600">
<li></li>
<li> (Pic)</li>
<li> (Ptt)</li>
<li> (Video)</li>
<li> (File)</li>
<li> (log)</li>
</ul>
<p className="text-warning text-sm"></p>
</div>
),
onConfirm: async () => {
setIsCleaningCache(true)
try {
const result = await WebUIManager.cleanCache()
if (result.result) {
toast.success(result.message || '缓存清理成功')
} else {
toast.error(result.message || '缓存清理失败')
}
} catch (error) {
const msg = (error as Error).message
toast.error(`清理缓存失败: ${msg}`)
} finally {
setIsCleaningCache(false)
}
}
})
}
useEffect(() => {
reset()
}, [configData])
@@ -173,30 +131,6 @@ const ServerConfigCard = () => {
/>
</div>
<div className="flex flex-col gap-2">
<div className="flex-shrink-0 w-full"></div>
<div className="flex flex-col gap-2 p-4 rounded-lg bg-default-50">
<div className="flex items-start justify-between gap-2">
<div className="flex-1">
<div className="font-medium"></div>
<div className="text-sm text-default-500">
</div>
</div>
<Button
color="danger"
variant="flat"
startContent={<MdDeleteSweep size={20} />}
onPress={handleCleanCache}
isLoading={isCleaningCache}
isDisabled={!!configError}
>
</Button>
</div>
</div>
</div>
<div className="flex flex-col gap-2">
<div className="flex-shrink-0 w-full"></div>
<Controller
@@ -248,4 +182,4 @@ const ServerConfigCard = () => {
)
}
export default ServerConfigCard
export default ServerConfigCard

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "napcat",
"version": "4.8.119",
"version": "4.8.98",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "napcat",
"version": "4.8.119",
"version": "4.8.98",
"dependencies": {
"express": "^5.0.0",
"silk-wasm": "^3.6.1",

View File

@@ -2,7 +2,7 @@
"name": "napcat",
"private": true,
"type": "module",
"version": "4.8.119",
"version": "4.8.116",
"scripts": {
"build:universal": "npm run build:webui && vite build --mode universal || exit 1",
"build:framework": "npm run build:webui && vite build --mode framework || exit 1",

View File

@@ -1 +1 @@
export const napCatVersion = '4.8.119';
export const napCatVersion = '4.8.116';

View File

@@ -386,9 +386,5 @@
"9.9.21-39038": {
"appid": 537313906,
"qua": "V1_WIN_NQ_9.9.21_39038_GW_B"
},
"9.9.22-40362": {
"appid": 537314212,
"qua": "V1_WIN_NQ_9.9.22_40362_GW_B"
}
}

View File

@@ -507,12 +507,8 @@
"send": "7B025C8",
"recv": "7B05F58"
},
"9.9.21-39038-x64": {
"9.9.21-39038-x64": {
"send": "313FB58",
"recv": "31432FC"
},
"9.9.22-40362-x64": {
"send": "31C0EB8",
"recv": "31C465C"
}
}

View File

@@ -22,8 +22,9 @@ export class MoveGroupFile extends GetPacketStatusDepends<Payload, MoveGroupFile
async _handle(payload: Payload) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);
if (contextMsgFile?.fileUUID) {
await this.core.apis.PacketApi.pkt.operation.MoveGroupFile(+payload.group_id, contextMsgFile.fileUUID, payload.current_parent_directory, payload.target_parent_directory);
const fileUUID = contextMsgFile?.fileUUID || contextMsgFile?.fileId;
if (fileUUID) {
await this.core.apis.PacketApi.pkt.operation.MoveGroupFile(+payload.group_id, fileUUID, payload.current_parent_directory, payload.target_parent_directory);
return {
ok: true,
};

View File

@@ -22,8 +22,9 @@ export class RenameGroupFile extends GetPacketStatusDepends<Payload, RenameGroup
async _handle(payload: Payload) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);
if (contextMsgFile?.fileUUID) {
await this.core.apis.PacketApi.pkt.operation.RenameGroupFile(+payload.group_id, contextMsgFile.fileUUID, payload.current_parent_directory, payload.new_name);
const fileUUID = contextMsgFile?.fileUUID || contextMsgFile?.fileId;
if (fileUUID) {
await this.core.apis.PacketApi.pkt.operation.RenameGroupFile(+payload.group_id, fileUUID, payload.current_parent_directory, payload.new_name);
return {
ok: true,
};

View File

@@ -20,8 +20,9 @@ export class TransGroupFile extends GetPacketStatusDepends<Payload, TransGroupFi
async _handle(payload: Payload) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);
if (contextMsgFile?.fileUUID) {
const result = await this.core.apis.GroupApi.transGroupFile(payload.group_id.toString(), contextMsgFile.fileUUID);
const fileUUID = contextMsgFile?.fileUUID || contextMsgFile?.fileId;
if (fileUUID) {
const result = await this.core.apis.GroupApi.transGroupFile(payload.group_id.toString(), fileUUID);
if (result.transGroupFileResult.result.retCode === 0) {
return {
ok: true

View File

@@ -20,9 +20,10 @@ export class GetGroupFileUrl extends GetPacketStatusDepends<Payload, GetGroupFil
async _handle(payload: Payload) {
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);
if (contextMsgFile?.fileUUID) {
const fileUUID = contextMsgFile?.fileUUID || contextMsgFile?.fileId;
if (fileUUID) {
return {
url: await this.core.apis.PacketApi.pkt.operation.GetGroupFileUrl(+payload.group_id, contextMsgFile.fileUUID)
url: await this.core.apis.PacketApi.pkt.operation.GetGroupFileUrl(+payload.group_id, fileUUID)
};
}
throw new Error('real fileUUID not found!');

View File

@@ -16,7 +16,7 @@ export class DeleteGroupFile extends OneBotAction<Payload, Awaited<ReturnType<NT
override actionName = ActionName.GOCQHTTP_DeleteGroupFile;
override payloadSchema = SchemaData;
async _handle(payload: Payload) {
const data = FileNapCatOneBotUUID.decodeModelId(payload.file_id);
const data = FileNapCatOneBotUUID.decode(payload.file_id) || FileNapCatOneBotUUID.decodeModelId(payload.file_id);
if (!data || !data.fileId) throw new Error('Invalid file_id');
return await this.core.apis.GroupApi.delGroupFile(payload.group_id.toString(), [data.fileId]);
}

View File

@@ -578,7 +578,7 @@ export class OneBotMsgApi {
};
}
if (!context.peer || !atQQ || context.peer.chatType == ChatType.KCHATTYPEC2C) return undefined; // 过滤掉空atQQ
if (!context.peer || context.peer.chatType == ChatType.KCHATTYPEC2C) return undefined;
if (atQQ === 'all') return at(atQQ, atQQ, NTMsgAtType.ATTYPEALL, '全体成员');
const atMember = await this.core.apis.GroupApi.getGroupMember(context.peer.peerUid, atQQ);
if (atMember) {

View File

@@ -217,15 +217,6 @@ export class NapCatOneBot11Adapter {
//this.context.logger.log(`OneBot11 配置更改:${JSON.stringify(prev)} -> ${JSON.stringify(newConfig)}`);
await this.reloadNetwork(prev, newConfig);
});
WebUiDataRuntime.setCleanCacheCall(async () => {
try {
await this.actions.get('clean_cache')?.handle({});
return { result: true, message: '缓存清理成功' };
} catch (error) {
this.context.logger.logError('清理缓存失败:', error);
return { result: false, message: `清理缓存失败: ${(error as Error).message}` };
}
});
}

View File

@@ -24,8 +24,3 @@ export const SetThemeConfigHandler: RequestHandler = async (req, res) => {
await WebUiConfig.UpdateTheme(theme);
sendSuccess(res, { message: '更新成功' });
};
export const CleanCacheHandler: RequestHandler = async (_, res) => {
const result = await WebUiDataRuntime.requestCleanCache();
sendSuccess(res, result);
};

View File

@@ -27,9 +27,6 @@ const LoginRuntime: LoginRuntimeType = {
onQuickLoginRequested: async () => {
return { result: false, message: '' };
},
onCleanCacheRequested: async () => {
return { result: false, message: '' };
},
QQLoginList: [],
NewQQLoginList: [],
},
@@ -133,14 +130,6 @@ export const WebUiDataRuntime = {
return LoginRuntime.NapCatHelper.onOB11ConfigChanged(ob11);
} as LoginRuntimeType['NapCatHelper']['onOB11ConfigChanged'],
setCleanCacheCall(func: LoginRuntimeType['NapCatHelper']['onCleanCacheRequested']): void {
LoginRuntime.NapCatHelper.onCleanCacheRequested = func;
},
requestCleanCache: function () {
return LoginRuntime.NapCatHelper.onCleanCacheRequested();
} as LoginRuntimeType['NapCatHelper']['onCleanCacheRequested'],
getPackageJson() {
return LoginRuntime.packageJson;
},

View File

@@ -1,5 +1,5 @@
import { Router } from 'express';
import { CleanCacheHandler, GetThemeConfigHandler, PackageInfoHandler, QQVersionHandler, SetThemeConfigHandler } from '../api/BaseInfo';
import { GetThemeConfigHandler, PackageInfoHandler, QQVersionHandler, SetThemeConfigHandler } from '../api/BaseInfo';
import { StatusRealTimeHandler } from '@webapi/api/Status';
import { GetProxyHandler } from '../api/Proxy';
@@ -11,6 +11,5 @@ router.get('/GetSysStatusRealTime', StatusRealTimeHandler);
router.get('/proxy', GetProxyHandler);
router.get('/Theme', GetThemeConfigHandler);
router.post('/SetTheme', SetThemeConfigHandler);
router.post('/CleanCache', CleanCacheHandler);
export { router as BaseRouter };

View File

@@ -15,7 +15,6 @@ interface LoginRuntimeType {
NapCatHelper: {
onQuickLoginRequested: (uin: string) => Promise<{ result: boolean; message: string }>;
onOB11ConfigChanged: (ob11: OneBotConfig) => Promise<void>;
onCleanCacheRequested: () => Promise<{ result: boolean; message: string }>;
QQLoginList: string[];
NewQQLoginList: LoginListItem[];
};