diff --git a/frontend/bun.lockb b/frontend/bun.lockb index df59f85..3d07fed 100755 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/components/SideNav.vue b/frontend/components/SideNav.vue index 98af2ef..a51f09b 100644 --- a/frontend/components/SideNav.vue +++ b/frontend/components/SideNav.vue @@ -19,5 +19,9 @@ const links = [{ label: 'Saves Management', icon: 'i-heroicons-archive-box', to: '/saves' +}, { + label: 'Config Editor', + icon: 'i-heroicons-adjustments-horizontal', + to: '/editor' }] diff --git a/frontend/components/editor.vue b/frontend/components/editor.vue new file mode 100644 index 0000000..14b76ab --- /dev/null +++ b/frontend/components/editor.vue @@ -0,0 +1,83 @@ + + + diff --git a/frontend/package.json b/frontend/package.json index 20a55bc..ca4ef0d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "@extractus/feed-extractor": "^7.0.9", + "@guolao/vue-monaco-editor": "^1.5.0", "@iconify-json/mdi": "^1.1.64", "@nuxt/ui": "^2.12.3", "@pinia/nuxt": "^0.5.1", diff --git a/frontend/pages/editor.vue b/frontend/pages/editor.vue new file mode 100644 index 0000000..11f65fa --- /dev/null +++ b/frontend/pages/editor.vue @@ -0,0 +1,5 @@ + diff --git a/gateway/Cargo.lock b/gateway/Cargo.lock index 6e0ec1c..a23f8b4 100644 --- a/gateway/Cargo.lock +++ b/gateway/Cargo.lock @@ -665,6 +665,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range-header" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ce4ef31cda248bbdb6e6820603b82dfcd9e833db65a43e997a0ccec777d11fe" + [[package]] name = "httparse" version = "1.8.0" @@ -856,6 +862,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1582,10 +1598,18 @@ checksum = "0da193277a4e2c33e59e09b5861580c33dd0a637c3883d0fa74ba40c0374af2e" dependencies = [ "bitflags 2.4.2", "bytes", + "futures-util", "http 1.0.0", "http-body 1.0.0", "http-body-util", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", "pin-project-lite", + "tokio", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -1702,6 +1726,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.15" diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 30ee9f2..173ee6c 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -22,6 +22,6 @@ thiserror = "1.0.56" tokio = { version = "1.35.1", features = ["full"] } tokio-stream = { version = "0.1.14", features = ["full"] } tokio-util = { version = "0.7.10", features = ["full"] } -tower-http = { version = "0.5.1", features = ["trace"] } +tower-http = { version = "0.5.1", features = ["trace", "fs"] } tracing = "0.1.40" tracing-subscriber = "0.3.18" diff --git a/gateway/src/game_config/mod.rs b/gateway/src/game_config/mod.rs new file mode 100644 index 0000000..b3c3b37 --- /dev/null +++ b/gateway/src/game_config/mod.rs @@ -0,0 +1,42 @@ +mod unreal_struct; + +pub mod route { + use std::path::Path; + + use axum::{routing::post, Router}; + use tower_http::services::ServeFile; + + use crate::AppResult; + + pub fn new_router(base_path: impl AsRef) -> Router<()> { + let base_path = base_path.as_ref(); + let default_path = base_path.join("DefaultPalWorldSettings.ini"); + let current_path = base_path.join("Pal/Saved/Config/LinuxServer/PalWorldSettings.ini"); + Router::new() + .route_service("/default", ServeFile::new(&default_path)) + .route_service("/current", ServeFile::new(¤t_path)) + .route("/save", post(|body| save(body, current_path))) + } + + async fn save(body: String, path: impl AsRef) -> AppResult<()> { + tokio::fs::create_dir_all(path.as_ref().parent().unwrap()).await?; + tokio::fs::write(path, body).await?; + Ok(()) + } +} + +// fn parse_ini() { +// let i = Ini::load_from_file("/Users/shiroki/Downloads/DefaultPalWorldSettings.ini").unwrap(); +// for (sec, prop) in i.iter() { +// println!("Section: {:?}", sec); +// for (k, v) in prop.iter() { +// // println!("{}:{}", k, v); +// if v.starts_with('(') && v.ends_with(')') { +// // assume as Unreal config struct +// println!("{k}: {:?}", unreal_struct::parse_struct(v)); +// } else { +// println!("{k}: {v}"); +// } +// } +// } +// } diff --git a/gateway/src/unreal_struct.pest b/gateway/src/game_config/unreal_struct.pest similarity index 100% rename from gateway/src/unreal_struct.pest rename to gateway/src/game_config/unreal_struct.pest diff --git a/gateway/src/unreal_struct.rs b/gateway/src/game_config/unreal_struct.rs similarity index 96% rename from gateway/src/unreal_struct.rs rename to gateway/src/game_config/unreal_struct.rs index 677a838..a095c02 100644 --- a/gateway/src/unreal_struct.rs +++ b/gateway/src/game_config/unreal_struct.rs @@ -2,7 +2,7 @@ use pest::Parser; use pest_derive::Parser; #[derive(Parser)] -#[grammar = "unreal_struct.pest"] +#[grammar = "game_config/unreal_struct.pest"] pub struct UnrealSturctParser; #[derive(Debug)] diff --git a/gateway/src/lib.rs b/gateway/src/lib.rs index 59b617b..3dfef22 100644 --- a/gateway/src/lib.rs +++ b/gateway/src/lib.rs @@ -7,12 +7,14 @@ use thiserror::Error; pub mod pal; pub mod rcon; pub mod steamcmd; -pub mod unreal_struct; +pub mod game_config; #[derive(Error, Debug)] enum AppError { #[error("error from the inner RCON client")] PalworldCommandError(#[from] pal::PalworldCommandError), + #[error("error during IO")] + IOError(#[from] std::io::Error), } impl IntoResponse for AppError { diff --git a/gateway/src/main.rs b/gateway/src/main.rs index 9974273..932b7ef 100644 --- a/gateway/src/main.rs +++ b/gateway/src/main.rs @@ -1,23 +1,6 @@ -// fn main() { -// let i = Ini::load_from_file("/Users/shiroki/Downloads/DefaultPalWorldSettings.ini").unwrap(); -// for (sec, prop) in i.iter() { -// println!("Section: {:?}", sec); -// for (k, v) in prop.iter() { -// // println!("{}:{}", k, v); -// if v.starts_with('(') && v.ends_with(')') { -// // assume as Unreal config struct -// println!("{k}: {:?}", gateway_rs::unreal_struct::parse_struct(v)); -// } else { -// println!("{k}: {v}"); -// } -// } -// } -// } - use axum::{routing::get, Router}; use palboard_gateway::{ - pal::{self, PalServerClient}, - steamcmd, + game_config, pal::{self, PalServerClient}, steamcmd }; use std::env; use tracing::{info, warn}; @@ -43,7 +26,8 @@ async fn main() { let app = Router::new() .route("/version", get(VERSION.unwrap_or("unknown"))) .nest("/pal", pal::route::new_router(client)) - .nest("/steam", steamcmd::route::new_router()); + .nest("/steam", steamcmd::route::new_router()) + .nest("/game_config", game_config::route::new_router("/home/steam/palserver/")); let listener = tokio::net::TcpListener::bind(env::var("GATEWAY_ADDR").unwrap_or_else(|_| { warn!("you should set `GATEWAY_ADDR` environment variable, frontend will connect to this address");