mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 15:13:16 +00:00
Do the same thing for save_state stuff
This commit is contained in:
parent
4f1096d8d6
commit
7dc4e6a9aa
5 changed files with 117 additions and 110 deletions
|
@ -2,6 +2,7 @@
|
||||||
pub mod mod_manager;
|
pub mod mod_manager;
|
||||||
pub mod noita_launcher;
|
pub mod noita_launcher;
|
||||||
pub mod releases;
|
pub mod releases;
|
||||||
|
pub mod save_paths;
|
||||||
pub mod save_state;
|
pub mod save_state;
|
||||||
pub mod self_restart;
|
pub mod self_restart;
|
||||||
pub mod self_update;
|
pub mod self_update;
|
||||||
|
|
83
noita-proxy/src/bookkeeping/save_paths.rs
Normal file
83
noita-proxy/src/bookkeeping/save_paths.rs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
use std::{
|
||||||
|
fs::{self, File},
|
||||||
|
io::{Read, Write},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
use directories::ProjectDirs;
|
||||||
|
use tracing::{info, warn};
|
||||||
|
|
||||||
|
use crate::Settings;
|
||||||
|
|
||||||
|
pub(crate) struct SavePaths {
|
||||||
|
settings_path: PathBuf,
|
||||||
|
pub save_state_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SavePaths {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
if Self::settings_next_to_exe_path().exists() {
|
||||||
|
Self::new_next_to_exe()
|
||||||
|
} else {
|
||||||
|
if let Some(project_dirs) = Self::project_dirs() {
|
||||||
|
info!("Using 'system' paths to store things");
|
||||||
|
let me = Self {
|
||||||
|
settings_path: project_dirs.config_dir().join("proxy.ron"),
|
||||||
|
save_state_path: project_dirs.data_dir().join("save_state"),
|
||||||
|
};
|
||||||
|
info!("Settings path: {}", me.settings_path.display());
|
||||||
|
let _ = fs::create_dir_all(project_dirs.config_dir());
|
||||||
|
let _ = fs::create_dir_all(&me.save_state_path);
|
||||||
|
me
|
||||||
|
} else {
|
||||||
|
warn!("Failed to get project dirst!");
|
||||||
|
Self::new_next_to_exe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_next_to_exe() -> Self {
|
||||||
|
info!("Using 'next to exe' path to store things");
|
||||||
|
Self {
|
||||||
|
settings_path: Self::settings_next_to_exe_path(),
|
||||||
|
save_state_path: Self::next_to_exe_path().join("save_state"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn project_dirs() -> Option<ProjectDirs> {
|
||||||
|
ProjectDirs::from("", "quant", "entangledworlds")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_to_exe_path() -> PathBuf {
|
||||||
|
let base_path = std::env::current_exe()
|
||||||
|
.map(|p| p.parent().unwrap().to_path_buf())
|
||||||
|
.unwrap_or(".".into());
|
||||||
|
base_path
|
||||||
|
}
|
||||||
|
|
||||||
|
fn settings_next_to_exe_path() -> PathBuf {
|
||||||
|
let base_path = std::env::current_exe()
|
||||||
|
.map(|p| p.parent().unwrap().to_path_buf())
|
||||||
|
.unwrap_or(".".into());
|
||||||
|
let config_name = "proxy.ron";
|
||||||
|
base_path.join(config_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_settings(&self) -> Settings {
|
||||||
|
if let Ok(mut file) = File::open(&self.settings_path) {
|
||||||
|
let mut s = String::new();
|
||||||
|
let _ = file.read_to_string(&mut s);
|
||||||
|
ron::from_str::<Settings>(&s).unwrap_or_default()
|
||||||
|
} else {
|
||||||
|
info!("Failed to load settings file, returing default settings");
|
||||||
|
Settings::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_settings(&self, settings: Settings) {
|
||||||
|
let settings = ron::to_string(&settings).unwrap();
|
||||||
|
if let Ok(mut file) = File::create(&self.settings_path) {
|
||||||
|
file.write_all(settings.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
fs, io,
|
fs, io,
|
||||||
path::PathBuf,
|
path::{Path, PathBuf},
|
||||||
sync::{
|
sync::{
|
||||||
Arc,
|
Arc,
|
||||||
atomic::{self, AtomicBool},
|
atomic::{self, AtomicBool},
|
||||||
|
@ -26,13 +26,16 @@ pub struct SaveState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SaveState {
|
impl SaveState {
|
||||||
pub(crate) fn new(path: PathBuf) -> Self {
|
pub(crate) fn new(path: impl AsRef<Path>) -> Self {
|
||||||
let has_savestate = path.join("run_info.bit").exists();
|
let has_savestate = path.as_ref().join("run_info.bit").exists();
|
||||||
info!("Has savestate: {has_savestate}");
|
info!("Has savestate: {has_savestate}");
|
||||||
if let Err(err) = fs::create_dir_all(&path) {
|
if let Err(err) = fs::create_dir_all(&path) {
|
||||||
error!("Error while creating directories: {err}");
|
error!("Error while creating directories: {err}");
|
||||||
}
|
}
|
||||||
let path = path.canonicalize().unwrap_or(path);
|
let path = path
|
||||||
|
.as_ref()
|
||||||
|
.canonicalize()
|
||||||
|
.unwrap_or(path.as_ref().to_path_buf());
|
||||||
info!("Will save to: {}", path.display());
|
info!("Will save to: {}", path.display());
|
||||||
Self {
|
Self {
|
||||||
path,
|
path,
|
||||||
|
|
|
@ -2,12 +2,12 @@ use bitcode::{Decode, Encode};
|
||||||
use bookkeeping::{
|
use bookkeeping::{
|
||||||
noita_launcher::{LaunchTokenResult, NoitaLauncher},
|
noita_launcher::{LaunchTokenResult, NoitaLauncher},
|
||||||
releases::Version,
|
releases::Version,
|
||||||
|
save_paths::SavePaths,
|
||||||
save_state::SaveState,
|
save_state::SaveState,
|
||||||
self_restart::SelfRestarter,
|
self_restart::SelfRestarter,
|
||||||
};
|
};
|
||||||
use clipboard::{ClipboardContext, ClipboardProvider};
|
use clipboard::{ClipboardContext, ClipboardProvider};
|
||||||
use cpal::traits::{DeviceTrait, HostTrait};
|
use cpal::traits::{DeviceTrait, HostTrait};
|
||||||
use directories::ProjectDirs;
|
|
||||||
use eframe::egui::load::TexturePoll;
|
use eframe::egui::load::TexturePoll;
|
||||||
use eframe::egui::{
|
use eframe::egui::{
|
||||||
self, Align2, Button, Color32, ComboBox, Context, DragValue, FontDefinitions, FontFamily,
|
self, Align2, Button, Color32, ComboBox, Context, DragValue, FontDefinitions, FontFamily,
|
||||||
|
@ -16,7 +16,6 @@ use eframe::egui::{
|
||||||
Visuals, Window, pos2,
|
Visuals, Window, pos2,
|
||||||
};
|
};
|
||||||
use eframe::epaint::TextureHandle;
|
use eframe::epaint::TextureHandle;
|
||||||
use eyre::{Context as _, OptionExt};
|
|
||||||
use image::DynamicImage::ImageRgba8;
|
use image::DynamicImage::ImageRgba8;
|
||||||
use image::RgbaImage;
|
use image::RgbaImage;
|
||||||
use lang::{LANGS, set_current_locale, tr};
|
use lang::{LANGS, set_current_locale, tr};
|
||||||
|
@ -31,8 +30,6 @@ use player_cosmetics::PlayerPngDesc;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use self_update::SelfUpdateManager;
|
use self_update::SelfUpdateManager;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{Read, Write};
|
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::{collections::HashMap, fs, str::FromStr};
|
use std::{collections::HashMap, fs, str::FromStr};
|
||||||
|
@ -49,7 +46,7 @@ use std::{net::IpAddr, path::PathBuf};
|
||||||
use steamworks::{LobbyId, SteamAPIInitError};
|
use steamworks::{LobbyId, SteamAPIInitError};
|
||||||
use tangled::{Peer, Reliability};
|
use tangled::{Peer, Reliability};
|
||||||
use tokio::time;
|
use tokio::time;
|
||||||
use tracing::{info, warn};
|
use tracing::info;
|
||||||
use unic_langid::LanguageIdentifier;
|
use unic_langid::LanguageIdentifier;
|
||||||
|
|
||||||
mod util;
|
mod util;
|
||||||
|
@ -1322,6 +1319,7 @@ pub struct App {
|
||||||
noitalog_number: usize,
|
noitalog_number: usize,
|
||||||
noitalog: Vec<String>,
|
noitalog: Vec<String>,
|
||||||
proxylog: String,
|
proxylog: String,
|
||||||
|
save_paths: SavePaths,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filled_group<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
|
fn filled_group<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
|
||||||
|
@ -1364,69 +1362,12 @@ pub struct Settings {
|
||||||
audio: AudioSettings,
|
audio: AudioSettings,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn settings_path() -> eyre::Result<PathBuf> {
|
|
||||||
let base_path = std::env::current_exe()
|
|
||||||
.map(|p| p.parent().unwrap().to_path_buf())
|
|
||||||
.unwrap_or(".".into());
|
|
||||||
let config_name = "proxy.ron";
|
|
||||||
let next_to_exe_path = base_path.join(config_name);
|
|
||||||
if next_to_exe_path.exists() {
|
|
||||||
info!("Using 'next to exe' path to store settings");
|
|
||||||
Ok(next_to_exe_path)
|
|
||||||
} else {
|
|
||||||
info!("Using 'system' path to store settings");
|
|
||||||
let project_dirs = ProjectDirs::from("", "quant", "entangledworlds")
|
|
||||||
.ok_or_eyre("Failed to retrieve ProjectDirs")?;
|
|
||||||
fs::create_dir_all(project_dirs.config_dir())
|
|
||||||
.wrap_err("Failed to create config directory")?;
|
|
||||||
let config_path = project_dirs.config_dir().join(config_name);
|
|
||||||
info!("Config path: {}", config_path.display());
|
|
||||||
Ok(config_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn settings_get() -> Settings {
|
|
||||||
if let Ok(settings_path) = settings_path() {
|
|
||||||
// info!("Settings path: {}", settings_path.display());
|
|
||||||
if let Ok(mut file) = File::open(settings_path) {
|
|
||||||
let mut s = String::new();
|
|
||||||
let _ = file.read_to_string(&mut s);
|
|
||||||
ron::from_str::<Settings>(&s).unwrap_or_default()
|
|
||||||
} else {
|
|
||||||
info!("Failed to load settings file, returing default settings");
|
|
||||||
Settings::default()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!("Failed to get settings file location, returing default settings");
|
|
||||||
Settings::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn settings_set(
|
|
||||||
app: AppSavedState,
|
|
||||||
color: PlayerAppearance,
|
|
||||||
modmanager: ModmanagerSettings,
|
|
||||||
audio: AudioSettings,
|
|
||||||
) {
|
|
||||||
if let Ok(settings_path) = settings_path() {
|
|
||||||
let settings = Settings {
|
|
||||||
app,
|
|
||||||
color,
|
|
||||||
modmanager,
|
|
||||||
audio,
|
|
||||||
};
|
|
||||||
let settings = ron::to_string(&settings).unwrap();
|
|
||||||
if let Ok(mut file) = File::create(settings_path) {
|
|
||||||
file.write_all(settings.as_bytes()).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn new(cc: &eframe::CreationContext<'_>, args: Args) -> Self {
|
pub fn new(cc: &eframe::CreationContext<'_>, args: Args) -> Self {
|
||||||
cc.egui_ctx.set_visuals(Visuals::dark());
|
cc.egui_ctx.set_visuals(Visuals::dark());
|
||||||
cc.egui_ctx.set_theme(ThemePreference::Dark);
|
cc.egui_ctx.set_theme(ThemePreference::Dark);
|
||||||
let settings = settings_get();
|
let save_paths = SavePaths::new();
|
||||||
|
let settings = save_paths.load_settings();
|
||||||
let mut saved_state: AppSavedState = settings.app;
|
let mut saved_state: AppSavedState = settings.app;
|
||||||
let modmanager_settings: ModmanagerSettings = settings.modmanager;
|
let modmanager_settings: ModmanagerSettings = settings.modmanager;
|
||||||
let appearance: PlayerAppearance = settings.color;
|
let appearance: PlayerAppearance = settings.color;
|
||||||
|
@ -1472,11 +1413,7 @@ impl App {
|
||||||
cc.egui_ctx
|
cc.egui_ctx
|
||||||
.set_zoom_factor(args.ui_zoom_factor.unwrap_or(default_zoom_factor));
|
.set_zoom_factor(args.ui_zoom_factor.unwrap_or(default_zoom_factor));
|
||||||
info!("Creating the app...");
|
info!("Creating the app...");
|
||||||
let run_save_state = if let Ok(path) = std::env::current_exe() {
|
let run_save_state = SaveState::new(&save_paths.save_state_path);
|
||||||
SaveState::new(path.parent().unwrap().join("save_state"))
|
|
||||||
} else {
|
|
||||||
SaveState::new("./save_state/".into())
|
|
||||||
};
|
|
||||||
let path = player_path(modmanager_settings.mod_path());
|
let path = player_path(modmanager_settings.mod_path());
|
||||||
let player_image = if path.exists() {
|
let player_image = if path.exists() {
|
||||||
image::open(path)
|
image::open(path)
|
||||||
|
@ -1514,6 +1451,7 @@ impl App {
|
||||||
noitalog_number: 0,
|
noitalog_number: 0,
|
||||||
noitalog: Vec::new(),
|
noitalog: Vec::new(),
|
||||||
proxylog: String::new(),
|
proxylog: String::new(),
|
||||||
|
save_paths,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(connect_to) = me.args.auto_connect_to {
|
if let Some(connect_to) = me.args.auto_connect_to {
|
||||||
|
@ -1527,12 +1465,12 @@ impl App {
|
||||||
let mut audio = self.audio.clone();
|
let mut audio = self.audio.clone();
|
||||||
audio.input_devices.clear();
|
audio.input_devices.clear();
|
||||||
audio.output_devices.clear();
|
audio.output_devices.clear();
|
||||||
settings_set(
|
self.save_paths.save_settings(Settings {
|
||||||
self.app_saved_state.clone(),
|
color: self.appearance.clone(),
|
||||||
self.appearance.clone(),
|
app: self.app_saved_state.clone(),
|
||||||
self.modmanager_settings.clone(),
|
modmanager: self.modmanager_settings.clone(),
|
||||||
audio,
|
audio,
|
||||||
)
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_netman_init(&self) -> NetManagerInit {
|
fn get_netman_init(&self) -> NetManagerInit {
|
||||||
|
@ -2839,7 +2777,7 @@ fn cli_setup(
|
||||||
AudioSettings,
|
AudioSettings,
|
||||||
steamworks::LobbyType,
|
steamworks::LobbyType,
|
||||||
) {
|
) {
|
||||||
let settings = settings_get();
|
let settings = SavePaths::new().load_settings();
|
||||||
let saved_state: AppSavedState = settings.app;
|
let saved_state: AppSavedState = settings.app;
|
||||||
let mut mod_manager: ModmanagerSettings = settings.modmanager;
|
let mut mod_manager: ModmanagerSettings = settings.modmanager;
|
||||||
let appearance: PlayerAppearance = settings.color;
|
let appearance: PlayerAppearance = settings.color;
|
||||||
|
@ -2860,7 +2798,7 @@ fn cli_setup(
|
||||||
let run_save_state = if let Ok(path) = std::env::current_exe() {
|
let run_save_state = if let Ok(path) = std::env::current_exe() {
|
||||||
SaveState::new(path.parent().unwrap().join("save_state"))
|
SaveState::new(path.parent().unwrap().join("save_state"))
|
||||||
} else {
|
} else {
|
||||||
SaveState::new("./save_state/".into())
|
SaveState::new("./save_state/")
|
||||||
};
|
};
|
||||||
let player_path = player_path(mod_manager.mod_path());
|
let player_path = player_path(mod_manager.mod_path());
|
||||||
let mut cosmetics = (false, false, false);
|
let mut cosmetics = (false, false, false);
|
||||||
|
|
|
@ -3151,11 +3151,8 @@ fn test_explosion_perf() {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
let iters = 64;
|
let iters = 64;
|
||||||
for _ in 0..iters {
|
for _ in 0..iters {
|
||||||
let (mut world, _, _, _, _) = WorldManager::new(
|
let (mut world, _, _, _, _) =
|
||||||
true,
|
WorldManager::new(true, OmniPeerId(0), SaveState::new("/tmp/ew_tmp_save"));
|
||||||
OmniPeerId(0),
|
|
||||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
|
||||||
);
|
|
||||||
world
|
world
|
||||||
.materials
|
.materials
|
||||||
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
||||||
|
@ -3203,11 +3200,8 @@ fn test_explosion_perf_unloaded() {
|
||||||
let iters = 4;
|
let iters = 4;
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
for _ in 0..iters {
|
for _ in 0..iters {
|
||||||
let (mut world, _, _, _, _) = WorldManager::new(
|
let (mut world, _, _, _, _) =
|
||||||
true,
|
WorldManager::new(true, OmniPeerId(0), SaveState::new("/tmp/ew_tmp_save"));
|
||||||
OmniPeerId(0),
|
|
||||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
|
||||||
);
|
|
||||||
world
|
world
|
||||||
.materials
|
.materials
|
||||||
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
||||||
|
@ -3271,11 +3265,8 @@ fn test_explosion_perf_large() {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
let iters = 16;
|
let iters = 16;
|
||||||
for _ in 0..iters {
|
for _ in 0..iters {
|
||||||
let (mut world, _, _, _, _) = WorldManager::new(
|
let (mut world, _, _, _, _) =
|
||||||
true,
|
WorldManager::new(true, OmniPeerId(0), SaveState::new("/tmp/ew_tmp_save"));
|
||||||
OmniPeerId(0),
|
|
||||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
|
||||||
);
|
|
||||||
world
|
world
|
||||||
.materials
|
.materials
|
||||||
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
||||||
|
@ -3322,11 +3313,8 @@ fn test_line_perf() {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
let iters = 64;
|
let iters = 64;
|
||||||
for _ in 0..iters {
|
for _ in 0..iters {
|
||||||
let (mut world, _, _, _, _) = WorldManager::new(
|
let (mut world, _, _, _, _) =
|
||||||
true,
|
WorldManager::new(true, OmniPeerId(0), SaveState::new("/tmp/ew_tmp_save"));
|
||||||
OmniPeerId(0),
|
|
||||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
|
||||||
);
|
|
||||||
world
|
world
|
||||||
.materials
|
.materials
|
||||||
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
||||||
|
@ -3361,11 +3349,8 @@ fn test_circle_perf() {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
let iters = 64;
|
let iters = 64;
|
||||||
for _ in 0..iters {
|
for _ in 0..iters {
|
||||||
let (mut world, _, _, _, _) = WorldManager::new(
|
let (mut world, _, _, _, _) =
|
||||||
true,
|
WorldManager::new(true, OmniPeerId(0), SaveState::new("/tmp/ew_tmp_save"));
|
||||||
OmniPeerId(0),
|
|
||||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
|
||||||
);
|
|
||||||
world
|
world
|
||||||
.materials
|
.materials
|
||||||
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
||||||
|
@ -3400,11 +3385,8 @@ fn test_cut_perf() {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
let iters = 64;
|
let iters = 64;
|
||||||
for _ in 0..iters {
|
for _ in 0..iters {
|
||||||
let (mut world, _, _, _, _) = WorldManager::new(
|
let (mut world, _, _, _, _) =
|
||||||
true,
|
WorldManager::new(true, OmniPeerId(0), SaveState::new("/tmp/ew_tmp_save"));
|
||||||
OmniPeerId(0),
|
|
||||||
SaveState::new("/tmp/ew_tmp_save".parse().unwrap()),
|
|
||||||
);
|
|
||||||
world
|
world
|
||||||
.materials
|
.materials
|
||||||
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
.insert(0, (0, 100, CellType::Liquid(LiquidType::Liquid), 0));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue