Working Instance Sync
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, fs, path::PathBuf};
|
||||
|
||||
use lyceris::auth::microsoft::MinecraftAccount;
|
||||
use tauri::State;
|
||||
|
||||
use crate::{features::Feature, GameVersion, SharedState};
|
||||
use crate::{features::Feature, launcher::launcher_dir, GameVersion, SharedState};
|
||||
|
||||
pub struct InstanceSync {}
|
||||
|
||||
@@ -20,7 +20,7 @@ impl Feature for InstanceSync {
|
||||
version: &GameVersion,
|
||||
account: &MinecraftAccount,
|
||||
) -> super::FeatureResult {
|
||||
println!("Launching {} for {}", version.id, account.username);
|
||||
sync_to_instance(version).map_err(|e| e.to_string())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -31,12 +31,70 @@ impl Feature for InstanceSync {
|
||||
version: &GameVersion,
|
||||
account: &MinecraftAccount,
|
||||
) -> super::FeatureResult {
|
||||
println!("Game launched!");
|
||||
sync_back_from_instance(version).map_err(|e| e.to_string())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn sync_to_instance(version: &GameVersion) -> std::io::Result<()> {
|
||||
let global_path = options_path_global();
|
||||
let instance_path = options_path_instance(version);
|
||||
|
||||
if !global_path.exists() {
|
||||
if let Ok(instance_content) = fs::read_to_string(instance_path) {
|
||||
fs::write(global_path, instance_content)?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let global_content = fs::read_to_string(global_path)?;
|
||||
|
||||
// Ensure instance dir exists
|
||||
if let Some(parent) = instance_path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
fs::write(instance_path, global_content)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn sync_back_from_instance(version: &GameVersion) -> std::io::Result<()> {
|
||||
let global_path = options_path_global();
|
||||
let instance_path = options_path_instance(version);
|
||||
|
||||
let global_content = fs::read_to_string(&global_path)?;
|
||||
let instance_content = fs::read_to_string(&instance_path)?;
|
||||
|
||||
let mut global_map = parse_options(&global_content);
|
||||
let instance_map = parse_options(&instance_content);
|
||||
|
||||
// Only apply changes (ignore deletions)
|
||||
for (key, instance_value) in instance_map {
|
||||
match global_map.get(&key) {
|
||||
Some(global_value) if global_value == &instance_value => {}
|
||||
_ => {
|
||||
// changed or new → update global
|
||||
global_map.insert(key, instance_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs::write(global_path, serialize_options(&global_map))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn options_path_global() -> PathBuf {
|
||||
launcher_dir().join("options.txt")
|
||||
}
|
||||
|
||||
fn options_path_instance(version: &GameVersion) -> PathBuf {
|
||||
launcher_dir().join(&version.id).join("options.txt")
|
||||
}
|
||||
|
||||
fn parse_options(content: &str) -> HashMap<String, String> {
|
||||
let mut map = HashMap::new();
|
||||
|
||||
@@ -52,3 +110,10 @@ fn parse_options(content: &str) -> HashMap<String, String> {
|
||||
|
||||
map
|
||||
}
|
||||
|
||||
fn serialize_options(map: &HashMap<String, String>) -> String {
|
||||
map.iter()
|
||||
.map(|(k, v)| format!("{k}:{v}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user