diff --git a/src/plugins/UIAF/index.ts b/src/plugins/UIAF/index.ts new file mode 100644 index 00000000..9ffd5d46 --- /dev/null +++ b/src/plugins/UIAF/index.ts @@ -0,0 +1,15 @@ +import { checkUIAFData, readUIAFData, importUIAFData } from "./utils/importData"; +import { getAchievements } from "./utils/exportData"; + +const UIAF_Oper = { + importOper: { + checkUIAFData, + readUIAFData, + importUIAFData, + }, + exportOper: { + getAchievements, + }, +}; + +export default UIAF_Oper; diff --git a/src/interface/UIAF.ts b/src/plugins/UIAF/interface/UIAF.ts similarity index 95% rename from src/interface/UIAF.ts rename to src/plugins/UIAF/interface/UIAF.ts index 3779af9f..d82b3a7a 100644 --- a/src/interface/UIAF.ts +++ b/src/plugins/UIAF/interface/UIAF.ts @@ -1,10 +1,12 @@ /** - * @file UIAF.ts + * @file plugins UIAF interface UIAF.ts * @description UIAF interface * @author BTMuli * @see https://github.com/DGP-Studio/Snap.Genshin.Docs/blob/main/docs/development/UIAF.md * @version v1.1 + * @since Alpha */ + /** * @interface Achievements * @description Achievements interface diff --git a/src/plugins/UIAF/utils/exportData.ts b/src/plugins/UIAF/utils/exportData.ts new file mode 100644 index 00000000..2e1d8436 --- /dev/null +++ b/src/plugins/UIAF/utils/exportData.ts @@ -0,0 +1,39 @@ +/** + * @file plugins UIAF utils exportData.ts + * @description UIAF export data utils + * @author BTMuli + * @since Alpha + */ + +import { Achievements, UIAF_Info, UIAF_Achievement } from "../interface/UIAF"; +import { app, fs } from "@tauri-apps/api"; + +/** + * @description 获取 UIAF_Info + * @return Promise + */ +async function getUIAFInfo(): Promise { + return { + export_app: "Tauri.Genshin", + export_timestamp: Date.now(), + export_app_version: await app.getVersion(), + uiaf_version: "v1.1", + }; +} + +/** + * @description 获取 Achievements + * @param {string} userPath - 本地文件路径 + * @return Promise + */ +export async function getAchievements(userPath: string): Promise { + // 读取本地文件 + const achievementsRaw = await fs.readTextFile(userPath); + // 解析 JSON + const achievements: UIAF_Achievement[] = JSON.parse(achievementsRaw); + // 返回 + return { + info: await getUIAFInfo(), + list: achievements, + }; +} diff --git a/src/plugins/UIAF/utils/importData.ts b/src/plugins/UIAF/utils/importData.ts new file mode 100644 index 00000000..8cefae1b --- /dev/null +++ b/src/plugins/UIAF/utils/importData.ts @@ -0,0 +1,78 @@ +/** + * @file plugins UIAF utils importData.ts + * @description UIAF import data utils + * @author BTMuli + * @since Alpha + */ + +import { Achievements, UIAF_Achievement, UIAF_Info } from "../interface/UIAF"; +import { fs } from "@tauri-apps/api"; + +/** + * @description 检测是否存在 UIAF 数据 + * @description 粗略检测,不保证数据完整性 + * @param {string} path - UIAF 数据路径 + * @return {Promise} 是否存在 UIAF 数据 + */ +export async function checkUIAFData(path: string): Promise { + const fileData: string = await fs.readTextFile(path); + const UIAFData: UIAF_Info = JSON.parse(fileData)["info"]; + return UIAFData.uiaf_version !== undefined; +} + +/** + * @description 读取本地 UIAF 数据 + * @param {string} userPath - UIAF 数据路径 + * @return {Promise|Promise} UIAF 数据 + */ +export async function readUIAFData(userPath: string): Promise { + if (await fs.exists(userPath)) { + const fileData = await fs.readTextFile(userPath); + if (fileData !== undefined && fileData !== null && fileData !== "" && fileData !== "{}") { + return fileData; + } else { + return false; + } + } else { + return false; + } +} + +/** + * @description 数据合并 + * @param {UIAF_Achievement[]|false} localData - 本地数据 + * @param {Achievements} remoteData - 远程数据 + * @return {Promise} 合并后的数据,如果合并失败则返回 false + */ +export async function importUIAFData( + localData: UIAF_Achievement[] | false, + remoteData: Achievements +): Promise { + if (localData !== false) { + // 遍历 remoteData.list + remoteData.list.map((remoteAchievement: UIAF_Achievement) => { + // 查找 id 相同的 localAchievement + const localAchievement = localData.find( + achievement => achievement.id === remoteAchievement.id + ); + // 如果没找到,就直接添加 + if (localAchievement === undefined) { + localData.push(remoteAchievement); + } else { + // 检测数据是否需要更新 + if (localAchievement.timestamp < remoteAchievement.timestamp) { + // 更新数据 + localAchievement.timestamp = remoteAchievement.timestamp; + localAchievement.current = remoteAchievement.current; + localAchievement.status = remoteAchievement.status; + } + } + }); + // 按照 id 排序 + localData.sort((a, b) => a.id - b.id); + // 返回合并后的数据 + return localData; + } else { + return remoteData.list; + } +}