FIX: All bug in Custom Enemy, UPDATE: Add specical main skill, optimaze ui in custom enemy
All checks were successful
Gitea Auto Deploy / Deploy-Container (push) Successful in 1m39s

This commit is contained in:
2025-09-26 18:29:33 +07:00
parent 95c700fd9f
commit af4451fd97
19 changed files with 1251278 additions and 128 deletions

View File

@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { AffixDetail, ASDetail, CharacterDetail, ConfigMaze, FreeSRJson, LightConeDetail, MocDetail, PeakDetail, PFDetail, PSResponse, RelicDetail } from "@/types";
import { AffixDetail, ASDetail, CharacterDetail, ConfigMaze, FreeSRJson, LightConeDetail, MocDetail, MonsterDetail, PeakDetail, PFDetail, PSResponse, RelicDetail } from "@/types";
import axios from 'axios';
import { pSResponseSchema } from "@/zod";
@@ -196,7 +196,6 @@ export async function fetchMOCByIdNative(ids: string, locale: string): Promise<M
}
}
export async function fetchPeakByIdsNative(ids: string[], locale: string): Promise<Record<string, PeakDetail> | null> {
try {
const res = await axios.post<Record<string, PeakDetail>>(`/api/${locale}/peak`, { peakIds: ids });
@@ -217,6 +216,28 @@ export async function fetchPeakByIdNative(ids: string, locale: string): Promise<
}
}
export async function fetchMonsterByIdsNative(ids: string[], locale: string): Promise<Record<string, MonsterDetail> | null> {
try {
const res = await axios.post<Record<string, MonsterDetail>>(`/api/${locale}/monster`, { monsterIds: ids });
return res.data;
} catch (error) {
console.error('Failed to fetch monster:', error);
return null;
}
}
export async function fetchMonsterByIdNative(ids: string, locale: string): Promise<MonsterDetail | null> {
try {
const res = await axios.get<MonsterDetail>(`/api/${locale}/monster/${ids}`);
return res.data;
} catch (error) {
console.error('Failed to fetch monster:', error);
return null;
}
}
export async function SendDataToServer(username: string, password: string, serverUrl: string, data: FreeSRJson | null): Promise<PSResponse | string> {
try {
const response = await axios.post(`${serverUrl}`, { username, password, data })

View File

@@ -1,5 +1,5 @@
import { convertAvatar, convertEvent, convertLightcone, convertMonster, convertRelicSet } from "@/helper";
import { ASDetail, CharacterBasic, CharacterBasicRaw, CharacterDetail, EventBasic, EventBasicRaw, LightConeBasic, LightConeBasicRaw, LightConeDetail, MocDetail, MonsterBasic, MonsterBasicRaw, MonsterDetail, PeakDetail, PFDetail, RelicBasic, RelicBasicRaw, RelicDetail } from "@/types";
import { ASDetail, CharacterBasic, CharacterBasicRaw, CharacterDetail, EventBasic, EventBasicRaw, LightConeBasic, LightConeBasicRaw, LightConeDetail, MocDetail, MonsterBasic, MonsterBasicRaw, MonsterDetail, MonsterValue, PeakDetail, PFDetail, RelicBasic, RelicBasicRaw, RelicDetail } from "@/types";
import axios from "axios";
export async function getLightconeInfoApi(lightconeId: number, locale: string): Promise<LightConeDetail | null> {
@@ -352,9 +352,9 @@ export async function getMonsterListApi(): Promise<{list: MonsterBasic[], map: R
}
}
export async function getMonsterDetailApi(): Promise<Record<string, MonsterDetail> | null> {
export async function getMonsterValueApi(): Promise<Record<string, MonsterValue> | null> {
try {
const res = await axios.get<Record<string, MonsterDetail>>(
const res = await axios.get<Record<string, MonsterValue>>(
`https://api.hakush.in/hsr/data/monstervalue.json`,
{
headers: {
@@ -373,3 +373,27 @@ export async function getMonsterDetailApi(): Promise<Record<string, MonsterDetai
return null;
}
}
export async function getMonsterDetailApi(monsterId: number, locale: string): Promise<MonsterDetail | null> {
try {
const res = await axios.get<MonsterDetail>(
`https://api.hakush.in/hsr/data/${locale}/monster/${monsterId}.json`,
{
headers: {
'Content-Type': 'application/json',
},
}
);
return res.data;
} catch (error: unknown) {
if (axios.isAxiosError(error)) {
console.log(`Error: ${error.response?.status} - ${error.message}`);
} else {
console.log(`Unexpected error: ${String(error)}`);
}
return null;
}
}

View File

@@ -7,4 +7,4 @@ export * from "./asLoader";
export * from "./pfLoader";
export * from "./mocLoader";
export * from "./peakLoader";
export * from "./monsterLoader";

View File

@@ -0,0 +1,51 @@
import fs from 'fs';
import path from 'path';
import { MonsterDetail } from '@/types';
import { getMonsterDetailApi } from '../api';
const DATA_DIR = path.join(process.cwd(), 'data');
const monsterFileCache: Record<string, Record<string, MonsterDetail>> = {};
export let monsterMap: Record<string, MonsterDetail> = {};
function getJsonFilePath(locale: string): string {
return path.join(DATA_DIR, `monster.${locale}.json`);
}
function loadFromFileIfExists(locale: string): Record<string, MonsterDetail> | null {
if (monsterFileCache[locale]) return monsterFileCache[locale];
const filePath = getJsonFilePath(locale);
if (fs.existsSync(filePath)) {
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8')) as Record<string, MonsterDetail>;
monsterFileCache[locale] = data;
return data;
}
return null;
}
export async function loadMonster(charIds: string[], locale: string): Promise<Record<string, MonsterDetail>> {
const fileData = loadFromFileIfExists(locale);
const fileIds = fileData ? Object.keys(fileData) : [];
if (fileData && charIds.every(id => fileIds.includes(id))) {
monsterMap = fileData;
return monsterMap;
}
const result: Record<string, MonsterDetail> = {};
await Promise.all(
charIds.map(async id => {
const info = await getMonsterDetailApi(Number(id), locale);
if (info) result[id] = info;
})
);
fs.mkdirSync(DATA_DIR, { recursive: true });
const filePath = getJsonFilePath(locale);
fs.writeFileSync(filePath, JSON.stringify(result, null, 2), 'utf-8');
monsterFileCache[locale] = result;
monsterMap = result;
return result;
}