From 32d25fc1058c315a9141957031da8c98633a96a8 Mon Sep 17 00:00:00 2001 From: Shiroki Date: Sat, 3 Feb 2024 19:34:49 +0800 Subject: [PATCH] feat: game config editor, monaco --- frontend/bun.lockb | Bin 362046 -> 363697 bytes frontend/components/SideNav.vue | 4 + frontend/components/editor.vue | 83 ++++++++++++++++++ frontend/package.json | 1 + frontend/pages/editor.vue | 5 ++ gateway/Cargo.lock | 33 +++++++ gateway/Cargo.toml | 2 +- gateway/src/game_config/mod.rs | 42 +++++++++ .../src/{ => game_config}/unreal_struct.pest | 0 .../src/{ => game_config}/unreal_struct.rs | 2 +- gateway/src/lib.rs | 4 +- gateway/src/main.rs | 22 +---- 12 files changed, 176 insertions(+), 22 deletions(-) create mode 100644 frontend/components/editor.vue create mode 100644 frontend/pages/editor.vue create mode 100644 gateway/src/game_config/mod.rs rename gateway/src/{ => game_config}/unreal_struct.pest (100%) rename gateway/src/{ => game_config}/unreal_struct.rs (96%) diff --git a/frontend/bun.lockb b/frontend/bun.lockb index df59f85ca5496d7cb846ef3d45e67b7402999bfc..3d07fed0f8665f3a2332f7e2eb21ab7dc374cc83 100755 GIT binary patch delta 53761 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≀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
NA`k-fQEwNLBl~wpkz=AC=E0Q#DhK$ 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 delta 52780 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 l`}Rd 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");