Expand the theme editor with multi-select, snapping, context menus, draft recovery and export validation; add theme backups and trust prompts. Add in-app diagnostics and rotating log bundle viewing, hardware-accelerated theme video playback on macOS, and refresh the settings, setup wizard and theme gallery layouts.
237 lines
9.1 KiB
Rust
237 lines
9.1 KiB
Rust
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
|
use hardware_id::get_id;
|
|
use std::path::PathBuf;
|
|
use std::sync::Mutex;
|
|
use tauri::Manager;
|
|
use tauri_plugin_fs::FsExt;
|
|
|
|
pub mod commands;
|
|
pub mod config;
|
|
pub mod logging;
|
|
#[cfg(target_os = "macos")]
|
|
pub mod macos;
|
|
pub mod osudb;
|
|
pub mod presence;
|
|
pub mod state;
|
|
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
|
pub mod theme_server;
|
|
pub mod utils;
|
|
use crate::{
|
|
commands::{
|
|
backup_theme_folder, check_for_corruption, config_all, config_clear, config_delete,
|
|
config_exists, config_get, config_set, download_and_extract_theme,
|
|
download_ezpp_launcher_update, download_ezpp_launcher_update_files, encrypt_string, exit,
|
|
export_theme, extract_theme, file_size, find_osu_installation, get_beatmapsets_count,
|
|
get_ezpp_launcher_update_files, get_hwid, get_launcher_version, get_osu_release_stream,
|
|
get_osu_skin, get_osu_version, get_platform, get_skins_count, has_net8, has_osuwinello,
|
|
has_wmctrl, install_ezpp_launcher_update, installation_diagnostics,
|
|
is_open_tablet_driver_path_valid, is_open_tablet_driver_running, is_osu_running,
|
|
list_theme_backups, log_frontend, open_logs_folder, open_theme_editor, open_theme_folder,
|
|
open_url_in_browser, opened_urls, optimize_theme_media, pick_osu_installation,
|
|
presence_connect, presence_disconnect, presence_is_connected, presence_update_button,
|
|
presence_update_status, presence_update_user, read_theme_info, replace_ui_files,
|
|
resolve_osu_folder, restore_theme_backup, run_open_tablet_driver, run_osu, run_osu_updater,
|
|
save_theme_project, set_logging_enabled, set_osu_config_values, set_osu_user_config_values,
|
|
stop_open_tablet_driver, theme_asset_base, theme_editor_context, theme_preview_url,
|
|
valid_osu_folder,
|
|
},
|
|
state::AppState,
|
|
};
|
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
pub fn run() {
|
|
let mut builder = tauri::Builder::default().plugin(logging::plugin());
|
|
#[cfg(desktop)]
|
|
{
|
|
builder = builder.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
|
|
let app_window = app.get_webview_window("main").expect("no main window");
|
|
app_window.set_focus().expect("failed to focus");
|
|
if args.len() > 1 {
|
|
use tauri::Emitter;
|
|
|
|
let mut files = Vec::new();
|
|
|
|
for maybe_file in args.iter().skip(1) {
|
|
if maybe_file.starts_with("-") {
|
|
continue;
|
|
}
|
|
|
|
let path = PathBuf::from(maybe_file);
|
|
|
|
if path.extension().and_then(|e| e.to_str()) == Some("ezpplauncher-theme") {
|
|
app.fs_scope().allow_file(&path).ok();
|
|
files.push(path);
|
|
}
|
|
}
|
|
|
|
app.emit("opened", files.clone()).ok();
|
|
}
|
|
}));
|
|
}
|
|
|
|
let app = builder
|
|
.setup(|app| {
|
|
log::info!(
|
|
target: "launcher",
|
|
"EZPPLauncher {} starting on {} ({}) — logs: {}",
|
|
env!("CARGO_PKG_VERSION"),
|
|
std::env::consts::OS,
|
|
std::env::consts::ARCH,
|
|
logging::logs_directory().display()
|
|
);
|
|
|
|
// ── Config ────────────────────────────────────────────────────────
|
|
let home = std::env::var("HOME")
|
|
.or_else(|_| std::env::var("USERPROFILE"))
|
|
.unwrap_or_else(|_| ".".into());
|
|
let db_path = PathBuf::from(home).join(".ezpplauncher").join("config.db");
|
|
|
|
let hwid = get_id().unwrap_or_else(|_| "recorderinsandybridge".into());
|
|
|
|
let mut cfg = config::Config::new(db_path);
|
|
cfg.init(&hwid)?;
|
|
|
|
// ── Opened files ──────────────────────────────────────────────────
|
|
let mut opened_files = Vec::new();
|
|
let args = std::env::args().collect::<Vec<_>>();
|
|
if args.len() > 1 {
|
|
for maybe_file in args.iter().skip(1) {
|
|
if maybe_file.starts_with("-") {
|
|
continue;
|
|
}
|
|
let path = PathBuf::from(maybe_file);
|
|
if path.extension().and_then(|e| e.to_str()) == Some("ezpplauncher-theme") {
|
|
app.fs_scope().allow_file(&path).ok();
|
|
opened_files.push(path);
|
|
}
|
|
}
|
|
}
|
|
|
|
app.manage(AppState {
|
|
config: Mutex::new(cfg),
|
|
opened_files: Mutex::new(opened_files),
|
|
editor_theme_folder: Mutex::new(None),
|
|
});
|
|
|
|
// WebKit's custom-protocol media pipeline is unreliable (and
|
|
// loads large WebMs into memory), so Linux and macOS use a real
|
|
// loopback HTTP server with byte-range support instead.
|
|
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
|
match commands::theme_root().and_then(|root| {
|
|
let media = theme_server::media_root()?;
|
|
theme_server::start(root, media)
|
|
}) {
|
|
Ok(_) => {}
|
|
Err(error) => log::warn!(
|
|
target: "launcher",
|
|
"Could not start the theme asset server: {error}"
|
|
),
|
|
}
|
|
|
|
#[cfg(target_os = "macos")]
|
|
if let Some(window) = app.get_webview_window("main") {
|
|
if let Err(error) = macos::round_window(&window, 12.0) {
|
|
log::warn!(target: "launcher", "Could not round the launcher window: {error}");
|
|
}
|
|
if let Err(error) = macos::allow_media_autoplay(&window) {
|
|
log::warn!(target: "launcher", "{error}");
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
})
|
|
.invoke_handler(tauri::generate_handler![
|
|
opened_urls,
|
|
get_hwid,
|
|
find_osu_installation,
|
|
pick_osu_installation,
|
|
resolve_osu_folder,
|
|
valid_osu_folder,
|
|
get_beatmapsets_count,
|
|
get_skins_count,
|
|
get_osu_version,
|
|
get_osu_release_stream,
|
|
installation_diagnostics,
|
|
set_osu_config_values,
|
|
set_osu_user_config_values,
|
|
run_osu_updater,
|
|
run_osu,
|
|
get_osu_skin,
|
|
get_ezpp_launcher_update_files,
|
|
download_ezpp_launcher_update_files,
|
|
replace_ui_files,
|
|
is_osu_running,
|
|
open_url_in_browser,
|
|
get_launcher_version,
|
|
exit,
|
|
get_platform,
|
|
file_size,
|
|
check_for_corruption,
|
|
presence_connect,
|
|
presence_disconnect,
|
|
presence_update_status,
|
|
presence_update_user,
|
|
presence_update_button,
|
|
presence_is_connected,
|
|
has_osuwinello,
|
|
has_wmctrl,
|
|
has_net8,
|
|
encrypt_string,
|
|
download_ezpp_launcher_update,
|
|
install_ezpp_launcher_update,
|
|
read_theme_info,
|
|
backup_theme_folder,
|
|
list_theme_backups,
|
|
restore_theme_backup,
|
|
extract_theme,
|
|
download_and_extract_theme,
|
|
save_theme_project,
|
|
export_theme,
|
|
open_theme_folder,
|
|
open_theme_editor,
|
|
theme_editor_context,
|
|
theme_asset_base,
|
|
theme_preview_url,
|
|
optimize_theme_media,
|
|
config_get,
|
|
config_set,
|
|
config_exists,
|
|
config_delete,
|
|
config_clear,
|
|
config_all,
|
|
run_open_tablet_driver,
|
|
stop_open_tablet_driver,
|
|
is_open_tablet_driver_running,
|
|
is_open_tablet_driver_path_valid,
|
|
log_frontend,
|
|
set_logging_enabled,
|
|
open_logs_folder,
|
|
logging::list_log_bundles,
|
|
logging::read_log_bundle
|
|
])
|
|
.plugin(tauri_plugin_fs::init())
|
|
.plugin(tauri_plugin_dialog::init())
|
|
.plugin(tauri_plugin_shell::init())
|
|
.plugin(tauri_plugin_cors_fetch::init())
|
|
.build(tauri::generate_context!())
|
|
.expect("error while building tauri application");
|
|
|
|
app.run(|app, event| {
|
|
// The content view can be replaced again while the webview is being
|
|
// built, so re-apply the corner mask once the app is ready.
|
|
#[cfg(target_os = "macos")]
|
|
if let tauri::RunEvent::Ready = &event {
|
|
if let Some(window) = app.get_webview_window("main") {
|
|
if let Err(error) = macos::round_window(&window, 12.0) {
|
|
log::warn!(target: "launcher", "Could not round the launcher window: {error}");
|
|
}
|
|
if let Err(error) = macos::allow_media_autoplay(&window) {
|
|
log::warn!(target: "launcher", "{error}");
|
|
}
|
|
}
|
|
}
|
|
|
|
presence::handle_run_event(app, &event);
|
|
});
|
|
}
|