From b1fe5b698738826f2a21ae96b73b41f9b8932ef5 Mon Sep 17 00:00:00 2001 From: BTMuli Date: Tue, 9 Dec 2025 01:10:36 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=B1=20=E8=83=8C=E5=8C=85=E7=89=A9?= =?UTF-8?q?=E5=93=81=E6=95=B0=E6=8D=AE=E5=BA=93=E5=BB=BA=E7=AB=8B&?= =?UTF-8?q?=E8=AF=BB=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/Sqlite/modules/userBagMaterial.ts | 148 ++++++++++++++++++ src/plugins/Sqlite/sql/createTable.sql | 15 +- src/types/Plugins/Yae.d.ts | 144 ++++++++++++++++- src/types/Sqlite/UserBag.d.ts | 51 ++++++ 4 files changed, 355 insertions(+), 3 deletions(-) create mode 100644 src/plugins/Sqlite/modules/userBagMaterial.ts create mode 100644 src/types/Sqlite/UserBag.d.ts diff --git a/src/plugins/Sqlite/modules/userBagMaterial.ts b/src/plugins/Sqlite/modules/userBagMaterial.ts new file mode 100644 index 00000000..ad24a66e --- /dev/null +++ b/src/plugins/Sqlite/modules/userBagMaterial.ts @@ -0,0 +1,148 @@ +/** + * 用户背包材料模块 + * @since Beta v0.9.0 + */ +import { timestampToDate } from "@utils/toolFunc.js"; + +import TGSqlite from "../index.js"; + +/** + * 获取插入Sql + * @since Beta v0.9.0 + * @param {TGApp.Sqlite.UserBag.TableMaterialRaw} tb -表格 + * @returns {string} + */ +function getInsertSql(tb: TGApp.Sqlite.UserBag.TableMaterialRaw): string { + return ` + INSERT INTO UserBagMaterial(uid, id, count, records, updated) + VALUES (${tb.uid}, ${tb.id}, ${tb.count}, '${tb.records}', '${tb.updated}') ON CONFLICT(uid, id) DO + UPDATE + SET count = ${tb.count}, + records = '${tb.records}', + updated = '${tb.updated}'; + `; +} + +/** + * 插入或更新材料数据 + * @since Beta v0.9.0 + * @param {number} uid - 存档UID + * @param {number} itemId - 材料ID + * @param {number} count - 材料数量 + * @param {Array} [records] - 更新记录 + * @returns {Promise} + */ +async function insertMaterial( + uid: number, + itemId: number, + count: number, + records: Array = [], +): Promise { + const now = Date.now(); + const newRecord: TGApp.Sqlite.UserBag.MaterialRecord = { + count: count, + time: Math.floor(now / 1000), + }; + const newRecords = [...records, newRecord]; + const newTable: TGApp.Sqlite.UserBag.TableMaterialRaw = { + uid: uid, + id: itemId, + count: count, + records: JSON.stringify(newRecords), + updated: timestampToDate(now), + }; + const db = await TGSqlite.getDB(); + const sql = getInsertSql(newTable); + await db.execute(sql); +} + +/** + * 获取UID列表 + * @since Beta v0.9.0 + */ +async function getAllUid(): Promise> { + const db = await TGSqlite.getDB(); + type resType = Array<{ uid: number }>; + const res = await db.select("SELECT DISTINCT uid FROM UserBagMaterial"); + return res.map((u) => u.uid); +} + +/** + * 解析表格数据 + * @since Beta v0.9.0 + * @param {TGApp.Sqlite.UserBag.TableMaterialRaw} raw 原始数据 + * @return {TGApp.Sqlite.UserBag.TableMaterial} 解析数据 + */ +function parseMaterial( + raw: TGApp.Sqlite.UserBag.TableMaterialRaw, +): TGApp.Sqlite.UserBag.TableMaterial { + return { + ...raw, + records: JSON.parse(raw.records), + }; +} + +/** + * 获取指定UID的材料数据 + * @since Beta v0.9.0 + * @param {number} uid - 存档UID + * @param {number} [id] - 材料ID + * @returns {Promise>} + */ +async function getMaterial( + uid: number, + id?: number, +): Promise> { + const db = await TGSqlite.getDB(); + let res: Array; + if (id) { + res = await db.select>( + "SELECT * FROM UserBagMaterial WHERE uid = ? AND id = ?", + [uid, id], + ); + } else { + res = await db.select>( + "SELECT * FROM UserBagMaterial WHERE uid =", + [uid], + ); + } + return res.map(parseMaterial); +} + +/** + * 保存Yae获取的材料数据 + * @since Beta v0.9.0 + * @param {number} uid - 存档UID + * @param {Array>} list - 材料数据 + * @returns {Promise} + */ +async function saveYaeData( + uid: number, + list: Array>, +): Promise { + let skip = 0; + for (const item of list) { + const read = await getMaterial(uid, item.item_id); + if (read.length === 0) { + await insertMaterial(uid, item.item_id, item.info.count); + continue; + } + const local = read[0]; + // 数量相同,不更新 + if (item.info.count === local.count) { + skip++; + continue; + } + await insertMaterial(uid, item.item_id, item.info.count, local.records); + } + return skip; +} + +const TSUserBagMaterial = { + getAllUid, + saveYaeData, + getMaterial, + insertMaterial, +}; + +export default TSUserBagMaterial; diff --git a/src/plugins/Sqlite/sql/createTable.sql b/src/plugins/Sqlite/sql/createTable.sql index cd58de86..63b1c14b 100644 --- a/src/plugins/Sqlite/sql/createTable.sql +++ b/src/plugins/Sqlite/sql/createTable.sql @@ -1,5 +1,16 @@ --- @brief sqlite数据库创建表语句 --- @since Beta v0.8.4 +-- sqlite数据库创建表语句 +-- @since Beta v0.9.0 + +-- @brief 创建背包物品表 +create table if not exists UserBagMaterial +( + uid integer not null, + id integer not null, + count integer default 0, + records text, + updated text, + primary key (uid, id) +); -- @brief 创建成就数据表 create table if not exists Achievements diff --git a/src/types/Plugins/Yae.d.ts b/src/types/Plugins/Yae.d.ts index 5afd2f31..aab71e69 100644 --- a/src/types/Plugins/Yae.d.ts +++ b/src/types/Plugins/Yae.d.ts @@ -1,6 +1,6 @@ /** * Yae 插件类型定义 - * @since Beta v0.7.8 + * @since Beta v0.9.0 */ declare namespace TGApp.Plugins.Yae { @@ -9,4 +9,146 @@ declare namespace TGApp.Plugins.Yae { * @since Beta v0.7.8 */ type AchiListRes = Array; + + /** + * 后端返的背包物品数据 + * @since Beta v0.9.0 + */ + type BagListRes = Array; + + /** + * 背包物品类型 + * @since Beta v0.9.0 + */ + type BagItemUnion = + | BagItem<"material"> + | BagItem<"weapon"> + | BagItem<"reliquary"> + | BagItem<"furniture"> + | BagItem<"virtual"> + | BagItem<"unknown">; + + /** + * 背包物品信息 + * @since Beta v0.9.0 + */ + type BagItem = { + /** 物品ID */ + item_id: number; + /** 物品类型 */ + kind: T; + /** 物品信息 */ + info: ItemInfoMap[T]; + }; + + /** + * 物品信息表,用于锁定类型 + * @since Beta v0.9.0 + */ + type ItemInfoMap = { + /** 材料 */ + material: MaterialInfo; + /** 圣遗物 */ + reliquary: ReliquaryInfo; + /** 武器 */ + weapon: WeaponInfo; + /** 家具 */ + furniture: FurnitureInfo; + /** 虚拟物品 */ + virtual: VirtualInfo; + /** 未知 */ + unknown: Record; + }; + + /** + * 物品类型 + * @since Beta v0.9.0 + */ + const ItemKindType = { + /** 材料 */ + material: "material", + /** 圣遗物 */ + relic: "reliquary", + /** 武器 */ + weapon: "weapon", + /** 家具 */ + furniture: "furniture", + /** 虚拟物品 */ + virtual: "virtual", + /** 未知 */ + unknown: "unknown", + }; + + /** + * 物品类型枚举 + * @since Beta v0.9.0 + */ + type ItemKindEnum = (typeof ItemKindType)[keyof typeof ItemKindType]; + + /** + * 材料物品信息 + * @since Beta v0.9.0 + */ + type MaterialInfo = { + /** 数量 */ + count: number; + }; + + /** + * 圣遗物物品信息 + * @since Beta v0.9.0 + */ + type ReliquaryInfo = { + /** 等级 */ + level: number; + /** 经验 */ + exp: number; + /** 精炼等级 */ + promote_level: number; + /** 主属性ID */ + main_prop_id: number; + /** 副属性 */ + append_prop_id_list: Array; + /** 是否标记 */ + is_marked: boolean; + /** 是否锁定 */ + is_locked: true; + }; + + /** + * 武器信息 + * @since Beta v0.9.0 + */ + type WeaponInfo = { + /** 等级 */ + level: number; + /** 经验 */ + exp: number; + /** 精炼等级 */ + promote_level: number; + /** 未知Map */ + affix_map: Record; + /** 未知属性 */ + is_arkhe_ousia: boolean; + /** 是否锁定 */ + is_locked: boolean; + }; + + /** + * 家具信息 + * @since Beta v0.9.0 + */ + type FurnitureInfo = { + /** 数量 */ + count: number; + }; + + /** + * 虚拟物品 + * @since Beta v0.9.0 + */ + type VirtualInfo = { + /** 数量 */ + count: number; + }; } diff --git a/src/types/Sqlite/UserBag.d.ts b/src/types/Sqlite/UserBag.d.ts new file mode 100644 index 00000000..b6775344 --- /dev/null +++ b/src/types/Sqlite/UserBag.d.ts @@ -0,0 +1,51 @@ +/** + * 用户背包物品相关类型定义文件 + * @since Beta v0.9.0 + */ + +declare namespace TGApp.Sqlite.UserBag { + /** + * 用户背包材料表-存储数据 + * @since Beta v0.9.0 + */ + type TableMaterialRaw = { + /** 存档/用户UID */ + uid: number; + /** 材料ID */ + id: number; + /** 材料数量 */ + count: number; + /** 材料更新记录 */ + records: string; + /** 更新时间 */ + updated: string; + }; + + /** + * 用户背包材料表-解析数据 + * @since Beta v0.9.0 + */ + type TableMaterial = { + /** 存档/用户UID */ + uid: number; + /** 材料ID */ + id: number; + /** 材料数量 */ + count: number; + /** 材料更新记录 */ + records: Array; + /** 更新时间 */ + updated: string; + }; + + /** + * 材料更新记录 + * @since Beta v0.9.0 + */ + type MaterialRecord = { + /** 数量 */ + count: number; + /** 时间戳(秒) */ + time: number; + }; +}