mirror of
https://git.ethanthesleepy.one/ethanaobrien/ew
synced 2026-07-12 00:32:20 +08:00
Ability to load masterdata from a folder
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
|
||||
#[cfg(not(feature = "library"))]
|
||||
fn main() -> std::io::Result<()> {
|
||||
ew::runtime::update_data_path(&ew::get_args().path);
|
||||
let args = ew::get_args();
|
||||
ew::runtime::update_data_path(&args.path);
|
||||
ew::runtime::update_masterdata_path(&args.masterdata);
|
||||
ew::run_server(false)
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,10 @@ pub struct Args {
|
||||
pub jp_android_asset_hash: String,
|
||||
|
||||
#[arg(long, default_value = "", help = "Path to image assets.")]
|
||||
pub image_asset_path: String
|
||||
pub image_asset_path: String,
|
||||
|
||||
#[arg(long, default_value = "", help = "Optional directory to load asset lists and master data CSVs from at runtime. Layout mirrors the bundled assets (asset_lists/, csv/, csv-en/). Missing files fall back to the internal copies.")]
|
||||
pub masterdata: String
|
||||
}
|
||||
|
||||
pub fn get_args() -> Args {
|
||||
|
||||
@@ -13,9 +13,9 @@ pub fn routes(cfg: &mut web::ServiceConfig) {
|
||||
|
||||
async fn get(_req: HttpRequest) -> impl Responder {
|
||||
let mut response = object!{};
|
||||
response["Bundle"] = include_file!("src/router/asset_lists/Bundle.json").into();
|
||||
response["Movie"] = include_file!("src/router/asset_lists/Movie.json").into();
|
||||
response["Sound"] = include_file!("src/router/asset_lists/Sound.json").into();
|
||||
response["Bundle"] = load_list("Bundle").into();
|
||||
response["Movie"] = load_list("Movie").into();
|
||||
response["Sound"] = load_list("Sound").into();
|
||||
|
||||
let body = jzon::stringify(response);
|
||||
HttpResponse::Ok()
|
||||
@@ -24,6 +24,21 @@ async fn get(_req: HttpRequest) -> impl Responder {
|
||||
.body(body)
|
||||
}
|
||||
|
||||
fn load_list(name: &str) -> String {
|
||||
let rel = format!("asset_lists/{}.json", name);
|
||||
if let Some(bytes) = crate::runtime::read_masterdata_file(&rel) {
|
||||
if let Ok(s) = String::from_utf8(bytes) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
match name {
|
||||
"Bundle" => include_file!("src/router/asset_lists/Bundle.json"),
|
||||
"Movie" => include_file!("src/router/asset_lists/Movie.json"),
|
||||
"Sound" => include_file!("src/router/asset_lists/Sound.json"),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn supported() -> impl Responder {
|
||||
"SUPPORTED"
|
||||
}
|
||||
|
||||
@@ -33,6 +33,13 @@ fn dir_for(region: Region) -> &'static Dir<'static> {
|
||||
}
|
||||
}
|
||||
|
||||
fn region_subdir(region: Region) -> &'static str {
|
||||
match region {
|
||||
Region::Jp => "csv",
|
||||
Region::En => "csv-en",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_all(region: Region) -> JsonValue {
|
||||
let mut rv = object!{};
|
||||
|
||||
@@ -42,18 +49,26 @@ pub fn get_all(region: Region) -> JsonValue {
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or_default();
|
||||
|
||||
if !table_name.is_empty() {
|
||||
rv[table_name] = file.contents_utf8().unwrap_or_default().into();
|
||||
if table_name.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(bytes) = csv_bytes(region, table_name) {
|
||||
rv[table_name] = String::from_utf8(bytes).unwrap_or_default().into();
|
||||
}
|
||||
}
|
||||
|
||||
rv
|
||||
}
|
||||
|
||||
pub fn csv_bytes(region: Region, name: &str) -> Option<&'static [u8]> {
|
||||
pub fn csv_bytes(region: Region, name: &str) -> Option<Vec<u8>> {
|
||||
let rel = format!("{}/{}.csv", region_subdir(region), name);
|
||||
if let Some(bytes) = crate::runtime::read_masterdata_file(&rel) {
|
||||
return Some(bytes);
|
||||
}
|
||||
dir_for(region)
|
||||
.get_file(format!("{name}.csv"))
|
||||
.map(|f| f.contents())
|
||||
.map(|f| f.contents().to_vec())
|
||||
}
|
||||
|
||||
pub fn table(region: Region, name: &str) -> JsonValue {
|
||||
@@ -65,7 +80,7 @@ pub fn table(region: Region, name: &str) -> JsonValue {
|
||||
let bytes = csv_bytes(region, name).unwrap_or_else(|| {
|
||||
panic!("masterdata CSV not bundled: {name}.csv ({region:?})")
|
||||
});
|
||||
let parsed = parse_csv(name, bytes);
|
||||
let parsed = parse_csv(name, &bytes);
|
||||
|
||||
TABLE_CACHE.lock().unwrap().insert(key, parsed.clone());
|
||||
parsed
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
use lazy_static::lazy_static;
|
||||
use std::sync::RwLock;
|
||||
use std::collections::HashSet;
|
||||
use std::path::Path;
|
||||
use std::sync::{Mutex, RwLock};
|
||||
use std::fs;
|
||||
|
||||
lazy_static! {
|
||||
static ref RUNNING: RwLock<bool> = RwLock::new(false);
|
||||
static ref DATAPATH: RwLock<String> = RwLock::new(String::new());
|
||||
static ref MASTERDATA_PATH: RwLock<String> = RwLock::new(String::new());
|
||||
static ref MASTERDATA_WARNED: Mutex<HashSet<String>> = Mutex::new(HashSet::new());
|
||||
static ref EASTER: RwLock<bool> = RwLock::new(false);
|
||||
}
|
||||
|
||||
@@ -33,6 +37,39 @@ pub fn update_data_path(path: &str) {
|
||||
*w = path.to_string();
|
||||
}
|
||||
|
||||
pub fn update_masterdata_path(path: &str) {
|
||||
let trimmed = path.trim_end_matches('/').to_string();
|
||||
let mut w = MASTERDATA_PATH.write().unwrap();
|
||||
if trimmed.is_empty() {
|
||||
*w = String::new();
|
||||
return;
|
||||
}
|
||||
if !Path::new(&trimmed).is_dir() {
|
||||
println!("Couldn't find masterdata directory {}", trimmed);
|
||||
*w = String::new();
|
||||
return;
|
||||
}
|
||||
*w = trimmed;
|
||||
}
|
||||
|
||||
pub fn read_masterdata_file(rel_path: &str) -> Option<Vec<u8>> {
|
||||
let base = MASTERDATA_PATH.read().unwrap().clone();
|
||||
if base.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let full_path = format!("{}/{}", base, rel_path);
|
||||
match fs::read(&full_path) {
|
||||
Ok(bytes) => Some(bytes),
|
||||
Err(_) => {
|
||||
let mut warned = MASTERDATA_WARNED.lock().unwrap();
|
||||
if warned.insert(rel_path.to_string()) {
|
||||
println!("Couldn't find masterdata {}", rel_path);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only currently editable by the android so
|
||||
pub fn set_easter_mode(enabled: bool) {
|
||||
let mut w = EASTER.write().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user