添加游戏配置文件类型定义并优化读取逻辑

This commit is contained in:
BTMuli
2026-03-29 18:47:02 +08:00
parent 0a53639285
commit 95ff9ce765
4 changed files with 85 additions and 21 deletions

View File

@@ -94,6 +94,7 @@
"date-fns": "^4.1.0",
"echarts": "^6.0.0",
"html2canvas": "^1.4.1",
"ini": "^6.0.0",
"js-md5": "^0.8.3",
"jsencrypt": "^3.5.4",
"json-bigint": "^1.0.0",
@@ -118,6 +119,7 @@
"@microsoft/tsdoc": "^0.16.0",
"@tauri-apps/cli": "2.10.1",
"@types/fs-extra": "^11.0.4",
"@types/ini": "^4.1.1",
"@types/js-md5": "^0.8.0",
"@types/json-bigint": "^1.0.4",
"@types/node": "^25.5.0",
@@ -126,7 +128,7 @@
"app-root-path": "^3.1.0",
"concurrently": "^9.2.1",
"envfile": "^7.1.0",
"eslint": "10.1.0",
"eslint": "^9.22.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsonc": "^3.1.2",
"eslint-plugin-prettier": "^5.5.5",

17
pnpm-lock.yaml generated
View File

@@ -80,6 +80,9 @@ importers:
html2canvas:
specifier: ^1.4.1
version: 1.4.1
ini:
specifier: ^6.0.0
version: 6.0.0
js-md5:
specifier: ^0.8.3
version: 0.8.3
@@ -147,6 +150,9 @@ importers:
'@types/fs-extra':
specifier: ^11.0.4
version: 11.0.4
'@types/ini':
specifier: ^4.1.1
version: 4.1.1
'@types/js-md5':
specifier: ^0.8.0
version: 0.8.0
@@ -1735,6 +1741,9 @@ packages:
'@types/fs-extra@11.0.4':
resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==}
'@types/ini@4.1.1':
resolution: {integrity: sha512-MIyNUZipBTbyUNnhvuXJTY7B6qNI78meck9Jbv3wk0OgNwRyOOVEKDutAkOs1snB/tx0FafyR6/SN4Ps0hZPeg==}
'@types/js-md5@0.8.0':
resolution: {integrity: sha512-gQkc1Felhyj+aB9jmz/ICLm1fDPQx7l/60JIBSSEC+j09JeaINlzd0Wj9LZlQkHnV5rJYkroOHE5wdbDgADJrw==}
@@ -2865,6 +2874,10 @@ packages:
ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
ini@6.0.0:
resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==}
engines: {node: ^20.17.0 || >=22.9.0}
internal-slot@1.1.0:
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
engines: {node: '>= 0.4'}
@@ -5849,6 +5862,8 @@ snapshots:
'@types/jsonfile': 6.1.4
'@types/node': 25.5.0
'@types/ini@4.1.1': {}
'@types/js-md5@0.8.0': {}
'@types/json-bigint@1.0.4': {}
@@ -7212,6 +7227,8 @@ snapshots:
ini@1.3.8: {}
ini@6.0.0: {}
internal-slot@1.1.0:
dependencies:
es-errors: 1.3.0

41
src/types/Game/Config.d.ts vendored Normal file
View File

@@ -0,0 +1,41 @@
/**
* 游戏配置文件相关
* @since Beta v0.9.9
*/
declare namespace TGApp.Game.Config {
/**
* Config.ini 文件
* @since Beta v0.9.9
*/
type GameConf = {
/** 通用配置 */
general: GeneralConf;
};
/**
* Config.ini 配置
* @since Beta v0.9.9
*/
type GeneralConf = {
/** channel */
channel: string;
/** cps */
cps: string;
/** downloading_mode */
downloading_mode: string;
/** game_version */
game_version: string;
/** plugin_sdk_version */
plugin_sdk_version: string;
/** sub_channel */
sub_channel: string;
/**
* uapc
* @remarks 序列化的JSON字符串
*/
uapc: string;
/** wpf_version */
wpf_version: string;
};
}

View File

@@ -1,26 +1,33 @@
/**
* 游戏文件相关功能
* @since Beta v0.9.8
* @since Beta v0.9.9
*/
import showDialog from "@comp/func/dialog.js";
import showSnackbar from "@comp/func/snackbar.js";
import { parse } from "ini";
import { invoke } from "@tauri-apps/api/core";
import { documentDir, resourceDir, sep } from "@tauri-apps/api/path";
import {
copyFile,
exists,
mkdir,
readDir,
readTextFile,
readTextFileLines,
} from "@tauri-apps/plugin-fs";
import { copyFile, exists, mkdir, readDir, readTextFile } from "@tauri-apps/plugin-fs";
import { platform } from "@tauri-apps/plugin-os";
import TGLogger from "@utils/TGLogger.js";
// YAE支持的游戏版本
export const YAE_GAME_VER: Readonly<string> = "6.4.0";
/**
* 验证游戏格式
* @since Beta v0.9.9
* @param data - ini数据
* @returns 类型收束
*/
function verifyConfigIni(data: object): data is TGApp.Game.Config.GameConf {
if (!("general" in data) || typeof data.general !== "object" || data.general === null) return false;
if (!("game_version" in data.general) || typeof data.general.game_version !== "string") return false;
// 简单验证general跟game_version
return true;
}
/**
* 尝试获取游戏版本
* @since Beta v0.9.1
@@ -37,14 +44,12 @@ export async function tryReadGameVer(gameDir: string): Promise<false | string> {
}
const iniPath = `${gameDir}${sep()}config.ini`;
if (await exists(iniPath)) {
const iniRead = await readTextFileLines(iniPath);
while (true) {
const line = await iniRead.next();
const lineRead = line.value;
if (typeof lineRead === "string" && lineRead.startsWith("game_version=")) {
return lineRead.split("=")[1];
}
if (line.done) break;
const iniRead = await readTextFile(iniPath);
try {
const iniParse = parse(iniRead);
if (verifyConfigIni(iniParse)) return iniParse.general.game_version;
} catch (e) {
showSnackbar.warn("config.ini 配置格式异常");
}
}
const scriptPath = `${gameDir}${sep()}YuanShen_Data${sep()}Persistent${sep()}ScriptVersion`;
@@ -56,12 +61,11 @@ export async function tryReadGameVer(gameDir: string): Promise<false | string> {
/**
* 判断是否是管理员模式
* @since Beta v0.9.1
* @since Beta v0.9.9
*/
export async function isRunInAdmin(): Promise<boolean> {
try {
const isAdmin = await invoke<boolean>("is_in_admin");
return isAdmin;
return await invoke<boolean>("is_in_admin");
} catch (err) {
showSnackbar.error(`检测管理员权限失败:${err}`);
await TGLogger.Error(`[TGGame][isRunInAdmin]检测管理员权限失败:${err}`);