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");