mirror of
https://github.com/timvisee/lazymc.git
synced 2025-07-31 04:02:02 -07:00
182 lines
4.7 KiB
Rust
182 lines
4.7 KiB
Rust
use std::collections::HashMap;
|
|
use std::fs;
|
|
use std::path::Path;
|
|
|
|
/// File name.
|
|
pub const FILE: &str = "server.properties";
|
|
|
|
/// EOL in server.properties file.
|
|
const EOL: &str = "\r\n";
|
|
|
|
/// Try to rewrite changes in server.properties file in dir.
|
|
///
|
|
/// Prints an error and stops on failure.
|
|
pub fn rewrite_dir<P: AsRef<Path>>(dir: P, changes: HashMap<&str, String>) {
|
|
if changes.is_empty() {
|
|
return;
|
|
}
|
|
|
|
// Ensure directory exists
|
|
if !dir.as_ref().is_dir() {
|
|
warn!(target: "lazymc",
|
|
"Not rewriting {} file, configured server directory doesn't exist: {}",
|
|
FILE,
|
|
dir.as_ref().to_str().unwrap_or("?")
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Rewrite file
|
|
rewrite_file(dir.as_ref().join(FILE), changes)
|
|
}
|
|
|
|
/// Try to rewrite changes in server.properties file.
|
|
///
|
|
/// Prints an error and stops on failure.
|
|
pub fn rewrite_file<P: AsRef<Path>>(file: P, changes: HashMap<&str, String>) {
|
|
if changes.is_empty() {
|
|
return;
|
|
}
|
|
|
|
// File must exist
|
|
if !file.as_ref().is_file() {
|
|
warn!(target: "lazymc",
|
|
"Not writing {} file, not found at: {}",
|
|
FILE,
|
|
file.as_ref().to_str().unwrap_or("?"),
|
|
);
|
|
return;
|
|
}
|
|
|
|
// Read contents
|
|
let contents = match fs::read_to_string(&file) {
|
|
Ok(contents) => contents,
|
|
Err(err) => {
|
|
error!(target: "lazymc",
|
|
"Failed to rewrite {} file, could not load: {}",
|
|
FILE,
|
|
err,
|
|
);
|
|
return;
|
|
}
|
|
};
|
|
|
|
// Rewrite file contents, return if nothing changed
|
|
let contents = match rewrite_contents(contents, changes) {
|
|
Some(contents) => contents,
|
|
None => {
|
|
debug!(target: "lazymc",
|
|
"Not rewriting {} file, no changes to apply",
|
|
FILE,
|
|
);
|
|
return;
|
|
}
|
|
};
|
|
|
|
// Write changes
|
|
match fs::write(file, contents) {
|
|
Ok(_) => {
|
|
info!(target: "lazymc",
|
|
"Rewritten {} file with updated values",
|
|
FILE,
|
|
);
|
|
}
|
|
Err(err) => {
|
|
error!(target: "lazymc",
|
|
"Failed to rewrite {} file, could not save changes: {}",
|
|
FILE,
|
|
err,
|
|
);
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Rewrite file contents with new properties.
|
|
///
|
|
/// Returns new file contents if anything has changed.
|
|
fn rewrite_contents(contents: String, mut changes: HashMap<&str, String>) -> Option<String> {
|
|
if changes.is_empty() {
|
|
return None;
|
|
}
|
|
|
|
let mut changed = false;
|
|
|
|
// Build new file
|
|
let mut new_contents: String = contents
|
|
.lines()
|
|
.map(|line| {
|
|
let mut line = line.to_owned();
|
|
|
|
// Skip comments or empty lines
|
|
let trim = line.trim();
|
|
if trim.starts_with('#') || trim.is_empty() {
|
|
return line;
|
|
}
|
|
|
|
// Try to split property
|
|
let (key, value) = match line.split_once("=") {
|
|
Some(result) => result,
|
|
None => return line,
|
|
};
|
|
|
|
// Take any new value, and update it
|
|
if let Some((_, new)) = changes.remove_entry(key.trim().to_lowercase().as_str()) {
|
|
if value != new {
|
|
line = format!("{}={}", key, new);
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
line
|
|
})
|
|
.collect::<Vec<_>>()
|
|
.join(EOL);
|
|
|
|
// Append any missed changes
|
|
for (key, value) in changes {
|
|
new_contents += &format!("{}{}={}", EOL, key, value);
|
|
changed = true;
|
|
}
|
|
|
|
// Return new contents if changed
|
|
if changed {
|
|
Some(new_contents)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
/// Read the given property from the given server.properties file.o
|
|
///
|
|
/// Returns `None` if file does not contain the property.
|
|
pub fn read_property<P: AsRef<Path>>(file: P, property: &str) -> Option<String> {
|
|
// File must exist
|
|
if !file.as_ref().is_file() {
|
|
warn!(target: "lazymc",
|
|
"Failed to read property from {} file, it does not exist",
|
|
FILE,
|
|
);
|
|
return None;
|
|
}
|
|
|
|
// Read contents
|
|
let contents = match fs::read_to_string(&file) {
|
|
Ok(contents) => contents,
|
|
Err(err) => {
|
|
error!(target: "lazymc",
|
|
"Failed to read property from {} file, could not load: {}",
|
|
FILE,
|
|
err,
|
|
);
|
|
return None;
|
|
}
|
|
};
|
|
|
|
// Find property, return value
|
|
contents
|
|
.lines()
|
|
.filter_map(|line| line.split_once('='))
|
|
.find(|(p, _)| p.trim().to_lowercase() == property.to_lowercase())
|
|
.map(|(_, v)| v.trim().to_string())
|
|
}
|