真境剧诗适配

close #113
This commit is contained in:
目棃
2024-11-11 15:09:21 +08:00
parent d35b94f79f
commit da4a095618
23 changed files with 1227 additions and 18 deletions

View File

@@ -7,21 +7,17 @@
/**
* @description 将本地数据转为上传用的数据
* @since Beta v0.6.3
* @param {number[]} avatars 角色
* @param {number} schedule 期数
* @param {number} uid UID
* @param {TGApp.Sqlite.Combat.SingleTable} data 数据
* @returns {TGApp.Plugins.Hutao.Combat.UploadData} 上传用的数据
*/
export function transCombatLocal(
avatars: number[],
schedule: number,
uid: string,
data: TGApp.Sqlite.Combat.SingleTable,
): TGApp.Plugins.Hutao.Combat.UploadData {
return {
Version: 1,
Uid: uid,
Uid: data.uid,
Identity: "TeyvatGuide",
BackupAvatars: avatars,
ScheduleId: schedule,
BackupAvatars: data.detail.backup_avatars.map((i) => i.avatar_id),
ScheduleId: data.id,
};
}

View File

@@ -0,0 +1,159 @@
/**
* @file plugins/Sqlite/modules/userCombat.ts
* @description Sqlite-幻想真境剧诗模块
* @since Beta v0.6.3
*/
import { path } from "@tauri-apps/api";
import { exists, mkdir, readTextFile, writeTextFile } from "@tauri-apps/plugin-fs";
import TGLogger from "../../../utils/TGLogger.js";
import { timestampToDate } from "../../../utils/toolFunc.js";
import TGSqlite from "../index.js";
import { transUserCombat } from "../utils/transUserCombat.js";
/**
* @description 直接插入数据
* @since Beta v0.6.3
* @param {string} uid 用户UID
* @param {TGApp.Sqlite.Combat.SingleTable} data 剧诗数据
* @returns {string}
*/
function getInsertSql(data: TGApp.Sqlite.Combat.SingleTable, uid?: string): string {
const timeNow = timestampToDate(new Date().getTime());
const hasData = data.hasData ? 1 : 0;
const hasDetailData = data.hasDetailData ? 1 : 0;
return `
INSERT INTO RoleCombat(uid, id, startTime, endTime, hasData, hasDetailData, stat, detail, updated)
VALUES ('${uid ?? data.uid}', ${data.id}, '${data.startTime}', '${data.endTime}', ${hasData}, ${hasDetailData},
'${JSON.stringify(data.stat)}', '${JSON.stringify(data.detail)}', '${timeNow}')
ON CONFLICT(uid,id) DO UPDATE
SET startTime = '${data.startTime}',
endTime = '${data.endTime}',
hasData = ${hasData},
hasDetailData = ${hasDetailData},
stat = '${JSON.stringify(data.stat)}',
detail = '${JSON.stringify(data.detail)}',
updated = '${timeNow}'
`;
}
/**
* @description 获取所有有数据的UID
* @since Beta v0.6.3
* @returns {Promise<void>}
*/
async function getAllUid(): Promise<Array<string>> {
const db = await TGSqlite.getDB();
type resType = Array<{ uid: string }>;
const res = await db.select<resType>("SELECT DISTINCT uid FROM RoleCombat;");
return res.map((i) => i.uid);
}
/**
* @description 获取剧诗数据
* @since Beta v0.6.3
* @param {string} uid - 游戏UID
* @returns {Promise<TGApp.Sqlite.Abyss.SingleTable[]>}
*/
async function getCombat(uid?: string): Promise<TGApp.Sqlite.Combat.SingleTable[]> {
const db = await TGSqlite.getDB();
let resR: TGApp.Sqlite.Combat.RawTable[];
if (uid === undefined) {
resR = await db.select<TGApp.Sqlite.Combat.RawTable[]>(
"SELECT * FROM RoleCombat order by id DESC;",
);
} else {
resR = await db.select<TGApp.Sqlite.Combat.RawTable[]>(
"SELECT * FROM RoleCombat WHERE uid = ? order by id DESC;",
[uid],
);
}
const res: TGApp.Sqlite.Combat.SingleTable[] = [];
for (const raw of resR) {
res.push({
uid: raw.uid,
detail: JSON.parse(raw.detail),
endTime: raw.endTime,
hasData: raw.hasData === 1,
hasDetailData: raw.hasDetailData === 1,
id: raw.id,
startTime: raw.startTime,
stat: JSON.parse(raw.stat),
updated: raw.updated,
});
}
return res;
}
/**
* @description 保存剧诗数据
* @since Beta v0.6.3
* @param {string} uid - 游戏UID
* @param {TGApp.Game.Abyss.FullData} data - 深渊数据
* @returns {Promise<void>}
*/
async function saveCombat(uid: string, data: TGApp.Game.Combat.Combat): Promise<void> {
const db = await TGSqlite.getDB();
await db.execute(getInsertSql(transUserCombat(data), uid));
}
/**
* @description 删除指定UID存档的数据
* @since Beta v0.6.3
* @param {string} uid - 游戏UID
* @returns {Promise<void>}
*/
async function delCombat(uid: string): Promise<void> {
const db = await TGSqlite.getDB();
await db.execute("DELETE FROM RoleCombat WHERE uid = ?;", [uid]);
}
/**
* @description 备份剧诗数据
* @since Beta v0.6.3
* @param {string} dir - 备份目录
* @returns {Promise<void>}
*/
async function backupCombat(dir: string): Promise<void> {
if (!(await exists(dir))) {
await mkdir(dir, { recursive: true });
await TGLogger.Warn(`未检测到备份目录,已创建`);
}
const data = await getCombat();
await writeTextFile(`${dir}${path.sep()}combat.json`, JSON.stringify(data));
}
/**
* @description 恢复剧诗数据
* @since Beta v0.6.3
* @param {string} dir - 备份文件目录
* @returns {Promise<boolean>}
*/
async function restoreCombat(dir: string): Promise<boolean> {
const filePath = `${dir}${path.sep()}combat.json`;
if (!(await exists(filePath))) return false;
try {
const data: TGApp.Sqlite.Combat.SingleTable[] = JSON.parse(await readTextFile(filePath));
const db = await TGSqlite.getDB();
for (const abyss of data) {
await db.execute(getInsertSql(abyss));
}
return true;
} catch (e) {
await TGLogger.Error(`恢复剧诗数据失败${filePath}`);
await TGLogger.Error(`${e}`);
return false;
}
}
const TSUserCombat = {
getAllUid,
getCombat,
saveCombat,
delCombat,
backupCombat,
restoreCombat,
};
export default TSUserCombat;

View File

@@ -1,6 +1,6 @@
-- @file plugins/Sqlite/sql/createTable.sql
-- @brief sqlite数据库创建表语句
-- @since Beta v0.6.1
-- @since Beta v0.6.3
-- @brief 创建成就数据表
create table if not exists Achievements
@@ -71,6 +71,21 @@ create table if not exists SpiralAbyss
primary key (uid, id)
);
-- @brief 创建幻想真境剧诗数据表
create table if not exists RoleCombat
(
uid text,
id integer,
startTime text,
endTime text,
hasData boolean,
hasDetailData boolean,
stat text,
detail text,
updated text,
primary key (uid, id)
);
-- @brief 创建战绩数据表
create table if not exists UserRecord
(

View File

@@ -0,0 +1,27 @@
/**
* @file plugins/Sqlite/utils/transUserCombat.ts
* @description Sqlite 数据转换-幻想真境剧诗
* @since Beta v0.6.3
*/
import { timestampToDate } from "../../../utils/toolFunc.js";
/**
* @description 将通过 api 获取到的数据转换为数据库中的数据
* @since Beta v0.6.3
* @param {TGApp.Game.Combat.Combat} data - 剧诗数据
* @returns {TGApp.Sqlite.Combat.SingleTable} 转换后端数据
*/
export function transUserCombat(data: TGApp.Game.Combat.Combat): TGApp.Sqlite.Combat.SingleTable {
return {
uid: "",
detail: data.detail,
endTime: timestampToDate(Number(data.schedule.end_time) * 1000),
hasData: data.has_data,
hasDetailData: data.has_detail_data,
id: data.schedule.schedule_id,
startTime: timestampToDate(Number(data.schedule.start_time) * 1000),
stat: data.stat,
updated: timestampToDate(new Date().getTime()),
};
}