feat(backend): load vehicle translation + icon caches
This commit is contained in:
@@ -29,6 +29,8 @@ struct AppState {
|
||||
battles_db: PathBuf,
|
||||
teams_db: PathBuf,
|
||||
leaderboard_cache: Mutex<Option<CachedLeaderboard>>,
|
||||
vehicle_names: HashMap<String, HashMap<String, String>>,
|
||||
vehicle_icons: HashMap<String, String>,
|
||||
}
|
||||
|
||||
struct CachedLeaderboard {
|
||||
@@ -317,7 +319,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
battles_db: resolve_db_path("TSS_BATTLES_DB", "tss_battles.db"),
|
||||
teams_db: resolve_db_path("TSS_TEAMS_DB", "tss_teams.db"),
|
||||
leaderboard_cache: Mutex::new(None),
|
||||
vehicle_names: load_vehicle_names(&resolve_db_path(
|
||||
"VEHICLE_TRANSLATIONS_JSON",
|
||||
"vehicle_translations.json",
|
||||
)),
|
||||
vehicle_icons: load_vehicle_icons(&resolve_db_path(
|
||||
"VEHICLE_DATA_CACHE_JSON",
|
||||
"vehicle_data_cache_all.json",
|
||||
)),
|
||||
});
|
||||
tracing::info!(
|
||||
"loaded {} vehicle name maps, {} vehicle icons",
|
||||
state.vehicle_names.len(),
|
||||
state.vehicle_icons.len()
|
||||
);
|
||||
spawn_leaderboard_refresh(state.clone());
|
||||
|
||||
let app = Router::new()
|
||||
@@ -1621,6 +1636,54 @@ fn allowed_origins() -> AllowOrigin {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_vehicle_names(path: &FsPath) -> HashMap<String, HashMap<String, String>> {
|
||||
match fs::read_to_string(path) {
|
||||
Ok(s) => serde_json::from_str(&s).unwrap_or_default(),
|
||||
Err(_) => HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn load_vehicle_icons(path: &FsPath) -> HashMap<String, String> {
|
||||
// vehicle_data_cache_all.json is [[cdk, name, icon, tags], ...]
|
||||
let raw: Vec<serde_json::Value> = match fs::read_to_string(path) {
|
||||
Ok(s) => serde_json::from_str(&s).unwrap_or_default(),
|
||||
Err(_) => Vec::new(),
|
||||
};
|
||||
let mut out = HashMap::new();
|
||||
for entry in raw {
|
||||
if let (Some(cdk), Some(icon)) = (
|
||||
entry.get(0).and_then(|v| v.as_str()),
|
||||
entry.get(2).and_then(|v| v.as_str()),
|
||||
) {
|
||||
out.insert(cdk.to_string(), icon.to_string());
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
fn lookup_vehicle_name(
|
||||
names: &HashMap<String, HashMap<String, String>>,
|
||||
cdk: &str,
|
||||
lang: &str,
|
||||
) -> String {
|
||||
if let Some(by_lang) = names.get(cdk) {
|
||||
if let Some(n) = by_lang.get(lang) {
|
||||
return n.clone();
|
||||
}
|
||||
if let Some(n) = by_lang.get("en") {
|
||||
return n.clone();
|
||||
}
|
||||
}
|
||||
cdk.to_string()
|
||||
}
|
||||
|
||||
fn lookup_vehicle_icon(icons: &HashMap<String, String>, cdk: &str) -> String {
|
||||
icons
|
||||
.get(cdk)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| format!("{cdk}.png"))
|
||||
}
|
||||
|
||||
fn resolve_db_path(env_key: &str, default_file: &str) -> PathBuf {
|
||||
let raw = env::var(env_key).unwrap_or_else(|_| default_file.to_string());
|
||||
let expanded = expand_home(&raw);
|
||||
@@ -1702,3 +1765,43 @@ fn load_env_file(path: &FsPath) {
|
||||
env::set_var(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn vehicle_name_prefers_lang_then_en_then_cdk() {
|
||||
let mut names = HashMap::new();
|
||||
let mut t = HashMap::new();
|
||||
t.insert("en".to_string(), "T-34".to_string());
|
||||
t.insert("ru".to_string(), "Т-34".to_string());
|
||||
names.insert("ussr_t_34".to_string(), t);
|
||||
assert_eq!(lookup_vehicle_name(&names, "ussr_t_34", "ru"), "Т-34");
|
||||
assert_eq!(lookup_vehicle_name(&names, "ussr_t_34", "de"), "T-34");
|
||||
assert_eq!(lookup_vehicle_name(&names, "unknown_cdk", "en"), "unknown_cdk");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vehicle_icon_falls_back_to_cdk_png() {
|
||||
let mut icons = HashMap::new();
|
||||
icons.insert("ussr_t_34".to_string(), "ussr_t_34.png".to_string());
|
||||
assert_eq!(lookup_vehicle_icon(&icons, "ussr_t_34"), "ussr_t_34.png");
|
||||
assert_eq!(lookup_vehicle_icon(&icons, "germ_pz"), "germ_pz.png");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_vehicle_icons_parses_cache_array() {
|
||||
let dir = std::env::temp_dir();
|
||||
let p = dir.join("test_vehicle_cache_all.json");
|
||||
fs::write(
|
||||
&p,
|
||||
r#"[["ussr_t_34","T-34","ussr_t_34.png",{}],["germ_pz","Pz","germ_pz.png",{}]]"#,
|
||||
)
|
||||
.unwrap();
|
||||
let icons = load_vehicle_icons(&p);
|
||||
assert_eq!(icons.get("ussr_t_34").unwrap(), "ussr_t_34.png");
|
||||
assert_eq!(icons.len(), 2);
|
||||
let _ = fs::remove_file(&p);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user