From 38f3301664ac998a6ccaaa68cdc22e72b9421e73 Mon Sep 17 00:00:00 2001 From: BTMuli Date: Mon, 1 Dec 2025 23:52:39 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E5=AE=8C=E6=88=90=E6=88=90?= =?UTF-8?q?=E5=B0=B1=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands.rs | 19 ++++-- src-tauri/src/yae/mod.rs | 4 ++ src-tauri/src/yae/proto.rs | 26 ++++---- src/enum/{yae.ts => uiaf.ts} | 2 +- src/pages/common/PageAchi.vue | 35 +++++++++-- src/plugins/Sqlite/modules/userAchi.ts | 38 ++++++++---- src/types/Plugins/UIAF.d.ts | 83 ++++++++++++++------------ src/types/Plugins/Yae.d.ts | 41 +------------ 8 files changed, 133 insertions(+), 115 deletions(-) rename src/enum/{yae.ts => uiaf.ts} (79%) diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 27d0e726..657fff1d 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -1,6 +1,5 @@ -//! @file src/commands.rs -//! @desc 命令模块,负责处理命令 -//! @since Beta v0.7.4 +//! 命令模块,负责处理命令 +//! @since Beta v0.7.8 use tauri::{AppHandle, Emitter, Manager, WebviewWindowBuilder}; use tauri_utils::config::{WebviewUrl, WindowConfig}; @@ -72,9 +71,13 @@ pub async fn get_dir_size(path: String) -> u64 { } // 判断是否是管理员权限 -#[cfg(target_os = "windows")] #[tauri::command] pub fn is_in_admin() -> bool { + #[cfg(not(target_os = "windows"))] + { + Err("This function is only supported on Windows.".into()) + } + use windows_sys::Win32::Foundation::HANDLE; use windows_sys::Win32::Security::{ AllocateAndInitializeSid, CheckTokenMembership, FreeSid, SID_IDENTIFIER_AUTHORITY, TOKEN_QUERY, @@ -113,10 +116,14 @@ pub fn is_in_admin() -> bool { } } -// 在 Windows 上以管理员权限重启应用 -#[cfg(target_os = "windows")] +// 以管理员权限重启应用 #[tauri::command] pub fn run_with_admin() -> Result<(), String> { + #[cfg(not(target_os = "windows"))] + { + Err("This function is only supported on Windows.".into()) + } + use std::ffi::OsStr; use std::iter::once; use std::os::windows::ffi::OsStrExt; diff --git a/src-tauri/src/yae/mod.rs b/src-tauri/src/yae/mod.rs index a7397552..e3bedfe6 100644 --- a/src-tauri/src/yae/mod.rs +++ b/src-tauri/src/yae/mod.rs @@ -104,6 +104,10 @@ fn read_exact_vec(r: &mut R, len: usize) -> io::Result> { /// 调用 dll #[tauri::command] pub fn call_yae_dll(app_handle: AppHandle, game_path: String) -> () { + #[cfg(not(target_os = "windows"))] + { + Err("This function is only supported on Windows.".into()) + } let dll_path = app_handle.path().resource_dir().unwrap().join("resources/YaeAchievementLib.dll"); dbg!(&dll_path); // 0. 创建 YaeAchievementPipe 的 命名管道,获取句柄 diff --git a/src-tauri/src/yae/proto.rs b/src-tauri/src/yae/proto.rs index 245ab77d..f4430256 100644 --- a/src-tauri/src/yae/proto.rs +++ b/src-tauri/src/yae/proto.rs @@ -1,13 +1,12 @@ //! Yae 成就信息的 Protobuf 定义 -//! @since Beta v0.9.0 +//! @since Beta v0.8.7 use prost::encoding::{decode_key, WireType}; use prost::DecodeError; use prost::Message; use serde::Serialize; use std::collections::HashMap; -use std::io::Cursor; -use std::io::Read; +use std::io::{Cursor, Read}; #[derive(Clone, PartialEq, Message, Serialize)] pub struct AchievementProtoFieldInfo { @@ -106,15 +105,14 @@ pub struct AchievementInfo { } #[derive(Debug, Default, Serialize)] -pub struct AchiItemRes { +pub struct UiafAchiItem { pub id: u32, - pub total: u32, - pub cur: u32, - pub ts: u32, - pub stat: u32, + pub current: u32, + pub timestamp: u32, + pub status: u32, } -pub fn parse_achi_list(bytes: &[u8]) -> Result, DecodeError> { +pub fn parse_achi_list(bytes: &[u8]) -> Result, DecodeError> { let mut cursor = Cursor::new(bytes); let mut dicts: Vec> = Vec::new(); @@ -146,13 +144,13 @@ pub fn parse_achi_list(bytes: &[u8]) -> Result, DecodeError> { let achievements = dicts .into_iter() - .map(|d| AchiItemRes { + .map(|d| UiafAchiItem { id: d.get(&15).copied().unwrap_or(0), - stat: d.get(&11).copied().unwrap_or(0), - total: d.get(&8).copied().unwrap_or(0), - cur: d.get(&13).copied().unwrap_or(0), - ts: d.get(&7).copied().unwrap_or(0), + status: d.get(&11).copied().unwrap_or(0), + current: d.get(&13).copied().unwrap_or(0), + timestamp: d.get(&7).copied().unwrap_or(0), }) + .filter(|a| a.timestamp != 0) .collect(); Ok(achievements) diff --git a/src/enum/yae.ts b/src/enum/uiaf.ts similarity index 79% rename from src/enum/yae.ts rename to src/enum/uiaf.ts index cd04de8c..cbeaa599 100644 --- a/src/enum/yae.ts +++ b/src/enum/uiaf.ts @@ -7,7 +7,7 @@ * 成就完成状态枚举 * @since Beta v0.7.8 */ -export const YaeAchiStatEnum: typeof TGApp.Plugins.Yae.AchiItemStat = { +export const UiafAchiStatEnum: typeof TGApp.Plugins.UIAF.AchiItemStat = { /** 无效状态 */ Invalid: 0, /** 未完成 */ diff --git a/src/pages/common/PageAchi.vue b/src/pages/common/PageAchi.vue index c677c4b1..f01634c7 100644 --- a/src/pages/common/PageAchi.vue +++ b/src/pages/common/PageAchi.vue @@ -79,7 +79,7 @@ import TSUserAchi from "@Sqlm/userAchi.js"; import useAppStore from "@store/app.js"; import { path } from "@tauri-apps/api"; import { invoke } from "@tauri-apps/api/core"; -import { listen, type UnlistenFn } from "@tauri-apps/api/event"; +import { listen, type UnlistenFn, type Event } from "@tauri-apps/api/event"; import { open, save } from "@tauri-apps/plugin-dialog"; import { exists, writeTextFile } from "@tauri-apps/plugin-fs"; import { platform } from "@tauri-apps/plugin-os"; @@ -133,7 +133,14 @@ onMounted(async () => { achiListener = await listen("updateAchi", async () => await refreshOverview()); yaeListener = await listen( "yae_achi_list", - (e: Event) => tryParseYaeAchi(e.payload), + async (e: Event) => { + try { + await tryParseYaeAchi(JSON.parse(e.payload)); + } catch (err) { + await TGLogger.Error(`[Achievements][yae_achi_list] 解析Yae成就数据失败: ${err}`); + showSnackbar.error(`解析Yae成就数据失败:${err}`); + } + }, ); }); @@ -327,8 +334,28 @@ async function toYae(): Promise { } async function tryParseYaeAchi(payload: TGApp.Plugins.Yae.AchiListRes): Promise { - console.log(payload); - showSnackbar.success(`已收到来自Yae的成就数据,共${payload.list.length}条`); + console.log(typeof payload, payload); + if (payload.length === 0) { + showSnackbar.warn(`未从Yae获取到成就数据`); + return; + } + const input = await showDialog.input("请输入存档UID", "UID:", uidCur.value.toString()); + if (!input) { + showSnackbar.cancel("已取消存档导入"); + return; + } + if (input === "" || isNaN(Number(input))) { + showSnackbar.warn("请输入合法数字"); + return; + } + await showLoading.start("正在导入成就数据", `UID:${input},数量:${payload.length}`); + await TSUserAchi.mergeUiaf(payload, input); + await showLoading.end(); + showSnackbar.success("导入成功,即将刷新页面"); + await TGLogger.Info("[Achievements][handleImportOuter] 导入成功"); + await new Promise((resolve) => setTimeout(resolve, 1500)); + await router.push("/achievements"); + window.location.reload(); }