mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Handle game event change situation in lobby queue
This commit is contained in:
@@ -389,7 +389,7 @@ fn default_rotation() -> GameEventSequence {
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Mars1,
|
||||
map: GameMap::Earth1,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
@@ -449,7 +449,7 @@ fn default_rotation() -> GameEventSequence {
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Mars1,
|
||||
map: GameMap::Earth2,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
|
||||
@@ -262,6 +262,7 @@ impl <C: Clone + Send> super::ConfigProvider<C> for CubeConfig {
|
||||
super::ServerConfig {
|
||||
database: self.settings.server.database.clone(),
|
||||
auto_signup: self.settings.server.auto_signup,
|
||||
queue_mode: super::QueueChangeMode::from_persist(self.settings.server.queue_mode.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ mod cubes_json;
|
||||
pub use cubes_json::CubeConfig;
|
||||
|
||||
mod traits;
|
||||
pub use traits::{ConfigProvider, CompleteCampaignProvider, DevMessageProvider, ServerConfig, GarageUpgrades, GarageUpgradeIncrement, ChatSystemConfig, GameEventSequence, GameEvents, GameRotationStrategy, GameEvent, GameMap, GameVisibility, GameType, SingleplayerConfig, VehicleInfo, VehicleDescriptor};
|
||||
pub use traits::{ConfigProvider, CompleteCampaignProvider, DevMessageProvider, ServerConfig, GarageUpgrades, GarageUpgradeIncrement, ChatSystemConfig, GameEventSequence, GameEvents, GameRotationStrategy, GameEvent, GameMap, GameVisibility, GameType, SingleplayerConfig, VehicleInfo, VehicleDescriptor, QueueChangeMode};
|
||||
|
||||
pub type ConfigImpl = CubeConfig;
|
||||
|
||||
|
||||
@@ -104,6 +104,23 @@ pub struct TypedDevMessage<C> {
|
||||
pub struct ServerConfig {
|
||||
pub database: String,
|
||||
pub auto_signup: bool,
|
||||
pub queue_mode: QueueChangeMode,
|
||||
}
|
||||
|
||||
pub enum QueueChangeMode {
|
||||
Upgrade, // move enqueued players into newer gamemode
|
||||
Notify, // send match change
|
||||
Ignore, // do nothing
|
||||
}
|
||||
|
||||
impl QueueChangeMode {
|
||||
pub(super) fn from_persist(persist: crate::persist::settings::QueueMode) -> Self {
|
||||
match persist {
|
||||
crate::persist::settings::QueueMode::Upgrade => Self::Upgrade,
|
||||
crate::persist::settings::QueueMode::Notify => Self::Notify,
|
||||
crate::persist::settings::QueueMode::Ignore => Self::Ignore,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
||||
@@ -27,7 +27,7 @@ mod client_config;
|
||||
pub use client_config::GameplaySettings;
|
||||
|
||||
mod settings;
|
||||
pub use settings::Settings;
|
||||
pub use settings::{Settings, QueueMode};
|
||||
|
||||
mod chat;
|
||||
pub use chat::{ChatConfig, ChatCommand, ChatOperation, BuiltInChatOperation};
|
||||
|
||||
@@ -74,6 +74,16 @@ pub struct ServerSettings {
|
||||
pub database: String,
|
||||
#[serde(default)]
|
||||
pub auto_signup: bool,
|
||||
#[serde(default)]
|
||||
pub queue_mode: QueueMode,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||
pub enum QueueMode {
|
||||
Upgrade, // move enqueued players into newer gamemode
|
||||
#[default]
|
||||
Notify, // send match change
|
||||
Ignore, // do nothing
|
||||
}
|
||||
|
||||
fn default_db_conn() -> String {
|
||||
@@ -84,5 +94,6 @@ fn default_server_conf() -> ServerSettings {
|
||||
ServerSettings {
|
||||
database: default_db_conn(),
|
||||
auto_signup: false,
|
||||
queue_mode: QueueMode::Notify,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
use std::{collections::HashMap, hash::Hash};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum GamemodeChangeStrategy {
|
||||
Upgrade, // move enqueued players into newer gamemode
|
||||
Notify, // send match change
|
||||
Ignore, // do nothing
|
||||
}
|
||||
|
||||
impl GamemodeChangeStrategy {
|
||||
fn from_core(core: oj_rc_core::persist::config::QueueChangeMode) -> Self {
|
||||
match core {
|
||||
oj_rc_core::persist::config::QueueChangeMode::Upgrade => Self::Upgrade,
|
||||
oj_rc_core::persist::config::QueueChangeMode::Notify => Self::Notify,
|
||||
oj_rc_core::persist::config::QueueChangeMode::Ignore => Self::Ignore,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Hash, Eq, PartialEq, Clone)]
|
||||
struct QueueKey {
|
||||
map: String,
|
||||
@@ -22,10 +39,11 @@ pub struct QueueHandler {
|
||||
hostport: u16,
|
||||
network_conf: crate::data::network::NetworkConfigData,
|
||||
cpu_counter: std::sync::Arc<oj_rc_core::cubes::CpuListParser>,
|
||||
change_strategy: GamemodeChangeStrategy,
|
||||
}
|
||||
|
||||
impl QueueHandler {
|
||||
pub fn new(conf: &oj_rc_core::ConfigImpl, game_host: &str, cpu_counter: std::sync::Arc<oj_rc_core::cubes::CpuListParser>,) -> Self {
|
||||
pub fn new(conf: &oj_rc_core::ConfigImpl, game_host: &str, cpu_counter: std::sync::Arc<oj_rc_core::cubes::CpuListParser>) -> Self {
|
||||
let (domain, port_str) = game_host.split_once(':').expect("Invalid redirect address (must be domain:port)");
|
||||
Self {
|
||||
users_in_queue: tokio::sync::Mutex::new(HashMap::new()),
|
||||
@@ -35,6 +53,7 @@ impl QueueHandler {
|
||||
hostport: port_str.parse().expect("Invalid redirect port"),
|
||||
network_conf: crate::data::network::NetworkConfigData::from_conf(oj_rc_core::ConfigProvider::<()>::network_config(conf)),
|
||||
cpu_counter,
|
||||
change_strategy: GamemodeChangeStrategy::from_core(<oj_rc_core::ConfigImpl as oj_rc_core::ConfigProvider<()>>::server_config(conf).queue_mode),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +61,7 @@ impl QueueHandler {
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = std::hash::DefaultHasher::new();
|
||||
key.hash(&mut hasher);
|
||||
chrono::Utc::now().timestamp().hash(&mut hasher);
|
||||
chrono::Utc::now().timestamp_micros().hash(&mut hasher);
|
||||
let guid = oj_rc_core::persist::user::uuid_sanitize(hasher.finish() as i64);
|
||||
let guid_str = oj_rc_core::persist::user::i64_as_uuid_str(guid);
|
||||
let player_descs = players.iter().map(|x| oj_rc_core::persist::user::PlayerLobbyDescriptor {
|
||||
@@ -120,6 +139,47 @@ impl QueueHandler {
|
||||
user_id: user.user_id(),
|
||||
};
|
||||
let mut lock = self.users_in_queue.lock().await;
|
||||
// handle game event change
|
||||
if !lock.contains_key(&key) && lock.len() == 1 {
|
||||
log::debug!("Game event change detected");
|
||||
match self.change_strategy {
|
||||
GamemodeChangeStrategy::Upgrade => {
|
||||
let mut new_queue_map = std::collections::HashMap::<QueueKey, Vec<QueueUser>>::with_capacity(lock.len());
|
||||
let mut count = 0;
|
||||
for (_key, mut users) in lock.drain() {
|
||||
count += users.len();
|
||||
if let Some(values) = new_queue_map.get_mut(&key) {
|
||||
values.append(&mut users);
|
||||
} else {
|
||||
new_queue_map.insert(key.clone(), users);
|
||||
}
|
||||
|
||||
}
|
||||
*lock = new_queue_map;
|
||||
if count != 0 {
|
||||
log::info!("Upgraded {} users in queue to new gamemode", count);
|
||||
}
|
||||
},
|
||||
GamemodeChangeStrategy::Notify => {
|
||||
let mut count = 0;
|
||||
for (_key, users) in lock.drain() {
|
||||
count += users.len();
|
||||
for player in users {
|
||||
player.emitter.emit(crate::events::enqueue_error::QueueJoinError {
|
||||
code: oj_rc_core::data::error_codes::LobbyReasonCode::EventSystemExpired as i16,
|
||||
text: "Please requeue".to_owned(),
|
||||
});
|
||||
}
|
||||
}
|
||||
if count != 0 {
|
||||
log::info!("Notified {} users in queue of new gamemode", count);
|
||||
}
|
||||
},
|
||||
GamemodeChangeStrategy::Ignore => {
|
||||
log::debug!("Gamemode appears to have changed, ignoring already-queued players");
|
||||
}
|
||||
}
|
||||
}
|
||||
let players_len = if let Some(players) = lock.get_mut(&key) {
|
||||
new_player.player.team = (players.len() % 2) as _; // alternate teams
|
||||
players.push(new_player);
|
||||
|
||||
@@ -78,7 +78,7 @@ async fn process_socket(mut socket: net::TcpStream, address: std::net::SocketAdd
|
||||
if let Ok(user_info) = user_state.user() {
|
||||
queue.leave_queue(user_info.as_ref().as_ref()).await;
|
||||
} else {
|
||||
log::info!("Unauthenticated user disconnected");
|
||||
log::debug!("Unauthenticated user disconnected");
|
||||
}
|
||||
log::debug!("Goodbye connection from address {}", address);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user