115 lines
3.0 KiB
TypeScript
115 lines
3.0 KiB
TypeScript
const MOMENTUM_API = "https://api.momentum-mod.org/v1";
|
|
|
|
interface MomentumMapThumbnail {
|
|
id: string;
|
|
small: string;
|
|
medium: string;
|
|
large: string;
|
|
xl: string;
|
|
}
|
|
|
|
interface MomentumMapLeaderboard {
|
|
gamemode: number;
|
|
trackType: number;
|
|
trackNum: number;
|
|
style: number;
|
|
tier: number | null;
|
|
tags: number[];
|
|
type: number;
|
|
linear: boolean | null;
|
|
}
|
|
|
|
interface MomentumMapInfo {
|
|
description: string;
|
|
youtubeID: string;
|
|
creationDate: string;
|
|
approvedDate: string;
|
|
requiredGames: number[];
|
|
}
|
|
|
|
interface MomentumMap {
|
|
id: number;
|
|
name: string;
|
|
thumbnail: MomentumMapThumbnail | null;
|
|
images: MomentumMapThumbnail[];
|
|
info: MomentumMapInfo | null;
|
|
leaderboards: MomentumMapLeaderboard[];
|
|
}
|
|
|
|
interface MomentumMapsResponse {
|
|
totalCount: number;
|
|
returnCount: number;
|
|
data: MomentumMap[];
|
|
}
|
|
|
|
export interface MapInfo {
|
|
mapId: number | null;
|
|
thumbnailUrl: string | null;
|
|
tier: number | null;
|
|
mapDate: string | null;
|
|
}
|
|
|
|
const mapInfoCache = new Map<string, MapInfo>();
|
|
|
|
function extractSurfTier(
|
|
leaderboards: MomentumMapLeaderboard[],
|
|
): number | null {
|
|
const mainLeaderboard = leaderboards.find(
|
|
(lb) => lb.gamemode === 1 && lb.trackType === 0 && lb.style === 0,
|
|
);
|
|
return mainLeaderboard?.tier ?? null;
|
|
}
|
|
|
|
export async function getMapInfo(mapName: string): Promise<MapInfo> {
|
|
const cached = mapInfoCache.get(mapName);
|
|
if (cached) return cached;
|
|
|
|
try {
|
|
const url = `${MOMENTUM_API}/maps?search=${encodeURIComponent(mapName)}&take=1&expand=info,leaderboards`;
|
|
const res = await fetch(url);
|
|
if (!res.ok) {
|
|
const info: MapInfo = {
|
|
mapId: null,
|
|
thumbnailUrl: null,
|
|
tier: null,
|
|
mapDate: null,
|
|
};
|
|
mapInfoCache.set(mapName, info);
|
|
return info;
|
|
}
|
|
const json: MomentumMapsResponse = await res.json();
|
|
const map = json.data?.[0];
|
|
if (!map || map.name !== mapName) {
|
|
const info: MapInfo = {
|
|
mapId: null,
|
|
thumbnailUrl: null,
|
|
tier: null,
|
|
mapDate: null,
|
|
};
|
|
mapInfoCache.set(mapName, info);
|
|
return info;
|
|
}
|
|
const thumbnailUrl =
|
|
map.thumbnail?.small ?? map.images?.[0]?.small ?? null;
|
|
const tier = extractSurfTier(map.leaderboards ?? []);
|
|
const mapDate = map.info?.creationDate ?? null;
|
|
const info: MapInfo = { mapId: map.id, thumbnailUrl, tier, mapDate };
|
|
mapInfoCache.set(mapName, info);
|
|
return info;
|
|
} catch {
|
|
const info: MapInfo = {
|
|
mapId: null,
|
|
thumbnailUrl: null,
|
|
tier: null,
|
|
mapDate: null,
|
|
};
|
|
mapInfoCache.set(mapName, info);
|
|
return info;
|
|
}
|
|
}
|
|
|
|
export async function getMapThumbnail(mapName: string): Promise<string | null> {
|
|
const info = await getMapInfo(mapName);
|
|
return info.thumbnailUrl;
|
|
}
|