diff --git a/src/grpc/account.rs b/src/grpc/account.rs index a8c1024..83fcde0 100644 --- a/src/grpc/account.rs +++ b/src/grpc/account.rs @@ -9,7 +9,7 @@ use tonic::codegen::InterceptedService; use tonic::transport::Channel; use crate::grpc::InterceptorFunc; use crate::grpc::protobufs::account::account_client::AccountClient; -use crate::grpc::protobufs::account::GetNexPasswordRequest; +use crate::grpc::protobufs::account::{GetNexPasswordRequest, GetUserDataRequest, GetUserDataResponse}; static API_KEY: Lazy> = Lazy::new(||{ let key = env::var("ACCOUNT_GRPC_API_KEY") @@ -74,6 +74,16 @@ impl Client{ Ok(response.password.as_bytes().try_into()?) } + + pub async fn get_user_data(&mut self , pid: u32) -> Result{ + let req = Request::new(GetUserDataRequest{ + pid + }); + + let response = self.0.get_user_data(req).await?.into_inner(); + + Ok(response) + } } #[cfg(test)] diff --git a/src/main.rs b/src/main.rs index 96d4ab9..e3d3448 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use simplelog::{ColorChoice, CombinedLogger, Config, LevelFilter, TerminalMode, use tokio::sync::Mutex; use tokio::task::JoinHandle; use crate::nex::account::Account; -use crate::protocols::auth; +use crate::protocols::{auth, block_if_maintenance}; use crate::protocols::auth::AuthProtocolConfig; use crate::protocols::matchmake_common::MatchmakeData; use crate::protocols::server::RMCProtocolServer; @@ -58,15 +58,22 @@ static SECURE_SERVER_PORT: Lazy = Lazy::new(||{ .unwrap_or(10001) }); -static OWN_IP: Lazy = Lazy::new(||{ +static OWN_IP_PRIVATE: Lazy = Lazy::new(||{ env::var("SERVER_IP") .ok() .and_then(|s| s.parse().ok()) .expect("no public ip specified") }); +static OWN_IP_PUBLIC: Lazy = Lazy::new(||{ + env::var("SERVER_IP_PUBLIC") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(*OWN_IP_PRIVATE) +}); + static SECURE_STATION_URL: Lazy = Lazy::new(|| - format!("prudps:/PID=2;sid=1;stream=10;type=2;address={};port={};CID=1", *OWN_IP, *SECURE_SERVER_PORT) + format!("prudps:/PID=2;sid=1;stream=10;type=2;address={};port={};CID=1", *OWN_IP_PUBLIC, *SECURE_SERVER_PORT) ); #[tokio::main] @@ -93,10 +100,10 @@ struct AuthServer{ } async fn start_auth_server() -> AuthServer{ - info!("starting auth server on {}:{}", *OWN_IP, *AUTH_SERVER_PORT); + info!("starting auth server on {}:{}", *OWN_IP_PRIVATE, *AUTH_SERVER_PORT); let (router, join_handle) = - Router::new(SocketAddrV4::new(*OWN_IP, *AUTH_SERVER_PORT)).await + Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT)).await .expect("unable to startauth server"); info!("setting up endpoints"); @@ -162,10 +169,10 @@ struct SecureServer{ } async fn start_secure_server() -> SecureServer{ - info!("starting secure server on {}:{}", *OWN_IP, *SECURE_SERVER_PORT); + info!("starting secure server on {}:{}", *OWN_IP_PRIVATE, *SECURE_SERVER_PORT); let (router, join_handle) = - Router::new(SocketAddrV4::new(*OWN_IP, *SECURE_SERVER_PORT)).await + Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT)).await .expect("unable to startauth server"); info!("setting up endpoints"); @@ -175,6 +182,7 @@ async fn start_secure_server() -> SecureServer{ )); let rmcserver = RMCProtocolServer::new(Box::new([ + Box::new(block_if_maintenance), Box::new(protocols::secure::bound_protocol()), Box::new(protocols::matchmake_extension::bound_protocol(matchmake_data)) ])); diff --git a/src/protocols/mod.rs b/src/protocols/mod.rs index 48ca1a6..82dcb66 100644 --- a/src/protocols/mod.rs +++ b/src/protocols/mod.rs @@ -1,4 +1,13 @@ +use std::env; +use std::future::Future; +use std::pin::Pin; +use log::warn; +use once_cell::sync::Lazy; +use crate::grpc; use crate::prudp::socket::ConnectionData; +use crate::rmc::message::RMCMessage; +use crate::rmc::response::{ErrorCode, RMCResponse}; + pub mod auth; pub mod server; @@ -6,6 +15,43 @@ pub mod secure; pub mod matchmake_extension; pub mod matchmake_common; + +static IS_MAINTENANCE: Lazy = Lazy::new(|| { + env::var("IS_MAINTENANCE") + .ok() + .map(|v| v.parse().expect("IS_MAINTENANCE should be a boolean value")) + .unwrap_or(false) +}); + + +pub fn block_if_maintenance<'a>(rmcmessage: &'a RMCMessage, conn: &'a mut ConnectionData) -> Pin> + Send + 'a)>> { + Box::pin(async move { + if let Some(active_conn) = conn.active_connection_data.as_ref() { + if let Some(secure_conn) = active_conn.active_secure_connection_data.as_ref() { + if let Ok(mut client) = grpc::account::Client::new().await { + if let Ok(client_data) = client.get_user_data(secure_conn.pid).await{ + if client_data.access_level >= 2{ + return None; + } + } + } + } + } + + + warn!("login attempted whilest servers are in maintenance"); + + if *IS_MAINTENANCE { + Some(RMCResponse { + protocol_id: rmcmessage.protocol_id as u8, + response_result: rmcmessage.error_result_with_code(ErrorCode::RendezVous_GameServerMaintenance), + }) + } else { + None + } + }) +} + #[macro_export] macro_rules! define_protocol { ($id:literal ($($varname:ident : $ty:ty),*) => {$($func_id:literal => $func:path),*} ) => {