feat: add osu! version and release stream retrieval, along with skins count functionality

This commit is contained in:
2025-07-03 14:23:11 +02:00
parent a677755451
commit 2896a68757
8 changed files with 295 additions and 31 deletions

33
src/lib/api/osuapi.ts Normal file
View File

@@ -0,0 +1,33 @@
import type { StreamsResult } from '@/types';
import { betterFetch } from '@better-fetch/fetch';
const API_ENDPOINT = 'https://osu.ppy.sh/api/';
const timeout = 5000; // 5 seconds;
export const osuapi = {
latestBuildVersion: async (releaseStream: string): Promise<string | undefined> => {
const request = await betterFetch<StreamsResult>(`${API_ENDPOINT}v2/changelog`, {
timeout,
query: {
stream: 'none',
},
headers: {
'Content-Type': 'application/json',
'User-Agent': 'EZPPLauncher',
},
});
if (request.error) {
if (request.error.status >= 500 && request.error.status < 600)
throw new Error('Server not reachable');
return undefined;
}
const releaseData = request.data;
const selectedRelease = releaseData.streams.find(
(releaseBuild) =>
releaseBuild.name.toLowerCase() === releaseStream.replaceAll(' ', '').toLowerCase()
);
if (!selectedRelease) return undefined;
return selectedRelease.latest_build.display_version;
},
};

View File

@@ -15,6 +15,10 @@ export const serverConnectionFails = writable(0);
export const onlineFriends = writable<number | undefined>(undefined);
export const beatmapSets = writable<number | undefined>(undefined);
export const skins = writable<number | undefined>(undefined);
export const osuStream = writable<string | undefined>(undefined);
export const osuBuild = writable<string | undefined>(undefined);
export const setupValues = () => {
updatePing();

View File

@@ -95,3 +95,27 @@ export type EZPPUserInfo = {
time: Date;
}[];
};
export type StreamsResult = {
streams: {
id: number;
name: string;
display_name: string;
is_featured: boolean;
latest_build: {
created_at: Date;
display_version: string;
id: number;
users: number;
version: string;
youtube_id: null | string;
update_stream: {
id: number;
name: string;
display_name: string;
is_featured: boolean;
};
};
user_count: number;
}[];
};

View File

@@ -50,3 +50,31 @@ export const formatTimeReadable = (initialSeconds: number) => {
return result.trim();
};
export const releaseStreamToReadable = (releaseStream: string) => {
if (releaseStream.toLowerCase() === 'cuttingedge') return 'Cutting Edge';
return 'Stable';
};
export const compareBuildNumbers = (current: string, target: string): number => {
const parse = (version: string): [number, number] => {
const cleaned = version.split(/[^0-9.]/)[0];
const [baseStr, hotfixStr] = cleaned.split('.');
const base = parseInt(baseStr, 10);
const hotfix = hotfixStr ? parseInt(hotfixStr, 10) : 0;
return [base, hotfix];
};
const [currentBase, currentHotfix] = parse(current);
const [targetBase, targetHotfix] = parse(target);
if (targetBase > currentBase) {
return targetBase - currentBase + targetHotfix;
} else if (targetBase === currentBase) {
return targetHotfix - currentHotfix;
} else {
return -1;
}
};