From bd8ee19b79dfa0526d4a6c5e7c49c9ec012abd5c Mon Sep 17 00:00:00 2001 From: BTMuli Date: Mon, 22 Dec 2025 14:15:43 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=B1=20=E7=95=99=E5=BD=B1=E5=8F=99?= =?UTF-8?q?=E4=BD=B3=E6=9C=9Fxml=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/common/PageTest.vue | 55 ++++------ src/types/Archive/Birth.d.ts | 190 +++++++++++++++++++++++----------- src/utils/birthParser.ts | 96 +++++++++++++++++ 3 files changed, 243 insertions(+), 98 deletions(-) create mode 100644 src/utils/birthParser.ts diff --git a/src/pages/common/PageTest.vue b/src/pages/common/PageTest.vue index 85be33f9..da1cbc50 100644 --- a/src/pages/common/PageTest.vue +++ b/src/pages/common/PageTest.vue @@ -19,45 +19,28 @@ diff --git a/src/types/Archive/Birth.d.ts b/src/types/Archive/Birth.d.ts index 37329bda..6340a275 100644 --- a/src/types/Archive/Birth.d.ts +++ b/src/types/Archive/Birth.d.ts @@ -1,112 +1,178 @@ /** - * @file types/Archive/Birth.d.ts - * @description 存档-留影叙佳期-数据类型 - * @since Beta v0.4.4 + * 留影叙佳期 + * @since Beta v0.9.1 */ -/** - * @description 存档-留影叙佳期-命名空间 - * @since Beta v0.4.4 - * @namespace TGApp.Archive.Birth - * @memberof TGApp.Archive - */ declare namespace TGApp.Archive.Birth { /** - * @description 日历数据 + * 日历数据 * @since Beta v0.4.4 - * @interface CalendarData - * @returns CalendarData */ - type CalendarData = Record; + type CalendarData = Record>; /** - * @description 日历数据-条目 + * 日历数据条目 * @since Beta v0.4.4 - * @interface CalendarItem - * @property {number} role_id 角色ID - * @property {string} name 角色名 - * @property {string} role_birthday 角色生日 - * @property {string} head_icon 头像 - * @property {boolean} is_subscribe 是否订阅 - * @returns CalendarItem */ - interface CalendarItem { + type CalendarItem = { + /** 角色ID */ role_id: number; + /** 角色名 */ name: string; + /** 角色生日 */ role_birthday: string; + /** 头像 */ head_icon: string; + /** 是否订阅 */ is_subscribe: boolean; - } + }; /** - * @description 卡片数据条目 + * 卡片数据条目 * @since Beta v0.4.4 - * @interface DrawItem - * @property {string} word_text - 留言 - * @property {number} year - 年份 - * @property {string} birthday - 生日 m/d - * @property {number} role_id - 角色 id - * @property {string} role_name - 角色名 - * @property {string[]} take_picture - 画片地址 [荧,空] - * @property {string[]} unread_picture - 未读画片地址 [荧,空] - * @property {string} gal_xml - 画片 xml - * @property {string} gal_resource - 画片资源 - * @property {number} op_id - 操作 id - * @returns DrawItem */ - interface DrawItem { + type DrawItem = { + /** 留言 */ word_text: string; + /** 年份 */ year: number; + /** 生日 m/d */ birthday: string; + /** 角色 id */ role_id: number; + /** 角色名 */ role_name: string; - take_picture: string[]; - unread_picture: string[]; + /** 画片地址 [荧,空] */ + take_picture: Array & { length: 2 }; + /** 未读画片地址 [荧,空] */ + unread_picture: Array & { length: 2 }; + /** 画片 xml */ gal_xml: string; + /** 画片资源 */ gal_resource: string; + /** 操作 id */ op_id: number; - } + }; /** - * @description 角色数据条目 + * 角色数据条目 * @since Beta v0.4.4 - * @interface RoleItem - * @property {number} role_id - 角色 id - * @property {string} name - 角色名 - * @property {string} belong - 所属 - * @property {string} divine_type - 神力类型 - * @property {boolean} is_god - 是否是神 - * @property {string} seat_life - 命座 - * @property {string} element - 元素 - * @property {string} text - 介绍 - * @property {string} role_birthday - 生日 m/d - * @property {string} head_icon - 头像 - * @property {string} head_image - 头像 - * @property {string} introduce - 介绍 - * @property {boolean} is_subscribe - 是否订阅 - * @property {boolean} is_finish_task - 是否完成任务 - * @property {number} current_compensate_num - 当前补偿数量 - * @property {boolean} is_compensate_num - 是否补偿数量 - * @property {number} year_compensate_num - 年份补偿数量 - * @returns RoleItem */ - interface RoleItem { + type RoleItem = { + /** 角色 id */ role_id: number; + /** 角色名 */ name: string; + /** 所属 */ belong: string; + /** 神力类型 */ divine_type: string; + /** 是否是神 */ is_god: boolean; + /** 命座 */ seat_life: string; + /** 元素 */ element: string; + /** 介绍 */ text: string; + /** 生日 m/d */ role_birthday: string; + /** 头像 */ head_icon: string; + /** 头像 */ head_image: string; + /** 介绍 */ introduce: string; + /** 是否订阅 */ is_subscribe: boolean; + /** 是否完成任务 */ is_finish_task: boolean; + /** 当前补偿数量 */ current_compensate_num: number; + /** 是否补偿数量 */ is_compensate_num: boolean; + /** 年份补偿数量 */ year_compensate_num: number; - } + }; + + /** + * 转换后的资源数据 + * @since Beta v0.9.1 + */ + type GalSrcFull = { + /** 资源数据 */ + resource: Array; + /** 角色数据 */ + roles: Array; + }; + + /** + * 资源数据条目 + * @since Beta v0.9.1 + */ + type GalSrcRes = { + /** 资源类型 */ + type: string; + /** 资源引用 */ + rel: string; + /** 资源地址 */ + src: string; + /** 资源ID */ + id: string; + /** 资源Group */ + group: string; + }; + + /** + * 角色资源数据条目 + * @since Beta v0.9.1 + */ + type GalSrcRole = { + /** 角色ID */ + id: string; + /** 角色名 */ + name: string; + /** 角色Key */ + key?: string; + }; + + /** + * 转换后的播放数据 + * @since Beta v0.9.1 + */ + type GalScenes = Array; + + /** + * 播放场景数据条目 + * @since Beta v0.9.1 + */ + type GalScriptScene = { + /** 场景ID */ + id: string; + /** 场景名称 */ + title: string; + /** 场景背景bg名称 */ + bg: string; + /** 前一个场景ID */ + prev?: string; + /** 场景脚本 */ + scripts: Array; + }; + + /** + * 播放脚本数据条目 + * @since Beta v0.9.1 + */ + type GalDialog = { + /** key */ + key: string; + /** 角色 */ + role?: string; + /** 图片名称 */ + img?: string; + /** 位置 */ + pos?: string; + /** 对话内容 */ + text: string; + }; } diff --git a/src/utils/birthParser.ts b/src/utils/birthParser.ts new file mode 100644 index 00000000..fea9cd1d --- /dev/null +++ b/src/utils/birthParser.ts @@ -0,0 +1,96 @@ +/** + * 解析留影叙佳期数据 + * @since Beta v0.9.1 + */ + +/** + * 解析资源数据 + * @since Beta v0.9.1 + */ +export function parseBirthSrc(data: Document): TGApp.Archive.Birth.GalSrcFull { + const res: TGApp.Archive.Birth.GalSrcFull = { resource: [], roles: [] }; + const tmpRes: TGApp.Archive.Birth.GalSrcRes[] = []; + const tmpRoles: TGApp.Archive.Birth.GalSrcRole[] = []; + const resElements = data.querySelector("resource"); + const roleElements = data.querySelector("characters"); + if (resElements !== null) { + for (let ci = 0; ci < resElements.children.length; ci++) { + const child = resElements.children.item(ci); + if (child === null) continue; + const tmpResItem: TGApp.Archive.Birth.GalSrcRes = { + id: child.getAttribute("id") ?? "", + group: child.getAttribute("group") ?? "", + type: child.tagName, + rel: child.getAttribute("rel") ?? "", + src: child.getAttribute("src") ?? "", + }; + // 检测是否都是空 + const isNotEmpty = Object.values(tmpResItem).every((v) => v !== ""); + if (isNotEmpty) tmpRes.push(tmpResItem); + } + res.resource = tmpRes; + } + if (roleElements !== null) { + for (let ri = 0; ri < roleElements.children.length; ri++) { + const child = roleElements.children.item(ri); + if (child === null) continue; + const tmpRoleItem: TGApp.Archive.Birth.GalSrcRole = { + id: child.getAttribute("id") ?? "", + name: child.getAttribute("name") ?? "", + key: child.getAttribute("key") ?? undefined, + }; + // 检测是否都是空 + const isNotEmpty = Object.values(tmpRoleItem).every((v) => v !== ""); + if (isNotEmpty) tmpRoles.push(tmpRoleItem); + } + res.roles = tmpRoles; + } + return res; +} + +/** + * 解析Gal数据 + * @since Beta v0.9.1 + * @todo 结合资源数据,补全图片路径 + */ +export function parseBirthGal(data: Document): TGApp.Archive.Birth.GalScenes { + const scenes: TGApp.Archive.Birth.GalScenes = []; + const sceneElements = data.querySelectorAll("scene"); + if (sceneElements.length > 1) console.log(sceneElements); + for (let si = 0; si < sceneElements.length; si++) { + const sceneData = parseBirthScenes(sceneElements.item(si)); + scenes.push(sceneData); + } + return scenes; +} + +/** + * 解析场景数据 + * @since Beta v0.9.1 + */ +function parseBirthScenes(data: Element): TGApp.Archive.Birth.GalScriptScene { + const res: TGApp.Archive.Birth.GalScriptScene = { + id: data.getAttribute("id") ?? "", + title: data.getAttribute("title") ?? "", + prev: data.getAttribute("prev") ?? undefined, + bg: "", + scripts: [], + }; + const bgElement = data.querySelector("bg"); + if (bgElement !== null) res.bg = bgElement.getAttribute("img") ?? ""; + const dialogElements = data.querySelectorAll("simple_dialog"); + const tmpScripts: TGApp.Archive.Birth.GalDialog[] = []; + for (let di = 0; di < dialogElements.length; di++) { + const dialogEl = dialogElements.item(di); + const scriptItem: TGApp.Archive.Birth.GalDialog = { + key: dialogEl.getAttribute("key") ?? "", + role: dialogEl.getAttribute("chara") ?? undefined, + img: dialogEl.getAttribute("img") ?? undefined, + pos: dialogEl.getAttribute("pos") ?? undefined, + text: dialogEl.textContent ?? "", + }; + tmpScripts.push(scriptItem); + } + res.scripts = tmpScripts; + return res; +}