From 2c451c3c01059ed04524dc02975889e327c25426 Mon Sep 17 00:00:00 2001 From: BTMuli Date: Sun, 4 Jan 2026 05:15:31 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=B1=20=E7=A5=88=E6=84=BF=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3&=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #202 --- src/pages/common/PageTest.vue | 2 +- src/plugins/Hutao/index.ts | 15 +++-- src/plugins/Hutao/request/accountReq.ts | 32 +-------- src/plugins/Hutao/request/gachaReq.ts | 80 ++++++++++++++++++++++ src/plugins/Hutao/types/Gacha.d.ts | 88 +++++++++++++++++++++++++ src/plugins/Hutao/utils/authUtils.ts | 29 ++++++++ src/store/modules/hutao.ts | 2 +- 7 files changed, 209 insertions(+), 39 deletions(-) create mode 100644 src/plugins/Hutao/request/gachaReq.ts create mode 100644 src/plugins/Hutao/types/Gacha.d.ts diff --git a/src/pages/common/PageTest.vue b/src/pages/common/PageTest.vue index 16a20096..9b260c8b 100644 --- a/src/pages/common/PageTest.vue +++ b/src/pages/common/PageTest.vue @@ -31,7 +31,7 @@ async function test() { if (!hutaoStore.checkIsValid()) { await hutaoStore.tryRefreshToken(); } - const resp = await hutao.Account.info(accessToken.value!); + const resp = await hutao.Gacha.entry(accessToken.value!); if ("retcode" in resp) { showSnackbar.warn(`${resp.retcode}-${resp.message}`); return; diff --git a/src/plugins/Hutao/index.ts b/src/plugins/Hutao/index.ts index 5833a7c3..cf0c96e4 100644 --- a/src/plugins/Hutao/index.ts +++ b/src/plugins/Hutao/index.ts @@ -14,6 +14,7 @@ import { } from "./request/abyssReq.js"; import { getUserInfo, loginPassport, refreshToken } from "./request/accountReq.js"; import { getCombatStatistic, uploadCombatData } from "./request/combatReq.js"; +import { getEndIds, getEntries, getGachaLogs } from "./request/gachaReq.js"; import { transAbyssAvatars, transAbyssLocal } from "./utils/abyssUtil.js"; import { transCombatLocal } from "./utils/combatUtil.js"; @@ -49,15 +50,17 @@ const Hutao = { username: _, password: _, }, - token: { - refresh: refreshToken, - revoke: _, - revokeAll: _, - }, info: getUserInfo, }, + Token: { + refresh: refreshToken, + revoke: _, + revokeAll: _, + }, Gacha: { - log: _, + entry: getEntries, + endIds: getEndIds, + logs: getGachaLogs, upload: _, delete: _, }, diff --git a/src/plugins/Hutao/request/accountReq.ts b/src/plugins/Hutao/request/accountReq.ts index 4972cacf..06018be7 100644 --- a/src/plugins/Hutao/request/accountReq.ts +++ b/src/plugins/Hutao/request/accountReq.ts @@ -4,41 +4,11 @@ */ import TGHttp from "@utils/TGHttp.js"; -import { importPublicKey, sha1 } from "rsa-oaep-encryption"; -import { getReqHeader } from "../utils/authUtils.js"; - -/** 加密公钥 */ -const HUTAO_PUB_KEY: Readonly = ` ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5W2SEyZSlP2zBI1Sn8Gd -TwbZoXlUGNKyoVrY8SVYu9GMefdGZCrUQNkCG/Np8pWPmSSEFGd5oeug/oIMtCZQ -NOn0drlR+pul/XZ1KQhKmj/arWjN1XNok2qXF7uxhqD0JyNT/Fxy6QvzqIpBsM9S -7ajm8/BOGlPG1SInDPaqTdTRTT30AuN+IhWEEFwT3Ctv1SmDupHs2Oan5qM7Y3uw -b6K1rbnk5YokiV2FzHajGUymmSKXqtG1USZzwPqImpYb4Z0M/StPFWdsKqexBqMM -mkXckI5O98GdlszEmQ0Ejv5Fx9fR2rXRwM76S4iZTfabYpiMbb4bM42mHMauupj6 -9QIDAQAB ------END PUBLIC KEY-----`; -const encrypt = importPublicKey(HUTAO_PUB_KEY); +import { getReqHeader, rsaEncrypt } from "../utils/authUtils.js"; const PassportUrl = "https://homa.gentle.house/Passport/v2/"; -/** - * rsa 加密 - * @since Beta v0.9.1 - * @param data - 待加密数据 - * @returns 加密后数据 - */ -function rsaEncrypt(data: string): string { - const res = encrypt.encrypt(data, sha1.create()); - const bytes = new Uint8Array(res); - let binary = ""; - for (let i = 0; i < bytes.byteLength; i++) { - binary += String.fromCharCode(bytes[i]); - } - return btoa(binary); -} - /** * 登录 * @since Beta v0.9.1 diff --git a/src/plugins/Hutao/request/gachaReq.ts b/src/plugins/Hutao/request/gachaReq.ts new file mode 100644 index 00000000..3834c875 --- /dev/null +++ b/src/plugins/Hutao/request/gachaReq.ts @@ -0,0 +1,80 @@ +/** + * 祈愿相关请求 + * @since Beta v0.9.1 + */ +import { getReqHeader } from "@Hutao/utils/authUtils.js"; +import TGHttp from "@utils/TGHttp.js"; + +const GachaUrl = "https://homa.gentle.house/GachaLog/"; + +/** + * 获取抽卡入口 + * @param tk - token + * @returns 抽卡记录概况 + */ +export async function getEntries( + tk: string, +): Promise { + const url = `${GachaUrl}Entries`; + const header = await getReqHeader(tk); + const resp = await TGHttp(url, { + method: "GET", + headers: header, + }); + if (resp.retcode !== 0) return resp; + return resp.data; +} + +/** + * 获取抽卡EndId + * @param tk - token + * @param uid - 记录UID + * @returns EndId + */ +export async function getEndIds( + tk: string, + uid: string, +): Promise { + const url = `${GachaUrl}EndIds`; + const header = await getReqHeader(tk); + const resp = await TGHttp(url, { + method: "GET", + headers: header, + query: { Uid: uid }, + }); + if (resp.retcode !== 0) return resp; + return resp.data; +} + +/** + * 获取抽卡记录 + * @since Beta v0.9.1 + * @param tk - token + * @param uid - 记录UID + * @param gType - 祈愿类型,按照EndId来 + * @param endId - endId + * @param count - 尺寸 + */ +export async function getGachaLogs( + tk: string, + uid: string, + gType: number, + endId: number, + count: number, +): Promise { + const url = `${GachaUrl}LimitedRetrieve`; + const header = await getReqHeader(tk); + const params = { + uid: uid, + configType: gType, + endId: endId, + count: count, + }; + const resp = await TGHttp(url, { + method: "GET", + headers: header, + query: params, + }); + if (resp.retcode !== 0) return resp; + return resp.data; +} diff --git a/src/plugins/Hutao/types/Gacha.d.ts b/src/plugins/Hutao/types/Gacha.d.ts new file mode 100644 index 00000000..707a00cf --- /dev/null +++ b/src/plugins/Hutao/types/Gacha.d.ts @@ -0,0 +1,88 @@ +/** + * 祈愿相关 + * @since Beta v0.9.1 + */ + +declare namespace TGApp.Plugins.Hutao.Gacha { + /** + * EntriesResp + * @since Beta v0.9.1 + */ + type EntryResp = TGApp.Plugins.Hutao.Base.Resp; + + /** + * EntriesRes + * @since Beta v0.9.1 + */ + type EntryRes = Array; + + /** + * EntryItem + * @since Beta v0.9.1 + */ + type EntryItem = { + /** UID */ + Uid: string; + /** cnt */ + ItemCount: number; + /** + * excluded + * @remarks 未知用途 + */ + Excluded: boolean; + }; + + /** + * 获取EndId列表响应 + * @since Beta v0.9.1 + */ + type EndIdResp = TGApp.Plugins.Hutao.Base.Resp; + + /** + * EndId返回 + * @since Beta v0.9.1 + */ + type EndIdRes = { + /** 新手 */ + "100": number; + /** 常驻 */ + "200": number; + /** 角色活动 */ + "301": number; + /** 武器活动 */ + "302": number; + /** 集录 */ + "500": number; + }; + + /** + * 祈愿记录返回响应 + * @since Beta v0.9.1 + */ + type GachaLogResp = TGApp.Plugins.Hutao.Base.Resp; + + /** + * 祈愿记录返回 + * @since Beta v0.9.1 + */ + type GachaLogRes = Array; + /** + * 祈愿记录 + * @since Beta v0.9.1 + */ + type GachaLog = { + /** 卡池类型 */ + GachaType: number; + /** 卡池类型(UIGF) */ + QueryType: number; + /** 物品ID */ + ItemId: number; + /** + * 时间 + * @example 2023-05-24T02:33:23+00:00 + */ + Time: string; + /** Id */ + Id: number; + }; +} diff --git a/src/plugins/Hutao/utils/authUtils.ts b/src/plugins/Hutao/utils/authUtils.ts index 0c904746..d7b389a0 100644 --- a/src/plugins/Hutao/utils/authUtils.ts +++ b/src/plugins/Hutao/utils/authUtils.ts @@ -4,8 +4,37 @@ */ import { commands } from "@skipperndt/plugin-machine-uid"; import { getVersion } from "@tauri-apps/api/app"; +import { importPublicKey, sha1 } from "rsa-oaep-encryption"; let DEVICE_ID: string | null = null; +/** 加密公钥 */ +const HUTAO_PUB_KEY: Readonly = ` +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5W2SEyZSlP2zBI1Sn8Gd +TwbZoXlUGNKyoVrY8SVYu9GMefdGZCrUQNkCG/Np8pWPmSSEFGd5oeug/oIMtCZQ +NOn0drlR+pul/XZ1KQhKmj/arWjN1XNok2qXF7uxhqD0JyNT/Fxy6QvzqIpBsM9S +7ajm8/BOGlPG1SInDPaqTdTRTT30AuN+IhWEEFwT3Ctv1SmDupHs2Oan5qM7Y3uw +b6K1rbnk5YokiV2FzHajGUymmSKXqtG1USZzwPqImpYb4Z0M/StPFWdsKqexBqMM +mkXckI5O98GdlszEmQ0Ejv5Fx9fR2rXRwM76S4iZTfabYpiMbb4bM42mHMauupj6 +9QIDAQAB +-----END PUBLIC KEY-----`; +const encrypt = importPublicKey(HUTAO_PUB_KEY); + +/** + * rsa 加密 + * @since Beta v0.9.1 + * @param data - 待加密数据 + * @returns 加密后数据 + */ +export function rsaEncrypt(data: string): string { + const res = encrypt.encrypt(data, sha1.create()); + const bytes = new Uint8Array(res); + let binary = ""; + for (let i = 0; i < bytes.byteLength; i++) { + binary += String.fromCharCode(bytes[i]); + } + return btoa(binary); +} /** * 获取请求头 diff --git a/src/store/modules/hutao.ts b/src/store/modules/hutao.ts index 00a0f925..3323a30c 100644 --- a/src/store/modules/hutao.ts +++ b/src/store/modules/hutao.ts @@ -78,7 +78,7 @@ const useHutaoStore = defineStore( return; } try { - const resp = await hutao.Account.token.refresh(refreshToken.value); + const resp = await hutao.Token.refresh(refreshToken.value); if ("retcode" in resp) { showSnackbar.warn(`[${resp.retcode}] ${resp.message}`); console.error(resp);