diff --git a/rc_multiplayer/src/events/kill_player.rs b/rc_multiplayer/src/events/kill_player.rs new file mode 100644 index 0000000..392669f --- /dev/null +++ b/rc_multiplayer/src/events/kill_player.rs @@ -0,0 +1,31 @@ +pub struct KillEnemy { + msg_router: tokio::sync::mpsc::Sender, +} + +pub(super) fn handler(init_ctx: &crate::InitConfig) -> crate::handlers::SimpleRlnl { + crate::handlers::SimpleRlnl::new(KillEnemy::new(init_ctx)) +} + +impl KillEnemy { + fn new(init_ctx: &crate::InitConfig) -> Self { + Self { + msg_router: init_ctx.matches_chann.clone(), + } + } +} + +#[async_trait::async_trait] +impl crate::handlers::RlnlEventCodeHandler for KillEnemy { + type In = rlnl::events::ingame::Kill; + const CODE: rlnl::event_code::NetworkEvent = rlnl::event_code::NetworkEvent::MachineDestroyed; + + async fn handle(&self, data: Self::In, _peer: &std::sync::Arc>, user: &crate::UserData, _sender: &std::sync::Arc>) { + if let Some(user_info) = user.user().await { + super::log_channel_send_failure(self.msg_router.send(crate::matches::GameMessage::DestroyVehicle { + user_id: user_info.user_id(), + remote_player: data.killee_player_id, + killer_player: data.killer_player_id, + }).await); + } + } +} diff --git a/rc_multiplayer/src/events/mod.rs b/rc_multiplayer/src/events/mod.rs index a37cc28..072609f 100644 --- a/rc_multiplayer/src/events/mod.rs +++ b/rc_multiplayer/src/events/mod.rs @@ -5,6 +5,8 @@ mod weapon_select; mod activate_sync; mod loading_done; //mod player_input; +mod spot_player; +mod kill_player; pub async fn handler(init_ctx: &crate::InitConfig) -> crate::handler::LnlEventHandler { crate::handler::LnlEventHandler::new(init_ctx.users.clone(), crate::vehicle_motion::handler(init_ctx)) @@ -42,34 +44,51 @@ pub async fn handler(init_ctx: &crate::InitConfig) -> crate::handler::LnlEventHa {literustlib::packet::Property::Unreliable as u8}, rlnl::events::ingame::FireMiss, >::handler(init_ctx)) - .add(crate::handlers::Broadcaster::< + /*.add(crate::handlers::Broadcaster::< true, {rlnl::event_code::NetworkEvent::EnemySpotted as i16}, {rlnl::event_code::NetworkEvent::EnemySpotted as i16}, {literustlib::packet::Property::ReliableOrdered as u8}, rlnl::events::ingame::SpottingIds, - >::handler(init_ctx)) + >::handler(init_ctx))*/ + .add(spot_player::handler(init_ctx)) .add(crate::handlers::Broadcaster::< - true, + false, {rlnl::event_code::NetworkEvent::DamageCube as i16}, {rlnl::event_code::NetworkEvent::DestroyCubesFull as i16}, {literustlib::packet::Property::ReliableOrdered as u8}, rlnl::events::ingame::DestroyCubesFull, >::handler(init_ctx)) .add(crate::handlers::Broadcaster::< - true, + false, {rlnl::event_code::NetworkEvent::DamageCubeNoEffect as i16}, {rlnl::event_code::NetworkEvent::DestroyCubeNoEffect as i16}, {literustlib::packet::Property::ReliableOrdered as u8}, rlnl::events::ingame::DestroyCubeNoEffect, >::handler(init_ctx)) .add(crate::handlers::Broadcaster::< - true, + false, {rlnl::event_code::NetworkEvent::DamageCubeEffectOnly as i16}, {rlnl::event_code::NetworkEvent::DestroyCubeEffectOnly as i16}, {literustlib::packet::Property::Unreliable as u8}, rlnl::events::ingame::DestroyCubeEffectOnly, >::handler(init_ctx)) + .add(crate::handlers::Stub::< + {rlnl::event_code::NetworkEvent::DestroyCubesBonusRequest as i16}, + rlnl::events::ingame::DestroyedHealedCubesBonus, + >::handler(init_ctx)) + .add(crate::handlers::Broadcaster::< + false, + {rlnl::event_code::NetworkEvent::HealSelf as i16}, + {rlnl::event_code::NetworkEvent::HealSelfResponse as i16}, + {literustlib::packet::Property::ReliableOrdered as u8}, + rlnl::events::HealedCubes, + >::handler(init_ctx)) + .add(crate::handlers::Stub::< + {rlnl::event_code::NetworkEvent::KillBonusRequest as i16}, + rlnl::events::ingame::Kill, // FIXME this is not a player ID -- it's actually sending 2 bytes not 1 + >::handler(init_ctx)) + .add(kill_player::handler(init_ctx)) } #[inline] diff --git a/rc_multiplayer/src/events/spot_player.rs b/rc_multiplayer/src/events/spot_player.rs new file mode 100644 index 0000000..1159e15 --- /dev/null +++ b/rc_multiplayer/src/events/spot_player.rs @@ -0,0 +1,30 @@ +pub struct SpotEnemy { + msg_router: tokio::sync::mpsc::Sender, +} + +pub(super) fn handler(init_ctx: &crate::InitConfig) -> crate::handlers::SimpleRlnl { + crate::handlers::SimpleRlnl::new(SpotEnemy::new(init_ctx)) +} + +impl SpotEnemy { + fn new(init_ctx: &crate::InitConfig) -> Self { + Self { + msg_router: init_ctx.matches_chann.clone(), + } + } +} + +#[async_trait::async_trait] +impl crate::handlers::RlnlEventCodeHandler for SpotEnemy { + type In = rlnl::events::ingame::SpottingIds; + const CODE: rlnl::event_code::NetworkEvent = rlnl::event_code::NetworkEvent::EnemySpotted; + + async fn handle(&self, data: Self::In, _peer: &std::sync::Arc>, user: &crate::UserData, _sender: &std::sync::Arc>) { + if let Some(user_info) = user.user().await { + super::log_channel_send_failure(self.msg_router.send(crate::matches::GameMessage::SpotVehicle { + user_id: user_info.user_id(), + remote_player: data.player_id, + }).await); + } + } +} diff --git a/rc_multiplayer/src/handlers/mod.rs b/rc_multiplayer/src/handlers/mod.rs index 6d8a75e..4cc86da 100644 --- a/rc_multiplayer/src/handlers/mod.rs +++ b/rc_multiplayer/src/handlers/mod.rs @@ -9,3 +9,6 @@ pub use ingame_broadcast::Broadcaster; mod ingame_broadcast_dataless; pub use ingame_broadcast_dataless::DatalessBroadcaster; + +mod stub; +pub use stub::Stub; diff --git a/rc_multiplayer/src/handlers/stub.rs b/rc_multiplayer/src/handlers/stub.rs new file mode 100644 index 0000000..d7b1373 --- /dev/null +++ b/rc_multiplayer/src/handlers/stub.rs @@ -0,0 +1,26 @@ +pub struct Stub + Send + Sync + 'static> { + _in: std::marker::PhantomData, +} + +impl + Send + Sync + 'static> Stub { + pub fn handler(init_ctx: &crate::InitConfig) -> crate::handlers::simple_typed::SimpleRlnl { + crate::handlers::simple_typed::SimpleRlnl::new(Stub::new(init_ctx)) + } + + fn new(_init_ctx: &crate::InitConfig) -> Self { + Self { + _in: std::marker::PhantomData::default(), + } + } +} + +#[async_trait::async_trait] +impl + Send + Sync + 'static> crate::handlers::simple_typed::RlnlEventCodeHandler for Stub { + type In = In; + const CODE: rlnl::event_code::NetworkEvent = crate::handler::i16_to_event_or_panic(CODE_IN); + + async fn handle(&self, _data: Self::In, _peer: &std::sync::Arc>, _user: &crate::UserData, _sender: &std::sync::Arc>) { + log::debug!("Got {:?} event", Self::CODE); + //log::debug!("Got {:?} event: {:?}", Self::CODE, data); + } +} diff --git a/rc_multiplayer/src/matches/generic.rs b/rc_multiplayer/src/matches/generic.rs index cfacc10..8d9c174 100644 --- a/rc_multiplayer/src/matches/generic.rs +++ b/rc_multiplayer/src/matches/generic.rs @@ -335,7 +335,7 @@ impl GenericGamemodeEngine { rlnl::event_code::NetworkEvent::BroadcastWeaponSelect, literustlib::packet::Property::ReliableOrdered, &data, - false + true ).await; } }, @@ -406,6 +406,25 @@ impl GenericGamemodeEngine { self.game_start.store(game_start.timestamp(), std::sync::atomic::Ordering::Relaxed); super::countdown::match_countdown(senders, game_start); } + }, + 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.rebroadcast( + user_id, + rlnl::event_code::NetworkEvent::MachineDestroyedConfirmed, + literustlib::packet::Property::ReliableOrdered, + &rlnl::events::ingame::Kill { killee_player_id: remote_player, killer_player_id: killer_player }, + true, + ).await; + log::warn!("Player {} was destroyed by {} ({}) !!!implement this!!!", remote_player, killer_player, user_id); } super::GameMessage::BroadcastRlnl { user_id: _, event, property, data } => { if let Some(data) = data { @@ -413,7 +432,7 @@ impl GenericGamemodeEngine { } else { self.broadcast_dataless(event, property, true).await; } - } + }, super::GameMessage::RebroadcastRlnl { skip_user_id, event, property, data } => { if let Some(data) = data { self.rebroadcast(skip_user_id, event, property, &*data, true).await; @@ -421,7 +440,7 @@ impl GenericGamemodeEngine { self.rebroadcast_dataless(skip_user_id, event, property, true).await; } - } + }, super::GameMessage::Motion { user_id, data } => { for conn in self.users.read().await.values() { if conn.user.user_id() == user_id { continue; } // fun fact: the game hard crashes if you omit this @@ -432,7 +451,7 @@ impl GenericGamemodeEngine { data: data.clone(), }, literustlib::packet::Property::Unreliable, &conn.connection.connection).await); } - } + }, super::GameMessage::NoOp => {}, } } diff --git a/rc_multiplayer/src/matches/messages.rs b/rc_multiplayer/src/matches/messages.rs index ef416b9..ead1c61 100644 --- a/rc_multiplayer/src/matches/messages.rs +++ b/rc_multiplayer/src/matches/messages.rs @@ -26,6 +26,15 @@ pub enum GameMessage { LoadComplete { user_id: i32, }, + SpotVehicle { + user_id: i32, + remote_player: u8, + }, + DestroyVehicle { + user_id: i32, + remote_player: u8, + killer_player: u8, + }, BroadcastRlnl { user_id: i32, event: rlnl::event_code::NetworkEvent, @@ -56,6 +65,8 @@ impl GameMessage { Self::WeaponSelect { user_id, .. } => *user_id, Self::RequestLoadingSync { user_id, .. } => *user_id, Self::LoadComplete { user_id, .. } => *user_id, + Self::SpotVehicle { user_id, .. } => *user_id, + Self::DestroyVehicle { user_id, .. } => *user_id, Self::BroadcastRlnl { user_id, .. } => *user_id, Self::RebroadcastRlnl { skip_user_id, .. } => *skip_user_id, Self::Motion { user_id, .. } => *user_id,