From 543239a85b120cb9b448884b1fc920f8c127415d Mon Sep 17 00:00:00 2001 From: BTMuli Date: Sun, 29 Mar 2026 20:13:42 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E8=83=A1=E6=A1=83=E6=95=B0=E6=8D=AE=E9=AA=8C=E8=AF=81=E5=99=A8?= =?UTF-8?q?=EF=BC=8C=E5=90=88=E5=B9=B6=E4=B8=BA=20RawValidator=20=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/Hutao/index.ts | 4 + src/plugins/Hutao/utils/RawValidator.ts | 122 ++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/plugins/Hutao/utils/RawValidator.ts diff --git a/src/plugins/Hutao/index.ts b/src/plugins/Hutao/index.ts index abb3fc17..808e9cbd 100644 --- a/src/plugins/Hutao/index.ts +++ b/src/plugins/Hutao/index.ts @@ -29,6 +29,7 @@ import { } from "./request/gachaReq.js"; import { transAbyssAvatars, transAbyssLocal } from "./utils/abyssUtil.js"; import { transCombatLocal } from "./utils/combatUtil.js"; +import { RawValidator } from "./utils/RawValidator.js"; const _ = "Not Implemented"; @@ -81,6 +82,9 @@ const Hutao = { upload: uploadGachaLogs, delete: deleteGachaLogs, }, + raw: { + valid: RawValidator, + }, }; export default Hutao; diff --git a/src/plugins/Hutao/utils/RawValidator.ts b/src/plugins/Hutao/utils/RawValidator.ts new file mode 100644 index 00000000..24479267 --- /dev/null +++ b/src/plugins/Hutao/utils/RawValidator.ts @@ -0,0 +1,122 @@ +/** + * 胡桃原始数据验证器 + * @since Beta v0.9.9 + */ + +import showSnackbar from "@comp/func/snackbar.js"; +import Ajv from "ajv"; + +import AbyssJson from "../schema/abyss.json" with { type: "json" }; +import ChallengeJson from "../schema/challenge.json" with { type: "json" }; +import CombatJson from "../schema/combat.json" with { type: "json" }; + +const ajv = new Ajv.Ajv(); + +const AbyssValidate = ajv.compile(AbyssJson); +const ChallengeValidate = ajv.compile(ChallengeJson); +const CombatValidate = ajv.compile(CombatJson); + +/** + * 验证深渊单条数据 + * @since Beta v0.9.9 + * @param data - 待验证的数据 + * @returns 验证是否通过(类型收束) + */ +function validateAbyss(data: unknown): data is TGApp.Plugins.Hutao.Abyss.ImportData { + if (!AbyssValidate(data)) { + const error = AbyssValidate.errors?.[0]; + if (error) { + showSnackbar.error( + `深渊数据验证失败:${error.instancePath || error.schemaPath} ${error.message}`, + ); + } + return false; + } + return true; +} + +/** + * 验证危战单条数据 + * @since Beta v0.9.9 + * @param data - 待验证的数据 + * @returns 验证是否通过(类型收束) + */ +function validateChallenge(data: unknown): data is TGApp.Plugins.Hutao.Challenge.ImportData { + if (!ChallengeValidate(data)) { + const error = ChallengeValidate.errors?.[0]; + if (error) { + showSnackbar.error( + `危战数据验证失败:${error.instancePath || error.schemaPath} ${error.message}`, + ); + } + return false; + } + return true; +} + +/** + * 验证剧诗单条数据 + * @since Beta v0.9.9 + * @param data - 待验证的数据 + * @returns 验证是否通过(类型收束) + */ +function validateCombat(data: unknown): data is TGApp.Plugins.Hutao.Combat.ImportData { + if (!CombatValidate(data)) { + const error = CombatValidate.errors?.[0]; + if (error) { + showSnackbar.error( + `剧诗数据验证失败:${error.instancePath || error.schemaPath} ${error.message}`, + ); + } + return false; + } + return true; +} + +/** + * 验证深渊数据数组 + * @since Beta v0.9.9 + * @param data - 待验证的数据 + * @returns 验证是否通过(类型收束) + */ +function verifyAbyssArray(data: unknown): data is Array { + if (!Array.isArray(data)) return false; + return data.every(validateAbyss); +} + +/** + * 验证危战数据数组 + * @since Beta v0.9.9 + * @param data - 待验证的数据 + * @returns 验证是否通过(类型收束) + */ +function verifyChallengeArray( + data: unknown, +): data is Array { + if (!Array.isArray(data)) return false; + return data.every(validateChallenge); +} + +/** + * 验证剧诗数据数组 + * @since Beta v0.9.9 + * @param data - 待验证的数据 + * @returns 验证是否通过(类型收束) + */ +function verifyCombatArray(data: unknown): data is Array { + if (!Array.isArray(data)) return false; + return data.every(validateCombat); +} + +/** + * 原始数据验证器 + * @since Beta v0.9.9 + */ +export const RawValidator = { + /** 深渊数据验证 */ + abyss: verifyAbyssArray, + /** 危战数据验证 */ + challenge: verifyChallengeArray, + /** 剧诗数据验证 */ + combat: verifyCombatArray, +};