mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Refactor multiplayer message handling into smaller functions
This commit is contained in:
@@ -323,13 +323,95 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
if let Some(msg) = recv.recv().await {
|
if let Some(msg) = recv.recv().await {
|
||||||
match msg {
|
match msg {
|
||||||
super::GameMessage::NewConnection { user, game_guid, connection, response, sender } => {
|
super::GameMessage::NewConnection { user, game_guid, connection, response, sender } => {
|
||||||
|
self.on_new_connection(user, game_guid, connection, response, sender).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::EndConnection { user_id } => {
|
||||||
|
is_engaged = self.on_end_connection(user_id).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::RequestLeave { user_id } => {
|
||||||
|
self.on_request_leave(user_id).await;
|
||||||
|
}
|
||||||
|
super::GameMessage::LoadingProgress { user_id, user_name, progress } => {
|
||||||
|
self.on_loading_progress(user_id, user_name, progress).await;
|
||||||
|
}
|
||||||
|
super::GameMessage::RequestLoadingProgress { user_id } => {
|
||||||
|
self.on_request_loading_progress(user_id).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::WeaponSelect { user_id, machine_id, category, size } => {
|
||||||
|
self.on_weapon_select(user_id, machine_id, category, size).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::RequestLoadingSync { user_id } => {
|
||||||
|
self.on_request_loading_sync(user_id).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::LoadComplete { user_id } => {
|
||||||
|
self.on_load_complete(user_id).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::SpotVehicle { user_id, remote_player } => {
|
||||||
|
self.rebroadcast(
|
||||||
|
user_id,
|
||||||
|
rlnl::event_code::NetworkEvent::RemoteEnemySpotted,
|
||||||
|
literustlib::packet::Property::ReliableOrdered,
|
||||||
|
&rlnl::events::ingame::PlayerId { player: remote_player },
|
||||||
|
true
|
||||||
|
).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::DestroyVehicle { user_id, remote_player, killer_player } => {
|
||||||
|
self.on_destroy_vehicle(user_id, remote_player, killer_player).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::SelfDestruct { user_id, is_classic } => {
|
||||||
|
self.on_self_destruct(user_id, is_classic).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::FlippingStarted { user_id } => {
|
||||||
|
self.on_flipping_started(user_id).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::MapPing { user_id, ping } => {
|
||||||
|
self.on_map_ping(user_id, ping).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::KillBonus { user_id, shootee, shooter } => {
|
||||||
|
self.on_kill_bonus(user_id, shootee, shooter).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::AssistBonus { user_id, shootee, shooters } => {
|
||||||
|
self.on_assist_bonus(user_id, shootee, shooters).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::DestroyCubesBonus { user_id, info } => {
|
||||||
|
self.on_destroy_cubes_bonus(user_id, info).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::HealCubesBonus { user_id, info } => {
|
||||||
|
self.on_heal_cubes_bonus(user_id, info).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::BroadcastRlnl { user_id, event, event_in, property, data } => {
|
||||||
|
self.on_broadcast(user_id, event, event_in, property, data, false).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::RebroadcastRlnl { skip_user_id, event, event_in, property, data } => {
|
||||||
|
self.on_broadcast(skip_user_id, event, event_in, property, data, true).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::CustomLogicRlnl { user_id, event, property, data } => {
|
||||||
|
self.custom_logic_handler.on_custom(&self, user_id, event, property, data).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::Motion { user_id, motion } => {
|
||||||
|
self.on_motion(user_id, motion).await;
|
||||||
|
},
|
||||||
|
super::GameMessage::NoOp => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.fakes_handler.stop();
|
||||||
|
log::info!("Game {} has exited", self.game_guid());
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_new_connection(&self,
|
||||||
|
user: std::sync::Arc<Box<dyn oj_rc_core::persist::user::MultiplayerUser + Send + Sync + 'static>>,
|
||||||
|
game_guid: String,
|
||||||
|
connection: std::sync::Arc<literustlib_server::Connection<crate::PacketData>>,
|
||||||
|
response: tokio::sync::oneshot::Sender<Option<super::messages::ErrorMessage>>,
|
||||||
|
sender: std::sync::Arc<literustlib_server::DataSender<crate::PacketData>>
|
||||||
|
) {
|
||||||
if self.game_guid() != game_guid {
|
if self.game_guid() != game_guid {
|
||||||
log::error!("Game guid does not match (got: {}, expected: {})", game_guid, self.game_guid());
|
log::error!("Game guid does not match (got: {}, expected: {})", game_guid, self.game_guid());
|
||||||
response.send(Some(super::messages::ErrorMessage {
|
response.send(Some(super::messages::ErrorMessage {
|
||||||
message: format!("Game guid does not match (got: {}, expected: {})", game_guid, self.game_guid()),
|
message: format!("Game guid does not match (got: {}, expected: {})", game_guid, self.game_guid()),
|
||||||
inner: None,
|
inner: None,
|
||||||
})).unwrap_or_default();
|
})).unwrap_or_default();
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
let mut users = self.users.write().await;
|
let mut users = self.users.write().await;
|
||||||
//tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
//tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||||
@@ -348,7 +430,7 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
descriptor: player_info.to_owned(),
|
descriptor: player_info.to_owned(),
|
||||||
counters: UserData::new(),
|
counters: UserData::new(),
|
||||||
};
|
};
|
||||||
if self.custom_logic_handler.on_player_join(&self, &new_user, &self.players_info).await {
|
if self.custom_logic_handler.on_player_join(self, &new_user, &self.players_info).await {
|
||||||
//self.spawn_send_loading_events(&new_user, id, self.players_info.clone());
|
//self.spawn_send_loading_events(&new_user, id, self.players_info.clone());
|
||||||
crate::events::log_lnl_send_failure(new_user.connection.rlnl().send_data(
|
crate::events::log_lnl_send_failure(new_user.connection.rlnl().send_data(
|
||||||
&rlnl::events::ingame::PlayerId { player: id },
|
&rlnl::events::ingame::PlayerId { player: id },
|
||||||
@@ -362,12 +444,13 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
}
|
}
|
||||||
response.send(None).unwrap_or_default();
|
response.send(None).unwrap_or_default();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::EndConnection { user_id } => {
|
|
||||||
|
async fn on_end_connection(&self, user_id: i32) -> bool {
|
||||||
if let Some(player_id) = self.user_key_by_user_id(user_id).await {
|
if let Some(player_id) = self.user_key_by_user_id(user_id).await {
|
||||||
let conn_opt = self.users.write().await.remove(&player_id);
|
let conn_opt = self.users.write().await.remove(&player_id);
|
||||||
if let Some(conn) = conn_opt {
|
if let Some(conn) = conn_opt {
|
||||||
if self.custom_logic_handler.on_player_end(&self, &conn).await {
|
if self.custom_logic_handler.on_player_end(self, &conn).await {
|
||||||
conn.state.mode.store(ConnectionMode::Disconnected.to_u8(), std::sync::atomic::Ordering::Relaxed);
|
conn.state.mode.store(ConnectionMode::Disconnected.to_u8(), std::sync::atomic::Ordering::Relaxed);
|
||||||
if !self.is_complete.load(std::sync::atomic::Ordering::Relaxed) {
|
if !self.is_complete.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
self.rebroadcast(
|
self.rebroadcast(
|
||||||
@@ -392,22 +475,24 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
let mode = ConnectionMode::from_u8(user.state.mode.load(std::sync::atomic::Ordering::Relaxed));
|
let mode = ConnectionMode::from_u8(user.state.mode.load(std::sync::atomic::Ordering::Relaxed));
|
||||||
has_active_connections |= !matches!(mode, ConnectionMode::Disconnected);
|
has_active_connections |= !matches!(mode, ConnectionMode::Disconnected);
|
||||||
}
|
}
|
||||||
is_engaged = has_active_connections;
|
//is_engaged = has_active_connections;
|
||||||
if !has_active_connections {
|
if !has_active_connections {
|
||||||
self.is_complete.store(true, std::sync::atomic::Ordering::Relaxed);
|
self.is_complete.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
if self.custom_logic_handler.on_game_completed(&self).await {
|
if self.custom_logic_handler.on_game_completed(self).await {
|
||||||
if let Err(e) = conn.user.complete_game(self.game_guid()).await {
|
if let Err(e) = conn.user.complete_game(self.game_guid()).await {
|
||||||
log::error!("Failed to mark game {} as complete: {}", self.game_guid(), e);
|
log::error!("Failed to mark game {} as complete: {}", self.game_guid(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn.connection.connection.goodbye(&conn.connection.sender).await;
|
conn.connection.connection.goodbye(&conn.connection.sender).await;
|
||||||
|
return has_active_connections;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
async fn on_request_leave(&self, user_id: i32) {
|
||||||
},
|
|
||||||
super::GameMessage::RequestLeave { user_id } => {
|
|
||||||
log::info!("User {} wants to leave game {}", user_id, self.game_guid());
|
log::info!("User {} wants to leave game {}", user_id, self.game_guid());
|
||||||
if let Some(player_id) = self.user_key_by_user_id(user_id).await {
|
if let Some(player_id) = self.user_key_by_user_id(user_id).await {
|
||||||
self.rebroadcast(
|
self.rebroadcast(
|
||||||
@@ -429,7 +514,8 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::GameMessage::LoadingProgress { user_id, user_name, progress } => {
|
|
||||||
|
async fn on_loading_progress(&self, user_id: i32, user_name: String, progress: f32) {
|
||||||
let progress_data = rlnl::events::loading::LoadingProgress {
|
let progress_data = rlnl::events::loading::LoadingProgress {
|
||||||
user_name: rlnl::types::BinaryWriterString(user_name),
|
user_name: rlnl::types::BinaryWriterString(user_name),
|
||||||
progress,
|
progress,
|
||||||
@@ -458,7 +544,8 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super::GameMessage::RequestLoadingProgress { user_id } => {
|
|
||||||
|
async fn on_request_loading_progress(&self, user_id: i32) {
|
||||||
log::info!("Got request loading progress");
|
log::info!("Got request loading progress");
|
||||||
if let Some(user_key) = self.user_key_by_user_id(user_id).await {
|
if let Some(user_key) = self.user_key_by_user_id(user_id).await {
|
||||||
if let Some(user_info) = self.users.read().await.get(&user_key) {
|
if let Some(user_info) = self.users.read().await.get(&user_key) {
|
||||||
@@ -501,9 +588,14 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
} else {
|
} else {
|
||||||
log::error!("Failed to find user {} in connected users for match {}", user_id, self.game_guid());
|
log::error!("Failed to find user {} in connected users for match {}", user_id, self.game_guid());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
async fn on_weapon_select(&self,
|
||||||
super::GameMessage::WeaponSelect { user_id, machine_id, category, size } => {
|
user_id: i32,
|
||||||
|
machine_id: u8,
|
||||||
|
category: oj_rc_core::data::weapon_list::ItemCategory,
|
||||||
|
size: oj_rc_core::data::cube_list::ItemTier
|
||||||
|
) {
|
||||||
if let Some(conn) = self.users.read().await.get(&machine_id) {
|
if let Some(conn) = self.users.read().await.get(&machine_id) {
|
||||||
let category_u32 = category as u32;
|
let category_u32 = category as u32;
|
||||||
let size_u32 = size as u32;
|
let size_u32 = size as u32;
|
||||||
@@ -522,8 +614,9 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
true
|
true
|
||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::RequestLoadingSync { user_id } => {
|
|
||||||
|
async fn on_request_loading_sync(&self, user_id: i32) {
|
||||||
// wait for all users to be ready before transitioning to loading sync
|
// wait for all users to be ready before transitioning to loading sync
|
||||||
let mut ready_count = 0;
|
let mut ready_count = 0;
|
||||||
for user in self.users.read().await.values() {
|
for user in self.users.read().await.values() {
|
||||||
@@ -543,12 +636,13 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
if ready_count == player_count {
|
if ready_count == player_count {
|
||||||
log::info!("All players ({}) awaiting sync for game {}", player_count, self.game_guid());
|
log::info!("All players ({}) awaiting sync for game {}", player_count, self.game_guid());
|
||||||
for (user_key, conn) in self.users.read().await.iter() {
|
for (user_key, conn) in self.users.read().await.iter() {
|
||||||
let extra_packets = self.custom_logic_handler.extra_sync_events(&self, conn).await;
|
let extra_packets = self.custom_logic_handler.extra_sync_events(self, conn).await;
|
||||||
self.spawn_send_sync_events(conn, conn.user.user_id(), *user_key, self.players_info.clone(), extra_packets, self.map_config.clone());
|
self.spawn_send_sync_events(conn, conn.user.user_id(), *user_key, self.players_info.clone(), extra_packets, self.map_config.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::LoadComplete { user_id } => {
|
|
||||||
|
async fn on_load_complete(&self, user_id: i32) {
|
||||||
if let Some(user_key) = self.user_key_by_user_id(user_id).await {
|
if let Some(user_key) = self.user_key_by_user_id(user_id).await {
|
||||||
if let Some(conn) = self.users.read().await.get(&user_key) {
|
if let Some(conn) = self.users.read().await.get(&user_key) {
|
||||||
log::info!("Loading complete for game {}, user {} (player {})", self.game_guid(), user_id, user_key);
|
log::info!("Loading complete for game {}, user {} (player {})", self.game_guid(), user_id, user_key);
|
||||||
@@ -561,11 +655,11 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
self.spawn_initial_ingame_events(conn, user_id);
|
self.spawn_initial_ingame_events(conn, user_id);
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Invalid LoadComplete user key {} for game {}", user_key, self.game_guid());
|
log::warn!("Invalid LoadComplete user key {} for game {}", user_key, self.game_guid());
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Unknown LoadComplete user id {} for game {}", user_id, self.game_guid());
|
log::warn!("Unknown LoadComplete user id {} for game {}", user_id, self.game_guid());
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
// wait for all users to be ready for starting game start countdown
|
// wait for all users to be ready for starting game start countdown
|
||||||
let mut all_users_loading_complete = true;
|
let mut all_users_loading_complete = true;
|
||||||
@@ -584,7 +678,7 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
.collect()
|
.collect()
|
||||||
);
|
);
|
||||||
let game_start = chrono::Utc::now() + Self::COUNTDOWN_DURATION;
|
let game_start = chrono::Utc::now() + Self::COUNTDOWN_DURATION;
|
||||||
if self.custom_logic_handler.on_countdown_start(&self, game_start).await {
|
if self.custom_logic_handler.on_countdown_start(self, game_start).await {
|
||||||
let mut senders = Vec::new();
|
let mut senders = Vec::new();
|
||||||
for conn in self.users.read().await.values() {
|
for conn in self.users.read().await.values() {
|
||||||
senders.push((conn.connection.clone(), conn.state.clone()));
|
senders.push((conn.connection.clone(), conn.state.clone()));
|
||||||
@@ -593,17 +687,13 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
super::countdown::match_countdown(senders, game_start);
|
super::countdown::match_countdown(senders, game_start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::SpotVehicle { user_id, remote_player } => {
|
|
||||||
self.rebroadcast(
|
async fn on_destroy_vehicle(&self,
|
||||||
user_id,
|
user_id: i32,
|
||||||
rlnl::event_code::NetworkEvent::RemoteEnemySpotted,
|
remote_player: u8,
|
||||||
literustlib::packet::Property::ReliableOrdered,
|
killer_player: u8,
|
||||||
&rlnl::events::ingame::PlayerId { player: remote_player },
|
) {
|
||||||
true
|
|
||||||
).await;
|
|
||||||
},
|
|
||||||
super::GameMessage::DestroyVehicle { user_id, remote_player, killer_player } => {
|
|
||||||
// FIXME allow custom_logic_handler to override the MachineDestroyedConfirmed send
|
// FIXME allow custom_logic_handler to override the MachineDestroyedConfirmed send
|
||||||
self.rebroadcast(
|
self.rebroadcast(
|
||||||
user_id,
|
user_id,
|
||||||
@@ -613,7 +703,7 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
true,
|
true,
|
||||||
).await;
|
).await;
|
||||||
log::info!("Player {} was destroyed by player {} (user {}) in game {}", remote_player, killer_player, user_id, self.game_guid());
|
log::info!("Player {} was destroyed by player {} (user {}) in game {}", remote_player, killer_player, user_id, self.game_guid());
|
||||||
if self.custom_logic_handler.on_vehicle_destroyed(&self, killer_player, remote_player).await {
|
if self.custom_logic_handler.on_vehicle_destroyed(self, killer_player, remote_player).await {
|
||||||
// the kill tracking is initiated separately by the client with kill bonus event
|
// the kill tracking is initiated separately by the client with kill bonus event
|
||||||
if let Some(killed) = self.users.read().await.get(&remote_player) {
|
if let Some(killed) = self.users.read().await.get(&remote_player) {
|
||||||
killed.counters.deaths.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
killed.counters.deaths.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
@@ -626,8 +716,9 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::SelfDestruct { user_id, is_classic } => {
|
|
||||||
|
async fn on_self_destruct(&self, user_id: i32, is_classic: bool) {
|
||||||
if let Some(player_id) = self.user_key_by_user_id(user_id).await {
|
if let Some(player_id) = self.user_key_by_user_id(user_id).await {
|
||||||
self.rebroadcast(
|
self.rebroadcast(
|
||||||
user_id,
|
user_id,
|
||||||
@@ -637,7 +728,7 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
true,
|
true,
|
||||||
).await;
|
).await;
|
||||||
log::info!("Player {} ({}) self-destructed in game {} (elimination? {})", player_id, user_id, self.game_guid(), is_classic);
|
log::info!("Player {} ({}) self-destructed in game {} (elimination? {})", player_id, user_id, self.game_guid(), is_classic);
|
||||||
if self.custom_logic_handler.on_vehicle_self_destruct(&self, player_id, is_classic).await {
|
if self.custom_logic_handler.on_vehicle_self_destruct(self, player_id, is_classic).await {
|
||||||
if is_classic {
|
if is_classic {
|
||||||
self.rebroadcast(
|
self.rebroadcast(
|
||||||
user_id,
|
user_id,
|
||||||
@@ -658,9 +749,9 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
async fn on_flipping_started(&self, user_id: i32) {
|
||||||
super::GameMessage::FlippingStarted { user_id } => {
|
|
||||||
if let Some(user_key) = self.user_key_by_user_id(user_id).await {
|
if let Some(user_key) = self.user_key_by_user_id(user_id).await {
|
||||||
self.rebroadcast(
|
self.rebroadcast(
|
||||||
user_id,
|
user_id,
|
||||||
@@ -670,8 +761,9 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
true,
|
true,
|
||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::MapPing { user_id: _, ping } => {
|
|
||||||
|
async fn on_map_ping(&self, _user_id: i32, ping: rlnl::events::ingame::MapPing) {
|
||||||
for (id, conn) in self.users.read().await.iter() {
|
for (id, conn) in self.users.read().await.iter() {
|
||||||
if (*id as i32) != ping.sender && conn.descriptor.team == ping.team_id {
|
if (*id as i32) != ping.sender && conn.descriptor.team == ping.team_id {
|
||||||
crate::events::log_lnl_send_failure(conn.connection.rlnl().send_data(
|
crate::events::log_lnl_send_failure(conn.connection.rlnl().send_data(
|
||||||
@@ -682,8 +774,13 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
).await);
|
).await);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::KillBonus { user_id: _, shootee, shooter } => {
|
|
||||||
|
async fn on_kill_bonus(&self,
|
||||||
|
_user_id: i32,
|
||||||
|
shootee: u8,
|
||||||
|
shooter: u8,
|
||||||
|
) {
|
||||||
if let Some(to_reward) = self.users.read().await.get(&shooter) {
|
if let Some(to_reward) = self.users.read().await.get(&shooter) {
|
||||||
to_reward.counters.kills.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
to_reward.counters.kills.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||||
crate::events::log_lnl_send_failure(to_reward.connection.rlnl().send_data(
|
crate::events::log_lnl_send_failure(to_reward.connection.rlnl().send_data(
|
||||||
@@ -703,8 +800,13 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
true,
|
true,
|
||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::AssistBonus { user_id: _, shootee, shooters } => {
|
|
||||||
|
async fn on_assist_bonus(&self,
|
||||||
|
_user_id: i32,
|
||||||
|
shootee: u8,
|
||||||
|
shooters: Vec<u8>,
|
||||||
|
) {
|
||||||
let lock = self.users.read().await;
|
let lock = self.users.read().await;
|
||||||
for shooter in shooters {
|
for shooter in shooters {
|
||||||
if let Some(to_reward) = lock.get(&shooter) {
|
if let Some(to_reward) = lock.get(&shooter) {
|
||||||
@@ -727,8 +829,12 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::DestroyCubesBonus { user_id: _, info } => {
|
|
||||||
|
async fn on_destroy_cubes_bonus(&self,
|
||||||
|
_user_id: i32,
|
||||||
|
info: rlnl::events::ingame::DestroyedHealedCubesBonus
|
||||||
|
) {
|
||||||
let lock = self.users.read().await;
|
let lock = self.users.read().await;
|
||||||
for shooter in info.shooters {
|
for shooter in info.shooters {
|
||||||
if let Some(to_reward) = lock.get(&shooter.shooting_player_id) {
|
if let Some(to_reward) = lock.get(&shooter.shooting_player_id) {
|
||||||
@@ -754,8 +860,12 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::HealCubesBonus { user_id: _, info } => {
|
|
||||||
|
async fn on_heal_cubes_bonus(&self,
|
||||||
|
_user_id: i32,
|
||||||
|
info: rlnl::events::ingame::DestroyedHealedCubesBonus,
|
||||||
|
) {
|
||||||
let lock = self.users.read().await;
|
let lock = self.users.read().await;
|
||||||
for shooter in info.shooters {
|
for shooter in info.shooters {
|
||||||
if let Some(to_reward) = lock.get(&shooter.shooting_player_id) {
|
if let Some(to_reward) = lock.get(&shooter.shooting_player_id) {
|
||||||
@@ -781,29 +891,35 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
).await;
|
).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
super::GameMessage::BroadcastRlnl { user_id, event, event_in, property, data } => {
|
|
||||||
if self.custom_logic_handler.on_broadcast(&self, user_id, event, event_in, property, &data, false).await {
|
async fn on_broadcast(&self,
|
||||||
|
user_id: i32,
|
||||||
|
event: rlnl::event_code::NetworkEvent,
|
||||||
|
event_in: rlnl::event_code::NetworkEvent,
|
||||||
|
property: literustlib::packet::Property,
|
||||||
|
data: Option<Box<dyn crate::Broadcastable>>,
|
||||||
|
skip_user: bool,
|
||||||
|
) {
|
||||||
|
if self.custom_logic_handler.on_broadcast(self, user_id, event, event_in, property, &data, skip_user).await {
|
||||||
|
#[allow(clippy::collapsible_else_if)]
|
||||||
if let Some(data) = data {
|
if let Some(data) = data {
|
||||||
|
if skip_user {
|
||||||
|
self.rebroadcast(user_id, event, property, &*data, true).await;
|
||||||
|
} else {
|
||||||
self.broadcast(event, property, &*data, true).await;
|
self.broadcast(event, property, &*data, true).await;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if skip_user {
|
||||||
|
self.rebroadcast_dataless(user_id, event, property, true).await;
|
||||||
} else {
|
} else {
|
||||||
self.broadcast_dataless(event, property, true).await;
|
self.broadcast_dataless(event, property, true).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
super::GameMessage::RebroadcastRlnl { skip_user_id, event, event_in, property, data } => {
|
|
||||||
if self.custom_logic_handler.on_broadcast(&self, skip_user_id, event, event_in, property, &data, true).await {
|
|
||||||
if let Some(data) = data {
|
|
||||||
self.rebroadcast(skip_user_id, event, property, &*data, true).await;
|
|
||||||
} else {
|
|
||||||
self.rebroadcast_dataless(skip_user_id, event, property, true).await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
super::GameMessage::CustomLogicRlnl { user_id, event, property, data } => {
|
async fn on_motion(&self, user_id: i32, motion: rlnl::machine_motion::MachineMotion) {
|
||||||
self.custom_logic_handler.on_custom(&self, user_id, event, property, data).await;
|
|
||||||
},
|
|
||||||
super::GameMessage::Motion { user_id, motion } => {
|
|
||||||
//let (looking_at_x, looking_at_y, looking_at_z) = motion.target_point.clone().into();
|
//let (looking_at_x, looking_at_y, looking_at_z) = motion.target_point.clone().into();
|
||||||
//log::info!("Player {} looking at ({}, {}, {})", motion.player_id, looking_at_x, looking_at_y, looking_at_z);
|
//log::info!("Player {} looking at ({}, {}, {})", motion.player_id, looking_at_x, looking_at_y, looking_at_z);
|
||||||
let (x, y, z) = motion.rb_state.rb_pos_rot.pos.into();
|
let (x, y, z) = motion.rb_state.rb_pos_rot.pos.into();
|
||||||
@@ -814,7 +930,7 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
let coords = unit_quat.rotate_vector([x2, y2, z2]);
|
let coords = unit_quat.rotate_vector([x2, y2, z2]);
|
||||||
let (x4, y4, z4) = (x + coords[0], y + coords[1], z + coords[2]);
|
let (x4, y4, z4) = (x + coords[0], y + coords[1], z + coords[2]);
|
||||||
//log::debug!("Player {} world CoM is at (x, y, z) ({}, {}, {})", motion.player_id, x4, y4, z4);
|
//log::debug!("Player {} world CoM is at (x, y, z) ({}, {}, {})", motion.player_id, x4, y4, z4);
|
||||||
if self.custom_logic_handler.on_motion(&self, &motion, (x4, y4, z4)).await {
|
if self.custom_logic_handler.on_motion(self, &motion, (x4, y4, z4)).await {
|
||||||
if let Some(conn) = self.users.read().await.get(&motion.player_id) {
|
if let Some(conn) = self.users.read().await.get(&motion.player_id) {
|
||||||
conn.machine.location.x.store(x4, std::sync::atomic::Ordering::Relaxed);
|
conn.machine.location.x.store(x4, std::sync::atomic::Ordering::Relaxed);
|
||||||
conn.machine.location.y.store(y4, std::sync::atomic::Ordering::Relaxed);
|
conn.machine.location.y.store(y4, std::sync::atomic::Ordering::Relaxed);
|
||||||
@@ -840,13 +956,6 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
super::GameMessage::NoOp => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.fakes_handler.stop();
|
|
||||||
log::info!("Game {} has exited", self.game_guid());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_send_loading_events(&self, user: &UserConnection, player_id: u8, players: std::sync::Arc<Vec<oj_rc_core::persist::user::PlayerDescriptor>>) {
|
fn spawn_send_loading_events(&self, user: &UserConnection, player_id: u8, players: std::sync::Arc<Vec<oj_rc_core::persist::user::PlayerDescriptor>>) {
|
||||||
|
|||||||
@@ -29,4 +29,5 @@ pub fn handler() -> OperationsHandler<crate::UserTy, crate::data::custom::Custom
|
|||||||
.add(platoon_data::platoon_provider())
|
.add(platoon_data::platoon_provider())
|
||||||
.add(polariton_server::operations::Ack::<6, _>::default()) // AvatarUpdatedRequest, sent on services_room avatar_set success (just needs to be ack-ed; no params)
|
.add(polariton_server::operations::Ack::<6, _>::default()) // AvatarUpdatedRequest, sent on services_room avatar_set success (just needs to be ack-ed; no params)
|
||||||
.add(calculate_mmr::mmr_provider())
|
.add(calculate_mmr::mmr_provider())
|
||||||
|
.add(polariton_server::operations::Ack::<25, _>::default()) // save social settings, sent on escape menu settings save (should probably be saved someday...)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user