mirror of
https://github.com/mat-1/azalea.git
synced 2024-09-19 22:52:32 +00:00
make ClientInformation and TabList their own components
This commit is contained in:
parent
5ce830ae6c
commit
f28efd5637
3 changed files with 40 additions and 49 deletions
|
@ -51,6 +51,7 @@ use bevy_ecs::{
|
||||||
};
|
};
|
||||||
use bevy_log::LogPlugin;
|
use bevy_log::LogPlugin;
|
||||||
use bevy_time::{prelude::FixedTime, TimePlugin};
|
use bevy_time::{prelude::FixedTime, TimePlugin};
|
||||||
|
use derive_more::{Deref, DerefMut};
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use std::{collections::HashMap, fmt::Debug, io, net::SocketAddr, sync::Arc, time::Duration};
|
use std::{collections::HashMap, fmt::Debug, io, net::SocketAddr, sync::Arc, time::Duration};
|
||||||
|
@ -58,8 +59,6 @@ use thiserror::Error;
|
||||||
use tokio::{sync::mpsc, time};
|
use tokio::{sync::mpsc, time};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub type ClientInformation = ServerboundClientInformationPacket;
|
|
||||||
|
|
||||||
/// `Client` has the things that a user interacting with the library will want.
|
/// `Client` has the things that a user interacting with the library will want.
|
||||||
/// Things that a player in the world will want to know are in [`LocalPlayer`].
|
/// Things that a player in the world will want to know are in [`LocalPlayer`].
|
||||||
///
|
///
|
||||||
|
@ -93,6 +92,16 @@ pub struct Client {
|
||||||
pub run_schedule_sender: mpsc::UnboundedSender<()>,
|
pub run_schedule_sender: mpsc::UnboundedSender<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A component that contains some of the "settings" for this client that are
|
||||||
|
/// sent to the server, such as render distance.
|
||||||
|
#[derive(Component, Clone, Debug, Deref, DerefMut, Default, Eq, PartialEq)]
|
||||||
|
pub struct ClientInformation(ServerboundClientInformationPacket);
|
||||||
|
|
||||||
|
/// A component that contains a map of player UUIDs to their information in the
|
||||||
|
/// tab list
|
||||||
|
#[derive(Component, Clone, Debug, Deref, DerefMut, Default)]
|
||||||
|
pub struct TabList(HashMap<Uuid, PlayerInfo>);
|
||||||
|
|
||||||
/// An error that happened while joining the server.
|
/// An error that happened while joining the server.
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum JoinError {
|
pub enum JoinError {
|
||||||
|
@ -238,6 +247,8 @@ impl Client {
|
||||||
game_profile: GameProfileComponent(game_profile),
|
game_profile: GameProfileComponent(game_profile),
|
||||||
physics_state: PhysicsState::default(),
|
physics_state: PhysicsState::default(),
|
||||||
local_player_events: LocalPlayerEvents(tx),
|
local_player_events: LocalPlayerEvents(tx),
|
||||||
|
client_information: ClientInformation::default(),
|
||||||
|
tab_list: TabList::default(),
|
||||||
_local: Local,
|
_local: Local,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -451,32 +462,21 @@ impl Client {
|
||||||
client_information: ServerboundClientInformationPacket,
|
client_information: ServerboundClientInformationPacket,
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
{
|
{
|
||||||
self.local_player_mut(&mut self.ecs.lock())
|
let mut ecs = self.ecs.lock();
|
||||||
.client_information = client_information;
|
let mut client_information_mut = self.query::<&mut ClientInformation>(&mut ecs);
|
||||||
|
**client_information_mut = client_information.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.logged_in() {
|
if self.logged_in() {
|
||||||
let client_information_packet = self
|
|
||||||
.local_player(&mut self.ecs.lock())
|
|
||||||
.client_information
|
|
||||||
.clone()
|
|
||||||
.get();
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Sending client information (already logged in): {:?}",
|
"Sending client information (already logged in): {:?}",
|
||||||
client_information_packet
|
client_information
|
||||||
);
|
);
|
||||||
self.write_packet(client_information_packet);
|
self.write_packet(client_information.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a HashMap of all the players in the tab list.
|
|
||||||
///
|
|
||||||
/// Internally, this fetches the `players` field in [`LocalPlayer`].
|
|
||||||
pub fn players(&mut self) -> HashMap<Uuid, PlayerInfo> {
|
|
||||||
self.local_player(&mut self.ecs.lock()).players.clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A bundle for the components that are present on a local player that received
|
/// A bundle for the components that are present on a local player that received
|
||||||
|
@ -488,6 +488,8 @@ pub struct JoinedClientBundle {
|
||||||
pub game_profile: GameProfileComponent,
|
pub game_profile: GameProfileComponent,
|
||||||
pub physics_state: PhysicsState,
|
pub physics_state: PhysicsState,
|
||||||
pub local_player_events: LocalPlayerEvents,
|
pub local_player_events: LocalPlayerEvents,
|
||||||
|
pub client_information: ClientInformation,
|
||||||
|
pub tab_list: TabList,
|
||||||
pub _local: Local,
|
pub _local: Local,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{collections::HashMap, io, sync::Arc};
|
use std::{io, sync::Arc};
|
||||||
|
|
||||||
use azalea_auth::game_profile::GameProfile;
|
use azalea_auth::game_profile::GameProfile;
|
||||||
use azalea_core::ChunkPos;
|
use azalea_core::ChunkPos;
|
||||||
|
@ -14,11 +14,10 @@ use derive_more::{Deref, DerefMut};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tokio::{sync::mpsc, task::JoinHandle};
|
use tokio::{sync::mpsc, task::JoinHandle};
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
events::{Event, LocalPlayerEvents},
|
events::{Event, LocalPlayerEvents},
|
||||||
ClientInformation, PlayerInfo, WalkDirection,
|
ClientInformation, WalkDirection,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This is a component for our local player entities that are probably in a
|
/// This is a component for our local player entities that are probably in a
|
||||||
|
@ -33,11 +32,7 @@ use crate::{
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct LocalPlayer {
|
pub struct LocalPlayer {
|
||||||
packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>,
|
packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>,
|
||||||
/// Some of the "settings" for this client that are sent to the server, such
|
|
||||||
/// as render distance.
|
|
||||||
pub client_information: ClientInformation,
|
|
||||||
/// A map of player UUIDs to their information in the tab list
|
|
||||||
pub players: HashMap<Uuid, PlayerInfo>,
|
|
||||||
/// The partial world is the world this client currently has loaded. It has
|
/// The partial world is the world this client currently has loaded. It has
|
||||||
/// a limited render distance.
|
/// a limited render distance.
|
||||||
pub partial_world: Arc<RwLock<PartialWorld>>,
|
pub partial_world: Arc<RwLock<PartialWorld>>,
|
||||||
|
@ -96,9 +91,6 @@ impl LocalPlayer {
|
||||||
LocalPlayer {
|
LocalPlayer {
|
||||||
packet_writer,
|
packet_writer,
|
||||||
|
|
||||||
client_information: ClientInformation::default(),
|
|
||||||
players: HashMap::new(),
|
|
||||||
|
|
||||||
world,
|
world,
|
||||||
partial_world: Arc::new(RwLock::new(PartialWorld::new(
|
partial_world: Arc::new(RwLock::new(PartialWorld::new(
|
||||||
client_information.view_distance.into(),
|
client_information.view_distance.into(),
|
||||||
|
|
|
@ -37,6 +37,7 @@ use tokio::sync::mpsc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
chat::{ChatPacket, ChatReceivedEvent},
|
chat::{ChatPacket, ChatReceivedEvent},
|
||||||
|
client::TabList,
|
||||||
disconnect::DisconnectEvent,
|
disconnect::DisconnectEvent,
|
||||||
local_player::{GameProfileComponent, LocalPlayer},
|
local_player::{GameProfileComponent, LocalPlayer},
|
||||||
ClientInformation, PlayerInfo,
|
ClientInformation, PlayerInfo,
|
||||||
|
@ -189,11 +190,12 @@ fn process_packet_events(ecs: &mut World) {
|
||||||
&mut LocalPlayer,
|
&mut LocalPlayer,
|
||||||
Option<&mut WorldName>,
|
Option<&mut WorldName>,
|
||||||
&GameProfileComponent,
|
&GameProfileComponent,
|
||||||
|
&ClientInformation,
|
||||||
)>,
|
)>,
|
||||||
ResMut<WorldContainer>,
|
ResMut<WorldContainer>,
|
||||||
)> = SystemState::new(ecs);
|
)> = SystemState::new(ecs);
|
||||||
let (mut commands, mut query, mut world_container) = system_state.get_mut(ecs);
|
let (mut commands, mut query, mut world_container) = system_state.get_mut(ecs);
|
||||||
let (mut local_player, world_name, game_profile) =
|
let (mut local_player, world_name, game_profile, client_information) =
|
||||||
query.get_mut(player_entity).unwrap();
|
query.get_mut(player_entity).unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -267,7 +269,7 @@ fn process_packet_events(ecs: &mut World) {
|
||||||
// world_container)
|
// world_container)
|
||||||
|
|
||||||
*local_player.partial_world.write() = PartialWorld::new(
|
*local_player.partial_world.write() = PartialWorld::new(
|
||||||
local_player.client_information.view_distance.into(),
|
client_information.view_distance.into(),
|
||||||
// this argument makes it so other clients don't update this
|
// this argument makes it so other clients don't update this
|
||||||
// player entity
|
// player entity
|
||||||
// in a shared world
|
// in a shared world
|
||||||
|
@ -291,13 +293,12 @@ fn process_packet_events(ecs: &mut World) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the client information that we have set
|
// send the client information that we have set
|
||||||
let client_information_packet: ClientInformation =
|
|
||||||
local_player.client_information.clone();
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Sending client information because login: {:?}",
|
"Sending client information because login: {:?}",
|
||||||
client_information_packet
|
client_information
|
||||||
);
|
);
|
||||||
local_player.write_packet(client_information_packet.get());
|
let client_information: ClientInformation = client_information.clone();
|
||||||
|
local_player.write_packet((*client_information).clone().get());
|
||||||
|
|
||||||
// brand
|
// brand
|
||||||
local_player.write_packet(
|
local_player.write_packet(
|
||||||
|
@ -444,13 +445,13 @@ fn process_packet_events(ecs: &mut World) {
|
||||||
debug!("Got player info packet {:?}", p);
|
debug!("Got player info packet {:?}", p);
|
||||||
|
|
||||||
let mut system_state: SystemState<(
|
let mut system_state: SystemState<(
|
||||||
Query<&mut LocalPlayer>,
|
Query<&mut TabList>,
|
||||||
EventWriter<AddPlayerEvent>,
|
EventWriter<AddPlayerEvent>,
|
||||||
EventWriter<UpdatePlayerEvent>,
|
EventWriter<UpdatePlayerEvent>,
|
||||||
)> = SystemState::new(ecs);
|
)> = SystemState::new(ecs);
|
||||||
let (mut query, mut add_player_events, mut update_player_events) =
|
let (mut query, mut add_player_events, mut update_player_events) =
|
||||||
system_state.get_mut(ecs);
|
system_state.get_mut(ecs);
|
||||||
let mut local_player = query.get_mut(player_entity).unwrap();
|
let mut tab_list = query.get_mut(player_entity).unwrap();
|
||||||
|
|
||||||
for updated_info in &p.entries {
|
for updated_info in &p.entries {
|
||||||
// add the new player maybe
|
// add the new player maybe
|
||||||
|
@ -462,16 +463,12 @@ fn process_packet_events(ecs: &mut World) {
|
||||||
latency: updated_info.latency,
|
latency: updated_info.latency,
|
||||||
display_name: updated_info.display_name.clone(),
|
display_name: updated_info.display_name.clone(),
|
||||||
};
|
};
|
||||||
local_player
|
tab_list.insert(updated_info.profile.uuid, info.clone());
|
||||||
.players
|
|
||||||
.insert(updated_info.profile.uuid, info.clone());
|
|
||||||
add_player_events.send(AddPlayerEvent {
|
add_player_events.send(AddPlayerEvent {
|
||||||
entity: player_entity,
|
entity: player_entity,
|
||||||
info: info.clone(),
|
info: info.clone(),
|
||||||
});
|
});
|
||||||
} else if let Some(info) =
|
} else if let Some(info) = tab_list.get_mut(&updated_info.profile.uuid) {
|
||||||
local_player.players.get_mut(&updated_info.profile.uuid)
|
|
||||||
{
|
|
||||||
// `else if` because the block for add_player above
|
// `else if` because the block for add_player above
|
||||||
// already sets all the fields
|
// already sets all the fields
|
||||||
if p.actions.update_game_mode {
|
if p.actions.update_game_mode {
|
||||||
|
@ -497,14 +494,14 @@ fn process_packet_events(ecs: &mut World) {
|
||||||
}
|
}
|
||||||
ClientboundGamePacket::PlayerInfoRemove(p) => {
|
ClientboundGamePacket::PlayerInfoRemove(p) => {
|
||||||
let mut system_state: SystemState<(
|
let mut system_state: SystemState<(
|
||||||
Query<&mut LocalPlayer>,
|
Query<&mut TabList>,
|
||||||
EventWriter<RemovePlayerEvent>,
|
EventWriter<RemovePlayerEvent>,
|
||||||
)> = SystemState::new(ecs);
|
)> = SystemState::new(ecs);
|
||||||
let (mut query, mut remove_player_events) = system_state.get_mut(ecs);
|
let (mut query, mut remove_player_events) = system_state.get_mut(ecs);
|
||||||
let mut local_player = query.get_mut(player_entity).unwrap();
|
let mut tab_list = query.get_mut(player_entity).unwrap();
|
||||||
|
|
||||||
for uuid in &p.profile_ids {
|
for uuid in &p.profile_ids {
|
||||||
if let Some(info) = local_player.players.remove(uuid) {
|
if let Some(info) = tab_list.remove(uuid) {
|
||||||
remove_player_events.send(RemovePlayerEvent {
|
remove_player_events.send(RemovePlayerEvent {
|
||||||
entity: player_entity,
|
entity: player_entity,
|
||||||
info,
|
info,
|
||||||
|
@ -642,10 +639,10 @@ fn process_packet_events(ecs: &mut World) {
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
let mut system_state: SystemState<(
|
let mut system_state: SystemState<(
|
||||||
Commands,
|
Commands,
|
||||||
Query<(&mut LocalPlayer, Option<&WorldName>)>,
|
Query<(&TabList, Option<&WorldName>)>,
|
||||||
)> = SystemState::new(ecs);
|
)> = SystemState::new(ecs);
|
||||||
let (mut commands, mut query) = system_state.get_mut(ecs);
|
let (mut commands, mut query) = system_state.get_mut(ecs);
|
||||||
let (local_player, world_name) = query.get_mut(player_entity).unwrap();
|
let (tab_list, world_name) = query.get_mut(player_entity).unwrap();
|
||||||
|
|
||||||
if let Some(WorldName(world_name)) = world_name {
|
if let Some(WorldName(world_name)) = world_name {
|
||||||
let bundle = p.as_player_bundle(world_name.clone());
|
let bundle = p.as_player_bundle(world_name.clone());
|
||||||
|
@ -655,7 +652,7 @@ fn process_packet_events(ecs: &mut World) {
|
||||||
bundle,
|
bundle,
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Some(player_info) = local_player.players.get(&p.uuid) {
|
if let Some(player_info) = tab_list.get(&p.uuid) {
|
||||||
spawned.insert(GameProfileComponent(player_info.profile.clone()));
|
spawned.insert(GameProfileComponent(player_info.profile.clone()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue