feat: add osu! version and release stream retrieval, along with skins count functionality
This commit is contained in:
parent
a677755451
commit
2896a68757
@ -6,9 +6,7 @@ use winreg::RegKey;
|
|||||||
use winreg::enums::*;
|
use winreg::enums::*;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
use crate::utils::check_folder_completeness;
|
use crate::utils::{check_folder_completeness, get_osu_user_config, get_osu_config};
|
||||||
use crate::utils::get_osu_user_config;
|
|
||||||
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn get_hwid() -> String {
|
fn get_hwid() -> String {
|
||||||
@ -140,8 +138,8 @@ fn find_osu_installation() -> Option<String> {
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn get_beatmapsets_count(folder: String) -> Option<u64> {
|
fn get_beatmapsets_count(folder: String) -> Option<u64> {
|
||||||
let path = PathBuf::from(folder);
|
let path = PathBuf::from(folder);
|
||||||
let osu_config = get_osu_user_config(path.clone());
|
let osu_user_config = get_osu_user_config(path.clone());
|
||||||
let songs_path = osu_config
|
let songs_path = osu_user_config
|
||||||
.and_then(|config| config.get("Songs").cloned())
|
.and_then(|config| config.get("Songs").cloned())
|
||||||
.unwrap_or_else(|| path.join("Songs").to_string_lossy().into_owned());
|
.unwrap_or_else(|| path.join("Songs").to_string_lossy().into_owned());
|
||||||
let songs_folder = PathBuf::from(songs_path);
|
let songs_folder = PathBuf::from(songs_path);
|
||||||
@ -169,6 +167,52 @@ fn get_beatmapsets_count(folder: String) -> Option<u64> {
|
|||||||
return Some(count);
|
return Some(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_skins_count(folder: String) -> Option<u64> {
|
||||||
|
let path = PathBuf::from(folder);
|
||||||
|
let skins_folder = path.join("Skins");
|
||||||
|
|
||||||
|
if !skins_folder.exists() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
if let Ok(entries) = std::fs::read_dir(skins_folder) {
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
if entry.file_type().map_or(false, |ft| ft.is_dir()) {
|
||||||
|
let dir_path = entry.path();
|
||||||
|
if let Ok(files) = std::fs::read_dir(&dir_path) {
|
||||||
|
for file in files.flatten() {
|
||||||
|
if file.path().extension().map_or(false, |ext| ext == "ini") {
|
||||||
|
count += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_osu_version(folder: String) -> String {
|
||||||
|
let path = PathBuf::from(folder);
|
||||||
|
let osu_user_config = get_osu_user_config(path.clone());
|
||||||
|
return osu_user_config
|
||||||
|
.and_then(|config| config.get("LastVersion").cloned())
|
||||||
|
.unwrap_or_else(|| "failed.".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn get_osu_release_stream(folder: String) -> String {
|
||||||
|
let path = PathBuf::from(folder);
|
||||||
|
let osu_config = get_osu_config(path.clone());
|
||||||
|
return osu_config
|
||||||
|
.and_then(|config| config.get("_ReleaseStream").cloned())
|
||||||
|
.unwrap_or_else(|| "Stable40".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
let mut builder = tauri::Builder::default();
|
let mut builder = tauri::Builder::default();
|
||||||
@ -188,7 +232,10 @@ pub fn run() {
|
|||||||
get_hwid,
|
get_hwid,
|
||||||
find_osu_installation,
|
find_osu_installation,
|
||||||
valid_osu_folder,
|
valid_osu_folder,
|
||||||
get_beatmapsets_count
|
get_beatmapsets_count,
|
||||||
|
get_skins_count,
|
||||||
|
get_osu_version,
|
||||||
|
get_osu_release_stream
|
||||||
])
|
])
|
||||||
.plugin(tauri_plugin_fs::init())
|
.plugin(tauri_plugin_fs::init())
|
||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
|
@ -52,3 +52,30 @@ pub fn get_osu_user_config<P: AsRef<Path>>(
|
|||||||
|
|
||||||
return Some(config_map);
|
return Some(config_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_osu_config<P: AsRef<Path>>(
|
||||||
|
osu_folder_path: P,
|
||||||
|
) -> Option<std::collections::HashMap<String, String>> {
|
||||||
|
// Ensure the osu! folder path is valid
|
||||||
|
if !osu_folder_path.as_ref().exists() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the osu!.cfg file from the osu! folder
|
||||||
|
let osu_config_path = osu_folder_path.as_ref().join("osu!.cfg");
|
||||||
|
if !osu_config_path.exists() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the osu config and return it as a map, key and value are separated by ' = '
|
||||||
|
let mut config_map = std::collections::HashMap::new();
|
||||||
|
if let Ok(contents) = std::fs::read_to_string(osu_config_path) {
|
||||||
|
for line in contents.lines() {
|
||||||
|
if let Some((key, value)) = line.split_once(" = ") {
|
||||||
|
config_map.insert(key.trim().to_string(), value.trim().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Some(config_map);
|
||||||
|
}
|
||||||
|
33
src/lib/api/osuapi.ts
Normal file
33
src/lib/api/osuapi.ts
Normal 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;
|
||||||
|
},
|
||||||
|
};
|
@ -15,6 +15,10 @@ export const serverConnectionFails = writable(0);
|
|||||||
export const onlineFriends = writable<number | undefined>(undefined);
|
export const onlineFriends = writable<number | undefined>(undefined);
|
||||||
|
|
||||||
export const beatmapSets = 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 = () => {
|
export const setupValues = () => {
|
||||||
updatePing();
|
updatePing();
|
||||||
|
@ -95,3 +95,27 @@ export type EZPPUserInfo = {
|
|||||||
time: Date;
|
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;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
@ -50,3 +50,31 @@ export const formatTimeReadable = (initialSeconds: number) => {
|
|||||||
|
|
||||||
return result.trim();
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -4,7 +4,15 @@
|
|||||||
import Badge from '@/components/ui/badge/badge.svelte';
|
import Badge from '@/components/ui/badge/badge.svelte';
|
||||||
import Button from '@/components/ui/button/button.svelte';
|
import Button from '@/components/ui/button/button.svelte';
|
||||||
import * as Select from '@/components/ui/select';
|
import * as Select from '@/components/ui/select';
|
||||||
import { beatmapSets, currentView, serverConnectionFails, serverPing } from '@/global';
|
import {
|
||||||
|
beatmapSets,
|
||||||
|
currentView,
|
||||||
|
osuBuild,
|
||||||
|
osuStream,
|
||||||
|
serverConnectionFails,
|
||||||
|
serverPing,
|
||||||
|
skins,
|
||||||
|
} from '@/global';
|
||||||
import {
|
import {
|
||||||
LoaderCircle,
|
LoaderCircle,
|
||||||
Logs,
|
Logs,
|
||||||
@ -20,11 +28,17 @@
|
|||||||
Circle,
|
Circle,
|
||||||
LogOut,
|
LogOut,
|
||||||
LogIn,
|
LogIn,
|
||||||
|
Brush,
|
||||||
} from 'lucide-svelte';
|
} from 'lucide-svelte';
|
||||||
import NumberFlow from '@number-flow/svelte';
|
import NumberFlow from '@number-flow/svelte';
|
||||||
import * as AlertDialog from '@/components/ui/alert-dialog';
|
import * as AlertDialog from '@/components/ui/alert-dialog';
|
||||||
import Progress from '@/components/ui/progress/progress.svelte';
|
import Progress from '@/components/ui/progress/progress.svelte';
|
||||||
import { formatTimeReadable, numberHumanReadable } from '@/utils';
|
import {
|
||||||
|
compareBuildNumbers,
|
||||||
|
formatTimeReadable,
|
||||||
|
numberHumanReadable,
|
||||||
|
releaseStreamToReadable,
|
||||||
|
} from '@/utils';
|
||||||
import { fade, scale } from 'svelte/transition';
|
import { fade, scale } from 'svelte/transition';
|
||||||
import { Checkbox } from '@/components/ui/checkbox';
|
import { Checkbox } from '@/components/ui/checkbox';
|
||||||
import Label from '@/components/ui/label/label.svelte';
|
import Label from '@/components/ui/label/label.svelte';
|
||||||
@ -52,9 +66,11 @@
|
|||||||
validModeTypeCombinationsSorted,
|
validModeTypeCombinationsSorted,
|
||||||
} from '@/gamemode';
|
} from '@/gamemode';
|
||||||
import { currentUserInfo } from '@/data';
|
import { currentUserInfo } from '@/data';
|
||||||
|
import { osuapi } from '@/api/osuapi';
|
||||||
|
|
||||||
let selectedTab = $state('home');
|
let selectedTab = $state('home');
|
||||||
let launching = $state(false);
|
let launching = $state(false);
|
||||||
|
let launchInfo = $state('');
|
||||||
|
|
||||||
let selectedGamemode = $derived(
|
let selectedGamemode = $derived(
|
||||||
getGamemodeInt(modeIntToStr($preferredMode), typeIntToStr($preferredType))
|
getGamemodeInt(modeIntToStr($preferredMode), typeIntToStr($preferredType))
|
||||||
@ -97,6 +113,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const launch = async (offline: boolean) => {
|
||||||
|
if (!$osuBuild || !$osuStream) {
|
||||||
|
toast.error('Hmmm...', {
|
||||||
|
description: 'There was an issue detecting your installed osu! version',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
launchInfo = 'Looking for updates...';
|
||||||
|
launching = true;
|
||||||
|
try {
|
||||||
|
const streamInfo = await osuapi.latestBuildVersion($osuStream ?? 'stable40');
|
||||||
|
if (!streamInfo) {
|
||||||
|
toast.error('Hmmm...', {
|
||||||
|
description: 'Failed to check for updates.',
|
||||||
|
});
|
||||||
|
launching = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const versions = compareBuildNumbers($osuBuild, streamInfo);
|
||||||
|
|
||||||
|
if (versions > 0) {
|
||||||
|
launchInfo = 'Update found!';
|
||||||
|
} else {
|
||||||
|
launchInfo = 'You are up to date!';
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
toast.error('Hmmm...', {
|
||||||
|
description: 'Failed to check for updates.',
|
||||||
|
});
|
||||||
|
launching = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
launching = false;
|
||||||
|
}, 5000);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AlertDialog.Root bind:open={launching}>
|
<AlertDialog.Root bind:open={launching}>
|
||||||
@ -109,7 +163,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-center justify-center gap-2 p-3 rounded-lg">
|
<div class="flex flex-col items-center justify-center gap-2 p-3 rounded-lg">
|
||||||
<Progress indeterminate />
|
<Progress indeterminate />
|
||||||
<span class="text-muted-foreground">Downloading update files...</span>
|
<span class="text-muted-foreground">{launchInfo}</span>
|
||||||
</div>
|
</div>
|
||||||
</AlertDialog.Content>
|
</AlertDialog.Content>
|
||||||
</AlertDialog.Root>
|
</AlertDialog.Root>
|
||||||
@ -350,7 +404,7 @@
|
|||||||
class="my-auto bg-theme-900/90 flex flex-col items-center justify-center gap-6 border border-theme-800/90 rounded-lg p-6"
|
class="my-auto bg-theme-900/90 flex flex-col items-center justify-center gap-6 border border-theme-800/90 rounded-lg p-6"
|
||||||
in:scale={{ duration: $reduceAnimations ? 0 : 400, start: 0.98 }}
|
in:scale={{ duration: $reduceAnimations ? 0 : 400, start: 0.98 }}
|
||||||
>
|
>
|
||||||
<div class="grid grid-cols-2 w-full gap-3">
|
<div class="grid grid-cols-3 w-full gap-3">
|
||||||
<div
|
<div
|
||||||
class="bg-theme-800/90 border border-theme-700/90 rounded-lg px-2 py-4 w-full flex flex-col gap-1 items-center justify-center"
|
class="bg-theme-800/90 border border-theme-700/90 rounded-lg px-2 py-4 w-full flex flex-col gap-1 items-center justify-center"
|
||||||
>
|
>
|
||||||
@ -379,6 +433,30 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="text-muted-foreground text-sm">Beatmap Sets imported</div>
|
<div class="text-muted-foreground text-sm">Beatmap Sets imported</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="bg-theme-800/90 border border-theme-700/90 rounded-lg px-2 py-4 w-full flex flex-col gap-1 items-center justify-center"
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-center p-2 rounded-lg bg-yellow-500/20">
|
||||||
|
<Brush class="text-yellow-500" size="26" />
|
||||||
|
</div>
|
||||||
|
<div class="relative font-bold text-xl text-yellow-400">
|
||||||
|
<div
|
||||||
|
class="absolute top-1 left-1/2 -translate-x-1/2 {!$skins
|
||||||
|
? 'opacity-100'
|
||||||
|
: 'opacity-0'} transition-opacity duration-1000"
|
||||||
|
>
|
||||||
|
<LoaderCircle class="animate-spin" />
|
||||||
|
</div>
|
||||||
|
<div class="{!$skins ? 'opacity-0' : 'opacity-100'} transition-opacity duration-1000">
|
||||||
|
{#if $reduceAnimations}
|
||||||
|
<span>{numberHumanReadable($skins ?? 0)}</span>
|
||||||
|
{:else}
|
||||||
|
<NumberFlow value={$skins ?? 0} trend={0} />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-muted-foreground text-sm">Skins</div>
|
||||||
|
</div>
|
||||||
<!-- <div
|
<!-- <div
|
||||||
class="bg-theme-800/90 border border-theme-700/90 rounded-lg px-2 py-4 w-full flex flex-col gap-1 items-center justify-center"
|
class="bg-theme-800/90 border border-theme-700/90 rounded-lg px-2 py-4 w-full flex flex-col gap-1 items-center justify-center"
|
||||||
>
|
>
|
||||||
@ -461,12 +539,7 @@
|
|||||||
<Button
|
<Button
|
||||||
size="lg"
|
size="lg"
|
||||||
disabled={launching || $osuInstallationPath === ''}
|
disabled={launching || $osuInstallationPath === ''}
|
||||||
onclick={() => {
|
onclick={() => launch($serverConnectionFails > 1)}
|
||||||
launching = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
launching = false;
|
|
||||||
}, 5000);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Play />
|
<Play />
|
||||||
Launch {$serverConnectionFails > 1 ? 'offline' : ''}
|
Launch {$serverConnectionFails > 1 ? 'offline' : ''}
|
||||||
@ -485,20 +558,26 @@
|
|||||||
<span class="font-semibold text-muted-foreground text-sm">Client Info</span>
|
<span class="font-semibold text-muted-foreground text-sm">Client Info</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-[1fr_auto] gap-1 mt-2 border-t border-theme-800 pt-2 px-2 pb-2">
|
<div class="grid grid-cols-[1fr_auto] gap-1 mt-2 border-t border-theme-800 pt-2 px-2 pb-2">
|
||||||
|
<span class="text-sm text-muted-foreground font-semibold">osu! Release Stream</span>
|
||||||
|
<span class="text-sm font-semibold text-end text-theme-50">
|
||||||
|
<Badge>
|
||||||
|
{#if $osuStream}
|
||||||
|
{releaseStreamToReadable($osuStream)}
|
||||||
|
{:else}
|
||||||
|
<LoaderCircle class="animate-spin" size={17} />
|
||||||
|
{/if}
|
||||||
|
</Badge>
|
||||||
|
</span>
|
||||||
<span class="text-sm text-muted-foreground font-semibold">osu! Version</span>
|
<span class="text-sm text-muted-foreground font-semibold">osu! Version</span>
|
||||||
<span class="text-sm font-semibold text-end text-theme-50">
|
<span class="text-sm font-semibold text-end text-theme-50">
|
||||||
<Badge>20250626.1</Badge>
|
<Badge>
|
||||||
|
{#if $osuBuild}
|
||||||
|
{$osuBuild}
|
||||||
|
{:else}
|
||||||
|
<LoaderCircle class="animate-spin" size={17} />
|
||||||
|
{/if}
|
||||||
|
</Badge>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="text-sm text-muted-foreground font-semibold">Beatmap Sets</span>
|
|
||||||
<span class="text-sm font-semibold text-end text-theme-50"
|
|
||||||
>{numberHumanReadable($beatmapSets ?? 0)}</span
|
|
||||||
>
|
|
||||||
|
|
||||||
<span class="text-sm text-muted-foreground font-semibold">Skins</span>
|
|
||||||
<span class="text-sm font-semibold text-end text-theme-50"
|
|
||||||
>{numberHumanReadable(727)}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else if selectedTab === 'settings'}
|
{:else if selectedTab === 'settings'}
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Logo from '$assets/logo.png';
|
import Logo from '$assets/logo.png';
|
||||||
import { estimateRefreshRate } from '@/displayUtils';
|
import { estimateRefreshRate } from '@/displayUtils';
|
||||||
import { beatmapSets, currentLoadingInfo, currentView, firstStartup } from '@/global';
|
import {
|
||||||
|
beatmapSets,
|
||||||
|
currentLoadingInfo,
|
||||||
|
currentView,
|
||||||
|
firstStartup,
|
||||||
|
osuBuild,
|
||||||
|
osuStream,
|
||||||
|
skins,
|
||||||
|
} from '@/global';
|
||||||
import {
|
import {
|
||||||
cursorSmoothness,
|
cursorSmoothness,
|
||||||
osuInstallationPath,
|
osuInstallationPath,
|
||||||
@ -107,13 +115,27 @@
|
|||||||
description: 'Your previously set osu! installation path seems to be invalid.',
|
description: 'Your previously set osu! installation path seems to be invalid.',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
currentLoadingInfo.set('Getting osu version...');
|
||||||
|
const osuReleaseStream: string = await invoke('get_osu_release_stream', {
|
||||||
|
folder: $osuInstallationPath,
|
||||||
|
});
|
||||||
|
osuStream.set(osuReleaseStream);
|
||||||
|
const osuVersion: string = await invoke('get_osu_version', {
|
||||||
|
folder: $osuInstallationPath,
|
||||||
|
});
|
||||||
|
osuBuild.set(osuVersion);
|
||||||
|
|
||||||
currentLoadingInfo.set('Counting beatmapsets...');
|
currentLoadingInfo.set('Counting beatmapsets...');
|
||||||
const beatmapSetCount: number | null = await invoke('get_beatmapsets_count', {
|
const beatmapSetCount: number | null = await invoke('get_beatmapsets_count', {
|
||||||
folder: $osuInstallationPath,
|
folder: $osuInstallationPath,
|
||||||
});
|
});
|
||||||
if (beatmapSetCount) {
|
if (beatmapSetCount) beatmapSets.set(beatmapSetCount);
|
||||||
beatmapSets.set(beatmapSetCount);
|
|
||||||
}
|
currentLoadingInfo.set('Counting skins...');
|
||||||
|
const skinCount: number | null = await invoke('get_skins_count', {
|
||||||
|
folder: $osuInstallationPath,
|
||||||
|
});
|
||||||
|
if (skinCount) skins.set(skinCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user