2025-03-22 16:47:21 -04:00
use std ::{
net ::{ IpAddr , SocketAddr } ,
str ::FromStr ,
} ;
2023-10-05 12:09:05 -04:00
use serde ::{ Deserialize , Serialize } ;
2025-03-22 16:47:21 -04:00
/// Configuration for the admin server.
2023-10-05 12:09:05 -04:00
#[ derive(Serialize, Deserialize) ]
2025-03-22 16:47:21 -04:00
pub struct AdminConfig {
pub port : u16 ,
pub listen_address : String ,
}
2024-06-29 14:06:44 -04:00
2025-03-22 16:47:21 -04:00
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 ,
2024-06-29 14:06:44 -04:00
pub login_open : bool ,
2025-03-22 16:47:21 -04:00
}
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 ,
) )
}
}
2024-05-11 13:41:00 -04:00
2025-03-22 16:47:21 -04:00
/// 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 ,
2025-03-23 07:35:11 -04:00
/// Publicly accessible URL to download patches from.
/// For example, "patch-dl.ffxiv.localhost". Patch files must be served so they're accessible as: "http://patch-dl.ffxiv.localhost/game/ex4/somepatchfilename.patch"
pub patch_dl_url : String ,
/// Location of the patches directory on disk. Must be setup like so:
/// ```
/// <channel> (e.g. ffxivneo_release_game) /
/// game/
/// ex1/
/// ...
/// ```
pub patches_location : String ,
2025-03-22 16:47:21 -04:00
}
impl Default for PatchConfig {
fn default ( ) -> Self {
Self {
port : 6900 ,
listen_address : " 127.0.0.1 " . to_string ( ) ,
2025-03-23 07:35:11 -04:00
patch_dl_url : " patch-dl.ffxiv.localhost " . to_string ( ) ,
patches_location : String ::new ( ) ,
2025-03-22 16:47:21 -04:00
}
}
}
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 ,
2025-03-22 17:00:21 -04:00
/// See the World Excel sheet.
pub world_id : u16 ,
2025-03-22 16:47:21 -04:00
}
impl Default for WorldConfig {
fn default ( ) -> Self {
Self {
port : 7100 ,
listen_address : " 127.0.0.1 " . to_string ( ) ,
2025-03-22 17:08:33 -04:00
world_id : 63 , // Gilgamesh
2025-03-22 16:47:21 -04:00
}
}
}
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) ]
pub struct Config {
2024-05-11 13:41:00 -04:00
#[ serde(default = " default_supported_platforms " ) ]
pub supported_platforms : Vec < String > ,
2024-06-29 14:44:13 -04:00
2025-03-15 19:34:29 -04:00
#[ serde(default) ]
pub game_location : String ,
2025-03-22 16:47:21 -04:00
#[ 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 ,
2024-05-11 13:13:03 -04:00
}
impl Default for Config {
fn default ( ) -> Self {
Self {
2025-03-08 13:27:41 -05:00
supported_platforms : default_supported_platforms ( ) ,
2025-03-15 19:34:29 -04:00
game_location : String ::new ( ) ,
2025-03-22 16:47:21 -04:00
admin : AdminConfig ::default ( ) ,
frontier : FrontierConfig ::default ( ) ,
lobby : LobbyConfig ::default ( ) ,
login : LoginConfig ::default ( ) ,
patch : PatchConfig ::default ( ) ,
web : WebConfig ::default ( ) ,
world : WorldConfig ::default ( ) ,
2024-05-11 13:13:03 -04:00
}
}
2024-05-11 13:41:00 -04:00
}
impl Config {
pub fn supports_platform ( & self , platform : & String ) -> bool {
self . supported_platforms . contains ( platform )
}
}
fn default_supported_platforms ( ) -> Vec < String > {
vec! [ " win32 " . to_string ( ) ]
}
pub fn get_config ( ) -> Config {
2025-03-22 16:47:21 -04:00
if let Ok ( data ) = std ::fs ::read_to_string ( " config.yaml " ) {
serde_yaml_ng ::from_str ( & data ) . expect ( " Failed to parse " )
2024-05-11 13:41:00 -04:00
} else {
Config ::default ( )
}
2025-03-08 13:27:41 -05:00
}