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_time::{prelude::FixedTime, TimePlugin};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use log::{debug, error};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
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 uuid::Uuid;
|
||||
|
||||
pub type ClientInformation = ServerboundClientInformationPacket;
|
||||
|
||||
/// `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`].
|
||||
///
|
||||
|
@ -93,6 +92,16 @@ pub struct Client {
|
|||
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.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum JoinError {
|
||||
|
@ -238,6 +247,8 @@ impl Client {
|
|||
game_profile: GameProfileComponent(game_profile),
|
||||
physics_state: PhysicsState::default(),
|
||||
local_player_events: LocalPlayerEvents(tx),
|
||||
client_information: ClientInformation::default(),
|
||||
tab_list: TabList::default(),
|
||||
_local: Local,
|
||||
});
|
||||
|
||||
|
@ -451,32 +462,21 @@ impl Client {
|
|||
client_information: ServerboundClientInformationPacket,
|
||||
) -> Result<(), std::io::Error> {
|
||||
{
|
||||
self.local_player_mut(&mut self.ecs.lock())
|
||||
.client_information = client_information;
|
||||
let mut ecs = self.ecs.lock();
|
||||
let mut client_information_mut = self.query::<&mut ClientInformation>(&mut ecs);
|
||||
**client_information_mut = client_information.clone();
|
||||
}
|
||||
|
||||
if self.logged_in() {
|
||||
let client_information_packet = self
|
||||
.local_player(&mut self.ecs.lock())
|
||||
.client_information
|
||||
.clone()
|
||||
.get();
|
||||
log::debug!(
|
||||
"Sending client information (already logged in): {:?}",
|
||||
client_information_packet
|
||||
client_information
|
||||
);
|
||||
self.write_packet(client_information_packet);
|
||||
self.write_packet(client_information.get());
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -488,6 +488,8 @@ pub struct JoinedClientBundle {
|
|||
pub game_profile: GameProfileComponent,
|
||||
pub physics_state: PhysicsState,
|
||||
pub local_player_events: LocalPlayerEvents,
|
||||
pub client_information: ClientInformation,
|
||||
pub tab_list: TabList,
|
||||
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_core::ChunkPos;
|
||||
|
@ -14,11 +14,10 @@ use derive_more::{Deref, DerefMut};
|
|||
use parking_lot::RwLock;
|
||||
use thiserror::Error;
|
||||
use tokio::{sync::mpsc, task::JoinHandle};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
events::{Event, LocalPlayerEvents},
|
||||
ClientInformation, PlayerInfo, WalkDirection,
|
||||
ClientInformation, WalkDirection,
|
||||
};
|
||||
|
||||
/// This is a component for our local player entities that are probably in a
|
||||
|
@ -33,11 +32,7 @@ use crate::{
|
|||
#[derive(Component)]
|
||||
pub struct LocalPlayer {
|
||||
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
|
||||
/// a limited render distance.
|
||||
pub partial_world: Arc<RwLock<PartialWorld>>,
|
||||
|
@ -96,9 +91,6 @@ impl LocalPlayer {
|
|||
LocalPlayer {
|
||||
packet_writer,
|
||||
|
||||
client_information: ClientInformation::default(),
|
||||
players: HashMap::new(),
|
||||
|
||||
world,
|
||||
partial_world: Arc::new(RwLock::new(PartialWorld::new(
|
||||
client_information.view_distance.into(),
|
||||
|
|
|
@ -37,6 +37,7 @@ use tokio::sync::mpsc;
|
|||
|
||||
use crate::{
|
||||
chat::{ChatPacket, ChatReceivedEvent},
|
||||
client::TabList,
|
||||
disconnect::DisconnectEvent,
|
||||
local_player::{GameProfileComponent, LocalPlayer},
|
||||
ClientInformation, PlayerInfo,
|
||||
|
@ -189,11 +190,12 @@ fn process_packet_events(ecs: &mut World) {
|
|||
&mut LocalPlayer,
|
||||
Option<&mut WorldName>,
|
||||
&GameProfileComponent,
|
||||
&ClientInformation,
|
||||
)>,
|
||||
ResMut<WorldContainer>,
|
||||
)> = SystemState::new(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();
|
||||
|
||||
{
|
||||
|
@ -267,7 +269,7 @@ fn process_packet_events(ecs: &mut World) {
|
|||
// world_container)
|
||||
|
||||
*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
|
||||
// player entity
|
||||
// in a shared world
|
||||
|
@ -291,13 +293,12 @@ fn process_packet_events(ecs: &mut World) {
|
|||
}
|
||||
|
||||
// send the client information that we have set
|
||||
let client_information_packet: ClientInformation =
|
||||
local_player.client_information.clone();
|
||||
log::debug!(
|
||||
"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
|
||||
local_player.write_packet(
|
||||
|
@ -444,13 +445,13 @@ fn process_packet_events(ecs: &mut World) {
|
|||
debug!("Got player info packet {:?}", p);
|
||||
|
||||
let mut system_state: SystemState<(
|
||||
Query<&mut LocalPlayer>,
|
||||
Query<&mut TabList>,
|
||||
EventWriter<AddPlayerEvent>,
|
||||
EventWriter<UpdatePlayerEvent>,
|
||||
)> = SystemState::new(ecs);
|
||||
let (mut query, mut add_player_events, mut update_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 updated_info in &p.entries {
|
||||
// add the new player maybe
|
||||
|
@ -462,16 +463,12 @@ fn process_packet_events(ecs: &mut World) {
|
|||
latency: updated_info.latency,
|
||||
display_name: updated_info.display_name.clone(),
|
||||
};
|
||||
local_player
|
||||
.players
|
||||
.insert(updated_info.profile.uuid, info.clone());
|
||||
tab_list.insert(updated_info.profile.uuid, info.clone());
|
||||
add_player_events.send(AddPlayerEvent {
|
||||
entity: player_entity,
|
||||
info: info.clone(),
|
||||
});
|
||||
} else if let Some(info) =
|
||||
local_player.players.get_mut(&updated_info.profile.uuid)
|
||||
{
|
||||
} else if let Some(info) = tab_list.get_mut(&updated_info.profile.uuid) {
|
||||
// `else if` because the block for add_player above
|
||||
// already sets all the fields
|
||||
if p.actions.update_game_mode {
|
||||
|
@ -497,14 +494,14 @@ fn process_packet_events(ecs: &mut World) {
|
|||
}
|
||||
ClientboundGamePacket::PlayerInfoRemove(p) => {
|
||||
let mut system_state: SystemState<(
|
||||
Query<&mut LocalPlayer>,
|
||||
Query<&mut TabList>,
|
||||
EventWriter<RemovePlayerEvent>,
|
||||
)> = SystemState::new(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 {
|
||||
if let Some(info) = local_player.players.remove(uuid) {
|
||||
if let Some(info) = tab_list.remove(uuid) {
|
||||
remove_player_events.send(RemovePlayerEvent {
|
||||
entity: player_entity,
|
||||
info,
|
||||
|
@ -642,10 +639,10 @@ fn process_packet_events(ecs: &mut World) {
|
|||
#[allow(clippy::type_complexity)]
|
||||
let mut system_state: SystemState<(
|
||||
Commands,
|
||||
Query<(&mut LocalPlayer, Option<&WorldName>)>,
|
||||
Query<(&TabList, Option<&WorldName>)>,
|
||||
)> = SystemState::new(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 {
|
||||
let bundle = p.as_player_bundle(world_name.clone());
|
||||
|
@ -655,7 +652,7 @@ fn process_packet_events(ecs: &mut World) {
|
|||
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()));
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue