1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// This file contains various mod management functions
use anyhow::{anyhow, Result};
use app::NorthstarMod;
use std::path::PathBuf;
use app::GameInstall;
use app::get_enabled_mods;
use json5;
/// Set the status of a passed mod to enabled/disabled
pub fn set_mod_enabled_status(
game_install: GameInstall,
mod_name: String,
is_enabled: bool,
) -> Result<(), String> {
let enabledmods_json_path = format!("{}/R2Northstar/enabledmods.json", game_install.game_path);
// Parse JSON
let mut res: serde_json::Value = get_enabled_mods(game_install)?;
// Check if key exists
if res.get(mod_name.clone()).is_none() {
return Err("Value not found in enabledmod.json".to_string());
}
// Update value
res[mod_name] = serde_json::Value::Bool(is_enabled);
// Save the JSON structure into the output file
std::fs::write(
enabledmods_json_path,
serde_json::to_string_pretty(&res).unwrap(),
)
.unwrap();
Ok(())
}
/// Parses `mod.json` for mod name
// TODO: Maybe pass PathBuf or serde json object
fn parse_mod_json_for_mod_name(mod_json_path: String) -> Result<String, anyhow::Error> {
// Read file into string and parse it
let data = std::fs::read_to_string(mod_json_path)?;
let parsed_json: serde_json::Value = json5::from_str(&data)?;
// Extract mod name
let mod_name = match parsed_json.get("Name").and_then(|value| value.as_str()) {
Some(name) => name,
None => return Err(anyhow!("No name found")),
};
Ok(mod_name.to_string())
}
/// Parse `mods` folder for installed mods.
fn get_installed_mods(game_install: GameInstall) -> Result<Vec<String>, String> {
let ns_mods_folder = format!("{}/R2Northstar/mods/", game_install.game_path);
let paths = std::fs::read_dir(ns_mods_folder).unwrap();
let mut directories: Vec<PathBuf> = Vec::new();
let mut mod_names: Vec<String> = Vec::new();
// Get list of folders in `mods` directory
for path in paths {
let my_path = path.unwrap().path();
let md = std::fs::metadata(my_path.clone()).unwrap();
if md.is_dir() {
directories.push(my_path);
}
}
// Iterate over folders and check if they are Northstar mods
for directory in directories {
// Check if mod.json exists
let mod_json_path = format!("{}/mod.json", directory.to_str().unwrap());
if !std::path::Path::new(&mod_json_path).exists() {
continue;
}
// Parse mod.json and get mod name
let mod_name = match parse_mod_json_for_mod_name(mod_json_path.clone()) {
Ok(mod_name) => mod_name,
Err(err) => {
println!("Failed parsing {} with {}", mod_json_path, err.to_string());
continue;
}
};
mod_names.push(mod_name);
}
// Return found mod names
Ok(mod_names)
}
/// Gets list of installed mods and their properties
/// - name
/// - is enabled?
pub fn get_installed_mods_and_properties(
game_install: GameInstall,
) -> Result<Vec<NorthstarMod>, String> {
// Get actually installed mods
let found_installed_mods = get_installed_mods(game_install.clone())?;
// Get enabled mods as JSON
let enabled_mods: serde_json::Value = match get_enabled_mods(game_install) {
Ok(enabled_mods) => enabled_mods,
Err(_) => serde_json::from_str("{}").unwrap(), // `enabledmods.json` not found, create empty object
};
let mut installed_mods = Vec::new();
let mapping = enabled_mods.as_object().unwrap();
// Use list of installed mods and set enabled based on `enabledmods.json`
for name in found_installed_mods {
let current_mod_enabled = match mapping.get(&name) {
Some(enabled) => enabled.as_bool().unwrap(),
None => true, // Northstar considers mods not in mapping as enabled.
};
let current_mod: NorthstarMod = NorthstarMod {
name: name,
enabled: current_mod_enabled,
};
installed_mods.push(current_mod);
}
Ok(installed_mods)
}
|