mirror of
https://github.com/YGGverse/hlstate-rs.git
synced 2026-03-31 17:15:37 +00:00
make tmp cli scrape impl
This commit is contained in:
parent
105409a76b
commit
e52ed711ba
8 changed files with 312 additions and 47 deletions
193
Cargo.lock
generated
193
Cargo.lock
generated
|
|
@ -70,6 +70,12 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.6"
|
||||
|
|
@ -202,10 +208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
|
|
@ -479,6 +482,12 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
|
|
@ -588,14 +597,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasip2",
|
||||
"wasip3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -647,6 +657,15 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
dependencies = [
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.1"
|
||||
|
|
@ -669,11 +688,9 @@ checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
|||
name = "hlstate-httpd"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"rocket",
|
||||
"rocket_dyn_templates",
|
||||
"serde",
|
||||
"toml 0.9.12+spec-1.1.0",
|
||||
]
|
||||
|
||||
|
|
@ -778,6 +795,12 @@ dependencies = [
|
|||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "id-arena"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.25"
|
||||
|
|
@ -801,7 +824,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"hashbrown 0.16.1",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
|
@ -891,6 +914,12 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "leb128fmt"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.182"
|
||||
|
|
@ -1257,6 +1286,16 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
|
|
@ -1290,9 +1329,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
|
|
@ -1417,6 +1456,7 @@ dependencies = [
|
|||
"rocket_codegen",
|
||||
"rocket_http",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"state",
|
||||
"tempfile",
|
||||
"time",
|
||||
|
|
@ -1525,6 +1565,12 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
|
|
@ -1718,7 +1764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom 0.3.4",
|
||||
"getrandom 0.4.2",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
|
|
@ -2091,6 +2137,15 @@ dependencies = [
|
|||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasip3"
|
||||
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.114"
|
||||
|
|
@ -2136,6 +2191,40 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
|
||||
dependencies = [
|
||||
"leb128fmt",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-metadata"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"hashbrown 0.15.5",
|
||||
"indexmap",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
|
|
@ -2449,6 +2538,88 @@ name = "wit-bindgen"
|
|||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||
dependencies = [
|
||||
"wit-bindgen-rust-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-core"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"indexmap",
|
||||
"prettyplease",
|
||||
"syn",
|
||||
"wasm-metadata",
|
||||
"wit-bindgen-core",
|
||||
"wit-component",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust-macro"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wit-bindgen-core",
|
||||
"wit-bindgen-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-component"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.11.0",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-encoder",
|
||||
"wasm-metadata",
|
||||
"wasmparser",
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
"indexmap",
|
||||
"log",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"unicode-xid",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
|
|
|
|||
|
|
@ -10,10 +10,12 @@ categories = ["parsing", "text-processing", "value-formatting"]
|
|||
repository = "https://github.com/YGGverse/hlstate-rs"
|
||||
|
||||
[dependencies]
|
||||
chrono = { version = "0.4.41", features = ["serde"] }
|
||||
#observer = { git = "https://github.com/YGGverse/xash3d-master.git", package = "xash3d-observer", branch = "ip6-only" }
|
||||
#protocol = { git = "https://github.com/YGGverse/xash3d-master.git", package = "xash3d-protocol", branch = "ip6-only" }
|
||||
#observer = { path = "../../../xash3d-master/observer", package = "xash3d-observer" }
|
||||
#protocol = { path = "../../../xash3d-master/protocol", package = "xash3d-protocol" }
|
||||
clap = { version = "4.5.54", features = ["derive"] }
|
||||
#mysql = { package = "hlstate-mysql", version = "0.1.0", path = "../mysql" }
|
||||
rocket = "0.5.1"
|
||||
rocket = { version = "0.5.1", features = ["json"] }
|
||||
rocket_dyn_templates = { version = "0.2.0", features = ["tera"] }
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
toml = "0.9.10"
|
||||
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
Web server implementation based on the Rocket engine
|
||||
|
||||
> [!NOTE]
|
||||
> In development!
|
||||
> [!IMPORTANT]
|
||||
> * IPv6-only servers implementation, make sure `xash3d-query` ([IPv6](https://github.com/YGGverse/xash3d-master/tree/ip6-only/query)) is installed!
|
||||
|
||||
```
|
||||
``` bash
|
||||
cd crates/httpd
|
||||
cargo run -- -c config.toml
|
||||
```
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
use serde::Deserialize;
|
||||
use rocket::serde::Deserialize;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
net::{IpAddr, SocketAddr},
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Config {
|
||||
pub debug: bool,
|
||||
pub description: Option<String>,
|
||||
|
|
|
|||
|
|
@ -5,30 +5,58 @@ mod argument;
|
|||
mod config;
|
||||
mod global;
|
||||
mod meta;
|
||||
mod scrape;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use global::Global;
|
||||
use meta::Meta;
|
||||
use rocket::{State, http::Status, serde::Serialize};
|
||||
use rocket::{State, http::Status};
|
||||
use rocket_dyn_templates::{Template, context};
|
||||
|
||||
#[get("/")]
|
||||
fn index(meta: &State<Meta>, global: &State<Global>) -> Result<Template, Status> {
|
||||
#[derive(Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
struct Server {
|
||||
name: String,
|
||||
// @TODO: requires library impl
|
||||
// https://github.com/FWGS/xash3d-master/issues/4
|
||||
let scrape = std::process::Command::new("xash3d-query")
|
||||
.arg("all")
|
||||
.arg("-M")
|
||||
.arg(
|
||||
global
|
||||
.masters
|
||||
.iter()
|
||||
.map(|a| a.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(","),
|
||||
)
|
||||
.arg("-j")
|
||||
.output()
|
||||
.map_err(|e| {
|
||||
error!("Make sure `xash3d-query` is installed: {e}");
|
||||
Status::InternalServerError
|
||||
})?;
|
||||
if scrape.status.success() {
|
||||
let result: scrape::Result = rocket::serde::json::serde_json::from_str(
|
||||
str::from_utf8(&scrape.stdout).map_err(|e| {
|
||||
error!("stdout parse error: {e}");
|
||||
Status::InternalServerError
|
||||
})?,
|
||||
)
|
||||
.map_err(|e| {
|
||||
error!("JSON parse error: {e}");
|
||||
Status::InternalServerError
|
||||
})?;
|
||||
Ok(Template::render(
|
||||
"index",
|
||||
context! {
|
||||
masters: &global.masters,
|
||||
title: &meta.title,
|
||||
version: &meta.version,
|
||||
servers: result.servers,
|
||||
},
|
||||
))
|
||||
} else {
|
||||
error!("Make sure `xash3d-query` is installed!");
|
||||
Err(Status::InternalServerError)
|
||||
}
|
||||
let servers: Vec<Server> = Vec::new();
|
||||
Ok(Template::render(
|
||||
"index",
|
||||
context! {
|
||||
masters: &global.masters,
|
||||
servers: servers,
|
||||
title: &meta.title,
|
||||
version: &meta.version,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[launch]
|
||||
|
|
@ -59,9 +87,3 @@ fn rocket() -> _ {
|
|||
})
|
||||
.mount("/", routes![index])
|
||||
}
|
||||
|
||||
const S: &str = " • ";
|
||||
|
||||
fn time(timestamp: i64) -> DateTime<Utc> {
|
||||
DateTime::<Utc>::from_timestamp(timestamp, 0).unwrap()
|
||||
}
|
||||
|
|
|
|||
33
crates/httpd/src/scrape.rs
Normal file
33
crates/httpd/src/scrape.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use rocket::serde::{Deserialize, Serialize};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Result {
|
||||
pub protocol: Vec<i32>,
|
||||
pub master_timeout: u32,
|
||||
pub server_timeout: u32,
|
||||
pub masters: Vec<SocketAddr>,
|
||||
pub filter: String,
|
||||
pub servers: Vec<Info>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Info {
|
||||
pub time: i64,
|
||||
pub address: SocketAddr,
|
||||
pub ping: f64,
|
||||
pub status: String,
|
||||
pub gamedir: String,
|
||||
pub map: String,
|
||||
pub host: String,
|
||||
pub protocol: i32,
|
||||
pub numcl: u32,
|
||||
pub maxcl: u32,
|
||||
pub dm: bool,
|
||||
pub team: bool,
|
||||
pub coop: bool,
|
||||
pub password: bool,
|
||||
pub dedicated: bool,
|
||||
}
|
||||
|
|
@ -2,11 +2,46 @@
|
|||
{% block content %}
|
||||
<h2>Game</h2>
|
||||
{% if servers %}
|
||||
{% for server in servers %}
|
||||
<div>
|
||||
<h2><a href="{{ server.host }}">{{ server.name }}</a></h2>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Address</th>
|
||||
<th>Host</th>
|
||||
<th>Ping</th>
|
||||
<th>Protocol</th>
|
||||
<th>Gamedir</th>
|
||||
<th>Map</th>
|
||||
<th>Team</th>
|
||||
<th>Coop</th>
|
||||
<th>Password</th>
|
||||
<th>Dedicated</th>
|
||||
<th>DM</th>
|
||||
<th>Max</th>
|
||||
<th>Online</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
<thead>
|
||||
</tbody>
|
||||
{% for server in servers %}
|
||||
<tr>
|
||||
<td>{{ server.address }}</td>
|
||||
<td>{{ server.host }}</td>
|
||||
<td>{{ server.ping }}</td>
|
||||
<td>{{ server.protocol }}</td>
|
||||
<td>{{ server.gamedir }}</td>
|
||||
<td>{{ server.map }}</td>
|
||||
<td>{{ server.team }}</td>
|
||||
<td>{{ server.coop }}</td>
|
||||
<td>{{ server.password }}</td>
|
||||
<td>{{ server.dedicated }}</td>
|
||||
<td>{{ server.dm }}</td>
|
||||
<td>{{ server.maxcl }}</td>
|
||||
<td>{{ server.numcl }}</td>
|
||||
<td>{{ server.status }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div>
|
||||
<p>Nobody.</p>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
padding: 0;
|
||||
font-family: monospace;
|
||||
color-scheme: light dark;
|
||||
--container-max-width: 768px;
|
||||
--container-max-width: 1024px;
|
||||
--color-success: #4bc432;
|
||||
--color-warning: #f37b21;
|
||||
--color-error: #ff6363;
|
||||
|
|
@ -47,15 +47,16 @@
|
|||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid var(--color-default);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table th,
|
||||
table td {
|
||||
border: 1px solid var(--color-default);
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table tr:hover td {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue