aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src/packet_handling
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2024-11-27 19:31:40 -0600
committerGitHub <noreply@github.com>2024-11-27 19:31:40 -0600
commit08958c2278b15ebeac8a964f392ebb792e479b61 (patch)
tree4ae3664cea38d7fd1a8f1e95ed06fac04ffe519e /azalea-client/src/packet_handling
parent139d77d3c2b0922fba5e9d4fa2bd9819d78bd773 (diff)
downloadazalea-drasl-08958c2278b15ebeac8a964f392ebb792e479b61.tar.xz
Refactor azalea-protocol (#190)
* start updating to 1.21.4 * fix block codegen and stop using block data from burger * rename packet related modules and structs to be simpler * ItemSlot -> ItemStack for more consistency with mojmap * .get() -> .into_packet() * simplify declare_state_packets by removing packet ids * rename read_from and write_into to azalea_read and azalea_write * rename McBufReadable and McBufWritable to AzaleaRead and AzaleaWrite * McBuf -> AzBuf * remove most uses of into_variant * update codegen and use resourcelocation names for packets * implement #[limit(i)] attribute for AzBuf derive macro * fixes for 1.21.4 * fix examples * update some physics code and fix ChatType * remove unused imports in codegen * re-add some things to migrate.py and update +mc version numbers automatically * downgrade to 1.21.3 lol
Diffstat (limited to 'azalea-client/src/packet_handling')
-rw-r--r--azalea-client/src/packet_handling/configuration.rs145
-rw-r--r--azalea-client/src/packet_handling/game.rs87
-rw-r--r--azalea-client/src/packet_handling/login.rs26
-rw-r--r--azalea-client/src/packet_handling/mod.rs4
4 files changed, 145 insertions, 117 deletions
diff --git a/azalea-client/src/packet_handling/configuration.rs b/azalea-client/src/packet_handling/configuration.rs
index de365394..e427e36e 100644
--- a/azalea-client/src/packet_handling/configuration.rs
+++ b/azalea-client/src/packet_handling/configuration.rs
@@ -1,15 +1,14 @@
use std::io::Cursor;
use azalea_entity::indexing::EntityIdIndex;
-use azalea_protocol::packets::configuration::serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket;
-use azalea_protocol::packets::configuration::serverbound_keep_alive_packet::ServerboundKeepAlivePacket;
-use azalea_protocol::packets::configuration::serverbound_pong_packet::ServerboundPongPacket;
-use azalea_protocol::packets::configuration::serverbound_resource_pack_packet::ServerboundResourcePackPacket;
-use azalea_protocol::packets::configuration::serverbound_select_known_packs_packet::ServerboundSelectKnownPacksPacket;
-use azalea_protocol::packets::configuration::{
- ClientboundConfigurationPacket, ServerboundConfigurationPacket,
+use azalea_protocol::packets::config::s_finish_configuration::ServerboundFinishConfiguration;
+use azalea_protocol::packets::config::s_keep_alive::ServerboundKeepAlive;
+use azalea_protocol::packets::config::s_select_known_packs::ServerboundSelectKnownPacks;
+use azalea_protocol::packets::config::{
+ self, ClientboundConfigPacket, ServerboundConfigPacket, ServerboundCookieResponse,
+ ServerboundResourcePack,
};
-use azalea_protocol::packets::ConnectionProtocol;
+use azalea_protocol::packets::{ConnectionProtocol, Packet};
use azalea_protocol::read::deserialize_packet;
use bevy_ecs::prelude::*;
use bevy_ecs::system::SystemState;
@@ -23,29 +22,29 @@ use crate::raw_connection::RawConnection;
use crate::InstanceHolder;
#[derive(Event, Debug, Clone)]
-pub struct ConfigurationPacketEvent {
+pub struct ConfigurationEvent {
/// The client entity that received the packet.
pub entity: Entity,
/// The packet that was actually received.
- pub packet: ClientboundConfigurationPacket,
+ pub packet: ClientboundConfigPacket,
}
pub fn send_packet_events(
query: Query<(Entity, &RawConnection), With<InConfigurationState>>,
- mut packet_events: ResMut<Events<ConfigurationPacketEvent>>,
+ mut packet_events: ResMut<Events<ConfigurationEvent>>,
) {
// we manually clear and send the events at the beginning of each update
// since otherwise it'd cause issues with events in process_packet_events
// running twice
packet_events.clear();
- for (player_entity, raw_connection) in &query {
- let packets_lock = raw_connection.incoming_packet_queue();
+ for (player_entity, raw_conn) in &query {
+ let packets_lock = raw_conn.incoming_packet_queue();
let mut packets = packets_lock.lock();
if !packets.is_empty() {
for raw_packet in packets.iter() {
- let packet = match deserialize_packet::<ClientboundConfigurationPacket>(
- &mut Cursor::new(raw_packet),
- ) {
+ let packet = match deserialize_packet::<ClientboundConfigPacket>(&mut Cursor::new(
+ raw_packet,
+ )) {
Ok(packet) => packet,
Err(err) => {
error!("failed to read packet: {:?}", err);
@@ -53,7 +52,7 @@ pub fn send_packet_events(
continue;
}
};
- packet_events.send(ConfigurationPacketEvent {
+ packet_events.send(ConfigurationEvent {
entity: player_entity,
packet,
});
@@ -66,10 +65,9 @@ pub fn send_packet_events(
pub fn process_packet_events(ecs: &mut World) {
let mut events_owned = Vec::new();
- let mut system_state: SystemState<EventReader<ConfigurationPacketEvent>> =
- SystemState::new(ecs);
+ let mut system_state: SystemState<EventReader<ConfigurationEvent>> = SystemState::new(ecs);
let mut events = system_state.get_mut(ecs);
- for ConfigurationPacketEvent {
+ for ConfigurationEvent {
entity: player_entity,
packet,
} in events.read()
@@ -79,7 +77,7 @@ pub fn process_packet_events(ecs: &mut World) {
}
for (player_entity, packet) in events_owned {
match packet {
- ClientboundConfigurationPacket::RegistryData(p) => {
+ ClientboundConfigPacket::RegistryData(p) => {
let mut system_state: SystemState<Query<&mut InstanceHolder>> =
SystemState::new(ecs);
let mut query = system_state.get_mut(ecs);
@@ -90,10 +88,10 @@ pub fn process_packet_events(ecs: &mut World) {
instance.registries.append(p.registry_id, p.entries);
}
- ClientboundConfigurationPacket::CustomPayload(p) => {
+ ClientboundConfigPacket::CustomPayload(p) => {
debug!("Got custom payload packet {p:?}");
}
- ClientboundConfigurationPacket::Disconnect(p) => {
+ ClientboundConfigPacket::Disconnect(p) => {
warn!("Got disconnect packet {p:?}");
let mut system_state: SystemState<EventWriter<DisconnectEvent>> =
SystemState::new(ecs);
@@ -103,20 +101,20 @@ pub fn process_packet_events(ecs: &mut World) {
reason: Some(p.reason.clone()),
});
}
- ClientboundConfigurationPacket::FinishConfiguration(p) => {
+ ClientboundConfigPacket::FinishConfiguration(p) => {
debug!("got FinishConfiguration packet: {p:?}");
let mut system_state: SystemState<Query<&mut RawConnection>> =
SystemState::new(ecs);
let mut query = system_state.get_mut(ecs);
- let mut raw_connection = query.get_mut(player_entity).unwrap();
+ let mut raw_conn = query.get_mut(player_entity).unwrap();
- raw_connection
- .write_packet(ServerboundFinishConfigurationPacket {}.get())
+ raw_conn
+ .write_packet(ServerboundFinishConfiguration {})
.expect(
"we should be in the right state and encoding this packet shouldn't fail",
);
- raw_connection.set_state(ConnectionProtocol::Game);
+ raw_conn.set_state(ConnectionProtocol::Game);
// these components are added now that we're going to be in the Game state
ecs.entity_mut(player_entity)
@@ -140,7 +138,7 @@ pub fn process_packet_events(ecs: &mut World) {
_local_entity: azalea_entity::LocalEntity,
});
}
- ClientboundConfigurationPacket::KeepAlive(p) => {
+ ClientboundConfigPacket::KeepAlive(p) => {
debug!("Got keep alive packet (in configuration) {p:?} for {player_entity:?}");
let mut system_state: SystemState<(
@@ -148,80 +146,91 @@ pub fn process_packet_events(ecs: &mut World) {
EventWriter<KeepAliveEvent>,
)> = SystemState::new(ecs);
let (query, mut keepalive_events) = system_state.get_mut(ecs);
- let raw_connection = query.get(player_entity).unwrap();
+ let raw_conn = query.get(player_entity).unwrap();
keepalive_events.send(KeepAliveEvent {
entity: player_entity,
id: p.id,
});
- raw_connection
- .write_packet(ServerboundKeepAlivePacket { id: p.id }.get())
+ raw_conn
+ .write_packet(ServerboundKeepAlive { id: p.id })
.unwrap();
}
- ClientboundConfigurationPacket::Ping(p) => {
+ ClientboundConfigPacket::Ping(p) => {
debug!("Got ping packet {p:?}");
let mut system_state: SystemState<Query<&RawConnection>> = SystemState::new(ecs);
let mut query = system_state.get_mut(ecs);
- let raw_connection = query.get_mut(player_entity).unwrap();
+ let raw_conn = query.get_mut(player_entity).unwrap();
- raw_connection
- .write_packet(ServerboundPongPacket { id: p.id }.get())
+ raw_conn
+ .write_packet(config::s_pong::ServerboundPong { id: p.id })
.unwrap();
}
- ClientboundConfigurationPacket::ResourcePackPush(p) => {
+ ClientboundConfigPacket::ResourcePackPush(p) => {
debug!("Got resource pack packet {p:?}");
let mut system_state: SystemState<Query<&RawConnection>> = SystemState::new(ecs);
let mut query = system_state.get_mut(ecs);
- let raw_connection = query.get_mut(player_entity).unwrap();
+ let raw_conn = query.get_mut(player_entity).unwrap();
// always accept resource pack
- raw_connection.write_packet(
- ServerboundResourcePackPacket {
+ raw_conn
+ .write_packet(ServerboundResourcePack {
id: p.id,
- action: azalea_protocol::packets::configuration::serverbound_resource_pack_packet::Action::Accepted
- }.get()
- ).unwrap();
+ action: config::s_resource_pack::Action::Accepted,
+ })
+ .unwrap();
}
- ClientboundConfigurationPacket::ResourcePackPop(_) => {
+ ClientboundConfigPacket::ResourcePackPop(_) => {
// we can ignore this
}
- ClientboundConfigurationPacket::UpdateEnabledFeatures(p) => {
+ ClientboundConfigPacket::UpdateEnabledFeatures(p) => {
debug!("Got update enabled features packet {p:?}");
}
- ClientboundConfigurationPacket::UpdateTags(_p) => {
+ ClientboundConfigPacket::UpdateTags(_p) => {
debug!("Got update tags packet");
}
- ClientboundConfigurationPacket::CookieRequest(p) => {
+ ClientboundConfigPacket::CookieRequest(p) => {
debug!("Got cookie request packet {p:?}");
+
+ let mut system_state: SystemState<Query<&RawConnection>> = SystemState::new(ecs);
+ let mut query = system_state.get_mut(ecs);
+ let raw_conn = query.get_mut(player_entity).unwrap();
+
+ raw_conn
+ .write_packet(ServerboundCookieResponse {
+ key: p.key,
+ // cookies aren't implemented
+ payload: None,
+ })
+ .unwrap();
}
- ClientboundConfigurationPacket::ResetChat(p) => {
+ ClientboundConfigPacket::ResetChat(p) => {
debug!("Got reset chat packet {p:?}");
}
- ClientboundConfigurationPacket::StoreCookie(p) => {
+ ClientboundConfigPacket::StoreCookie(p) => {
debug!("Got store cookie packet {p:?}");
}
- ClientboundConfigurationPacket::Transfer(p) => {
+ ClientboundConfigPacket::Transfer(p) => {
debug!("Got transfer packet {p:?}");
}
- ClientboundConfigurationPacket::SelectKnownPacks(p) => {
+ ClientboundConfigPacket::SelectKnownPacks(p) => {
debug!("Got select known packs packet {p:?}");
let mut system_state: SystemState<Query<&RawConnection>> = SystemState::new(ecs);
let mut query = system_state.get_mut(ecs);
- let raw_connection = query.get_mut(player_entity).unwrap();
+ let raw_conn = query.get_mut(player_entity).unwrap();
// resource pack management isn't implemented
- raw_connection
- .write_packet(
- ServerboundSelectKnownPacksPacket {
- known_packs: vec![],
- }
- .get(),
- )
+ raw_conn
+ .write_packet(ServerboundSelectKnownPacks {
+ known_packs: vec![],
+ })
.unwrap();
}
+ ClientboundConfigPacket::ServerLinks(_) => {}
+ ClientboundConfigPacket::CustomReportDetails(_) => {}
}
}
}
@@ -229,19 +238,25 @@ pub fn process_packet_events(ecs: &mut World) {
/// An event for sending a packet to the server while we're in the
/// `configuration` state.
#[derive(Event)]
-pub struct SendConfigurationPacketEvent {
- pub entity: Entity,
- pub packet: ServerboundConfigurationPacket,
+pub struct SendConfigurationEvent {
+ pub sent_by: Entity,
+ pub packet: ServerboundConfigPacket,
+}
+impl SendConfigurationEvent {
+ pub fn new(sent_by: Entity, packet: impl Packet<ServerboundConfigPacket>) -> Self {
+ let packet = packet.into_variant();
+ Self { sent_by, packet }
+ }
}
pub fn handle_send_packet_event(
- mut send_packet_events: EventReader<SendConfigurationPacketEvent>,
+ mut send_packet_events: EventReader<SendConfigurationEvent>,
mut query: Query<&mut RawConnection>,
) {
for event in send_packet_events.read() {
- if let Ok(raw_connection) = query.get_mut(event.entity) {
+ if let Ok(raw_conn) = query.get_mut(event.sent_by) {
// debug!("Sending packet: {:?}", event.packet);
- if let Err(e) = raw_connection.write_packet(event.packet.clone()) {
+ if let Err(e) = raw_conn.write_packet(event.packet.clone()) {
error!("Failed to send packet: {e}");
}
}
diff --git a/azalea-client/src/packet_handling/game.rs b/azalea-client/src/packet_handling/game.rs
index 3c6ad6b5..38178a63 100644
--- a/azalea-client/src/packet_handling/game.rs
+++ b/azalea-client/src/packet_handling/game.rs
@@ -17,14 +17,15 @@ use azalea_entity::{
Physics, PlayerBundle, Position, RelativeEntityUpdate,
};
use azalea_protocol::{
- packets::game::{
- clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket,
- serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket,
- serverbound_configuration_acknowledged_packet::ServerboundConfigurationAcknowledgedPacket,
- serverbound_keep_alive_packet::ServerboundKeepAlivePacket,
- serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket,
- serverbound_pong_packet::ServerboundPongPacket, ClientboundGamePacket,
- ServerboundGamePacket,
+ packets::{
+ game::{
+ c_player_combat_kill::ClientboundPlayerCombatKill,
+ s_accept_teleportation::ServerboundAcceptTeleportation,
+ s_configuration_acknowledged::ServerboundConfigurationAcknowledged,
+ s_keep_alive::ServerboundKeepAlive, s_move_player_pos_rot::ServerboundMovePlayerPosRot,
+ s_pong::ServerboundPong, ClientboundGamePacket, ServerboundGamePacket,
+ },
+ Packet,
},
read::deserialize_packet,
};
@@ -103,12 +104,12 @@ pub struct UpdatePlayerEvent {
}
/// Event for when an entity dies. dies. If it's a local player and there's a
-/// reason in the death screen, the [`ClientboundPlayerCombatKillPacket`] will
+/// reason in the death screen, the [`ClientboundPlayerCombatKill`] will
/// be included.
#[derive(Event, Debug, Clone)]
pub struct DeathEvent {
pub entity: Entity,
- pub packet: Option<ClientboundPlayerCombatKillPacket>,
+ pub packet: Option<ClientboundPlayerCombatKill>,
}
/// A KeepAlive packet is sent from the server to verify that the client is
@@ -340,10 +341,9 @@ pub fn process_packet_events(ecs: &mut World) {
"Sending client information because login: {:?}",
client_information
);
- send_packet_events.send(SendPacketEvent {
- entity: player_entity,
- packet: azalea_protocol::packets::game::serverbound_client_information_packet::ServerboundClientInformationPacket { information: client_information.clone() }.get(),
- });
+ send_packet_events.send(SendPacketEvent::new(player_entity,
+ azalea_protocol::packets::game::s_client_information::ServerboundClientInformation { information: client_information.clone() },
+ ));
system_state.apply(ecs);
}
@@ -493,13 +493,13 @@ pub fn process_packet_events(ecs: &mut World) {
**position = new_pos;
}
- send_packet_events.send(SendPacketEvent {
- entity: player_entity,
- packet: ServerboundAcceptTeleportationPacket { id: p.id }.get(),
- });
- send_packet_events.send(SendPacketEvent {
- entity: player_entity,
- packet: ServerboundMovePlayerPosRotPacket {
+ send_packet_events.send(SendPacketEvent::new(
+ player_entity,
+ ServerboundAcceptTeleportation { id: p.id },
+ ));
+ send_packet_events.send(SendPacketEvent::new(
+ player_entity,
+ ServerboundMovePlayerPosRot {
x: new_pos.x,
y: new_pos.y,
z: new_pos.z,
@@ -507,9 +507,8 @@ pub fn process_packet_events(ecs: &mut World) {
x_rot,
// this is always false
on_ground: false,
- }
- .get(),
- });
+ },
+ ));
}
ClientboundGamePacket::PlayerInfoUpdate(p) => {
debug!("Got player info packet {p:?}");
@@ -983,10 +982,10 @@ pub fn process_packet_events(ecs: &mut World) {
entity: player_entity,
id: p.id,
});
- send_packet_events.send(SendPacketEvent {
- entity: player_entity,
- packet: ServerboundKeepAlivePacket { id: p.id }.get(),
- });
+ send_packet_events.send(SendPacketEvent::new(
+ player_entity,
+ ServerboundKeepAlive { id: p.id },
+ ));
}
ClientboundGamePacket::RemoveEntities(p) => {
debug!("Got remove entities packet {:?}", p);
@@ -1096,7 +1095,7 @@ pub fn process_packet_events(ecs: &mut World) {
}
}
ClientboundGamePacket::GameEvent(p) => {
- use azalea_protocol::packets::game::clientbound_game_event_packet::EventType;
+ use azalea_protocol::packets::game::c_game_event::EventType;
debug!("Got game event packet {p:?}");
@@ -1279,10 +1278,10 @@ pub fn process_packet_events(ecs: &mut World) {
SystemState::new(ecs);
let mut send_packet_events = system_state.get_mut(ecs);
- send_packet_events.send(SendPacketEvent {
- entity: player_entity,
- packet: ServerboundPongPacket { id: p.id }.get(),
- });
+ send_packet_events.send(SendPacketEvent::new(
+ player_entity,
+ ServerboundPong { id: p.id },
+ ));
}
ClientboundGamePacket::PlaceGhostRecipe(_) => {}
ClientboundGamePacket::PlayerCombatEnd(_) => {}
@@ -1423,10 +1422,10 @@ pub fn process_packet_events(ecs: &mut World) {
SystemState::new(ecs);
let (mut commands, mut packet_events) = system_state.get_mut(ecs);
- packet_events.send(SendPacketEvent {
- entity: player_entity,
- packet: ServerboundConfigurationAcknowledgedPacket {}.get(),
- });
+ packet_events.send(SendPacketEvent::new(
+ player_entity,
+ ServerboundConfigurationAcknowledged {},
+ ));
commands
.entity(player_entity)
@@ -1459,7 +1458,7 @@ pub fn process_packet_events(ecs: &mut World) {
ClientboundGamePacket::TabList(_) => {}
ClientboundGamePacket::TagQuery(_) => {}
ClientboundGamePacket::TakeItemEntity(_) => {}
- ClientboundGamePacket::Bundle(_) => {}
+ ClientboundGamePacket::BundleDelimiter(_) => {}
ClientboundGamePacket::DamageEvent(_) => {}
ClientboundGamePacket::HurtAnimation(_) => {}
@@ -1472,7 +1471,7 @@ pub fn process_packet_events(ecs: &mut World) {
ClientboundGamePacket::PongResponse(_) => {}
ClientboundGamePacket::StoreCookie(_) => {}
ClientboundGamePacket::Transfer(_) => {}
- ClientboundGamePacket::MoveMinecart(_) => {}
+ ClientboundGamePacket::MoveMinecartAlongTrack(_) => {}
ClientboundGamePacket::SetHeldSlot(_) => {}
ClientboundGamePacket::SetPlayerInventory(_) => {}
ClientboundGamePacket::ProjectilePower(_) => {}
@@ -1490,16 +1489,22 @@ pub fn process_packet_events(ecs: &mut World) {
/// An event for sending a packet to the server while we're in the `game` state.
#[derive(Event)]
pub struct SendPacketEvent {
- pub entity: Entity,
+ pub sent_by: Entity,
pub packet: ServerboundGamePacket,
}
+impl SendPacketEvent {
+ pub fn new(sent_by: Entity, packet: impl Packet<ServerboundGamePacket>) -> Self {
+ let packet = packet.into_variant();
+ Self { sent_by, packet }
+ }
+}
pub fn handle_send_packet_event(
mut send_packet_events: EventReader<SendPacketEvent>,
mut query: Query<&mut RawConnection>,
) {
for event in send_packet_events.read() {
- if let Ok(raw_connection) = query.get_mut(event.entity) {
+ if let Ok(raw_connection) = query.get_mut(event.sent_by) {
// debug!("Sending packet: {:?}", event.packet);
if let Err(e) = raw_connection.write_packet(event.packet.clone()) {
error!("Failed to send packet: {e}");
diff --git a/azalea-client/src/packet_handling/login.rs b/azalea-client/src/packet_handling/login.rs
index 7d71b440..11c0b8e9 100644
--- a/azalea-client/src/packet_handling/login.rs
+++ b/azalea-client/src/packet_handling/login.rs
@@ -3,9 +3,12 @@
use std::{collections::HashSet, sync::Arc};
-use azalea_protocol::packets::login::{
- serverbound_custom_query_answer_packet::ServerboundCustomQueryAnswerPacket,
- ClientboundLoginPacket, ServerboundLoginPacket,
+use azalea_protocol::packets::{
+ login::{
+ s_custom_query_answer::ServerboundCustomQueryAnswer, ClientboundLoginPacket,
+ ServerboundLoginPacket,
+ },
+ Packet,
};
use bevy_ecs::{prelude::*, system::SystemState};
use derive_more::{Deref, DerefMut};
@@ -33,6 +36,12 @@ pub struct SendLoginPacketEvent {
pub entity: Entity,
pub packet: ServerboundLoginPacket,
}
+impl SendLoginPacketEvent {
+ pub fn new(entity: Entity, packet: impl Packet<ServerboundLoginPacket>) -> Self {
+ let packet = packet.into_variant();
+ Self { entity, packet }
+ }
+}
#[derive(Component)]
pub struct LoginSendPacketQueue {
@@ -86,14 +95,13 @@ pub fn process_packet_events(ecs: &mut World) {
}
}
- send_packet_events.send(SendLoginPacketEvent {
- entity: player_entity,
- packet: ServerboundCustomQueryAnswerPacket {
+ send_packet_events.send(SendLoginPacketEvent::new(
+ player_entity,
+ ServerboundCustomQueryAnswer {
transaction_id: p.transaction_id,
data: None,
- }
- .get(),
- });
+ },
+ ));
}
_ => {}
}
diff --git a/azalea-client/src/packet_handling/mod.rs b/azalea-client/src/packet_handling/mod.rs
index eb8f1d47..6bb9c319 100644
--- a/azalea-client/src/packet_handling/mod.rs
+++ b/azalea-client/src/packet_handling/mod.rs
@@ -61,9 +61,9 @@ impl Plugin for PacketHandlerPlugin {
)
// we do this instead of add_event so we can handle the events ourselves
.init_resource::<Events<game::PacketEvent>>()
- .init_resource::<Events<configuration::ConfigurationPacketEvent>>()
+ .init_resource::<Events<configuration::ConfigurationEvent>>()
.add_event::<game::SendPacketEvent>()
- .add_event::<configuration::SendConfigurationPacketEvent>()
+ .add_event::<configuration::SendConfigurationEvent>()
.add_event::<AddPlayerEvent>()
.add_event::<RemovePlayerEvent>()
.add_event::<UpdatePlayerEvent>()