1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00

Add game event refresh freezing when user enters lobby; fix #84

This commit is contained in:
NG (Graham)
2026-08-21 21:04:37 -04:00
parent 1f0aa22f68
commit b717ca1ed3
14 changed files with 347 additions and 86 deletions

View File

@@ -651,20 +651,20 @@ impl GameConfig {
fn as_core(&self) -> oj_rc_core::persist::user::intercom::IntercomLobbyCustomGameConfig {
oj_rc_core::persist::user::intercom::IntercomLobbyCustomGameConfig {
game_mode: match self.game_mode {
oj_rc_core::data::game_mode::GameMode::BattleArena => oj_rc_core::persist::user::intercom::CustomGameMode::BattleArena,
oj_rc_core::data::game_mode::GameMode::TeamDeathmatch => oj_rc_core::persist::user::intercom::CustomGameMode::TeamDeathmatch,
oj_rc_core::data::game_mode::GameMode::Pit => oj_rc_core::persist::user::intercom::CustomGameMode::Pit,
oj_rc_core::data::game_mode::GameMode::SuddenDeath => oj_rc_core::persist::user::intercom::CustomGameMode::SuddenDeath,
oj_rc_core::data::game_mode::GameMode::BattleArena => oj_rc_core::persist::user::intercom::IntercomGameMode::BattleArena,
oj_rc_core::data::game_mode::GameMode::TeamDeathmatch => oj_rc_core::persist::user::intercom::IntercomGameMode::TeamDeathmatch,
oj_rc_core::data::game_mode::GameMode::Pit => oj_rc_core::persist::user::intercom::IntercomGameMode::Pit,
oj_rc_core::data::game_mode::GameMode::SuddenDeath => oj_rc_core::persist::user::intercom::IntercomGameMode::SuddenDeath,
invalid => {
log::warn!("Custom game set to invalid mode {:?} (using sudden death as fallback)", invalid);
oj_rc_core::persist::user::intercom::CustomGameMode::SuddenDeath
oj_rc_core::persist::user::intercom::IntercomGameMode::SuddenDeath
},
},
map: self.map.clone(),
map_visibility: match self.map_visibility {
oj_rc_core::data::game_mode::MapVisibility::Good => oj_rc_core::persist::user::intercom::CustomGameVisibility::Good,
oj_rc_core::data::game_mode::MapVisibility::Poor => oj_rc_core::persist::user::intercom::CustomGameVisibility::Poor,
oj_rc_core::data::game_mode::MapVisibility::Bad => oj_rc_core::persist::user::intercom::CustomGameVisibility::Bad,
oj_rc_core::data::game_mode::MapVisibility::Good => oj_rc_core::persist::user::intercom::IntercomGameVisibility::Good,
oj_rc_core::data::game_mode::MapVisibility::Poor => oj_rc_core::persist::user::intercom::IntercomGameVisibility::Poor,
oj_rc_core::data::game_mode::MapVisibility::Bad => oj_rc_core::persist::user::intercom::IntercomGameVisibility::Bad,
},
health_regen: self.health_regen,
capture_segment_memory: self.capture_segment_memory,

View File

@@ -1,11 +1,12 @@
use oj_rc_core::persist::user::IntercomListener;
use oj_rc_core::persist::user::intercom::{IntercomWebServiceUserMessage, IntercomWorkaroundMessage};
use oj_rc_core::persist::user::intercom::{IntercomWebServiceUserMessage, IntercomWebServiceWorkaroundMessage};
pub struct IntercomHandler {
listener: IntercomListener<IntercomWebServiceUserMessage>,
user: std::sync::Weak<Box<dyn oj_rc_core::persist::user::User<()> + Send + Sync>>,
emitter: polariton_server::events::WeakEventEmitter<()>,
keybind_workaround: std::sync::Arc<crate::workarounds::EditModeInputLockupWorkaround>,
game_event_seq: std::sync::Arc<tokio::sync::Mutex<oj_rc_core::persist::config::GameEventSequence>>,
}
impl IntercomHandler {
@@ -14,12 +15,14 @@ impl IntercomHandler {
user: &std::sync::Arc<Box<dyn oj_rc_core::persist::user::User<()> + Send + Sync>>,
emitter: &polariton_server::events::EventEmitter<()>,
keybind_workaround: &std::sync::Arc<crate::workarounds::EditModeInputLockupWorkaround>,
game_event_seq: &std::sync::Arc<tokio::sync::Mutex<oj_rc_core::persist::config::GameEventSequence>>,
) -> Self {
Self {
listener,
user: std::sync::Arc::downgrade(user),
emitter: emitter.to_owned().downgrade(),
keybind_workaround: keybind_workaround.to_owned(),
game_event_seq: game_event_seq.to_owned(),
}
}
@@ -28,6 +31,7 @@ impl IntercomHandler {
user: std::sync::Weak<Box<dyn oj_rc_core::persist::user::User<()> + Send + Sync>>,
emitter: polariton_server::events::WeakEventEmitter<()>,
keybind_workaround: std::sync::Arc<crate::workarounds::EditModeInputLockupWorkaround>,
game_event_seq: std::sync::Arc<tokio::sync::Mutex<oj_rc_core::persist::config::GameEventSequence>>,
) {
use futures::StreamExt;
let mut listener = listener.listen().await;
@@ -54,7 +58,7 @@ impl IntercomHandler {
};
emitter.emit(event);
}
IntercomWebServiceUserMessage::Workaround(IntercomWorkaroundMessage::KeybindLockout { }) => {
IntercomWebServiceUserMessage::Workaround(IntercomWebServiceWorkaroundMessage::KeybindLockout { }) => {
let session = keybind_workaround.add_user(user.account_id(), user.public_id().to_owned()).await;
let non_me = session.users.first().unwrap();
let event = super::CustomGameInvite {
@@ -65,6 +69,22 @@ impl IntercomHandler {
invited_to_team_a: true,
};
emitter.emit(event);
},
IntercomWebServiceUserMessage::Workaround(IntercomWebServiceWorkaroundMessage::GameModeEventLock { event }) => {
let is_replaced = game_event_seq.lock().await.add_lockout(
user.account_id(),
oj_rc_core::persist::config::GameEvent {
map: event.map.into_conf(),
visibility: event.visibility.into_conf(),
mode: event.mode.into_conf(),
auto_heal: event.auto_heal,
},
);
log::info!("Activated game event lockout for user {} (replaced? {})", user.public_id(), is_replaced);
},
IntercomWebServiceUserMessage::Workaround(IntercomWebServiceWorkaroundMessage::GameModeEventUnlock { }) => {
let is_existed = game_event_seq.lock().await.remove_lockout(user.account_id());
log::info!("Deactivated game event lockout for user {} (existed? {})", user.public_id(), is_existed);
}
}
} else {
@@ -80,6 +100,6 @@ impl IntercomHandler {
}
pub fn run(self) -> tokio::task::JoinHandle<()> {
tokio::spawn(Self::run_loop(self.listener, self.user, self.emitter, self.keybind_workaround))
tokio::spawn(Self::run_loop(self.listener, self.user, self.emitter, self.keybind_workaround, self.game_event_seq))
}
}

View File

@@ -31,6 +31,7 @@ pub struct InitConfig {
pub custom_games: std::sync::Arc<custom_game_tracker::CustomGameMesh>,
pub user_mesh: std::sync::Arc<user_service::UserMesh>,
pub workarounds: workarounds::Workarounds,
pub game_event_sequence: std::sync::Arc<tokio::sync::Mutex<oj_rc_core::persist::config::GameEventSequence>>,
}
#[tokio::main]
@@ -49,6 +50,7 @@ async fn main() -> std::io::Result<()> {
&parsers,
vehicle_validator_plugins_path,
);
let game_event_sequence = std::sync::Arc::new(tokio::sync::Mutex::new(<oj_rc_core::ConfigImpl as oj_rc_core::ConfigProvider<()>>::gamemode_events(&cubes)));
let init_ctx = std::sync::Arc::new(InitConfig {
cubes,
users,
@@ -58,6 +60,7 @@ async fn main() -> std::io::Result<()> {
custom_games: std::sync::Arc::new(custom_game_tracker::CustomGameMesh::new()),
user_mesh: std::sync::Arc::new(user_service::UserMesh::new()),
workarounds: workarounds::Workarounds::new(),
game_event_sequence,
});
let server = std::sync::Arc::new(polariton_server::Server::new(operations::handler(&init_ctx), polariton_server::events::EventsHandler::new()));

View File

@@ -21,7 +21,7 @@ RC_Planet_Neptune_01_CTF
*/
pub struct GameEventsParamsProvider {
sequence: std::sync::Mutex<oj_rc_core::persist::config::GameEventSequence>,
sequence: std::sync::Arc<tokio::sync::Mutex<oj_rc_core::persist::config::GameEventSequence>>,
}
#[async_trait::async_trait]
@@ -32,7 +32,7 @@ impl Operation<()> for GameEventsParamsProvider {
match user.user() {
Ok(user_info) => {
let mut params = params.to_dict();
let current_mode = self.sequence.lock().unwrap().now(user_info.current_game_event_setter());
let current_mode = self.sequence.lock().await.now(user_info.current_game_event_setter(), user_info.account_id());
params.insert(MAP_NAMES_PARAM_KEY, current_mode.maps);
params.insert(VISIBILITY_PARAM_KEY, current_mode.visibilities);
params.insert(MODE_PARAM_KEY, current_mode.modes);
@@ -64,9 +64,8 @@ impl OperationCode for GameEventsParamsProvider {
}
}
pub(super) fn event_system_params_provider(conf: &oj_rc_core::ConfigImpl) -> GameEventsParamsProvider {
let game_seq = <oj_rc_core::ConfigImpl as oj_rc_core::ConfigProvider<()>>::gamemode_events(conf);
pub(super) fn event_system_params_provider(init_ctx: &crate::InitConfig) -> GameEventsParamsProvider {
GameEventsParamsProvider {
sequence: std::sync::Mutex::new(game_seq),
sequence: init_ctx.game_event_sequence.clone(),
}
}

View File

@@ -124,7 +124,7 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy>
OperationsHandler::new()
.modify(<oj_rc_core::ConfigImpl as oj_rc_core::ConfigProvider<()>>::polariton_operation_modifier(&init_ctx.cubes))
.add(eac::EacChallengeIgnorer)
.add(more_auth::more_auth_provider(&init_ctx.user_mesh, init_ctx.workarounds.edit_mode_input_lockup()))
.add(more_auth::more_auth_provider(&init_ctx.user_mesh, init_ctx.workarounds.edit_mode_input_lockup(), &init_ctx.game_event_sequence))
.add(versioner::version_teller(&init_ctx.cubes))
.add(maintenancer::maintenace_teller(&init_ctx.cubes))
.add(game_quality::QualityConfigTeller)
@@ -166,7 +166,7 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy>
.add(custom_game_session::custom_session_provider(&init_ctx.custom_games, init_ctx.workarounds.edit_mode_input_lockup()))
.add(user_xp::get_user_xp_provider())
.add(garage_upgrades::garage_upgrades_provider(&init_ctx.cubes))
.add(game_event_params::event_system_params_provider(&init_ctx.cubes))
.add(game_event_params::event_system_params_provider(init_ctx))
.add(garage_bay_uuid::garage_id_provider())
.add(tech_tree_data::tech_tree_layout_provider(&init_ctx.cubes))
.add(item_shop_bundles::item_bundle_provider(&init_ctx.cubes))

View File

@@ -4,12 +4,14 @@ use polariton_server::operations::{Operation, OperationCode};
pub struct MoreLobbyAuth {
mesh: std::sync::Arc<crate::user_service::UserMesh>,
keybind_workaround: std::sync::Arc<crate::workarounds::EditModeInputLockupWorkaround>,
game_event_seq: std::sync::Arc<tokio::sync::Mutex<oj_rc_core::persist::config::GameEventSequence>>,
}
pub fn more_auth_provider(mesh: &std::sync::Arc<crate::user_service::UserMesh>, keybind_workaround: std::sync::Arc<crate::workarounds::EditModeInputLockupWorkaround>) -> MoreLobbyAuth {
pub fn more_auth_provider(mesh: &std::sync::Arc<crate::user_service::UserMesh>, keybind_workaround: std::sync::Arc<crate::workarounds::EditModeInputLockupWorkaround>, game_event_seq: &std::sync::Arc<tokio::sync::Mutex<oj_rc_core::persist::config::GameEventSequence>>,) -> MoreLobbyAuth {
MoreLobbyAuth {
mesh: mesh.to_owned(),
keybind_workaround,
game_event_seq: game_event_seq.to_owned(),
}
}
@@ -50,6 +52,7 @@ impl <C: Send + 'static> Operation<C> for MoreLobbyAuth {
&user_info,
user.event_sender(),
&self.keybind_workaround,
&self.game_event_seq,
).run();
return polariton::operation::OperationResponse {
code: Self::op_code(),