♻️ 请求模块重构

This commit is contained in:
目棃
2024-11-19 09:34:18 +08:00
parent 9b1fa22cbe
commit c6f45f0a35
49 changed files with 660 additions and 1120 deletions

View File

@@ -29,7 +29,7 @@ import { useAppStore } from "./store/modules/app.js";
import { useUserStore } from "./store/modules/user.js";
import { getBuildTime } from "./utils/TGBuild.js";
import TGLogger from "./utils/TGLogger.js";
import TGRequest from "./web/request/TGRequest.js";
import OtherApi from "./web/request/otherReq.js";
const appStore = useAppStore();
const userStore = storeToRefs(useUserStore());
@@ -133,7 +133,7 @@ async function checkDeviceFp(): Promise<void> {
const deviceFind = appData.find((item) => item.key === "deviceInfo");
if (typeof deviceFind === "undefined") {
if (deviceLocal.device_fp === "0000000000000") {
appStore.deviceInfo = await TGRequest.Device.getFp(appStore.deviceInfo);
appStore.deviceInfo = await OtherApi.fp(appStore.deviceInfo);
}
await TGSqlite.saveAppData("deviceInfo", JSON.stringify(deviceLocal));
return;

View File

@@ -25,7 +25,7 @@ import { computed } from "vue";
import { useAppStore } from "../../store/modules/app.js";
import { useUserStore } from "../../store/modules/user.js";
import TGLogger from "../../utils/TGLogger.js";
import TGRequest from "../../web/request/TGRequest.js";
import PassportApi from "../../web/request/passportReq.js";
import showSnackbar from "../func/snackbar.js";
const userStore = storeToRefs(useUserStore());
@@ -50,7 +50,7 @@ async function tryPlayGame(): Promise<void> {
showSnackbar.warn("未检测到原神本体应用!");
return;
}
const resp = await TGRequest.User.getAuthTicket(account.value, userStore.cookie.value);
const resp = await PassportApi.authTicket(account.value, userStore.cookie.value);
if (typeof resp !== "string") {
showSnackbar.error(`[${resp.retcode}] ${resp.message}`);
await TGLogger.Error(
@@ -104,13 +104,6 @@ async function tryPlayGame(): Promise<void> {
font-size: 18px;
}
.tgb-btns {
display: flex;
align-items: center;
justify-content: center;
column-gap: 10px;
}
.tgb-name {
font-family: var(--font-title);
}

View File

@@ -110,7 +110,9 @@ import TSUserAccount from "../../plugins/Sqlite/modules/userAccount.js";
import { useAppStore } from "../../store/modules/app.js";
import { useUserStore } from "../../store/modules/user.js";
import TGLogger from "../../utils/TGLogger.js";
import TGRequest from "../../web/request/TGRequest.js";
import BBSApi from "../../web/request/bbsReq.js";
import PassportApi from "../../web/request/passportReq.js";
import TakumiApi from "../../web/request/takumiReq.js";
import showDialog from "../func/dialog.js";
import showGeetest from "../func/geetest.js";
import showLoading from "../func/loading.js";
@@ -164,7 +166,7 @@ async function tryCaptchaLogin(): Promise<void> {
ltoken: "",
};
showLoading.update("正在登录...", "正在获取 LToken");
const ltokenRes = await TGRequest.User.bySToken.getLToken(ck.mid, ck.stoken);
const ltokenRes = await PassportApi.lToken.get(ck);
if (typeof ltokenRes !== "string") {
showLoading.end();
showSnackbar.error(`[${ltokenRes.retcode}]${ltokenRes.message}`);
@@ -174,7 +176,7 @@ async function tryCaptchaLogin(): Promise<void> {
showSnackbar.success("获取LToken成功");
ck.ltoken = ltokenRes;
showLoading.update("正在登录...", "正在获取 CookieToken");
const cookieTokenRes = await TGRequest.User.bySToken.getCookieToken(ck.mid, ck.stoken);
const cookieTokenRes = await PassportApi.cookieToken(ck);
if (typeof cookieTokenRes !== "string") {
showLoading.end();
showSnackbar.error(`[${cookieTokenRes.retcode}]${cookieTokenRes.message}`);
@@ -186,7 +188,7 @@ async function tryCaptchaLogin(): Promise<void> {
showSnackbar.success("获取CookieToken成功");
ck.cookie_token = cookieTokenRes;
showLoading.update("正在登录...", "正在获取用户信息");
const briefRes = await TGRequest.User.byCookie.getUserInfo(ck.cookie_token, ck.account_id);
const briefRes = await BBSApi.userInfo(ck);
if ("retcode" in briefRes) {
showLoading.end();
showSnackbar.error(`[${briefRes.retcode}]${briefRes.message}`);
@@ -212,7 +214,7 @@ async function tryCaptchaLogin(): Promise<void> {
userStore.cookie.value = ck;
appStore.isLogin.value = true;
showLoading.update("正在登录...", "正在获取游戏账号");
const gameRes = await TGRequest.User.byCookie.getAccounts(ck.cookie_token, ck.account_id);
const gameRes = await TakumiApi.bind.gameRoles(userStore.cookie.value);
if (!Array.isArray(gameRes)) {
showLoading.end();
showSnackbar.error(`[${gameRes.retcode}]${gameRes.message}`);
@@ -240,7 +242,7 @@ async function refreshUser(uid: string) {
}
let ck = account.cookie;
showLoading.start("正在刷新用户信息", "正在验证 LToken");
const verifyLTokenRes = await TGRequest.User.verifyLToken(ck.ltoken, ck.ltuid);
const verifyLTokenRes = await PassportApi.lToken.verify(ck);
if (typeof verifyLTokenRes === "string") {
showLoading.update("正在刷新用户信息", "验证 LToken 成功");
showSnackbar.success("验证 LToken 成功");
@@ -252,7 +254,7 @@ async function refreshUser(uid: string) {
await TGLogger.Warn(
`[tc-userBadge][refreshUser] ${verifyLTokenRes.retcode}: ${verifyLTokenRes.message}`,
);
const ltokenRes = await TGRequest.User.bySToken.getLToken(ck.mid, ck.stoken);
const ltokenRes = await PassportApi.lToken.get(ck);
if (typeof ltokenRes === "string") {
showLoading.update("正在刷新用户信息", "获取 LToken 成功");
ck.ltoken = ltokenRes;
@@ -267,7 +269,7 @@ async function refreshUser(uid: string) {
}
}
showLoading.update("正在刷新用户信息", "正在获取 CookieToken");
const cookieTokenRes = await TGRequest.User.bySToken.getCookieToken(ck.mid, ck.stoken);
const cookieTokenRes = await PassportApi.cookieToken(ck);
if (typeof cookieTokenRes === "string") {
showLoading.update("正在刷新用户信息", "获取 CookieToken 成功");
ck.cookie_token = cookieTokenRes;
@@ -282,7 +284,7 @@ async function refreshUser(uid: string) {
}
account.cookie = ck;
showLoading.update("正在刷新用户信息", "正在获取用户信息");
const infoRes = await TGRequest.User.byCookie.getUserInfo(ck.cookie_token, ck.account_id);
const infoRes = await BBSApi.userInfo(ck);
if ("retcode" in infoRes) {
showLoading.update("正在刷新用户信息", "获取用户信息失败");
showSnackbar.error(`[${infoRes.retcode}]${infoRes.message}`);
@@ -300,7 +302,7 @@ async function refreshUser(uid: string) {
}
await TSUserAccount.account.saveAccount(account);
showLoading.update("正在刷新用户信息", "正在获取账号信息");
const accountRes = await TGRequest.User.byCookie.getAccounts(ck.cookie_token, ck.account_id);
const accountRes = await TakumiApi.bind.gameRoles(ck);
if (Array.isArray(accountRes)) {
showLoading.update("正在刷新用户信息", "获取账号信息成功");
await TGLogger.Info("[tc-userBadge][refreshUserInfo] 获取账号信息成功");
@@ -453,7 +455,7 @@ async function addByCookie(): Promise<void> {
ltoken: "",
};
showLoading.update("正在添加用户", "正在获取 LToken");
const ltokenRes = await TGRequest.User.bySToken.getLToken(ck.mid, ck.stoken);
const ltokenRes = await PassportApi.lToken.get(ck);
if (typeof ltokenRes !== "string") {
showLoading.end();
showSnackbar.error(`[${ltokenRes.retcode}]${ltokenRes.message}`);
@@ -462,7 +464,7 @@ async function addByCookie(): Promise<void> {
}
ck.ltoken = ltokenRes;
showLoading.update("正在添加用户", "正在获取 CookieToken");
const cookieTokenRes = await TGRequest.User.bySToken.getCookieToken(ck.mid, ck.stoken);
const cookieTokenRes = await PassportApi.cookieToken(ck);
if (typeof cookieTokenRes !== "string") {
showLoading.end();
showSnackbar.error(`[${cookieTokenRes.retcode}]${cookieTokenRes.message}`);
@@ -473,7 +475,7 @@ async function addByCookie(): Promise<void> {
}
ck.cookie_token = cookieTokenRes;
showLoading.update("正在添加用户", "正在获取用户信息");
const briefRes = await TGRequest.User.byCookie.getUserInfo(ck.cookie_token, ck.account_id);
const briefRes = await BBSApi.userInfo(ck);
if ("retcode" in briefRes) {
showLoading.end();
showSnackbar.error(`[${briefRes.retcode}]${briefRes.message}`);
@@ -494,7 +496,7 @@ async function addByCookie(): Promise<void> {
updated: "",
});
showLoading.update("正在添加用户", "正在获取游戏账号");
const gameRes = await TGRequest.User.bySToken.getAccounts(ck.stoken, ck.stuid);
const gameRes = await TakumiApi.bind.gameRoles(ck);
if (!Array.isArray(gameRes)) {
showLoading.end();
showSnackbar.error(`[${gameRes.retcode}]${gameRes.message}`);

View File

@@ -19,7 +19,7 @@ import { useAppStore } from "../../store/modules/app.js";
import TGClient from "../../utils/TGClient.js";
import TGLogger from "../../utils/TGLogger.js";
import { createPost } from "../../utils/TGWindow.js";
import TGRequest from "../../web/request/TGRequest.js";
import OtherApi from "../../web/request/otherReq.js";
import showDialog from "../func/dialog.js";
import showSnackbar from "../func/snackbar.js";
import ToLivecode from "../overlay/to-livecode.vue";
@@ -64,7 +64,7 @@ async function tryGetCode(): Promise<void> {
return;
}
actId.value = actIdFind;
const res = await TGRequest.Nav.getCode(actIdFind);
const res = await OtherApi.code(actIdFind);
if (!Array.isArray(res)) {
showSnackbar.warn(`[${res.retcode}] ${res.message}`);
return;

View File

@@ -82,7 +82,7 @@ interface TPostCardProps {
}
interface TPostCardEmits {
(e: "update:selected", value: string[]): void;
(e: "onSelected", value: string[]): void;
}
const props = withDefaults(defineProps<TPostCardProps>(), {
@@ -96,7 +96,7 @@ const selectedList = computed({
get: () => props.selected,
set: (v) => {
if (v === undefined) return;
emits("update:selected", v);
emits("onSelected", v);
},
});
const cardBg = computed<string>(() => {

View File

@@ -69,7 +69,7 @@ function getImageUrl(): string {
async function download(): Promise<void> {
const image = props.data.insert.custom_emoticon.url;
if (buffer.value === null) buffer.value = await getImageBuffer(image);
let size = 0;
let size: number;
if (props.data.insert.custom_emoticon.size.file_size) {
size = props.data.insert.custom_emoticon.size.file_size;
} else {

View File

@@ -127,7 +127,7 @@ import TSUserCombat from "../../plugins/Sqlite/modules/userCombat.js";
import { useUserStore } from "../../store/modules/user.js";
import TGLogger from "../../utils/TGLogger.js";
import { generateShareImg } from "../../utils/TGShare.js";
import TGRequest from "../../web/request/TGRequest.js";
import TakumiRecordGenshinApi from "../../web/request/recordReq.js";
// store
const userStore = storeToRefs(useUserStore());
@@ -211,7 +211,7 @@ async function refreshAbyss(): Promise<void> {
}
await TGLogger.Info("[UserAbyss][getAbyssData] 更新深渊数据");
showLoading.start("正在获取上期深渊数据...", `UID: ${user.value.gameUid}`);
const resP = await TGRequest.User.byCookie.getAbyss(userStore.cookie.value, "2", user.value);
const resP = await TakumiRecordGenshinApi.spiralAbyss(userStore.cookie.value, user.value, "2");
if ("retcode" in resP) {
showLoading.end();
showSnackbar.error(`[${resP.retcode}]${resP.message}`);
@@ -223,7 +223,7 @@ async function refreshAbyss(): Promise<void> {
showLoading.update("正在保存上期深渊数据...", `UID: ${user.value.gameUid}`);
await TSUserAbyss.saveAbyss(user.value.gameUid, resP);
showLoading.update("正在获取本期深渊数据...", `UID: ${user.value.gameUid}`);
const res = await TGRequest.User.byCookie.getAbyss(userStore.cookie.value, "1", user.value);
const res = await TakumiRecordGenshinApi.spiralAbyss(userStore.cookie.value, user.value, "1");
if ("retcode" in res) {
showLoading.end();
showSnackbar.error(`[${res.retcode}]${res.message}`);

View File

@@ -110,11 +110,12 @@ import TuaDetailOverlay from "../../components/userAvatar/tua-detail-overlay.vue
import TwoSelectC, { SelectedCValue } from "../../components/wiki/two-select-c.vue";
import { AppCharacterData } from "../../data/index.js";
import TSUserAvatar from "../../plugins/Sqlite/modules/userAvatar.js";
import TSUserRecord from "../../plugins/Sqlite/modules/userRecord.js";
import { useUserStore } from "../../store/modules/user.js";
import TGLogger from "../../utils/TGLogger.js";
import { generateShareImg } from "../../utils/TGShare.js";
import { timestampToDate } from "../../utils/toolFunc.js";
import TGRequest from "../../web/request/TGRequest.js";
import TakumiRecordGenshinApi from "../../web/request/recordReq.js";
// store
const userStore = storeToRefs(useUserStore());
@@ -274,16 +275,20 @@ async function refresh(): Promise<void> {
loadData.value = false;
return;
}
showLoading.update("正在更新角色数据...", "正在获取角色列表");
const indexRes = await TGRequest.User.byCookie.getAvatarIndex(userStore.cookie.value, user.value);
if (indexRes.retcode !== 0) {
showLoading.update("正在更新角色数据...", "正在获取战绩数据");
const indexRes = await TakumiRecordGenshinApi.index(userStore.cookie.value, user.value);
if ("retcode" in indexRes) {
showSnackbar.error(`[${indexRes.retcode}] ${indexRes.message}`);
await TGLogger.Error(JSON.stringify(indexRes.message));
showLoading.end();
loadData.value = false;
return;
} else {
showLoading.update("正在更新角色数据...", "正在保存战绩数据");
await TSUserRecord.saveRecord(Number(user.value.gameUid), indexRes);
}
const listRes = await TGRequest.User.byCookie.getAvatarList(userStore.cookie.value, user.value);
showLoading.update("正在更新角色数据...", "正在获取角色列表");
const listRes = await TakumiRecordGenshinApi.character.list(userStore.cookie.value, user.value);
if (!Array.isArray(listRes)) {
showSnackbar.error(`[${listRes.retcode}] ${listRes.message}`);
await TGLogger.Error(`[Character][refreshRoles][${user.value.gameUid}] 获取角色列表失败`);
@@ -296,7 +301,7 @@ async function refresh(): Promise<void> {
}
const idList = listRes.map((i) => i.id.toString());
showLoading.update("正在更新角色数据...", `${idList.length}个角色`);
const res = await TGRequest.User.byCookie.getAvatarDetail(
const res = await TakumiRecordGenshinApi.character.detail(
userStore.cookie.value,
user.value,
idList,

View File

@@ -107,7 +107,7 @@ import TSUserCombat from "../../plugins/Sqlite/modules/userCombat.js";
import { useUserStore } from "../../store/modules/user.js";
import TGLogger from "../../utils/TGLogger.js";
import { generateShareImg } from "../../utils/TGShare.js";
import TGRequest from "../../web/request/TGRequest.js";
import TakumiRecordGenshinApi from "../../web/request/recordReq.js";
// store
const userStore = storeToRefs(useUserStore());
@@ -183,7 +183,7 @@ async function refreshCombat(): Promise<void> {
}
await TGLogger.Info("[UserCombat][getCombatData] 更新剧诗数据");
showLoading.start("正在获取剧诗数据...", `UID: ${user.value.gameUid}`);
const res = await TGRequest.User.byCookie.getCombat(userStore.cookie.value, user.value);
const res = await TakumiRecordGenshinApi.roleCombat(userStore.cookie.value, user.value);
if (res === false) {
showLoading.end();
showSnackbar.warn("用户未解锁幻想真境剧诗");

View File

@@ -72,7 +72,8 @@ import {
verifyUigfData,
exportUigf4Data,
} from "../../utils/UIGF.js";
import TGRequest from "../../web/request/TGRequest.js";
import Hk4eApi from "../../web/request/hk4eReq.js";
import TakumiApi from "../../web/request/takumiReq.js";
// store
const userStore = storeToRefs(useUserStore());
@@ -147,7 +148,7 @@ async function confirmRefresh(force: boolean): Promise<void> {
await TGLogger.Warn("[UserGacha][${account.gameUid}][confirmRefresh] 未检测到 cookie");
return;
}
const authkeyRes = await TGRequest.User.getAuthkey(userStore.cookie.value, account.value);
const authkeyRes = await TakumiApi.bind.authKey(userStore.cookie.value, account.value);
if (typeof authkeyRes === "string") {
authkey.value = authkeyRes;
await TGLogger.Info(`[UserGacha][${account.value.gameUid}][confirmRefresh] 成功获取 authkey`);
@@ -204,7 +205,7 @@ async function getGachaLogs(
await TGLogger.Info(
`[UserGacha][${uid}][getGachaLogs] 获取祈愿数据pool${pool}endId${endId}`,
);
const gachaRes = await TGRequest.User.getGachaLog(authkey.value, pool, endId);
const gachaRes = await Hk4eApi.gacha(authkey.value, pool, endId);
console.log(pool, endId, gachaRes);
if (Array.isArray(gachaRes)) {
await TGLogger.Info(

View File

@@ -72,7 +72,7 @@ import TSUserRecord from "../../plugins/Sqlite/modules/userRecord.js";
import { useUserStore } from "../../store/modules/user.js";
import TGLogger from "../../utils/TGLogger.js";
import { generateShareImg } from "../../utils/TGShare.js";
import TGRequest from "../../web/request/TGRequest.js";
import TakumiRecordGenshinApi from "../../web/request/recordReq.js";
// store
const userStore = storeToRefs(useUserStore());
@@ -144,27 +144,25 @@ async function refreshRecord(): Promise<void> {
await TGLogger.Warn(`[UserRecord][refresh][${user.value.gameUid}] 未登录`);
return;
}
const cookie = {
account_id: userStore.cookie.value.account_id,
cookie_token: userStore.cookie.value.cookie_token,
};
const res = await TGRequest.User.getRecord(cookie, user.value);
if (!("retcode" in res)) {
await TGLogger.Info(`[UserRecord][refresh][${user.value.gameUid}] 获取战绩数据成功`);
await TGLogger.Info(`[UserRecord][refresh][${user.value.gameUid}]`, false);
await TGLogger.Info(JSON.stringify(res), false);
showLoading.update("正在保存战绩数据");
await TSUserRecord.saveRecord(Number(user.value.gameUid), res);
await loadUid();
await loadRecord();
if (recordData.value === undefined) await loadRecord();
} else {
const res = await TakumiRecordGenshinApi.index(userStore.cookie.value, user.value);
if ("retcode" in res) {
showLoading.end();
showSnackbar.error(`[${res.retcode}] ${res.message}`);
await TGLogger.Error(`[UserRecord][refresh][${user.value.gameUid}] 获取战绩数据失败`);
await TGLogger.Error(
`[UserRecord][refresh][${user.value.gameUid}] ${res.retcode} ${res.message}`,
);
return;
}
await TGLogger.Info(`[UserRecord][refresh][${user.value.gameUid}] 获取战绩数据成功`);
await TGLogger.Info(`[UserRecord][refresh][${user.value.gameUid}]`, false);
await TGLogger.Info(JSON.stringify(res), false);
showLoading.update("正在保存战绩数据");
await TSUserRecord.saveRecord(Number(user.value.gameUid), res);
showLoading.update("正在加载战绩数据");
await loadUid();
await loadRecord();
if (recordData.value === undefined) await loadRecord();
showLoading.end();
}

View File

@@ -41,7 +41,7 @@
<v-window v-model="tab">
<v-window-item v-for="(value, index) in tabValues" :key="index" :value="value">
<div class="anno-grid">
<TAnnocard
<TAnnoCard
v-for="item in annoCards[value]"
:key="item.id"
:model-value="item"
@@ -59,11 +59,10 @@ import { useRouter } from "vue-router";
import showLoading from "../../components/func/loading.js";
import showSnackbar from "../../components/func/snackbar.js";
import TAnnocard from "../../components/main/t-annocard.vue";
import TAnnoCard from "../../components/main/t-annocard.vue";
import { useAppStore } from "../../store/modules/app.js";
import TGLogger from "../../utils/TGLogger.js";
import { AnnoLang, AnnoServer } from "../../web/request/getAnno.js";
import TGRequest from "../../web/request/TGRequest.js";
import Hk4eApi, { AnnoLang, AnnoServer } from "../../web/request/hk4eReq.js";
import { getAnnoCard } from "../../web/utils/getAnnoCard.js";
import { decodeRegExp } from "../../web/utils/tools.js";
@@ -144,12 +143,12 @@ async function loadData(): Promise<void> {
"正在获取公告数据",
`服务器:${getRegionName(curRegion.value)},语言:${getLangName(curLang.value)}`,
);
const annoData = await TGRequest.Anno.getList(curRegion.value, curLang.value);
const annoData = await Hk4eApi.anno.list(curRegion.value, curLang.value);
const listCards = getAnnoCard(annoData);
await Promise.all(
listCards.map(async (item) => {
if (item.typeLabel === AnnoType.game) return;
const detail = await TGRequest.Anno.getContent(item.id, curRegion.value, "zh-cn");
const detail = await Hk4eApi.anno.content(item.id, curRegion.value, "zh-cn");
const timeStr = getAnnoTime(detail.content);
if (timeStr !== false) item.timeStr = timeStr;
}),

View File

@@ -129,7 +129,7 @@ import { backUpUserData, restoreUserData } from "../../utils/dataBS.js";
import { getBuildTime } from "../../utils/TGBuild.js";
import TGLogger from "../../utils/TGLogger.js";
import { bytesToSize, getCacheDir, getDeviceInfo, getRandomString } from "../../utils/toolFunc.js";
import TGRequest from "../../web/request/TGRequest.js";
import OtherApi from "../../web/request/otherReq.js";
// Store
const appStore = useAppStore();
@@ -244,7 +244,7 @@ async function confirmUpdateDevice(force?: boolean): Promise<void> {
await TGLogger.Info("[Config][confirmUpdateDevice][force] 取消强制更新设备信息");
return;
}
appStore.deviceInfo = await TGRequest.Device.getFp();
appStore.deviceInfo = await OtherApi.fp();
if (appStore.deviceInfo.device_fp === "0000000000000") {
appStore.deviceInfo.device_fp = getRandomString(13, "hex");
showSnackbar.warn(`设备信息获取失败!已使用随机值${appStore.deviceInfo.device_fp}代替`);
@@ -267,7 +267,7 @@ async function confirmUpdateDevice(force?: boolean): Promise<void> {
}
}
console.log(appStore.deviceInfo);
appStore.deviceInfo = await TGRequest.Device.getFp(appStore.deviceInfo);
appStore.deviceInfo = await OtherApi.fp(appStore.deviceInfo);
console.log(appStore.deviceInfo);
if (appStore.deviceInfo.device_fp === "0000000000000") {
appStore.deviceInfo.device_fp = getRandomString(13, "hex");

View File

@@ -78,7 +78,7 @@
<div class="pc-posts">
<div v-for="item in getPageItems()" :key="item.post.post_id">
<TPostCard
@update:selected="(v) => (selectedPost = v)"
@onSelected="handleSelected"
:model-value="item"
:selected="selectedPost"
:select-mode="selectedMode"
@@ -102,7 +102,7 @@ import ToCollectPost from "../../components/overlay/to-collectPost.vue";
import TSUserCollection from "../../plugins/Sqlite/modules/userCollect.js";
import { useUserStore } from "../../store/modules/user.js";
import TGLogger from "../../utils/TGLogger.js";
import TGRequest from "../../web/request/TGRequest.js";
import BBSApi from "../../web/request/bbsReq.js";
const userStore = storeToRefs(useUserStore());
@@ -134,6 +134,10 @@ onUnmounted(() => {
}
});
function handleSelected(v: string[]) {
selectedPost.value = v;
}
function sortPost(value: boolean) {
let ori = sortId.value;
sortId.value = value;
@@ -364,12 +368,9 @@ async function freshUser(uid?: string): Promise<void> {
showSnackbar.warn("请先登录");
return;
}
const cookie = {
cookie_token: userStore.cookie.value.cookie_token,
account_id: userStore.cookie.value.account_id,
};
showLoading.start("获取用户收藏...", `UID: ${uid || userStore.briefInfo.value.uid}`);
let res = await TGRequest.User.getCollect(cookie, uid || userStore.briefInfo.value.uid);
const uidReal = uid || userStore.briefInfo.value.uid;
showLoading.start("获取用户收藏...", `UID: ${uidReal}`);
let res = await BBSApi.lovePost(userStore.cookie.value, uidReal);
while (true) {
if ("retcode" in res) {
showLoading.end();
@@ -385,8 +386,8 @@ async function freshUser(uid?: string): Promise<void> {
await mergePosts(posts, uid || userStore.briefInfo.value.uid);
if (res.is_last) break;
showLoading.update("获取用户收藏...", `[offset]${res.next_offset} [is_last]${res.is_last}`);
res = await TGRequest.User.getCollect(
cookie,
res = await BBSApi.lovePost(
userStore.cookie.value,
uid || userStore.briefInfo.value.uid,
res.next_offset,
);

View File

@@ -9,7 +9,7 @@ import { defineStore } from "pinia";
import { reactive, ref } from "vue";
import { getInitDeviceInfo } from "../../utils/toolFunc.js";
import { type AnnoLang, AnnoServer } from "../../web/request/getAnno.js";
import { type AnnoLang, AnnoServer } from "../../web/request/hk4eReq.js";
// 用于存储用户数据的路径
const userDataDir = `${await path.appLocalDataDir()}${path.sep()}userData`;

View File

@@ -89,91 +89,6 @@ declare namespace TGApp.BBS.Response {
};
}
/**
* @description 通过 gameToken 获取 stoken 的返回类型
* @interface getStokenByGameToken
* @since Beta v0.3.0
* @extends BaseWithData
* @property {getStokenByGameTokenData} data - 返回数据
* @return getStokenByGameToken
*/
interface getStokenByGameToken extends BaseWithData {
data: getStokenByGameTokenData;
}
/**
* @description 通过 gameToken 获取 stoken 的返回类型数据
* @interface getStokenByGameTokenData
* @since Beta v0.3.0
* @property {number} token.token_type - token 类型
* @property {string} token.token - token 值
* @property {TGApp.BBS.Account.getStokenByGameTokenInfo} user_info - 用户信息
* @property {unknown} realname_info - 实名信息
* @property {boolean} need_realperson - 是否需要实名认证
* @return getStokenByGameToken
*/
interface getStokenByGameTokenData {
token: {
token_type: number;
token: string;
};
user_info: TGApp.BBS.Account.getStokenByGameTokenInfo;
realname_info: unknown;
need_realperson: boolean;
}
/**
* @description 通过 stoken v1 获取 stoken v2 的返回类型
* @interface getTokenBySToken
* @since Beta v0.4.3
* @extends BaseWithData
* @property {getStokenByGameTokenData} data - 返回数据
* @return getTokenBySToken
*/
interface getTokenBySToken extends BaseWithData {
data: getStokenByGameTokenData;
}
/**
* @description 通过 stoken v1 获取 stoken v2 的返回类型数据
* @interface getTokenBySTokenData
* @since Beta v0.4.3
* @property {unknown} need_realperson - 是否需要实名认证
* @property {string} token.token - token 值
* @property {number} token.token_type - token 类型
* @description user_info 只写了用到的字段
* @property {string} user_info.aid - 用户 aid
* @property {string} user_info.mid - 用户 mid
* @returns getTokenBySTokenData
*/
interface getTokenBySTokenData {
need_realperson: boolean;
token: {
token: string;
token_type: number;
};
user_info: {
aid: string;
mid: string;
};
}
/**
* @description 通过 gameToken 获取 cookie_token 的返回类型
* @interface getCookieTokenByGameToken
* @since Beta v0.3.0
* @extends BaseWithData
* @property {string} data.uid - 用户 uid
* @property {string} data.cookie_token - cookie_token 值
* @return getCookieTokenByGameToken
*/
interface getCookieTokenByGameToken extends BaseWithData {
data: {
uid: string;
cookie_token: string;
};
}
/**
* @description 通过 sToken 获取 actionTicket 的返回类型
* @interface getActionTicketBySToken

View File

@@ -45,7 +45,7 @@ declare namespace TGApp.Game.Combat {
* @property {number} avatar_id 角色id
* @property {number} avatar_type 角色类型 // 0-自己角色1-试用角色2-助演角色
* @property {string} name 角色名称
* @property {string} element 角色元素 // todo Dendro
* @property {string} element 角色元素
* @property {string} image 角色图像
* @property {number} level 角色等级
* @property {number} rarity 角色稀有度
@@ -116,7 +116,7 @@ declare namespace TGApp.Game.Combat {
* @since Beta v0.6.3
* @property {string} icon 图标
* @property {string} name 名称
* @property {string} desc 描述 // todo 带 <color>
* @property {string} desc 描述
* @property {boolean} is_enhanced 是否加强
* @property {number} id ID
* @return Card

View File

@@ -13,8 +13,10 @@ import TGSqlite from "../plugins/Sqlite/index.js";
import { useAppStore } from "../store/modules/app.js";
import { useUserStore } from "../store/modules/user.js";
import TGConstant from "../web/constant/TGConstant.js";
import { getCookieTokenBySToken } from "../web/request/getCookieToken.js";
import TGRequest from "../web/request/TGRequest.js";
import BBSApi from "../web/request/bbsReq.js";
import OtherApi from "../web/request/otherReq.js";
import PassportApi from "../web/request/passportReq.js";
import TakumiApi from "../web/request/takumiReq.js";
import { getDS4JS } from "../web/utils/getRequestHeader.js";
import { parseLink } from "./linkParser.js";
@@ -531,7 +533,7 @@ class TGClient {
const userStore = useUserStore();
if (!userStore.cookie) return;
const cookie = { mid: userStore.cookie.mid, stoken: userStore.cookie.stoken };
const res = await TGRequest.User.getAuthkey2(cookie, arg.payload);
const res = await TakumiApi.bind.authKey2(cookie, arg.payload);
await this.callback(arg.callback, res.data);
}
@@ -545,16 +547,12 @@ class TGClient {
async getActionTicket(
arg: TGApp.Plugins.JSBridge.Arg<TGApp.Plugins.JSBridge.GetActionTicketPayload>,
): Promise<void> {
const user = useUserStore();
if (!user.cookie) return;
const uid = user.account.gameUid;
const mid = user.cookie.mid;
const stoken = user.cookie.stoken;
const ActionTicket = await TGRequest.User.bySToken.getActionTicket(
const userStore = useUserStore();
if (!userStore.cookie) return;
const ActionTicket = await TakumiApi.auth.actionTicket(
userStore.cookie,
userStore.account,
arg.payload.action_type,
stoken,
mid,
uid,
);
await this.callback(arg.callback, ActionTicket.data);
}
@@ -586,7 +584,7 @@ class TGClient {
const user = useUserStore();
if (!user.cookie) return;
if (arg.payload.forceRefresh) {
const res = await getCookieTokenBySToken(user.cookie.mid, user.cookie.stoken);
const res = await PassportApi.cookieToken(user.cookie);
if (typeof res !== "string") return;
user.cookie.cookie_token = res;
await TGSqlite.saveAppData("cookie", JSON.stringify(user.cookie));
@@ -647,9 +645,7 @@ class TGClient {
async getHTTPRequestHeaders(arg: TGApp.Plugins.JSBridge.NullArg): Promise<void> {
const localFp = getDeviceInfo("device_fp");
let deviceInfo = useAppStore().deviceInfo;
if (localFp === "0000000000000") {
deviceInfo = await TGRequest.Device.getFp(deviceInfo);
}
if (localFp === "0000000000000") deviceInfo = await OtherApi.fp(deviceInfo);
const data = {
"user-agent": TGConstant.BBS.UA_MOBILE,
"x-rpc-client_type": "2",
@@ -682,9 +678,7 @@ class TGClient {
async getUserInfo(arg: TGApp.Plugins.JSBridge.NullArg): Promise<void> {
const user = useUserStore();
if (!user.cookie) return;
const cookieToken = user.cookie.cookie_token;
const accountId = user.cookie.account_id;
const userInfo = await TGRequest.User.byCookie.getUserInfo(cookieToken, accountId);
const userInfo = await BBSApi.userInfo(user.cookie);
if ("retcode" in userInfo) {
console.error(`[${arg.callback}] ${userInfo.message}`);
return;

View File

@@ -14,8 +14,7 @@ import { useRoute } from "vue-router";
import TSwitchTheme from "../components/app/t-switchTheme.vue";
import showLoading from "../components/func/loading.js";
import { AnnoLang, AnnoServer } from "../web/request/getAnno.js";
import TGRequest from "../web/request/TGRequest.js";
import Hk4eApi, { AnnoLang, AnnoServer } from "../web/request/hk4eReq.js";
// 数据
const route = useRoute();
@@ -32,13 +31,13 @@ onMounted(async () => {
return;
}
showLoading.update("正在获取数据...", `公告ID: ${annoId}`);
const listData = await TGRequest.Anno.getList();
const listData = await Hk4eApi.anno.list(region, lang);
listData.list.map((item: TGApp.BBS.Announcement.ListItem) => {
return item.list.map((single: TGApp.BBS.Announcement.AnnoSingle) => {
return single.ann_id === annoId ? (jsonList.value = single) : null;
});
});
jsonContent.value = await TGRequest.Anno.getContent(annoId, region, lang);
jsonContent.value = await Hk4eApi.anno.content(annoId, region, lang);
showLoading.end();
});
</script>

View File

@@ -24,8 +24,7 @@ import showLoading from "../components/func/loading.js";
import { useAppStore } from "../store/modules/app.js";
import TGLogger from "../utils/TGLogger.js";
import { createTGWindow } from "../utils/TGWindow.js";
import { AnnoLang, AnnoServer } from "../web/request/getAnno.js";
import TGRequest from "../web/request/TGRequest.js";
import Hk4eApi, { AnnoLang, AnnoServer } from "../web/request/hk4eReq.js";
const annoRef = ref<HTMLElement>(<HTMLElement>{});
const annoTitle = ref<string>("");
@@ -48,7 +47,7 @@ onMounted(async () => {
}
showLoading.update("正在获取数据...", `公告ID:${annoId}`);
try {
annoData.value = await TGRequest.Anno.getContent(annoId, region, lang);
annoData.value = await Hk4eApi.anno.content(annoId, region, lang);
showLoading.update("正在渲染数据...", `公告ID${annoId}`);
annoTitle.value = `Anno_${annoId}`;
await webviewWindow

View File

@@ -1,10 +0,0 @@
/**
* @file web api BBS.ts
* @description BBS API
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
*/
const BBS_API = "https://bbs-api.miyoushe.com/"; // 基础 API
export const BBSUserInfoApi = `${BBS_API}user/wapi/getUserFullInfo`; // 用户信息 API

View File

@@ -1,8 +0,0 @@
/**
* @file web api ENKA.ts
* @description ENKA API
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
*/
export const ENKA_API = "https://enka.network/api/uid/"; // 基础 API

View File

@@ -1,14 +0,0 @@
/**
* @file web api Passport.ts
* @description 定义 Passport API
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.0
*/
const PassportApi = "https://passport-api.mihoyo.com/"; // 基础 API
const PassportV4Api = "https://passport-api-v4.mihoyo.com/"; // 基础 API
const PassportAuthApi = `${PassportApi}account/auth/api/`; // 认证 API
export const PassportTokenApi = `${PassportAuthApi}getLTokenBySToken`; // 根据 stoken 获取 ltoken
export const PassportCookieTokenApi = `${PassportAuthApi}getCookieAccountInfoBySToken`; // 根据 Cookie 获取 Token
export const PassportVerifyApi = `${PassportV4Api}account/ma-cn-session/web/verifyLtoken`; // 验证 stoken 有效性

View File

@@ -1,58 +0,0 @@
/**
* @file web/api/TGApi.ts
* @description 应用用到的 API
* @since Beta v0.6.2
*/
import { BBSUserInfoApi } from "./BBS.js";
import { ENKA_API } from "./ENKA.js";
import { PassportTokenApi, PassportCookieTokenApi, PassportVerifyApi } from "./Passport.js";
import {
TakumiTokensApi,
TakumiRecordCardApi,
TakumiRecordCharactersApi,
TakumiRecordDailyNotesApi,
TakumiRecordIndexApi,
TakumiRecordAbyssApi,
TakumiSTokenBindingRolesApi,
TakumiCookieBindingRolesApi,
TakumiCalculateSyncAvatarListApi,
TakumiCalculateSyncAvatarDetailApi,
TakumiRecordCharacterListApi,
TakumiRecordCharacterDetailApi,
TakumiRecordCombatApi,
} from "./Takumi.js";
// 应用 API
const TGApi = {
GameEnka: ENKA_API, // 游戏 ENKA API
GameTokens: {
getTokens: TakumiTokensApi, // 根据 login_ticket 获取游戏 Token
getLToken: PassportTokenApi, // 根据 stoken 获取 ltoken
getCookieToken: PassportCookieTokenApi, // 根据 Cookie 获取 Token
verifyLToken: PassportVerifyApi, // 验证 ltoken 有效性
},
GameData: {
byCookie: {
getUserInfo: BBSUserInfoApi, // 获取用户信息
getAccounts: TakumiCookieBindingRolesApi, // 获取绑定角色
getCharacter: TakumiRecordCharactersApi, // 获取角色信息
getAvatarList: TakumiRecordCharacterListApi, // 获取角色列表
getAvatarDetail: TakumiRecordCharacterDetailApi, // 获取角色详情
},
bySToken: {
getAccounts: TakumiSTokenBindingRolesApi, // 获取绑定角色
},
calculate: {
getSyncAvatarList: TakumiCalculateSyncAvatarListApi, // 同步角色列表
getSyncAvatarDetail: TakumiCalculateSyncAvatarDetailApi, // 同步角色详情
},
getUserCard: TakumiRecordCardApi, // 获取用户卡片
getUserBase: TakumiRecordIndexApi, // 获取用户基本信息
getDailyNotes: TakumiRecordDailyNotesApi, // 获取实时便笺
getAbyss: TakumiRecordAbyssApi, // 获取深境螺旋信息
getRoleCombat: TakumiRecordCombatApi, // 获取幻想真境剧诗
},
};
export default TGApi;

View File

@@ -1,28 +0,0 @@
/**
* @file web/api/Takumi.ts
* @description 定义 Takumi API
* @since Beta v0.6.2
*/
const TakumiApi = "https://api-takumi.mihoyo.com/"; // 基础 API
const TakumiAuthApi = `${TakumiApi}auth/api/`; // 认证 API
const TakumiBindingApi = `${TakumiApi}binding/api/`; // 绑定 API
const TakumiCalculateApi = `${TakumiApi}event/e20200928calculate/`; // 计算 API
const TakumiRecordApi = "https://api-takumi-record.mihoyo.com/"; // 游戏记录 API
const TakumiRecordGenshinApi = `${TakumiRecordApi}game_record/app/genshin/api/`; // 原神游戏记录 API
export const TakumiTokensApi = `${TakumiAuthApi}getMultiTokenByLoginTicket`; // 登录票据 API
export const TakumiRecordDailyNotesApi = `${TakumiRecordGenshinApi}dailyNote`; // 游戏记录便笺 API
export const TakumiRecordCardApi = `${TakumiRecordApi}game_record/app/card/wapi/getGameRecordCard`; // 游戏记录卡片 API
export const TakumiRecordIndexApi = `${TakumiRecordGenshinApi}index`; // 原神游戏记录索引 API
export const TakumiRecordCharactersApi = `${TakumiRecordGenshinApi}character`; // 原神游戏记录角色 API
export const TakumiRecordCharacterListApi = `${TakumiRecordCharactersApi}/list`; // 原神游戏记录角色列表 API
export const TakumiRecordCharacterDetailApi = `${TakumiRecordCharactersApi}/detail`; // 原神游戏记录角色详情 API
export const TakumiRecordAbyssApi = `${TakumiRecordGenshinApi}spiralAbyss`; // 原神游戏记录深境螺旋 API
export const TakumiRecordCombatApi = `${TakumiRecordGenshinApi}role_combat`;
export const TakumiSTokenBindingRolesApi = `${TakumiBindingApi}getUserGameRolesBySToken`; // 获取绑定角色 API-根据 stoken
export const TakumiCookieBindingRolesApi = `${TakumiBindingApi}getUserGameRolesByCookie`; // 获取绑定角色 API-根据 Cookie
// 养成计算器 API
export const TakumiCalculateSyncAvatarListApi = `${TakumiCalculateApi}v1/sync/avatar/list`;
export const TakumiCalculateSyncAvatarDetailApi = `${TakumiCalculateApi}v1/sync/avatar/detail`;

View File

@@ -1,68 +0,0 @@
/**
* @file web/request/TGRequest.ts
* @description 应用用到的请求函数
* @since Beta v0.6.3
*/
import { genAuthkey, genAuthkey2 } from "./genAuthkey.js";
import { getAbyss } from "./getAbyss.js";
import { getActionTicketBySToken } from "./getActionTicket.js";
import { getAnnoContent, getAnnoList } from "./getAnno.js";
import getAuthTicket from "./getAuthTicket.js";
import { getAvatarList, getAvatarDetail, getAvatarIndex } from "./getAvatarDetail.js";
import getCode from "./getCode.js";
import { getCookieTokenByGameToken, getCookieTokenBySToken } from "./getCookieToken.js";
import { getDeviceFp } from "./getDeviceFp.js";
import { getGachaLog } from "./getGachaLog.js";
import { getGameAccountsByCookie, getGameAccountsBySToken } from "./getGameAccounts.js";
import { getGameRecord } from "./getGameRecord.js";
import { getLTokenBySToken } from "./getLToken.js";
import { getRoleCombat } from "./getRoleCombat.js";
import { getStokenByGameToken, getTokenBySToken } from "./getStoken.js";
import { getUserCollect } from "./getUserCollect.js";
import { getUserInfoByCookie } from "./getUserInfo.js";
import { verifyLToken } from "./verifyLToken.js";
const TGRequest = {
Anno: {
getList: getAnnoList,
getContent: getAnnoContent,
},
Device: {
getFp: getDeviceFp,
},
User: {
getAuthkey: genAuthkey,
getAuthkey2: genAuthkey2,
getAuthTicket,
getCollect: getUserCollect,
getGachaLog,
getRecord: getGameRecord,
verifyLToken,
byCookie: {
getAbyss,
getAccounts: getGameAccountsByCookie,
getUserInfo: getUserInfoByCookie,
getAvatarIndex,
getAvatarList,
getAvatarDetail,
getCombat: getRoleCombat,
},
bySToken: {
update: getTokenBySToken,
getAccounts: getGameAccountsBySToken,
getCookieToken: getCookieTokenBySToken,
getLToken: getLTokenBySToken,
getActionTicket: getActionTicketBySToken,
},
bgGameToken: {
getCookieToken: getCookieTokenByGameToken,
getStoken: getStokenByGameToken,
},
},
Nav: {
getCode,
},
};
export default TGRequest;

63
src/web/request/bbsReq.ts Normal file
View File

@@ -0,0 +1,63 @@
/**
* @file web/request/bbsReq.ts
* @description BBS 请求模块
* @since Beta v0.6.3
*/
import TGHttp from "../../utils/TGHttp.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 根据 cookie 获取用户信息
* @since Beta v0.5.0
* @param {TGApp.App.Account.Cookie} cookie - 账户 cookie
* @returns {Promise<TGApp.BBS.Response.Base | TGApp.Plugins.Mys.User.Info>}
*/
async function getUserFullInfo(
cookie: TGApp.App.Account.Cookie,
): Promise<TGApp.BBS.Response.Base | TGApp.Plugins.Mys.User.Info> {
const url = "https://bbs-api.miyoushe.com/user/wapi/getUserFullInfo";
const ck = { cookie_token: cookie.cookie_token, account_id: cookie.account_id };
const params = { gids: "2" };
const header = getRequestHeader(ck, "GET", params, "common", true);
const resp = await TGHttp<TGApp.Plugins.Mys.User.HomeResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.user_info;
}
/**
* @description 获取用户收藏帖子
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie - 用户 cookie
* @param {string} uid - 用户 uid
* @param {string} offset - 偏移量
* @returns {Promise<TGApp.BBS.Collection.PostRespData|TGApp.BBS.Response.Base>} 用户收藏帖子
*/
async function userFavouritePost(
cookie: TGApp.App.Account.Cookie,
uid: string,
offset: string = "",
): Promise<TGApp.BBS.Collection.PostRespData | TGApp.BBS.Response.Base> {
const url = "https://bbs-api.miyoushe.com/post/wapi/userFavouritePost";
const ck = { cookie_token: cookie.cookie_token, account_id: cookie.account_id };
const params = { size: "20", uid, offset };
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.BBS.Collection.PostResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}
const BBSApi = {
userInfo: getUserFullInfo,
lovePost: userFavouritePost,
};
export default BBSApi;

View File

@@ -1,58 +0,0 @@
/**
* @file web/request/genAuthkey.ts
* @description 生成 authkey
* @since Beta v0.6.2
*/
import TGHttp from "../../utils/TGHttp.js";
import TGConstant from "../constant/TGConstant.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 生成 authkey
* @since Beta v0.6.2
* @param {TGApp.App.Account.Cookie} cookie cookie
* @param {TGApp.Sqlite.Account.Game} account 账户
* @returns {Promise<string|TGApp.BBS.Response.Base>} authkey
*/
export async function genAuthkey(
cookie: TGApp.App.Account.Cookie,
account: TGApp.Sqlite.Account.Game,
): Promise<string | TGApp.BBS.Response.Base> {
const url = "https://api-takumi.mihoyo.com/binding/api/genAuthKey";
const ck = { stoken: cookie.stoken, mid: cookie.mid };
const data = {
auth_appid: "webview_gacha",
game_biz: TGConstant.GAME_BIZ,
game_uid: account.gameUid,
region: account.region,
};
const header = getRequestHeader(ck, "POST", JSON.stringify(data), "lk2", true);
const resp = await TGHttp<TGApp.Game.Gacha.AuthkeyResponse | TGApp.BBS.Response.Base>(url, {
method: "POST",
headers: header,
body: JSON.stringify(data),
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.authkey;
}
/**
* @description 生成 authkey
* @since Beta v0.5.0
* @param {Record<string, string>} cookie cookie // stoken_v2 & mid
* @param {object} payload payload
* @returns {Promise<string|TGApp.BBS.Response.Base>} authkey
*/
export async function genAuthkey2(
cookie: Record<string, string>,
payload: Record<string, string>,
): Promise<TGApp.BBS.Response.Base> {
const url = "https://api-takumi.mihoyo.com/binding/api/genAuthKey";
const header = getRequestHeader(cookie, "POST", JSON.stringify(payload), "lk2", true);
return await TGHttp<TGApp.BBS.Response.Base>(url, {
method: "POST",
headers: header,
body: JSON.stringify(payload),
});
}

View File

@@ -1,40 +0,0 @@
/**
* @file web/request/getAbyss.ts
* @description 获取深渊信息
* @since Beta v0.6.1
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 获取深渊信息
* @since Beta v0.6.1
* @param {TGApp.App.Account.Cookie} cookie cookie
* @param {string} schedule 1: 本期, 2: 上期
* @param {TGApp.Sqlite.Account.Game} account 游戏账号
* @returns {Promise<TGApp.Game.Abyss.FullData|TGApp.BBS.Response.Base>}
*/
export async function getAbyss(
cookie: TGApp.App.Account.Cookie,
schedule: string,
account: TGApp.Sqlite.Account.Game,
): Promise<TGApp.Game.Abyss.FullData | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.getAbyss;
const params = { role_id: account.gameUid, schedule_type: schedule, server: account.region };
const ck = {
account_id: cookie.account_id,
cookie_token: cookie.cookie_token,
ltoken: cookie.ltoken,
ltuid: cookie.ltuid,
};
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.Game.Abyss.Response | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}

View File

@@ -1,34 +0,0 @@
/**
* @file web/request/getActionTicket.ts
* @description 获取米游社动态的 ActionTicket
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 通过 stoken 获取 ActionTicket
* @since Beta v0.5.0
* @param {string} ActionType 动作类型
* @param {string} SToken stoken
* @param {string} MID 用户 MID
* @param {string} UID 用户 UID
* @returns {Promise<TGApp.BBS.Response.getActionTicketBySToken>}
*/
export async function getActionTicketBySToken(
ActionType: string,
SToken: string,
MID: string,
UID: string,
): Promise<TGApp.BBS.Response.getActionTicketBySToken> {
const url = "https://api-takumi.mihoyo.com/auth/api/getActionTicketBySToken";
const params = { action_type: ActionType, stoken: SToken, uid: UID };
const cookie = { mid: MID, stoken: SToken };
const header = getRequestHeader(cookie, "GET", params, "k2");
return await TGHttp<TGApp.BBS.Response.getActionTicketBySToken>(url, {
method: "GET",
headers: header,
query: params,
});
}

View File

@@ -1,41 +0,0 @@
/**
* @files web/request/getAuthTicket.ts
* @description 获取登录 ticket
* @since Beta v0.6.0
*/
import TGHttp from "../../utils/TGHttp.js";
/**
* @description 获取登录ticket
* @since Beta v0.6.0
* @param {TGApp.Sqlite.Account.Game} account - 账户
* @param {TGApp.App.Account.Cookie} cookie - cookie
* @returns {Promise<TGApp.BBS.Response.Base|string>}
*/
async function getAuthTicket(
account: TGApp.Sqlite.Account.Game,
cookie: TGApp.App.Account.Cookie,
): Promise<TGApp.BBS.Response.Base | string> {
const url =
"https://passport-api.mihoyo.com/account/ma-cn-verifier/app/createAuthTicketByGameBiz";
const params = {
game_biz: account.gameBiz,
stoken: cookie.stoken,
uid: account.gameUid,
mid: cookie.mid,
};
const header = {
"x-rpc-client_type": "3",
"x-rpc-app_id": "ddxf5dufpuyo",
};
const resp = await TGHttp<TGApp.BBS.Response.getAuthTicketByGameBiz>(url, {
method: "POST",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.ticket;
}
export default getAuthTicket;

View File

@@ -1,81 +0,0 @@
/**
* @file web/request/getAvatarDetail.ts
* @description 获取角色详情相关请求函数
* @since Beta v0.6.1
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 手动刷新角色数据
* @since Beta v0.6.1
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @returns {Promise<void>}
*/
export async function getAvatarIndex(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
): Promise<TGApp.BBS.Response.Base> {
const url = TGApi.GameData.getUserBase;
const params = { avatar_list_type: 1, role_id: user.gameUid, server: user.region };
const ck = { cookie_token: cookie.cookie_token, account_id: cookie.account_id };
const header = getRequestHeader(ck, "GET", params, "common");
return await TGHttp<TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
}
/**
* @description 获取角色列表
* @since Beta v0.6.1
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @return {Promise<TGApp.Game.Avatar.Avatar[]|TGApp.BBS.Response.Base>}
*/
export async function getAvatarList(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
): Promise<TGApp.Game.Avatar.Avatar[] | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.byCookie.getAvatarList;
const data = { role_id: user.gameUid, server: user.region };
const ck = { cookie_token: cookie.cookie_token, account_id: cookie.account_id };
const header = getRequestHeader(ck, "POST", data, "common");
const resp = await TGHttp<TGApp.Game.Avatar.ListResponse | TGApp.BBS.Response.Base>(url, {
method: "POST",
body: JSON.stringify(data),
headers: header,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.list;
}
/**
* @description 获取角色详情
* @since Beta v0.6.1
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @param {string[]} avatarIds 角色 id 列表
* @return {Promise<TGApp.Game.Avatar.AvatarDetail|TGApp.BBS.Response.Base>}
*/
export async function getAvatarDetail(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
avatarIds: string[],
): Promise<TGApp.Game.Avatar.AvatarDetail | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.byCookie.getAvatarDetail;
const data = { role_id: user.gameUid, server: user.region, character_ids: avatarIds };
const ck = { cookie_token: cookie.cookie_token, account_id: cookie.account_id };
const header = getRequestHeader(ck, "POST", data, "common");
const resp = await TGHttp<TGApp.Game.Avatar.DetailResponse | TGApp.BBS.Response.Base>(url, {
method: "POST",
body: JSON.stringify(data),
headers: header,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}

View File

@@ -1,28 +0,0 @@
/**
* @file web/request/getCode.ts
* @description 获取兑换码相关请求
* @since Beta v0.5.3
*/
import TGHttp from "../../utils/TGHttp.js";
/**
* @description 获取兑换码请求
* @since Beta v0.5.3
* @param {string} act_id - 活动 id
* @return {Promise<TGApp.BBS.Navigator.CodeData[]|TGApp.BBS.Response.Base>}
*/
async function getCode(
act_id: string,
): Promise<TGApp.BBS.Navigator.CodeData[] | TGApp.BBS.Response.Base> {
const url = "https://api-takumi-static.mihoyo.com/event/miyolive/refreshCode";
const header = { "x-rpc-act_id": act_id };
const res = await TGHttp<TGApp.BBS.Navigator.CodeResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
});
if (res.retcode !== 0) return <TGApp.BBS.Response.Base>res;
return res.data.code_list;
}
export default getCode;

View File

@@ -1,60 +0,0 @@
/**
* @file web/request/getCookieToken.ts
* @description 获取 Cookie Token 的请求函数
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 根据 stoken 获取 cookie_token
* @since Beta v0.5.0
* @param {string} Mid 登录用户的 mid
* @param {string} Stoken stoken_v2
* @returns {Promise<string|TGApp.BBS.Response.Base>}
*/
export async function getCookieTokenBySToken(
Mid: string,
Stoken: string,
): Promise<string | TGApp.BBS.Response.Base> {
const url = TGApi.GameTokens.getCookieToken;
const cookie = { mid: Mid, stoken: Stoken };
const params = { stoken: Stoken };
const header = getRequestHeader(cookie, "GET", params, "common");
const resp = await TGHttp<TGApp.BBS.Response.getCookieTokenBySToken | TGApp.BBS.Response.Base>(
url,
{
method: "GET",
headers: header,
query: params,
},
);
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.cookie_token;
}
/**
* @description 根据 gameToken 获取 cookie_token
* @since Beta v0.5.0
* @param {string} accountId 账号 id
* @param {string} gameToken gameToken
* @returns {Promise<string|TGApp.BBS.Response.Base>}
*/
export async function getCookieTokenByGameToken(
accountId: string,
gameToken: string,
): Promise<string | TGApp.BBS.Response.Base> {
const url = "https://api-takumi.mihoyo.com/auth/api/getCookieAccountInfoByGameToken";
const data = { account_id: Number(accountId), game_token: gameToken };
const resp = await TGHttp<TGApp.BBS.Response.getCookieTokenByGameToken | TGApp.BBS.Response.Base>(
url,
{
method: "POST",
body: JSON.stringify(data),
},
);
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.cookie_token;
}

View File

@@ -1,39 +0,0 @@
/**
* @file web/request/getGachaLog.ts
* @description 获取抽卡记录请求函数
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
/**
* @description 获取抽卡记录
* @since Beta v0.5.0
* @param {string} authkey authkey
* @param {string} gachaType 抽卡类型
* @param {string} endId 结束 id默认为 0
* @returns {Promise<TGApp.Game.Gacha.GachaItem[] | TGApp.BBS.Response.Base>} 抽卡记录
*/
export async function getGachaLog(
authkey: string,
gachaType: string,
endId: string = "0",
): Promise<TGApp.Game.Gacha.GachaItem[] | TGApp.BBS.Response.Base> {
const url = "https://public-operation-hk4e.mihoyo.com/gacha_info/api/getGachaLog";
const params = {
lang: "zh-cn",
auth_appid: "webview_gacha",
authkey,
authkey_ver: "1",
sign_type: "2",
gacha_type: gachaType,
size: "20",
end_id: endId,
};
const resp = await TGHttp<TGApp.Game.Gacha.GachaLogResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.list;
}

View File

@@ -1,67 +0,0 @@
/**
* @file web/request/getGameAccounts.ts
* @description 获取游戏账号信息相关请求函数
* @since Beta v0.6.0
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import TGConstant from "../constant/TGConstant.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 通过 stoken 获取游戏账号
* @since Alpha v0.1.5
* @param {string} stoken stoken
* @param {string} stuid 登录用户 uid
* @returns {Promise<TGApp.BBS.Account.GameAccount[]|TGApp.BBS.Response.Base>}
*/
export async function getGameAccountsBySToken(
stoken: string,
stuid: string,
): Promise<TGApp.BBS.Account.GameAccount[] | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.bySToken.getAccounts;
const cookie = { stuid, stoken };
const params = { stoken, stuid, game_biz: TGConstant.GAME_BIZ };
return await getGameAccounts(url, cookie, params);
}
/**
* @description 通过 cookie 获取游戏账号
* @since Alpha v0.1.5
* @param {string} cookie_token cookie_token
* @param {string} account_id 游戏账号 id
* @returns {Promise<TGApp.BBS.Account.GameAccount[]|TGApp.BBS.Response.Base>}
*/
export async function getGameAccountsByCookie(
cookie_token: string,
account_id: string,
): Promise<TGApp.BBS.Account.GameAccount[] | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.byCookie.getAccounts;
const cookie = { account_id, cookie_token };
const params = { game_biz: TGConstant.GAME_BIZ };
return await getGameAccounts(url, cookie, params);
}
/**
* @description 获取游戏账号信息
* @since Beta v0.5.0
* @param {string} url 请求地址
* @param {Record<string, string>} cookie cookie
* @param {Record<string, string>} params 请求参数
* @returns {Promise<TGApp.BBS.Account.GameAccount[]|TGApp.BBS.Response.Base>}
*/
async function getGameAccounts(
url: string,
cookie: Record<string, string>,
params: Record<string, string>,
): Promise<TGApp.BBS.Response.Base | TGApp.BBS.Account.GameAccount[]> {
const header = getRequestHeader(cookie, "GET", params, "common");
const resp = await TGHttp<TGApp.BBS.Response.getGameAccounts | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.list;
}

View File

@@ -1,34 +0,0 @@
/**
* @file core/utils/getGameRecord.ts
* @description 获取游戏数据的函数
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 获取用户游戏数据
* @since Beta v0.5.0
* @description 这边的 ck 可以是 cookie_token 和 account_id
* @description 也可以是 ltoken 和 ltuid
* @param {Record<string, string>} cookie cookie
* @param {TGApp.Sqlite.Account.Game} user 用户的基本信息
* @returns {Promise<TGApp.Game.Record.FullData|TGApp.BBS.Response.Base>} 用户基本信息
*/
export async function getGameRecord(
cookie: Record<string, string>,
user: TGApp.Sqlite.Account.Game,
): Promise<TGApp.Game.Record.FullData | TGApp.BBS.Response.Base> {
const url = TGApi.GameData.getUserBase;
const params = { role_id: user.gameUid, server: user.region };
const header = getRequestHeader(cookie, "GET", params, "common");
const resp = await TGHttp<TGApp.Game.Record.Response | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}

View File

@@ -1,33 +0,0 @@
/**
* @file web/request/getLToken.ts
* @description 获取 ltoken 的请求
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 根据 stoken_v2 获取 ltoken
* @since Beta v0.5.0
* @param {string} Mid 登录用户 mid
* @param {string} Stoken stoken_v2
* @returns {Promise<string|TGApp.BBS.Response.Base>}
*/
export async function getLTokenBySToken(
Mid: string,
Stoken: string,
): Promise<string | TGApp.BBS.Response.Base> {
const url = TGApi.GameTokens.getLToken;
const cookie = { mid: Mid, stoken: Stoken };
const params = { stoken: Stoken };
const header = getRequestHeader(cookie, "GET", params, "common");
const resp = await TGHttp<TGApp.BBS.Response.getLTokenBySToken | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.ltoken;
}

View File

@@ -1,39 +0,0 @@
/**
* @file web/request/getRoleCombat.ts
* @description 真境剧诗
* @since Beta v0.6.3
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 获取剧诗信息
* @since Beta v.0.6.3
* @param {TGApp.App.Account.Cookie} cookie
* @param {TGApp.Sqlite.Account.Game} account
* @returns {Promise<TGApp.Game.Combat.Combat[]|TGApp.BBS.Response.Base|false>}
*/
export async function getRoleCombat(
cookie: TGApp.App.Account.Cookie,
account: TGApp.Sqlite.Account.Game,
): Promise<TGApp.Game.Combat.Combat[] | TGApp.BBS.Response.Base | false> {
const url = TGApi.GameData.getRoleCombat;
const params = { role_id: account.gameUid, server: account.region, active: 1, need_detail: true };
const ck = {
account_id: cookie.account_id,
cookie_token: cookie.cookie_token,
ltoken: cookie.ltoken,
ltuid: cookie.ltuid,
};
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.Game.Combat.Response | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode != 0) return <TGApp.BBS.Response.Base>resp;
if (!resp.data.is_unlock) return false;
return resp.data.data;
}

View File

@@ -1,61 +0,0 @@
/**
* @file web/request/getStoken.ts
* @description 获取 stoken
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
import TGConstant from "../constant/TGConstant.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 获取 stoken
* @since Beta v0.5.0
* @param {string} accountId 账户 ID
* @param {string} token 游戏 Token
* @param {string} isGameToken 是否为游戏 Token
* @returns {Promise<TGApp.BBS.Response.getStokenByGameTokenData | TGApp.BBS.Response.Base>}
*/
export async function getStokenByGameToken(
accountId: string,
token: string,
isGameToken: boolean,
): Promise<TGApp.BBS.Response.getStokenByGameTokenData | TGApp.BBS.Response.Base> {
let url = "https://api-takumi.mihoyo.com/account/ma-cn-session/app/getSTokenByGameToken";
if (isGameToken) {
url = "https://api-takumi.mihoyo.com/account/ma-cn-session/app/getTokenByGameToken";
}
const data = { account_id: Number(accountId), game_token: token };
const header = { "x-rpc-app_id": TGConstant.BBS.APP_ID };
const resp = await TGHttp<TGApp.BBS.Response.getStokenByGameToken | TGApp.BBS.Response.Base>(
url,
{ method: "POST", headers: header, body: JSON.stringify(data) },
);
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}
/**
* @description stoken v1 到 v2
* @since Beta v0.5.0
* @param {string} stoken 账户 ID
* @param {string} stuid 游戏 Token
* @returns {Promise<TGApp.BBS.Response.getStokenByGameTokenData | TGApp.BBS.Response.Base>}
*/
export async function getTokenBySToken(
stoken: string,
stuid: string,
): Promise<TGApp.BBS.Response.getTokenBySTokenData | TGApp.BBS.Response.Base> {
const url = "https://passport-api.mihoyo.com/account/ma-cn-session/app/getTokenBySToken";
const cookie = { stoken, stuid };
const header = {
"x-rpc-app_id": TGConstant.BBS.APP_ID,
...getRequestHeader(cookie, "POST", "", "prod"),
};
const resp = await TGHttp<TGApp.BBS.Response.getTokenBySToken | TGApp.BBS.Response.Base>(url, {
method: "POST",
headers: header,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}

View File

@@ -1,33 +0,0 @@
/**
* @file web/request/getUserCollect.ts
* @description 获取用户收藏请求模块
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 获取用户收藏帖子
* @since Beta v0.5.0
* @param {Record<string, string>} cookie - 用户 cookie
* @param {string} uid - 用户 uid
* @param {string} offset - 偏移量
* @returns {Promise<TGApp.BBS.Collection.PostRespData|TGApp.BBS.Response.Base>} 用户收藏帖子
*/
export async function getUserCollect(
cookie: Record<string, string>,
uid: string,
offset: string = "",
): Promise<TGApp.BBS.Collection.PostRespData | TGApp.BBS.Response.Base> {
const url = "https://bbs-api.miyoushe.com/post/wapi/userFavouritePost";
const params = { size: "20", uid, offset };
const header = getRequestHeader(cookie, "GET", params, "common");
const resp = await TGHttp<TGApp.BBS.Collection.PostResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}

View File

@@ -1,36 +0,0 @@
/**
* @file web/request/getUserInfo.ts
* @description 获取用户信息请求
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 根据 cookie 获取用户信息
* @since Beta v0.5.0
* @param {string} cookie_token cookie token
* @param {string} account_id 用户 account_id
* @returns {Promise<TGApp.BBS.Response.Base | TGApp.Plugins.Mys.User.Info>}
*/
export async function getUserInfoByCookie(
cookie_token: string,
account_id: string,
): Promise<TGApp.BBS.Response.Base | TGApp.Plugins.Mys.User.Info> {
const cookie = {
cookie_token,
account_id,
};
const url = TGApi.GameData.byCookie.getUserInfo;
const params = { gids: "2" };
const header = getRequestHeader(cookie, "GET", params, "common", true);
const resp = await TGHttp<TGApp.Plugins.Mys.User.HomeResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.user_info;
}

View File

@@ -1,7 +1,7 @@
/**
* @file web/request/getAnnouncement.ts
* @description
* @since Beta v0.6.0
* @file web/request/hk4eReq.ts
* @description Hk4eApi
* @since Beta v0.6.3
*/
import TGHttp from "../../utils/TGHttp.js";
@@ -56,7 +56,7 @@ function getAnnoParams(
* @param {AnnoLang} lang
* @returns {Promise<TGApp.BBS.Announcement.ListData>}
*/
export async function getAnnoList(
async function getAnnoList(
region: AnnoServer = AnnoServer.CN_ISLAND,
lang: AnnoLang = "zh-cn",
): Promise<TGApp.BBS.Announcement.ListData> {
@@ -80,7 +80,7 @@ export async function getAnnoList(
* @param {AnnoLang} lang
* @returns {Promise<TGApp.BBS.Announcement.ContentItem>}
*/
export async function getAnnoContent(
async function getAnnoContent(
annId: number,
region: AnnoServer = AnnoServer.CN_ISLAND,
lang: AnnoLang = "zh-cn",
@@ -101,3 +101,45 @@ export async function getAnnoContent(
throw new Error("公告内容不存在");
}
}
/**
* @description
* @since Beta v0.5.0
* @param {string} authKey authKey
* @param {string} gachaType
* @param {string} endId id 0
* @returns {Promise<TGApp.Game.Gacha.GachaItem[] | TGApp.BBS.Response.Base>}
*/
async function getGachaLog(
authKey: string,
gachaType: string,
endId: string = "0",
): Promise<TGApp.Game.Gacha.GachaItem[] | TGApp.BBS.Response.Base> {
const url = "https://public-operation-hk4e.mihoyo.com/gacha_info/api/getGachaLog";
const params = {
lang: "zh-cn",
auth_appid: "webview_gacha",
authkey: authKey,
authkey_ver: "1",
sign_type: "2",
gacha_type: gachaType,
size: "20",
end_id: endId,
};
const resp = await TGHttp<TGApp.Game.Gacha.GachaLogResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.list;
}
const Hk4eApi = {
anno: {
list: getAnnoList,
content: getAnnoContent,
},
gacha: getGachaLog,
};
export default Hk4eApi;

View File

@@ -1,7 +1,7 @@
/**
* @file src/web/request/getDeviceFp.ts
* @description
* @since Beta v0.5.5
* @file web/request/otherReq.ts
* @description Other API
* @since Beta v0.6.3
*/
import TGHttp from "../../utils/TGHttp.js";
@@ -15,7 +15,7 @@ import TGConstant from "../constant/TGConstant.js";
* @param {TGApp.App.Device.DeviceInfo} Info -
* @returns {Promise<TGApp.App.Device.DeviceInfo>}
*/
export async function getDeviceFp(
async function getDeviceFp(
Info?: TGApp.App.Device.DeviceInfo,
): Promise<TGApp.App.Device.DeviceInfo> {
const info = Info ?? getInitDeviceInfo();
@@ -86,7 +86,7 @@ export async function getDeviceFp(
device_fp: info.device_fp,
};
const header = {
"User-Agent": `Mozilla/5.0 (Linux; Android 12) Mobile miHoYoBBS/${TGConstant.BBS.VERSION}`,
"User-Agent": TGConstant.BBS.UA_MOBILE,
"x-rpc-app_version": TGConstant.BBS.VERSION,
"x-rpc-client_type": "5",
"x-requested-with": "com.mihoyo.hyperion",
@@ -109,3 +109,29 @@ export async function getDeviceFp(
}
return info;
}
/**
* @description
* @since Beta v0.5.3
* @param {string} actId - id
* @return {Promise<TGApp.BBS.Navigator.CodeData[]|TGApp.BBS.Response.Base>}
*/
async function refreshCode(
actId: string,
): Promise<TGApp.BBS.Navigator.CodeData[] | TGApp.BBS.Response.Base> {
const url = "https://api-takumi-static.mihoyo.com/event/miyolive/refreshCode";
const header = { "x-rpc-act_id": actId };
const res = await TGHttp<TGApp.BBS.Navigator.CodeResponse | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
});
if (res.retcode !== 0) return <TGApp.BBS.Response.Base>res;
return res.data.code_list;
}
const OtherApi = {
code: refreshCode,
fp: getDeviceFp,
};
export default OtherApi;

View File

@@ -0,0 +1,126 @@
/**
* @file web/request/passportReq.ts
* @description Passport 相关请求
* @since Beta v0.6.3
*/
import TGHttp from "../../utils/TGHttp.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
// PassportApiBaseUrl => pAbu
const pAbu = "https://passport-api.mihoyo.com/";
// PassportV4ApiBaseUrl => p4Abu
const p4Abu = "https://passport-api-v4.mihoyo.com/";
/**
* @description 获取登录ticket
* @since Beta v0.6.0
* @param {TGApp.Sqlite.Account.Game} account - 账户
* @param {TGApp.App.Account.Cookie} cookie - cookie
* @returns {Promise<TGApp.BBS.Response.Base|string>}
*/
async function createAuthTicketByGameBiz(
account: TGApp.Sqlite.Account.Game,
cookie: TGApp.App.Account.Cookie,
): Promise<TGApp.BBS.Response.Base | string> {
const url = `${pAbu}account/ma-cn-verifier/app/createAuthTicketByGameBiz`;
const params = {
game_biz: account.gameBiz,
stoken: cookie.stoken,
uid: account.gameUid,
mid: cookie.mid,
};
const header = {
"x-rpc-client_type": "3",
"x-rpc-app_id": "ddxf5dufpuyo",
};
const resp = await TGHttp<TGApp.BBS.Response.getAuthTicketByGameBiz>(url, {
method: "POST",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.ticket;
}
/**
* @description 根据 stoken 获取 cookie_token
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @returns {Promise<string|TGApp.BBS.Response.Base>}
*/
async function getCookieAccountInfoBySToken(
cookie: TGApp.App.Account.Cookie,
): Promise<string | TGApp.BBS.Response.Base> {
const url = `${pAbu}account/auth/api/getCookieAccountInfoBySToken`;
const ck = { stoken: cookie.stoken, mid: cookie.mid };
const params = { stoken: cookie.stoken };
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.BBS.Response.getCookieTokenBySToken | TGApp.BBS.Response.Base>(
url,
{
method: "GET",
headers: header,
query: params,
},
);
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.cookie_token;
}
/**
* @description 根据 stoken_v2 获取 ltoken
* @since Beta v0.5.0
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @returns {Promise<string|TGApp.BBS.Response.Base>}
*/
async function getLTokenBySToken(
cookie: TGApp.App.Account.Cookie,
): Promise<string | TGApp.BBS.Response.Base> {
const url = `${pAbu}account/auth/api/getLTokenBySToken`;
const ck = { mid: cookie.mid, stoken: cookie.stoken };
const params = { stoken: cookie.stoken };
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.BBS.Response.getLTokenBySToken | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.ltoken;
}
/**
* @description 验证 ltoken 有效性,返回 mid
* @since Beta v0.5.0
* @param {TGApp.App.Account.Cookie} cookie - 账户 cookie
* @returns {Promise<string | TGApp.BBS.Response.Base>}
*/
async function verifyLToken(
cookie: TGApp.App.Account.Cookie,
): Promise<string | TGApp.BBS.Response.Base> {
const url = `${p4Abu}account/ma-cn-session/web/verifyLtoken`;
const ck = { ltoken: cookie.ltoken, ltuid: cookie.ltuid };
const data = { ltoken: cookie.ltoken };
const header = getRequestHeader(ck, "POST", data, "common");
const resp = await TGHttp<TGApp.BBS.Response.verifyUserInfoBySToken | TGApp.BBS.Response.Base>(
url,
{
method: "POST",
headers: header,
body: JSON.stringify(data),
},
);
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.user_info.mid;
}
const PassportApi = {
authTicket: createAuthTicketByGameBiz,
cookieToken: getCookieAccountInfoBySToken,
lToken: {
get: getLTokenBySToken,
verify: verifyLToken,
},
};
export default PassportApi;

View File

@@ -0,0 +1,158 @@
/**
* @file web/request/record/genshinReq.ts
* @description TakumiRecordGenshinApi 相关请求
* @since Beta v0.6.3
*/
import TGHttp from "../../utils/TGHttp.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
// TakumiRecordGenshinApiBaseUrl => trgAbu
const trgAbu = "https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/";
/**
* @description 获取角色详情
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @param {string[]} avatarIds 角色 id 列表
* @returns {Promise<TGApp.Game.Avatar.AvatarDetail | TGApp.BBS.Response.Base>}
*/
async function characterDetail(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
avatarIds: string[],
): Promise<TGApp.Game.Avatar.AvatarDetail | TGApp.BBS.Response.Base> {
const url = `${trgAbu}character/detail`;
const ck = { account_id: cookie.account_id, cookie_token: cookie.cookie_token };
const data = { role_id: user.gameUid, server: user.region, character_ids: avatarIds };
const header = getRequestHeader(ck, "POST", data, "common");
const resp = await TGHttp<TGApp.Game.Avatar.DetailResponse | TGApp.BBS.Response.Base>(url, {
method: "POST",
body: JSON.stringify(data),
headers: header,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}
/**
* @description 获取角色列表
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @returns {Promise<TGApp.Game.Avatar.Avatar[] | TGApp.BBS.Response.Base>}
*/
async function characterList(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
): Promise<TGApp.Game.Avatar.Avatar[] | TGApp.BBS.Response.Base> {
const url = `${trgAbu}character/list`;
const ck = { account_id: cookie.account_id, cookie_token: cookie.cookie_token };
const data = { role_id: user.gameUid, server: user.region };
const header = getRequestHeader(ck, "POST", data, "common");
const resp = await TGHttp<TGApp.Game.Avatar.ListResponse | TGApp.BBS.Response.Base>(url, {
method: "POST",
body: JSON.stringify(data),
headers: header,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.list;
}
/**
* @description 获取首页信息
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @returns {Promise<TGApp.Game.Record.FullData | TGApp.BBS.Response.Base>}
*/
async function index(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
): Promise<TGApp.Game.Record.FullData | TGApp.BBS.Response.Base> {
const url = `${trgAbu}index`;
const ck = { account_id: cookie.account_id, cookie_token: cookie.cookie_token };
const params = { avatar_list_type: 1, role_id: user.gameUid, server: user.region };
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.Game.Record.Response | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}
/**
* @description 获取真境剧诗数据
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @returns {Promise<TGApp.Game.Combat.Combat[] | TGApp.BBS.Response.Base|false>}
*/
async function roleCombat(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
): Promise<TGApp.Game.Combat.Combat[] | TGApp.BBS.Response.Base | false> {
const url = `${trgAbu}role_combat`;
const ck = {
account_id: cookie.account_id,
cookie_token: cookie.cookie_token,
ltoken: cookie.ltoken,
ltuid: cookie.ltuid,
};
const params = { role_id: user.gameUid, server: user.region, active: 1, need_detail: true };
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.Game.Combat.Response | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
if (!resp.data.is_unlock) return false;
return resp.data.data;
}
/**
* @description 获取深渊螺旋记录
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @param {string} schedule 1: 本期, 2: 上期
* @returns {Promise<TGApp.Game.Abyss.FullData | TGApp.BBS.Response.Base>}
*/
async function spiralAbyss(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
schedule: string,
): Promise<TGApp.Game.Abyss.FullData | TGApp.BBS.Response.Base> {
const url = `${trgAbu}spiralAbyss`;
const ck = {
account_id: cookie.account_id,
cookie_token: cookie.cookie_token,
ltoken: cookie.ltoken,
ltuid: cookie.ltuid,
};
const params = { role_id: user.gameUid, schedule_type: schedule, server: user.region };
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.Game.Abyss.Response | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}
const TakumiRecordGenshinApi = {
index: index,
character: {
list: characterList,
detail: characterDetail,
},
roleCombat: roleCombat,
spiralAbyss: spiralAbyss,
};
export default TakumiRecordGenshinApi;

View File

@@ -0,0 +1,121 @@
/**
* @file web/request/takumiReq.ts
* @description Takumi 相关请求函数
* @since Beta v0.6.3
*/
import TGHttp from "../../utils/TGHttp.js";
import TGConstant from "../constant/TGConstant.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
// TakumiAuthApiBaseUrl => taAbu
const taAbu = "https://api-takumi.mihoyo.com/auth/api/";
// TakumiBingApiBaseUrl => tbAbu
const tbAbu = "https://api-takumi.mihoyo.com/binding/api/";
/**
* @description 根据stoken获取action_ticket
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie Cookie
* @param {TGApp.Sqlite.Account.Game} user 用户
* @param {string} actionType 动作类型
* @returns {Promise<TGApp.BBS.Response.getActionTicketBySToken>}
*/
async function getActionTicketBySToken(
cookie: TGApp.App.Account.Cookie,
user: TGApp.Sqlite.Account.Game,
actionType: string,
): Promise<TGApp.BBS.Response.getActionTicketBySToken> {
const url = `${taAbu}getActionTicketBySToken`;
const ck = { stoken: cookie.stoken, mid: cookie.mid };
const params = { action_type: actionType, stoken: cookie.stoken, uid: user.gameUid };
const header = getRequestHeader(ck, "GET", params, "k2");
return await TGHttp<TGApp.BBS.Response.getActionTicketBySToken>(url, {
method: "GET",
headers: header,
query: params,
});
}
/**
* @description 生成authkey
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie cookie
* @param {TGApp.Sqlite.Account.Game} account 账户
* @return {Promise<string|TGApp.BBS.Response.Base>} authkey
*/
async function genAuthKey(
cookie: TGApp.App.Account.Cookie,
account: TGApp.Sqlite.Account.Game,
): Promise<string | TGApp.BBS.Response.Base> {
const url = `${tbAbu}genAuthKey`;
const ck = { stoken: cookie.stoken, mid: cookie.mid };
const data = {
auth_appid: "webview_gacha",
game_biz: account.gameBiz,
game_uid: account.gameUid,
region: account.region,
};
const header = getRequestHeader(ck, "POST", JSON.stringify(data), "lk2", true);
const resp = await TGHttp<TGApp.Game.Gacha.AuthkeyResponse | TGApp.BBS.Response.Base>(url, {
method: "POST",
headers: header,
body: JSON.stringify(data),
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.authkey;
}
/**
* @description 生成authkey-v2专门用于JSBridge
* @since Beta v0.6.3
* @param {Record<string,string>} cookie cookie
* @param {Record<string,string>} payload payload
* @returns {Promise<TGApp.BBS.Response.Base>}
*/
async function genAuthKey2(
cookie: Record<string, string>,
payload: Record<string, string>,
): Promise<TGApp.BBS.Response.Base> {
const url = `${tbAbu}genAuthKey`;
const header = getRequestHeader(cookie, "POST", JSON.stringify(payload), "lk2", true);
return await TGHttp<TGApp.BBS.Response.Base>(url, {
method: "POST",
headers: header,
body: JSON.stringify(payload),
});
}
/**
* @description 通过cookie获取游戏账号
* @since Beta v0.6.3
* @param {TGApp.App.Account.Cookie} cookie cookie
* @returns {Promise<TGApp.BBS.Account.GameAccount[]|TGApp.BBS.Response.Base>}
*/
async function getUserGameRolesByCookie(
cookie: TGApp.App.Account.Cookie,
): Promise<TGApp.BBS.Account.GameAccount[] | TGApp.BBS.Response.Base> {
const url = `${tbAbu}getUserGameRolesByCookie`;
const ck = { account_id: cookie.account_id, cookie_token: cookie.cookie_token };
const params = { game_biz: TGConstant.GAME_BIZ };
const header = getRequestHeader(ck, "GET", params, "common");
const resp = await TGHttp<TGApp.BBS.Response.getGameAccounts | TGApp.BBS.Response.Base>(url, {
method: "GET",
headers: header,
query: params,
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.list;
}
const TakumiApi = {
auth: {
actionTicket: getActionTicketBySToken,
},
bind: {
authKey: genAuthKey,
authKey2: genAuthKey2,
gameRoles: getUserGameRolesByCookie,
},
};
export default TakumiApi;

View File

@@ -1,36 +0,0 @@
/**
* @file web/request/verifyLToken.ts
* @description 验证 stoken 的请求函数
* @since Beta v0.5.0
*/
import TGHttp from "../../utils/TGHttp.js";
import TGApi from "../api/TGApi.js";
import { getRequestHeader } from "../utils/getRequestHeader.js";
/**
* @description 验证 ltoken 有效性,返回 mid
* @since Beta v0.5.0
* @param {string} ltoken ltoken
* @param {string} ltuid 登录用户 uid
* @returns {Promise<string | TGApp.BBS.Response.Base>}
*/
export async function verifyLToken(
ltoken: string,
ltuid: string,
): Promise<string | TGApp.BBS.Response.Base> {
const url = TGApi.GameTokens.verifyLToken;
const cookie = { ltoken, ltuid };
const data = { ltoken };
const header = getRequestHeader(cookie, "POST", data, "common");
const resp = await TGHttp<TGApp.BBS.Response.verifyUserInfoBySToken | TGApp.BBS.Response.Base>(
url,
{
method: "POST",
headers: header,
body: JSON.stringify(data),
},
);
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data.user_info.mid;
}

View File

@@ -11,14 +11,16 @@ import TGConstant from "../constant/TGConstant.js";
import { transCookie, transParams } from "./tools.js";
type SaltType = "common" | "prod" | "lk2" | "k2";
/**
* @description 获取 salt
* @since Beta v0.3.3
* @since Beta v0.6.3
* @version 2.59.1
* @param {string} saltType salt 类型
* @param {SaltType} saltType salt 类型
* @returns {string} salt
*/
function getSalt(saltType: string): string {
function getSalt(saltType: SaltType): string {
switch (saltType) {
case "common":
return TGConstant.Salt.X4;
@@ -26,6 +28,8 @@ function getSalt(saltType: string): string {
return TGConstant.Salt.PROD;
case "lk2":
return TGConstant.Salt.LK2;
case "k2":
return TGConstant.Salt.K2;
default:
return TGConstant.Salt.X4;
}
@@ -48,11 +52,11 @@ function getRandomNumber(min: number, max: number): number {
* @version 2.50.1
* @param {string} method 请求方法
* @param {string} data 请求数据
* @param {string} saltType salt 类型
* @param {SaltType} saltType salt 类型
* @param {boolean} isSign 是否为签名
* @returns {string} ds
*/
function getDS(method: string, data: string, saltType: string, isSign: boolean): string {
function getDS(method: string, data: string, saltType: SaltType, isSign: boolean): string {
const salt = getSalt(saltType);
const time = Math.floor(Date.now() / 1000).toString();
let random = getRandomNumber(100000, 200000).toString();
@@ -71,7 +75,7 @@ function getDS(method: string, data: string, saltType: string, isSign: boolean):
* @param {Record<string, string>} cookie cookie
* @param {string} method 请求方法
* @param {Record<string, string|number|string[]|boolean>|string} data 请求数据
* @param {string} saltType salt 类型
* @param {SaltType} saltType salt 类型
* @param {boolean} isSign 是否为签名
* @returns {Record<string, string>} 请求头
*/
@@ -79,7 +83,7 @@ export function getRequestHeader(
cookie: Record<string, string>,
method: string,
data: Record<string, string | number | string[] | boolean> | string,
saltType: string,
saltType: SaltType,
isSign: boolean = false,
): Record<string, string> {
let ds;
@@ -104,21 +108,21 @@ export function getRequestHeader(
/**
* @description 获取 DS
* @since Beta v0.3.9
* @param {string} saltType salt 类型
* @param {SaltType} saltType salt 类型
* @param {number} dsType ds 类型
* @param {Record<string, string|number>|string} body
* @param {Record<string, string|number>|string} query
* @returns {string} DS
*/
export function getDS4JS(saltType: string, dsType: 1, body: undefined, query: undefined): string;
export function getDS4JS(saltType: SaltType, dsType: 1, body: undefined, query: undefined): string;
export function getDS4JS(
saltType: string,
saltType: SaltType,
dsType: 2,
body: Record<string, string | number> | string,
query: Record<string, string | number> | string,
): string;
export function getDS4JS(
saltType: string,
saltType: SaltType,
dsType: 1 | 2,
body?: Record<string, string | number> | string,
query?: Record<string, string | number> | string,