mirror of
https://github.com/redstrate/Kawari.git
synced 2025-04-19 22:36:49 +00:00
Add configurable boot patch location, fix verifying boot components
And more, this is mostly laying the groundwork for serving patch files.
This commit is contained in:
parent
91e80a36f8
commit
c1ad0c023c
4 changed files with 76 additions and 4 deletions
|
@ -24,7 +24,7 @@ async fn root() -> Html<String> {
|
|||
|
||||
let environment = setup_default_environment();
|
||||
let template = environment.get_template("admin.html").unwrap();
|
||||
Html(template.render(context! { worlds_open => config.worlds_open, login_open => config.login_open }).unwrap())
|
||||
Html(template.render(context! { worlds_open => config.worlds_open, login_open => config.login_open, boot_patch_location => config.boot_patches_location }).unwrap())
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
|
@ -32,6 +32,7 @@ async fn root() -> Html<String> {
|
|||
struct Input {
|
||||
worlds_open: Option<String>,
|
||||
login_open: Option<String>,
|
||||
boot_patch_location: Option<String>,
|
||||
}
|
||||
|
||||
async fn apply(Form(input): Form<Input>) -> Redirect {
|
||||
|
@ -51,6 +52,10 @@ async fn apply(Form(input): Form<Input>) -> Redirect {
|
|||
config.login_open = false;
|
||||
}
|
||||
|
||||
if let Some(boot_patch_location) = input.boot_patch_location {
|
||||
config.boot_patches_location = boot_patch_location;
|
||||
}
|
||||
|
||||
serde_json::to_writer(
|
||||
&std::fs::File::create("config.json").unwrap(),
|
||||
&config,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::fs::read_dir;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use axum::{Form, Json, Router, routing::get};
|
||||
|
@ -9,6 +11,40 @@ use kawari::config::{Config, get_config};
|
|||
use axum::extract::Path;
|
||||
use axum::response::IntoResponse;
|
||||
use axum::http::{HeaderMap, StatusCode};
|
||||
use minijinja::filters::list;
|
||||
|
||||
fn list_patch_files(dir_path: &str) -> Vec<String> {
|
||||
let mut entries: Vec<_> = read_dir(dir_path).unwrap().flatten().collect();
|
||||
entries.sort_by_key(|dir| dir.path());
|
||||
let mut game_patches: Vec<_> = entries
|
||||
.into_iter()
|
||||
.flat_map(|entry| {
|
||||
let Ok(meta) = entry.metadata() else {
|
||||
return vec![];
|
||||
};
|
||||
if meta.is_dir() {
|
||||
return vec![];
|
||||
}
|
||||
if meta.is_file() && entry.file_name().to_str().unwrap().contains(".patch") {
|
||||
return vec![entry.path()];
|
||||
}
|
||||
vec![]
|
||||
})
|
||||
.collect();
|
||||
game_patches.sort_by(|a, b| {
|
||||
// Ignore H/D in front of filenames
|
||||
let mut a_path = a.as_path().file_name().unwrap().to_str().unwrap().to_string();
|
||||
if a_path.starts_with("H") {
|
||||
return Ordering::Less;
|
||||
}
|
||||
let mut b_path = b.as_path().file_name().unwrap().to_str().unwrap().to_string();
|
||||
/*if b_path.starts_with("H") {
|
||||
return Ordering::Greater;
|
||||
}*/
|
||||
a_path.partial_cmp(&b_path).unwrap()
|
||||
}); // ensure we're actually installing them in the correct order
|
||||
game_patches.iter().map(|x| x.file_stem().unwrap().to_str().unwrap().to_string() ).collect()
|
||||
}
|
||||
|
||||
async fn verify_session(Path((platform, game_version, sid)): Path<(String, String, String)>) -> impl IntoResponse {
|
||||
let config = get_config();
|
||||
|
@ -22,12 +58,28 @@ async fn verify_session(Path((platform, game_version, sid)): Path<(String, Strin
|
|||
(headers).into_response()
|
||||
}
|
||||
|
||||
|
||||
async fn verify_boot(Path((platform, boot_version)): Path<(String, String)>) -> impl IntoResponse {
|
||||
tracing::info!("Verifying boot components...");
|
||||
|
||||
let config = get_config();
|
||||
if !config.supports_platform(&platform) {
|
||||
return StatusCode::INTERNAL_SERVER_ERROR.into_response();
|
||||
}
|
||||
|
||||
// Turns 2019.03.12.0000.0001/?time=2024-06-29-18-30 into just 2019.03.12.0000.0001
|
||||
let actual_boot_version = boot_version.split("?time").collect::<Vec<&str>>()[0];
|
||||
|
||||
// check if we need any patching
|
||||
let patches = list_patch_files(&config.boot_patches_location);
|
||||
for patch in patches {
|
||||
let patch_str: &str = &patch;
|
||||
if actual_boot_version.partial_cmp(patch_str).unwrap() == Ordering::Less {
|
||||
// not up to date!
|
||||
// TODO: serve patchlist
|
||||
}
|
||||
}
|
||||
|
||||
let mut headers = HeaderMap::new();
|
||||
(headers).into_response()
|
||||
}
|
||||
|
@ -38,7 +90,7 @@ async fn main() {
|
|||
|
||||
let app = Router::new()
|
||||
.route("/http/:platform/ffxivneo_release_game/:game_version/:sid", post(verify_session))
|
||||
.route("/http/:platform/ffxivneo_release_boot/:boot_version", get(verify_boot));
|
||||
.route("/http/:platform/ffxivneo_release_boot/*boot_version", get(verify_boot)); // NOTE: for future programmers, this is a wildcard because axum hates the /version/?time=blah format.
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 6900));
|
||||
tracing::info!("Patch server started on {}", addr);
|
||||
|
|
|
@ -10,6 +10,9 @@ pub struct Config {
|
|||
|
||||
#[serde(default = "default_supported_platforms")]
|
||||
pub supported_platforms: Vec<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub boot_patches_location: String
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -17,6 +20,7 @@ impl Default for Config {
|
|||
Self {
|
||||
worlds_open: false,
|
||||
login_open: false,
|
||||
boot_patches_location: String::new(),
|
||||
supported_platforms: default_supported_platforms()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
<p>Gate open:{{ worlds_open }}</p>
|
||||
<p>Gate open:{{ login_open }}</p>
|
||||
<p>Boot patch location:{{ boot_patch_location }}</p>
|
||||
<form action='apply' method='post'>
|
||||
<input type='checkbox' id='worlds_open' name='worlds_open' checked/>
|
||||
<input type='checkbox' id='login_open' name='login_open' checked/>
|
||||
<label>
|
||||
Worlds Open:
|
||||
<input type='checkbox' id='worlds_open' name='worlds_open' checked/>
|
||||
</label>
|
||||
<label>
|
||||
Login Open:
|
||||
<input type='checkbox' id='login_open' name='login_open' checked/>
|
||||
</label>
|
||||
<label>
|
||||
Boot Patch Location:
|
||||
<input type='text' id='boot_patch_location' name='boot_patch_location'/>
|
||||
</label>
|
||||
<button type='submit'>Apply</button>
|
||||
</form>
|
Loading…
Add table
Reference in a new issue