2023-05-02 13:40:31 +00:00
|
|
|
#![feature(
|
|
|
|
generators,
|
|
|
|
generator_trait,
|
|
|
|
type_alias_impl_trait,
|
|
|
|
impl_trait_in_assoc_type
|
|
|
|
)]
|
2023-03-23 00:37:02 +00:00
|
|
|
|
2023-02-04 01:01:49 +00:00
|
|
|
mod core;
|
2023-01-19 17:18:41 +00:00
|
|
|
mod prelude;
|
2023-02-04 01:01:49 +00:00
|
|
|
mod projections;
|
2023-02-07 15:21:00 +00:00
|
|
|
mod protos;
|
2023-02-04 01:01:49 +00:00
|
|
|
mod util;
|
2023-01-19 17:18:41 +00:00
|
|
|
|
2023-01-19 14:25:52 +00:00
|
|
|
use std::future::Future;
|
|
|
|
|
|
|
|
use figment::providers::Format;
|
|
|
|
use figment::{providers::Toml, Figment};
|
2023-02-09 18:19:03 +00:00
|
|
|
use prometheus::Registry as MetricsRegistry;
|
2023-01-19 14:25:52 +00:00
|
|
|
use serde::Deserialize;
|
|
|
|
|
2023-02-09 18:19:03 +00:00
|
|
|
use crate::core::player::PlayerRegistry;
|
2023-07-07 13:09:24 +00:00
|
|
|
use crate::core::repo::Storage;
|
2023-02-09 18:19:03 +00:00
|
|
|
use crate::core::room::RoomRegistry;
|
|
|
|
use crate::prelude::*;
|
2023-01-19 14:25:52 +00:00
|
|
|
|
|
|
|
#[derive(Deserialize, Debug)]
|
2023-02-09 18:19:03 +00:00
|
|
|
struct ServerConfig {
|
|
|
|
telemetry: util::telemetry::ServerConfig,
|
|
|
|
irc: projections::irc::ServerConfig,
|
2023-02-17 21:27:58 +00:00
|
|
|
xmpp: projections::xmpp::ServerConfig,
|
2023-07-07 13:09:24 +00:00
|
|
|
storage: core::repo::StorageConfig,
|
2023-01-19 14:25:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn load_config() -> Result<ServerConfig> {
|
|
|
|
let raw_config = Figment::new().merge(Toml::file("config.toml"));
|
|
|
|
let config: ServerConfig = raw_config.extract()?;
|
|
|
|
Ok(config)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() -> Result<()> {
|
|
|
|
set_up_logging()?;
|
|
|
|
let sleep = ctrl_c()?;
|
|
|
|
let config = load_config()?;
|
2023-01-27 20:43:20 +00:00
|
|
|
|
2023-02-09 18:19:03 +00:00
|
|
|
tracing::info!("Booting up");
|
|
|
|
tracing::info!("Loaded config: {config:?}");
|
2023-02-10 17:09:29 +00:00
|
|
|
let ServerConfig {
|
|
|
|
telemetry: telemetry_config,
|
|
|
|
irc: irc_config,
|
2023-02-17 21:27:58 +00:00
|
|
|
xmpp: xmpp_config,
|
2023-07-07 13:09:24 +00:00
|
|
|
storage: storage_config,
|
2023-02-10 17:09:29 +00:00
|
|
|
} = config;
|
2023-02-12 22:23:52 +00:00
|
|
|
let mut metrics = MetricsRegistry::new();
|
2023-07-07 13:09:24 +00:00
|
|
|
let storage = Storage::open(storage_config).await?;
|
2023-08-17 13:41:28 +00:00
|
|
|
let rooms = RoomRegistry::new(&mut metrics, storage.clone())?;
|
2023-08-24 12:10:31 +00:00
|
|
|
let mut players = PlayerRegistry::empty(rooms.clone(), &mut metrics)?;
|
2023-02-15 17:10:54 +00:00
|
|
|
let telemetry_terminator =
|
|
|
|
util::telemetry::launch(telemetry_config, metrics.clone(), rooms.clone()).await?;
|
2023-08-16 14:30:02 +00:00
|
|
|
let irc = projections::irc::launch(irc_config, players.clone(), rooms.clone(), metrics.clone(), storage.clone()).await?;
|
2023-08-17 16:35:50 +00:00
|
|
|
let xmpp = projections::xmpp::launch(xmpp_config, players.clone(), rooms.clone(), metrics.clone()).await?;
|
2023-01-19 14:25:52 +00:00
|
|
|
tracing::info!("Started");
|
|
|
|
|
2023-02-09 18:19:03 +00:00
|
|
|
sleep.await;
|
2023-01-19 14:25:52 +00:00
|
|
|
|
|
|
|
tracing::info!("Begin shutdown");
|
2023-02-17 21:27:58 +00:00
|
|
|
xmpp.terminate().await?;
|
2023-02-07 15:21:00 +00:00
|
|
|
irc.terminate().await?;
|
2023-02-09 18:19:03 +00:00
|
|
|
telemetry_terminator.terminate().await?;
|
2023-08-24 12:10:31 +00:00
|
|
|
players.shutdown_all().await?;
|
2023-08-17 16:35:50 +00:00
|
|
|
drop(players);
|
|
|
|
drop(rooms);
|
|
|
|
storage.close().await?;
|
2023-01-19 14:25:52 +00:00
|
|
|
tracing::info!("Shutdown complete");
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-07-30 16:59:33 +00:00
|
|
|
#[cfg(windows)]
|
|
|
|
fn ctrl_c() -> Result<impl Future<Output = ()>> {
|
|
|
|
use tokio::signal::windows::*;
|
|
|
|
let chan = ctrl_c()?;
|
|
|
|
async fn recv(mut chan: CtrlC) {
|
|
|
|
let _ = chan.recv().await;
|
|
|
|
}
|
|
|
|
Ok(recv(chan))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
2023-01-19 14:25:52 +00:00
|
|
|
fn ctrl_c() -> Result<impl Future<Output = ()>> {
|
|
|
|
use tokio::signal::unix::*;
|
|
|
|
let chan = signal(SignalKind::interrupt())?;
|
|
|
|
async fn recv(mut chan: Signal) {
|
|
|
|
let _ = chan.recv().await;
|
|
|
|
}
|
|
|
|
Ok(recv(chan))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_up_logging() -> Result<()> {
|
|
|
|
tracing_subscriber::fmt::init();
|
|
|
|
Ok(())
|
|
|
|
}
|