mirror of
https://github.com/redstrate/Kawari.git
synced 2025-04-22 15:27:44 +00:00
Change configuration format to YAML, allow configuring the address and ports
This removes all of the hardcoded localhost stuff, and allows changing the ports of various services.
This commit is contained in:
parent
f523aa189f
commit
3f27d2b3df
13 changed files with 317 additions and 59 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@
|
||||||
config.json
|
config.json
|
||||||
*.bin
|
*.bin
|
||||||
*.db
|
*.db
|
||||||
|
config.yaml
|
||||||
|
|
36
Cargo.lock
generated
36
Cargo.lock
generated
|
@ -217,6 +217,12 @@ version = "1.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fallible-iterator"
|
name = "fallible-iterator"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -419,6 +425,16 @@ dependencies = [
|
||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
|
@ -438,6 +454,7 @@ dependencies = [
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_yaml_ng",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
@ -742,6 +759,19 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml_ng"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b4db627b98b36d4203a7b458cf3573730f2bb591b28871d916dfa9efabfd41f"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"unsafe-libyaml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
|
@ -924,6 +954,12 @@ version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unsafe-libyaml"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
|
|
@ -44,6 +44,7 @@ axum = { version = "0.6", features = ["json", "tokio", "http1", "form", "query",
|
||||||
# Serialization used in almost every server
|
# Serialization used in almost every server
|
||||||
serde = { version = "1.0", features = ["derive"], default-features = false }
|
serde = { version = "1.0", features = ["derive"], default-features = false }
|
||||||
serde_json = { version = "1.0", default-features = false }
|
serde_json = { version = "1.0", default-features = false }
|
||||||
|
serde_yaml_ng = "0.10"
|
||||||
|
|
||||||
# Async runtime
|
# Async runtime
|
||||||
tokio = { version = "1.37", features = ["macros", "rt", "rt-multi-thread", "io-util"], default-features = false }
|
tokio = { version = "1.37", features = ["macros", "rt", "rt-multi-thread", "io-util"], default-features = false }
|
||||||
|
|
16
USAGE.md
16
USAGE.md
|
@ -15,21 +15,13 @@ Kawari is designed to be easy to run, with the goal of being accessible to anyon
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
Build Kawari with `cargo build`. Afterwards, create a `config.json` in the current directory that looks like this:
|
Build Kawari with `cargo build`. Afterwards, create a `config.yaml` in the current directory. Currently the minimal config you need to run most services looks like this:
|
||||||
|
|
||||||
```json
|
```yaml
|
||||||
{
|
game_location: pathtogamedir
|
||||||
"worlds_open": true,
|
|
||||||
"login_open": true,
|
|
||||||
"supported_platforms": ["win32"],
|
|
||||||
"boot_patches_location": "/path/to/boot/patches",
|
|
||||||
"game_location": "/path/to/game"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
All values in the config are optional, but some may be required for certain services to work correctly.
|
More configuration options can be found in `config.rs`, such as changing the ports services run on. Finally, run Kawari with the helper script:
|
||||||
|
|
||||||
Finally, run Kawari with the helper script:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ ./run.sh
|
$ ./run.sh
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::net::SocketAddr;
|
|
||||||
|
|
||||||
use axum::response::{Html, Redirect};
|
use axum::response::{Html, Redirect};
|
||||||
use axum::routing::post;
|
use axum::routing::post;
|
||||||
use axum::{Router, extract::Form, routing::get};
|
use axum::{Router, extract::Form, routing::get};
|
||||||
|
@ -20,7 +18,7 @@ async fn root() -> Html<String> {
|
||||||
|
|
||||||
let environment = setup_default_environment();
|
let environment = setup_default_environment();
|
||||||
let template = environment.get_template("admin.html").unwrap();
|
let template = environment.get_template("admin.html").unwrap();
|
||||||
Html(template.render(context! { worlds_open => config.worlds_open, login_open => config.login_open, boot_patch_location => config.boot_patches_location }).unwrap())
|
Html(template.render(context! { worlds_open => config.frontier.worlds_open, login_open => config.frontier.login_open, boot_patch_location => config.boot_patches_location }).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
|
@ -37,22 +35,22 @@ async fn apply(Form(input): Form<Input>) -> Redirect {
|
||||||
let mut config = get_config();
|
let mut config = get_config();
|
||||||
|
|
||||||
if let Some(gate_open) = input.worlds_open {
|
if let Some(gate_open) = input.worlds_open {
|
||||||
config.worlds_open = gate_open == "on";
|
config.frontier.worlds_open = gate_open == "on";
|
||||||
} else {
|
} else {
|
||||||
config.worlds_open = false;
|
config.frontier.worlds_open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(gate_open) = input.login_open {
|
if let Some(gate_open) = input.login_open {
|
||||||
config.login_open = gate_open == "on";
|
config.frontier.login_open = gate_open == "on";
|
||||||
} else {
|
} else {
|
||||||
config.login_open = false;
|
config.frontier.login_open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(boot_patch_location) = input.boot_patch_location {
|
if let Some(boot_patch_location) = input.boot_patch_location {
|
||||||
config.boot_patches_location = boot_patch_location;
|
config.boot_patches_location = boot_patch_location;
|
||||||
}
|
}
|
||||||
|
|
||||||
serde_json::to_writer(&std::fs::File::create("config.json").unwrap(), &config)
|
serde_yaml_ng::to_writer(&std::fs::File::create("config.yaml").unwrap(), &config)
|
||||||
.expect("TODO: panic message");
|
.expect("TODO: panic message");
|
||||||
|
|
||||||
Redirect::to("/")
|
Redirect::to("/")
|
||||||
|
@ -66,8 +64,10 @@ async fn main() {
|
||||||
.route("/", get(root))
|
.route("/", get(root))
|
||||||
.route("/apply", post(apply));
|
.route("/apply", post(apply));
|
||||||
|
|
||||||
let addr = SocketAddr::from(([127, 0, 0, 1], 5800));
|
let config = get_config();
|
||||||
tracing::info!("Admin server started on {}", addr);
|
|
||||||
|
let addr = config.admin.get_socketaddr();
|
||||||
|
tracing::info!("Admin server started on {addr}");
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service())
|
.serve(app.into_make_service())
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::net::SocketAddr;
|
|
||||||
|
|
||||||
use axum::{Json, Router, routing::get};
|
use axum::{Json, Router, routing::get};
|
||||||
use kawari::config::get_config;
|
use kawari::config::get_config;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -14,7 +12,7 @@ async fn get_login_status() -> Json<GateStatus> {
|
||||||
|
|
||||||
let config = get_config();
|
let config = get_config();
|
||||||
Json(GateStatus {
|
Json(GateStatus {
|
||||||
status: config.login_open.into(),
|
status: config.frontier.login_open.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +21,7 @@ async fn get_world_status() -> Json<GateStatus> {
|
||||||
|
|
||||||
let config = get_config();
|
let config = get_config();
|
||||||
Json(GateStatus {
|
Json(GateStatus {
|
||||||
status: config.worlds_open.into(),
|
status: config.frontier.worlds_open.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +74,10 @@ async fn main() {
|
||||||
.route("/worldStatus/login_status.json", get(get_login_status))
|
.route("/worldStatus/login_status.json", get(get_login_status))
|
||||||
.route("/news/headline.json", get(get_headline));
|
.route("/news/headline.json", get(get_headline));
|
||||||
|
|
||||||
let addr = SocketAddr::from(([127, 0, 0, 1], 5857));
|
let config = get_config();
|
||||||
tracing::info!("Frontier server started on {}", addr);
|
|
||||||
|
let addr = config.frontier.get_socketaddr();
|
||||||
|
tracing::info!("Frontier server started on {addr}");
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service())
|
.serve(app.into_make_service())
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use kawari::common::custom_ipc::CustomIpcData;
|
use kawari::common::custom_ipc::CustomIpcData;
|
||||||
use kawari::common::custom_ipc::CustomIpcSegment;
|
use kawari::common::custom_ipc::CustomIpcSegment;
|
||||||
use kawari::common::custom_ipc::CustomIpcType;
|
use kawari::common::custom_ipc::CustomIpcType;
|
||||||
|
use kawari::config::get_config;
|
||||||
use kawari::lobby::LobbyConnection;
|
use kawari::lobby::LobbyConnection;
|
||||||
use kawari::lobby::ipc::{
|
use kawari::lobby::ipc::{
|
||||||
CharacterDetails, ClientLobbyIpcData, LobbyCharacterActionKind, ServerLobbyIpcData,
|
CharacterDetails, ClientLobbyIpcData, LobbyCharacterActionKind, ServerLobbyIpcData,
|
||||||
|
@ -18,9 +19,13 @@ use tokio::net::TcpListener;
|
||||||
async fn main() {
|
async fn main() {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let listener = TcpListener::bind("127.0.0.1:7000").await.unwrap();
|
let config = get_config();
|
||||||
|
|
||||||
tracing::info!("Lobby server started on 127.0.0.1:7000");
|
let addr = config.lobby.get_socketaddr();
|
||||||
|
|
||||||
|
let listener = TcpListener::bind(addr).await.unwrap();
|
||||||
|
|
||||||
|
tracing::info!("Lobby server started on {addr}");
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let (socket, _) = listener.accept().await.unwrap();
|
let (socket, _) = listener.accept().await.unwrap();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use std::net::SocketAddr;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use axum::extract::{Query, State};
|
use axum::extract::{Query, State};
|
||||||
use axum::response::{Html, Redirect};
|
use axum::response::{Html, Redirect};
|
||||||
use axum::routing::post;
|
use axum::routing::post;
|
||||||
use axum::{Form, Router, routing::get};
|
use axum::{Form, Router, routing::get};
|
||||||
|
use kawari::config::get_config;
|
||||||
use kawari::login::{LoginDatabase, LoginError};
|
use kawari::login::{LoginDatabase, LoginError};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
@ -128,8 +128,10 @@ async fn main() {
|
||||||
.route("/private/check_session", get(check_session))
|
.route("/private/check_session", get(check_session))
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
||||||
let addr = SocketAddr::from(([127, 0, 0, 1], 6700));
|
let config = get_config();
|
||||||
tracing::info!("Login server started on {}", addr);
|
|
||||||
|
let addr = config.login.get_socketaddr();
|
||||||
|
tracing::info!("Login server started on {addr}");
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service())
|
.serve(app.into_make_service())
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fs::read_dir;
|
use std::fs::read_dir;
|
||||||
use std::net::SocketAddr;
|
|
||||||
|
|
||||||
use axum::extract::Path;
|
use axum::extract::Path;
|
||||||
use axum::http::{HeaderMap, StatusCode};
|
use axum::http::{HeaderMap, StatusCode};
|
||||||
|
@ -132,8 +131,10 @@ async fn main() {
|
||||||
get(verify_boot),
|
get(verify_boot),
|
||||||
); // NOTE: for future programmers, this is a wildcard because axum hates the /version/?time=blah format.
|
); // 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));
|
let config = get_config();
|
||||||
tracing::info!("Patch server started on {}", addr);
|
|
||||||
|
let addr = config.patch.get_socketaddr();
|
||||||
|
tracing::info!("Patch server started on {addr}");
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service())
|
.serve(app.into_make_service())
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::net::SocketAddr;
|
|
||||||
|
|
||||||
use axum::response::Html;
|
use axum::response::Html;
|
||||||
use axum::{Router, routing::get};
|
use axum::{Router, routing::get};
|
||||||
use kawari::config::get_config;
|
use kawari::config::get_config;
|
||||||
|
@ -37,7 +35,7 @@ async fn world_status() -> Html<String> {
|
||||||
let template = environment.get_template("worldstatus.html").unwrap();
|
let template = environment.get_template("worldstatus.html").unwrap();
|
||||||
Html(
|
Html(
|
||||||
template
|
template
|
||||||
.render(context! { login_open => config.login_open, worlds_open => config.worlds_open })
|
.render(context! { login_open => config.frontier.login_open, worlds_open => config.frontier.worlds_open })
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -52,8 +50,10 @@ async fn main() {
|
||||||
.route("/register", get(register))
|
.route("/register", get(register))
|
||||||
.route("/worldstatus", get(world_status));
|
.route("/worldstatus", get(world_status));
|
||||||
|
|
||||||
let addr = SocketAddr::from(([127, 0, 0, 1], 5801));
|
let config = get_config();
|
||||||
tracing::info!("Web server started on {}", addr);
|
|
||||||
|
let addr = config.web.get_socketaddr();
|
||||||
|
tracing::info!("Web server started on {addr}");
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service())
|
.serve(app.into_make_service())
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -29,9 +29,13 @@ use tokio::net::TcpListener;
|
||||||
async fn main() {
|
async fn main() {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let listener = TcpListener::bind("127.0.0.1:7100").await.unwrap();
|
let config = get_config();
|
||||||
|
|
||||||
tracing::info!("World server started on 127.0.0.1:7100");
|
let addr = config.world.get_socketaddr();
|
||||||
|
|
||||||
|
let listener = TcpListener::bind(addr).await.unwrap();
|
||||||
|
|
||||||
|
tracing::info!("World server started on {addr}");
|
||||||
|
|
||||||
let database = Arc::new(WorldDatabase::new());
|
let database = Arc::new(WorldDatabase::new());
|
||||||
|
|
||||||
|
|
233
src/config.rs
233
src/config.rs
|
@ -1,13 +1,200 @@
|
||||||
|
use std::{
|
||||||
|
net::{IpAddr, SocketAddr},
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Configuration for the admin server.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct AdminConfig {
|
||||||
|
pub port: u16,
|
||||||
|
pub listen_address: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AdminConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
port: 5800,
|
||||||
|
listen_address: "127.0.0.1".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AdminConfig {
|
||||||
|
/// Returns the configured IP address & port as a `SocketAddr`.
|
||||||
|
pub fn get_socketaddr(&self) -> SocketAddr {
|
||||||
|
SocketAddr::from((
|
||||||
|
IpAddr::from_str(&self.listen_address).expect("Invalid IP address format in config!"),
|
||||||
|
self.port,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the frontier server.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct FrontierConfig {
|
||||||
|
pub port: u16,
|
||||||
|
pub listen_address: String,
|
||||||
|
pub worlds_open: bool,
|
||||||
|
pub login_open: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FrontierConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
port: 5857,
|
||||||
|
listen_address: "127.0.0.1".to_string(),
|
||||||
|
worlds_open: true,
|
||||||
|
login_open: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FrontierConfig {
|
||||||
|
/// Returns the configured IP address & port as a `SocketAddr`.
|
||||||
|
pub fn get_socketaddr(&self) -> SocketAddr {
|
||||||
|
SocketAddr::from((
|
||||||
|
IpAddr::from_str(&self.listen_address).expect("Invalid IP address format in config!"),
|
||||||
|
self.port,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the lobby server.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct LobbyConfig {
|
||||||
|
pub port: u16,
|
||||||
|
pub listen_address: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LobbyConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
port: 7000,
|
||||||
|
listen_address: "127.0.0.1".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LobbyConfig {
|
||||||
|
/// Returns the configured IP address & port as a `SocketAddr`.
|
||||||
|
pub fn get_socketaddr(&self) -> SocketAddr {
|
||||||
|
SocketAddr::from((
|
||||||
|
IpAddr::from_str(&self.listen_address).expect("Invalid IP address format in config!"),
|
||||||
|
self.port,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the login server.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct LoginConfig {
|
||||||
|
pub port: u16,
|
||||||
|
pub listen_address: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LoginConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
port: 6700,
|
||||||
|
listen_address: "127.0.0.1".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LoginConfig {
|
||||||
|
/// Returns the configured IP address & port as a `SocketAddr`.
|
||||||
|
pub fn get_socketaddr(&self) -> SocketAddr {
|
||||||
|
SocketAddr::from((
|
||||||
|
IpAddr::from_str(&self.listen_address).expect("Invalid IP address format in config!"),
|
||||||
|
self.port,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the patch server.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct PatchConfig {
|
||||||
|
pub port: u16,
|
||||||
|
pub listen_address: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PatchConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
port: 6900,
|
||||||
|
listen_address: "127.0.0.1".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PatchConfig {
|
||||||
|
/// Returns the configured IP address & port as a `SocketAddr`.
|
||||||
|
pub fn get_socketaddr(&self) -> SocketAddr {
|
||||||
|
SocketAddr::from((
|
||||||
|
IpAddr::from_str(&self.listen_address).expect("Invalid IP address format in config!"),
|
||||||
|
self.port,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the web server.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct WebConfig {
|
||||||
|
pub port: u16,
|
||||||
|
pub listen_address: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WebConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
port: 5801,
|
||||||
|
listen_address: "127.0.0.1".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebConfig {
|
||||||
|
/// Returns the configured IP address & port as a `SocketAddr`.
|
||||||
|
pub fn get_socketaddr(&self) -> SocketAddr {
|
||||||
|
SocketAddr::from((
|
||||||
|
IpAddr::from_str(&self.listen_address).expect("Invalid IP address format in config!"),
|
||||||
|
self.port,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the world server.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct WorldConfig {
|
||||||
|
pub port: u16,
|
||||||
|
pub listen_address: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WorldConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
port: 7100,
|
||||||
|
listen_address: "127.0.0.1".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WorldConfig {
|
||||||
|
/// Returns the configured IP address & port as a `SocketAddr`.
|
||||||
|
pub fn get_socketaddr(&self) -> SocketAddr {
|
||||||
|
SocketAddr::from((
|
||||||
|
IpAddr::from_str(&self.listen_address).expect("Invalid IP address format in config!"),
|
||||||
|
self.port,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Global and all-encompassing config.
|
||||||
|
/// Settings that affect all servers belong here.
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[serde(default)]
|
|
||||||
pub worlds_open: bool,
|
|
||||||
|
|
||||||
#[serde(default)]
|
|
||||||
pub login_open: bool,
|
|
||||||
|
|
||||||
#[serde(default = "default_supported_platforms")]
|
#[serde(default = "default_supported_platforms")]
|
||||||
pub supported_platforms: Vec<String>,
|
pub supported_platforms: Vec<String>,
|
||||||
|
|
||||||
|
@ -16,16 +203,42 @@ pub struct Config {
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub game_location: String,
|
pub game_location: String,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub admin: AdminConfig,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub frontier: FrontierConfig,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub lobby: LobbyConfig,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub login: LoginConfig,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub patch: PatchConfig,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub web: WebConfig,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub world: WorldConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
worlds_open: false,
|
|
||||||
login_open: false,
|
|
||||||
boot_patches_location: String::new(),
|
boot_patches_location: String::new(),
|
||||||
supported_platforms: default_supported_platforms(),
|
supported_platforms: default_supported_platforms(),
|
||||||
game_location: String::new(),
|
game_location: String::new(),
|
||||||
|
admin: AdminConfig::default(),
|
||||||
|
frontier: FrontierConfig::default(),
|
||||||
|
lobby: LobbyConfig::default(),
|
||||||
|
login: LoginConfig::default(),
|
||||||
|
patch: PatchConfig::default(),
|
||||||
|
web: WebConfig::default(),
|
||||||
|
world: WorldConfig::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,8 +254,8 @@ fn default_supported_platforms() -> Vec<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_config() -> Config {
|
pub fn get_config() -> Config {
|
||||||
if let Ok(data) = std::fs::read_to_string("config.json") {
|
if let Ok(data) = std::fs::read_to_string("config.yaml") {
|
||||||
serde_json::from_str(&data).expect("Failed to parse")
|
serde_yaml_ng::from_str(&data).expect("Failed to parse")
|
||||||
} else {
|
} else {
|
||||||
Config::default()
|
Config::default()
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
custom_ipc::{CustomIpcData, CustomIpcSegment, CustomIpcType},
|
custom_ipc::{CustomIpcData, CustomIpcSegment, CustomIpcType},
|
||||||
timestamp_secs,
|
timestamp_secs,
|
||||||
},
|
},
|
||||||
|
config::get_config,
|
||||||
oodle::OodleNetwork,
|
oodle::OodleNetwork,
|
||||||
packet::{
|
packet::{
|
||||||
CompressionType, ConnectionType, PacketSegment, PacketState, SegmentType,
|
CompressionType, ConnectionType, PacketSegment, PacketState, SegmentType,
|
||||||
|
@ -278,17 +279,15 @@ impl LobbyConnection {
|
||||||
|
|
||||||
/// Send the host information for the world server to the client.
|
/// Send the host information for the world server to the client.
|
||||||
pub async fn send_enter_world(&mut self, sequence: u64, content_id: u64, actor_id: u32) {
|
pub async fn send_enter_world(&mut self, sequence: u64, content_id: u64, actor_id: u32) {
|
||||||
let Some(session_id) = &self.session_id else {
|
let config = get_config();
|
||||||
panic!("Missing session id!");
|
|
||||||
};
|
|
||||||
|
|
||||||
let enter_world = ServerLobbyIpcData::LobbyEnterWorld {
|
let enter_world = ServerLobbyIpcData::LobbyEnterWorld {
|
||||||
sequence,
|
sequence,
|
||||||
actor_id,
|
actor_id,
|
||||||
content_id,
|
content_id,
|
||||||
token: String::new(),
|
token: String::new(),
|
||||||
port: 7100,
|
port: config.world.port,
|
||||||
host: "127.0.0.1".to_string(),
|
host: config.world.listen_address,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ipc = ServerLobbyIpcSegment {
|
let ipc = ServerLobbyIpcSegment {
|
||||||
|
@ -339,7 +338,11 @@ impl LobbyConnection {
|
||||||
/// Sends a custom IPC packet to the world server, meant for private server-to-server communication.
|
/// Sends a custom IPC packet to the world server, meant for private server-to-server communication.
|
||||||
/// Returns the first custom IPC segment returned.
|
/// Returns the first custom IPC segment returned.
|
||||||
pub async fn send_custom_world_packet(segment: CustomIpcSegment) -> Option<CustomIpcSegment> {
|
pub async fn send_custom_world_packet(segment: CustomIpcSegment) -> Option<CustomIpcSegment> {
|
||||||
let mut stream = TcpStream::connect("127.0.0.1:7100").await.unwrap();
|
let config = get_config();
|
||||||
|
|
||||||
|
let addr = config.world.get_socketaddr();
|
||||||
|
|
||||||
|
let mut stream = TcpStream::connect(addr).await.unwrap();
|
||||||
|
|
||||||
let mut packet_state = PacketState {
|
let mut packet_state = PacketState {
|
||||||
client_key: None,
|
client_key: None,
|
||||||
|
|
Loading…
Add table
Reference in a new issue