@@ -20,11 +20,12 @@ import NodeDetailsWindow from "@/sub/NodeDetailsWindow";
2020import SettingsWindow from "@/sub/SettingsWindow" ;
2121import { getDeviceId } from "@/utils/otherApi" ;
2222import { deserialize , serialize } from "@graphif/serializer" ;
23+ import { Decoder } from "@msgpack/msgpack" ;
2324import { getVersion } from "@tauri-apps/api/app" ;
2425import { appCacheDir , dataDir , join } from "@tauri-apps/api/path" ;
2526import { getCurrentWindow } from "@tauri-apps/api/window" ;
2627import { open , save } from "@tauri-apps/plugin-dialog" ;
27- import { readTextFile , writeTextFile } from "@tauri-apps/plugin-fs" ;
28+ import { readFile , writeTextFile } from "@tauri-apps/plugin-fs" ;
2829import { open as shellOpen } from "@tauri-apps/plugin-shell" ;
2930import { useAtom } from "jotai" ;
3031import {
@@ -609,8 +610,14 @@ export async function onOpenFile(uri?: URI, source: string = "unknown") {
609610 uri = URI . file ( path ) ;
610611 }
611612 let upgraded : ReturnType < typeof ProjectUpgrader . convertVAnyToN1 > extends Promise < infer T > ? T : never ;
612- if ( uri . fsPath . endsWith ( ".json" ) ) {
613- const content = await readTextFile ( uri . fsPath ) ;
613+
614+ // 读取文件内容并判断格式
615+ const fileData = await readFile ( uri . fsPath ) ;
616+
617+ // 检查是否是以 '{' 开头的 JSON 文件
618+ if ( fileData [ 0 ] === 0x7b ) {
619+ // 0x7B 是 '{' 的 ASCII 码
620+ const content = new TextDecoder ( ) . decode ( fileData ) ;
614621 const json = JSON . parse ( content ) ;
615622 const t = performance . now ( ) ;
616623 upgraded = await toast
@@ -630,6 +637,32 @@ export async function onOpenFile(uri?: URI, source: string = "unknown") {
630637 toast . info ( "您正在尝试导入旧版的文件!稍后如果点击了保存文件,文件会保存为相同文件夹内的 .prg 后缀的文件" ) ;
631638 uri = uri . with ( { path : uri . path . replace ( / \. j s o n $ / , ".prg" ) } ) ;
632639 }
640+ // 检查是否是以 0x91 0x86 开头的 msgpack 数据
641+ if ( fileData . length >= 2 && fileData [ 0 ] === 0x84 && fileData [ 1 ] === 0xa7 ) {
642+ const decoder = new Decoder ( ) ;
643+ const decodedData = decoder . decode ( fileData ) ;
644+ if ( typeof decodedData !== "object" || decodedData === null ) {
645+ throw new Error ( "msgpack 解码结果不是有效的对象" ) ;
646+ }
647+ const t = performance . now ( ) ;
648+ upgraded = await toast
649+ . promise ( ProjectUpgrader . convertVAnyToN1 ( decodedData as Record < string , any > , uri ) , {
650+ loading : "正在转换旧版项目文件..." ,
651+ success : ( ) => {
652+ const time = performance . now ( ) - t ;
653+ Telemetry . event ( "转换vany->n1" , { time, length : fileData . length } ) ;
654+ return `转换成功,耗时 ${ time } ms` ;
655+ } ,
656+ error : ( e ) => {
657+ Telemetry . event ( "转换vany->n1报错" , { error : String ( e ) } ) ;
658+ return `转换失败,已发送错误报告,可在群内联系开发者\n${ String ( e ) } ` ;
659+ } ,
660+ } )
661+ . unwrap ( ) ;
662+ toast . info ( "您正在尝试导入旧版的文件!稍后如果点击了保存文件,文件会保存为相同文件夹内的 .prg 后缀的文件" ) ;
663+ uri = uri . with ( { path : uri . path . replace ( / \. j s o n $ / , ".prg" ) } ) ;
664+ }
665+
633666 if ( store . get ( projectsAtom ) . some ( ( p ) => p . uri . toString ( ) === uri . toString ( ) ) ) {
634667 store . set ( activeProjectAtom , store . get ( projectsAtom ) . find ( ( p ) => p . uri . toString ( ) === uri . toString ( ) ) ! ) ;
635668 store . get ( activeProjectAtom ) ?. loop ( ) ;
0 commit comments