chore: force release stream to stable, connecting to ezppfarm does now work

This commit is contained in:
HorizonCode 2025-07-04 09:16:07 +02:00
parent d7015d6252
commit 493d425ee7
4 changed files with 120 additions and 107 deletions

View File

@ -216,13 +216,6 @@ pub fn get_osu_release_stream(folder: String) -> String {
.unwrap_or_else(|| "Stable40".to_string());
}
#[tauri::command]
pub fn get_osu_previous_release_stream(folder: String) -> Option<String> {
let path = PathBuf::from(folder);
let osu_config = get_osu_config(path.clone());
osu_config.and_then(|config| config.get("_PreviousReleaseStream").cloned())
}
#[derive(serde::Deserialize)]
pub struct ConfigEntry {
pub key: String,
@ -261,77 +254,106 @@ pub fn set_osu_config_values(
#[tauri::command]
pub fn run_osu_updater(folder: String) -> Result<(), String> {
let osu_exe_path = PathBuf::from(folder.clone()).join("osu!.exe");
#[cfg(windows)]
const DETACHED_PROCESS: u32 = 0x00000008;
#[cfg(windows)]
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
let handle = thread::spawn(move || {
#[cfg(windows)]
let mut updater_process = Command::new(&osu_exe_path)
.arg("-repair")
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
.spawn()
.ok()?; // Ignore error, just exit thread
#[cfg(not(windows))]
let mut updater_process = Command::new(&osu_exe_path).arg("-repair").spawn().ok()?; // Ignore error, just exit thread
thread::sleep(Duration::from_millis(500));
let mut sys = System::new_all();
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
let mut termination_thread_running = true;
while termination_thread_running {
for (_, process) in sys.processes() {
if process.name() == "osu!.exe" {
let process_id = process.pid();
let window_title = get_window_title_by_pid(process_id);
if !window_title.is_empty() && !window_title.contains("updater") {
if let Ok(_) = process.kill_and_wait() {
termination_thread_running = false;
break;
}
}
}
}
if !termination_thread_running {
break;
}
thread::sleep(Duration::from_millis(500));
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
}
let _ = updater_process.wait();
let force_update_files = [".require_update", "help.txt", "_pending"];
for update_file_name in &force_update_files {
let update_file = PathBuf::from(&folder).join(update_file_name);
if update_file.exists() {
let metadata = std::fs::symlink_metadata(&update_file);
if let Ok(meta) = metadata {
let result = if meta.is_dir() {
std::fs::remove_dir_all(&update_file)
} else {
std::fs::remove_file(&update_file)
};
if let Err(e) = result {
eprintln!(
"Failed to remove force update file {:?}: {}",
update_file, e
);
}
}
}
}
Some(())
});
handle.join().map_err(|_| "Thread panicked".to_string())?;
Ok(())
}
#[tauri::command]
pub fn run_osu(folder: String) -> Result<(), String> {
let osu_exe_path = PathBuf::from(folder).join("osu!.exe");
#[cfg(windows)]
const DETACHED_PROCESS: u32 = 0x00000008;
#[cfg(windows)]
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
#[cfg(windows)]
let mut updater_process = Command::new(osu_exe_path)
.arg("-repair")
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
.spawn()
.map_err(|e| e.to_string())?;
#[cfg(not(windows))]
let mut updater_process = Command::new(osu_exe_path)
.arg("-repair")
.spawn()
.map_err(|e| e.to_string())?;
thread::sleep(Duration::from_millis(500));
let mut sys = System::new_all();
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
let mut termination_thread_running = true;
while termination_thread_running {
for (_, process) in sys.processes() {
if process.name() == "osu!.exe" {
let process_id = process.pid();
let window_title = get_window_title_by_pid(process_id);
if !window_title.is_empty() && !window_title.contains("updater") {
if let Ok(_) = process.kill_and_wait() {
termination_thread_running = false;
break;
}
}
}
}
if !termination_thread_running {
break;
}
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
thread::sleep(Duration::from_millis(500));
}
updater_process.wait().map_err(|e| e.to_string())?;
Ok(())
}
#[tauri::command]
pub fn run_osu(folder: String) -> Result<(), String> {
let osu_exe_path = PathBuf::from(folder).join("osu!.exe");
#[cfg(windows)]
const DETACHED_PROCESS: u32 = 0x00000008;
#[cfg(windows)]
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
#[cfg(windows)]
let mut game_process = Command::new(osu_exe_path)
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
.spawn()
.map_err(|e| e.to_string())?;
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
.arg("-devserver")
.arg("ez-pp.farm")
.spawn()
.map_err(|e| e.to_string())?;
#[cfg(not(windows))]
let mut game_process = Command::new(osu_exe_path)
.spawn()
.map_err(|e| e.to_string())?;
.arg("-devserver")
.arg("ez-pp.farm")
.spawn()
.map_err(|e| e.to_string())?;
game_process.wait().map_err(|e| e.to_string())?;

View File

@ -4,9 +4,9 @@ use tauri::Manager;
pub mod commands;
pub mod utils;
use crate::commands::{
find_osu_installation, get_beatmapsets_count, get_hwid, get_osu_previous_release_stream,
get_osu_release_stream, get_osu_version, get_skins_count, run_osu, run_osu_updater,
set_osu_config_values, set_osu_user_config_values, valid_osu_folder,
find_osu_installation, get_beatmapsets_count, get_hwid, get_osu_release_stream,
get_osu_version, get_skins_count, run_osu, run_osu_updater, set_osu_config_values,
set_osu_user_config_values, valid_osu_folder,
};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
@ -32,7 +32,6 @@ pub fn run() {
get_skins_count,
get_osu_version,
get_osu_release_stream,
get_osu_previous_release_stream,
set_osu_config_values,
set_osu_user_config_values,
run_osu_updater,

View File

@ -18,7 +18,7 @@ export const setConfigValues = async (
entries,
});
export const getPreviousReleaseStream = async (folder: string) => {
const result = await invoke('get_osu_previous_release_stream', { folder });
export const getReleaseStream = async (folder: string) => {
const result = await invoke('get_osu_release_stream', { folder });
return typeof result === 'string' ? result : undefined;
};

View File

@ -67,7 +67,7 @@
} from '@/gamemode';
import { currentUserInfo } from '@/data';
import { osuapi } from '@/api/osuapi';
import { getPreviousReleaseStream, setConfigValues, setUserConfigValues } from '@/osuUtil';
import { getReleaseStream, setConfigValues, setUserConfigValues } from '@/osuUtil';
import { getCurrentWindow } from '@tauri-apps/api/window';
let selectedTab = $state('home');
@ -125,7 +125,7 @@
};
const launch = async (offline: boolean) => {
if (!$osuBuild || !$osuStream) {
if (!$osuBuild) {
toast.error('Hmmm...', {
description: 'There was an issue detecting your installed osu! version',
});
@ -145,7 +145,7 @@
}
try {
const streamInfo = await osuapi.latestBuildVersion($osuStream ?? 'stable40');
const streamInfo = await osuapi.latestBuildVersion('stable40');
if (!streamInfo) {
toast.error('Hmmm...', {
description: 'Failed to check for updates.',
@ -154,17 +154,37 @@
return;
}
const previousReleaseStream = await getPreviousReleaseStream(osuPath);
let forceUpdate = previousReleaseStream && previousReleaseStream !== $osuStream;
const releaseStream = await getReleaseStream(osuPath);
let forceUpdate = releaseStream && releaseStream.toLowerCase() !== 'stable40';
const versions = compareBuildNumbers($osuBuild, streamInfo);
if (versions > 0 || forceUpdate) {
launchInfo = 'Update found!';
await new Promise((res) => setTimeout(res, 1500));
launchInfo = 'Running osu! updater...';
await setUserConfigValues(osuPath, [{ key: 'LastVersion', value: streamInfo }]);
await setUserConfigValues(osuPath, [
{
key: 'LastVersion',
value: `b${streamInfo}`,
},
]);
await setConfigValues(osuPath, [
{
key: '_ReleaseStream',
value: 'Stable40',
},
]);
osuStream.set('Stable40');
osuBuild.set(`b${streamInfo}`);
await invoke('run_osu_updater', { folder: osuPath });
launchInfo = 'osu! is now up to date!';
if (forceUpdate)
await setConfigValues(osuPath, [
{
key: '_UpdateFailCount',
value: '0',
},
]);
} else {
launchInfo = 'You are up to date!';
}
@ -764,34 +784,6 @@
onclick={browse_osu_installation}>Browse</Button
>
</div>
<div class="flex flex-col">
<Label class="text-sm" for="setting-custom-cursor">osu! release stream</Label>
<div class="text-muted-foreground text-xs">The release stream of your osu! client</div>
</div>
<div class="flex flex-row w-full">
<Select.Root
type="single"
value={$osuStream}
onValueChange={async (newStream) => {
const oldStream = $osuStream;
osuStream.set(newStream);
await setConfigValues($osuInstallationPath, [
{ key: '_ReleaseStream', value: newStream },
{ key: '_PreviousReleaseStream', value: oldStream ?? newStream },
]);
}}
>
<Select.Trigger class="border-theme-800 bg-theme-950 text-white font-semibold">
<div class="flex flex-row items-center gap-2">
{releaseStreamToReadable($osuStream ?? 'Stable40')}
</div>
</Select.Trigger>
<Select.Content class="bg-theme-950 border border-theme-900 rounded-lg">
<Select.Item value="Stable40">Stable</Select.Item>
<Select.Item value="CuttingEdge">Cutting Edge</Select.Item>
</Select.Content>
</Select.Root>
</div>
</div>
</div>
{/if}