From 14ff151d88f27d9062efcdf0844058f4fa5f79c1 Mon Sep 17 00:00:00 2001 From: Snowiiii Date: Wed, 23 Oct 2024 16:38:30 +0200 Subject: [PATCH] Move from ids to uuids --- pumpkin/src/client/client_packet.rs | 40 +++++++++++++------------- pumpkin/src/client/container.rs | 2 +- pumpkin/src/client/mod.rs | 27 ++++++------------ pumpkin/src/client/player_packet.rs | 12 ++++---- pumpkin/src/entity/player.rs | 4 +-- pumpkin/src/main.rs | 14 ++------- pumpkin/src/server/mod.rs | 6 ++-- pumpkin/src/world/mod.rs | 44 +++++++++++++---------------- pumpkin/src/world/player_chunker.rs | 4 +-- 9 files changed, 65 insertions(+), 88 deletions(-) diff --git a/pumpkin/src/client/client_packet.rs b/pumpkin/src/client/client_packet.rs index 7ecd1f660..54b3ebb09 100644 --- a/pumpkin/src/client/client_packet.rs +++ b/pumpkin/src/client/client_packet.rs @@ -18,7 +18,7 @@ use pumpkin_protocol::{ use uuid::Uuid; use crate::{ - client::authentication::{self, validate_textures, GameProfile}, + client::authentication::{self, offline_uuid, validate_textures, GameProfile}, entity::player::{ChatMode, Hand}, proxy::{ bungeecord, @@ -39,11 +39,7 @@ impl Client { .store(version, std::sync::atomic::Ordering::Relaxed); *self.server_address.lock().await = handshake.server_address; - log::debug!( - "Handshake: id {} is now in state {:?}", - self.id, - &handshake.next_state - ); + log::debug!("Handshake: next state {:?}", &handshake.next_state); self.connection_state.store(handshake.next_state); if self.connection_state.load() != ConnectionState::Status { let protocol = version; @@ -60,13 +56,13 @@ impl Client { } pub async fn handle_status_request(&self, server: &Server, _status_request: SStatusRequest) { - log::debug!("Handling status request for id {}", self.id); + log::debug!("Handling status request for id"); let status = server.get_status(); self.send_packet(&status.lock().await.get_status()).await; } pub async fn handle_ping_request(&self, ping_request: SStatusPingRequest) { - log::debug!("Handling ping request for id {}", self.id); + log::debug!("Handling ping request for id"); self.send_packet(&CPingResponse::new(ping_request.payload)) .await; self.close(); @@ -80,11 +76,7 @@ impl Client { } pub async fn handle_login_start(&self, server: &Server, login_start: SLoginStart) { - log::debug!( - "login start for id {}, State {:?}", - self.id, - self.connection_state - ); + log::debug!("login start"); if !Self::is_valid_player_name(&login_start.name) { self.kick("Invalid characters in username").await; @@ -108,8 +100,14 @@ impl Client { } } } else { + let id = if BASIC_CONFIG.online_mode { + login_start.uuid + } else { + offline_uuid(&login_start.name).expect("This is very not safe and bad") + }; + let profile = GameProfile { - id: login_start.uuid, + id, name: login_start.name, properties: vec![], profile_actions: None, @@ -137,7 +135,7 @@ impl Client { server: &Server, encryption_response: SEncryptionResponse, ) { - log::debug!("Handling encryption for id {}", self.id); + log::debug!("Handling encryption for id"); let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap(); if let Err(error) = self.set_encryption(Some(&shared_secret)).await { @@ -228,7 +226,7 @@ impl Client { } pub async fn handle_plugin_response(&self, plugin_response: SLoginPluginResponse) { - log::debug!("Handling plugin for id {}", self.id); + log::debug!("Handling plugin for id"); let velocity_config = &ADVANCED_CONFIG.proxy.velocity; if velocity_config.enabled { let mut address = self.address.lock().await; @@ -252,7 +250,7 @@ impl Client { server: &Server, _login_acknowledged: SLoginAcknowledged, ) { - log::debug!("Handling login acknowledged for id {}", self.id); + log::debug!("Handling login acknowledged for id"); self.connection_state.store(ConnectionState::Config); self.send_packet(&server.get_branding()).await; @@ -289,7 +287,7 @@ impl Client { &self, client_information: SClientInformationConfig, ) { - log::debug!("Handling client settings for id {}", self.id); + log::debug!("Handling client settings for id"); if let (Some(main_hand), Some(chat_mode)) = ( Hand::from_i32(client_information.main_hand.into()), ChatMode::from_i32(client_information.chat_mode.into()), @@ -310,7 +308,7 @@ impl Client { } pub async fn handle_plugin_message(&self, plugin_message: SPluginMessage) { - log::debug!("Handling plugin message for id {}", self.id); + log::debug!("Handling plugin message for id"); if plugin_message.channel.starts_with("minecraft:brand") || plugin_message.channel.starts_with("MC|Brand") { @@ -323,7 +321,7 @@ impl Client { } pub async fn handle_known_packs(&self, server: &Server, _config_acknowledged: SKnownPacks) { - log::debug!("Handling known packs for id {}", self.id); + log::debug!("Handling known packs for id"); for registry in &server.cached_registry { self.send_packet(&CRegistryData::new( ®istry.registry_id, @@ -338,7 +336,7 @@ impl Client { } pub fn handle_config_acknowledged(&self, _config_acknowledged: &SAcknowledgeFinishConfig) { - log::debug!("Handling config acknowledge for id {}", self.id); + log::debug!("Handling config acknowledge for id"); self.connection_state.store(ConnectionState::Play); self.make_player .store(true, std::sync::atomic::Ordering::Relaxed); diff --git a/pumpkin/src/client/container.rs b/pumpkin/src/client/container.rs index b5c04a297..4dbc46f70 100644 --- a/pumpkin/src/client/container.rs +++ b/pumpkin/src/client/container.rs @@ -406,7 +406,7 @@ impl Player { .filter(|player_id| *player_id != self.entity_id()) .collect_vec() }; - let player_token = self.client.id; + let player_token = self.gameprofile.id; // TODO: Figure out better way to get only the players from player_ids // Also refactor out a better method to get individual advanced state ids diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 4ee077531..fdd6e6ab9 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -107,8 +107,6 @@ pub struct Client { pub encryption: AtomicBool, /// Indicates if the client connection is closed. pub closed: AtomicBool, - /// A unique id identifying the client. - pub id: usize, /// The underlying TCP connection to the client. pub connection_reader: Arc>, pub connection_writer: Arc>, @@ -126,7 +124,7 @@ pub struct Client { impl Client { #[must_use] - pub fn new(id: usize, connection: tokio::net::TcpStream, address: SocketAddr) -> Self { + pub fn new(connection: tokio::net::TcpStream, address: SocketAddr) -> Self { let (connection_reader, connection_writer) = connection.into_split(); Self { protocol_version: AtomicI32::new(0), @@ -134,7 +132,6 @@ impl Client { config: Mutex::new(None), brand: Mutex::new(None), server_address: Mutex::new(String::new()), - id, address: Mutex::new(address), connection_state: AtomicCell::new(ConnectionState::HandShake), connection_reader: Arc::new(Mutex::new(connection_reader)), @@ -198,11 +195,7 @@ impl Client { { self.kick(&error.to_string()).await; } else if let Err(error) = writer.flush().await { - log::warn!( - "Failed to flush writer for id {}: {}", - self.id, - error.to_string() - ); + log::warn!("Failed to flush writer for: {}", error.to_string()); } } @@ -280,7 +273,7 @@ impl Client { &self, packet: &mut RawPacket, ) -> Result<(), DeserializerError> { - log::debug!("Handling handshake group for id {}", self.id); + log::debug!("Handling handshake group"); let bytebuf = &mut packet.bytebuf; match packet.id.0 { 0 => { @@ -301,7 +294,7 @@ impl Client { server: &Arc, packet: &mut RawPacket, ) -> Result<(), DeserializerError> { - log::debug!("Handling status group for id {}", self.id); + log::debug!("Handling status group"); let bytebuf = &mut packet.bytebuf; if let Some(packet) = ServerboundStatusPackets::from_i32(packet.id.0) { match packet { @@ -329,7 +322,7 @@ impl Client { server: &Arc, packet: &mut RawPacket, ) -> Result<(), DeserializerError> { - log::debug!("Handling login group for id {}", self.id); + log::debug!("Handling login group for id"); let bytebuf = &mut packet.bytebuf; if let Some(packet) = ServerboundLoginPackets::from_i32(packet.id.0) { match packet { @@ -366,7 +359,7 @@ impl Client { server: &Arc, packet: &mut RawPacket, ) -> Result<(), DeserializerError> { - log::debug!("Handling config group for id {}", self.id); + log::debug!("Handling config group"); let bytebuf = &mut packet.bytebuf; if let Some(packet) = ServerboundConfigPackets::from_i32(packet.id.0) { #[expect(clippy::match_same_arms)] @@ -414,11 +407,7 @@ impl Client { return true; } Ok(None) => (), //log::debug!("Waiting for more data to complete packet..."), - Err(err) => log::warn!( - "Failed to decode packet for id {}: {}", - self.id, - err.to_string() - ), + Err(err) => log::warn!("Failed to decode packet for: {}", err.to_string()), } dec.reserve(4096); @@ -448,7 +437,7 @@ impl Client { /// Kicks the Client with a reason depending on the connection state pub async fn kick(&self, reason: &str) { - log::info!("Kicking Client id {} for {}", self.id, reason); + log::info!("Kicking Client for {}", reason); match self.connection_state.load() { ConnectionState::Login => { self.try_send_packet(&CLoginDisconnect::new( diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index fc7e29a7d..d0a67557c 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -113,7 +113,7 @@ impl Player { // send new position to all other players world .broadcast_packet_expect( - &[self.client.id], + &[self.gameprofile.id], &CUpdateEntityPos::new( entity_id.into(), x.mul_add(4096.0, -(last_x * 4096.0)) as i16, @@ -186,7 +186,7 @@ impl Player { world .broadcast_packet_expect( - &[self.client.id], + &[self.gameprofile.id], &CUpdateEntityPosRot::new( entity_id.into(), x.mul_add(4096.0, -(last_x * 4096.0)) as i16, @@ -200,7 +200,7 @@ impl Player { .await; world .broadcast_packet_expect( - &[self.client.id], + &[self.gameprofile.id], &CHeadRot::new(entity_id.into(), yaw as u8), ) .await; @@ -230,11 +230,11 @@ impl Player { let packet = CUpdateEntityRot::new(entity_id.into(), yaw as u8, pitch as u8, rotation.ground); world - .broadcast_packet_expect(&[self.client.id], &packet) + .broadcast_packet_expect(&[self.gameprofile.id], &packet) .await; let packet = CHeadRot::new(entity_id.into(), yaw as u8); world - .broadcast_packet_expect(&[self.client.id], &packet) + .broadcast_packet_expect(&[self.gameprofile.id], &packet) .await; } @@ -325,7 +325,7 @@ impl Player { let world = &self.living_entity.entity.world; world .broadcast_packet_expect( - &[self.client.id], + &[self.gameprofile.id], &CEntityAnimation::new(id.into(), animation as u8), ) .await; diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 6dd9e2690..554470dcc 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -157,7 +157,7 @@ impl Player { log::debug!( "Removing player id {}, unwatching {} chunks", - self.client.id, + self.gameprofile.name, all_chunks.len() ); self.living_entity @@ -168,7 +168,7 @@ impl Player { log::debug!( "Removed player id {} ({} chunks remain cached)", - self.client.id, + self.gameprofile.name, self.living_entity.entity.world.get_cached_chunk_len().await ); } diff --git a/pumpkin/src/main.rs b/pumpkin/src/main.rs index 0d8422e88..4b17ef4ea 100644 --- a/pumpkin/src/main.rs +++ b/pumpkin/src/main.rs @@ -171,7 +171,6 @@ async fn main() -> io::Result<()> { ticker.run(&server).await; }); } - let mut player_count = 0; loop { // Asynchronously wait for an inbound socket. let (connection, address) = listener.accept().await?; @@ -180,16 +179,12 @@ async fn main() -> io::Result<()> { log::warn!("failed to set TCP_NODELAY {e}"); } - player_count += 1; - let id = player_count; - log::info!( - "Accepted connection from: {} (id: {})", + "Accepted connection from: {} ", scrub_address(&format!("{address}")), - id ); - let client = Arc::new(Client::new(id, connection, addr)); + let client = Arc::new(Client::new(connection, addr)); let server = server.clone(); tokio::spawn(async move { @@ -207,9 +202,7 @@ async fn main() -> io::Result<()> { .make_player .load(std::sync::atomic::Ordering::Relaxed) { - let id = client.id; - log::debug!("Creating player for id {}", id); - let (player, world) = server.add_player(id, client).await; + let (player, world) = server.add_player(client).await; world.spawn_player(&BASIC_CONFIG, player.clone()).await; // poll Player while !player @@ -226,6 +219,5 @@ async fn main() -> io::Result<()> { server.remove_player().await; } }); - player_count -= 1; } } diff --git a/pumpkin/src/server/mod.rs b/pumpkin/src/server/mod.rs index 854a4959b..00d29dd71 100644 --- a/pumpkin/src/server/mod.rs +++ b/pumpkin/src/server/mod.rs @@ -93,7 +93,7 @@ impl Server { } } - pub async fn add_player(&self, id: usize, client: Arc) -> (Arc, Arc) { + pub async fn add_player(&self, client: Arc) -> (Arc, Arc) { let entity_id = self.new_entity_id(); let gamemode = match BASIC_CONFIG.default_gamemode { GameMode::Undefined => GameMode::Survival, @@ -104,7 +104,9 @@ impl Server { let world = &self.worlds[0]; let player = Arc::new(Player::new(client, world.clone(), entity_id, gamemode).await); - world.add_player(id, player.clone()).await; + world + .add_player(player.gameprofile.id, player.clone()) + .await; // TODO: Config if we want increase online if let Some(config) = player.client.config.lock().await.as_ref() { // TODO: Config so we can also just ignore this hehe diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 95e37ac40..3a8152355 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -42,7 +42,7 @@ pub struct World { /// The underlying level, responsible for chunk management and terrain generation. pub level: Arc>, /// A map of active players within the world, keyed by their unique token. - pub current_players: Arc>>>, + pub current_players: Arc>>>, pub scoreboard: Mutex, // TODO: entities } @@ -77,7 +77,7 @@ impl World { /// Sends the specified packet to every player currently logged in to the server, excluding the players listed in the `except` parameter. /// /// **Note:** This function acquires a lock on the `current_players` map, ensuring thread safety. - pub async fn broadcast_packet_expect

(&self, except: &[usize], packet: &P) + pub async fn broadcast_packet_expect

(&self, except: &[uuid::Uuid], packet: &P) where P: ClientPacket, { @@ -100,11 +100,10 @@ impl World { let gamemode = player.gamemode.load(); log::debug!( "spawning player {}, entity id {}", - player.client.id, + player.gameprofile.name, entity_id ); - log::debug!("Sending login packet to {}", player.client.id); // login packet for our new player player .client @@ -134,7 +133,7 @@ impl World { // player abilities // TODO: this is for debug purpose, remove later - log::debug!("Sending player abilities to {}", player.client.id); + log::debug!("Sending player abilities to {}", player.gameprofile.name); player .client .send_packet(&CPlayerAbilities::new(0x02, 0.4, 0.1)) @@ -145,7 +144,7 @@ impl World { let yaw = 10.0; let pitch = 10.0; - log::debug!("Sending player teleport to {}", player.client.id); + log::debug!("Sending player teleport to {}", player.gameprofile.name); player.teleport(position, yaw, pitch).await; let pos = player.living_entity.entity.pos.load(); @@ -154,7 +153,7 @@ impl World { let gameprofile = &player.gameprofile; // first send info update to our new player, So he can see his Skin // also send his info to everyone else - log::debug!("Broadcasting player info for {}", player.client.id); + log::debug!("Broadcasting player info for {}", player.gameprofile.name); self.broadcast_packet_all(&CPlayerInfoUpdate::new( 0x01 | 0x08, &[pumpkin_protocol::client::play::Player { @@ -176,7 +175,7 @@ impl World { let current_players = self.current_players.lock().await; for (_, playerr) in current_players .iter() - .filter(|(c, _)| **c != player.client.id) + .filter(|(c, _)| **c != player.gameprofile.id) { let gameprofile = &playerr.gameprofile; entries.push(pumpkin_protocol::client::play::Player { @@ -190,7 +189,7 @@ impl World { ], }); } - log::debug!("Sending player info to {}", player.client.id); + log::debug!("Sending player info to {}", player.gameprofile.name); player .client .send_packet(&CPlayerInfoUpdate::new(0x01 | 0x08, &entries)) @@ -199,10 +198,10 @@ impl World { let gameprofile = &player.gameprofile; - log::debug!("Broadcasting player spawn for {}", player.client.id); + log::debug!("Broadcasting player spawn for {}", player.gameprofile.name); // spawn player for every client self.broadcast_packet_expect( - &[player.client.id], + &[player.gameprofile.id], // TODO: add velo &CSpawnEntity::new( entity_id.into(), @@ -222,18 +221,18 @@ impl World { ) .await; // spawn players for our client - let token = player.client.id; + let id = player.gameprofile.id; for (_, existing_player) in self .current_players .lock() .await .iter() - .filter(|c| c.0 != &token) + .filter(|c| c.0 != &id) { let entity = &existing_player.living_entity.entity; let pos = entity.pos.load(); let gameprofile = &existing_player.gameprofile; - log::debug!("Sending player entities to {}", player.client.id); + log::debug!("Sending player entities to {}", player.gameprofile.name); player .client .send_packet(&CSpawnEntity::new( @@ -260,12 +259,12 @@ impl World { entity_id.into(), Metadata::new(17, VarInt(0), config.skin_parts), ); - log::debug!("Broadcasting skin for {}", player.client.id); + log::debug!("Broadcasting skin for {}", player.gameprofile.name); self.broadcast_packet_all(&packet).await; } // Start waiting for level chunks, Sets the "Loading Terrain" screen - log::debug!("Sending waiting chunks to {}", player.client.id); + log::debug!("Sending waiting chunks to {}", player.gameprofile.name); player .client .send_packet(&CGameEvent::new(GameEvent::StartWaitingChunks, 0.0)) @@ -292,10 +291,7 @@ impl World { fn spawn_world_chunks(&self, client: Arc, chunks: Vec>) { if client.closed.load(std::sync::atomic::Ordering::Relaxed) { - log::info!( - "The connection with {} has closed before world chunks were spawned", - client.id - ); + log::info!("The connection has closed before world chunks were spawned",); return; } let inst = std::time::Instant::now(); @@ -351,19 +347,19 @@ impl World { None } - pub async fn add_player(&self, id: usize, player: Arc) { - self.current_players.lock().await.insert(id, player); + pub async fn add_player(&self, uuid: uuid::Uuid, player: Arc) { + self.current_players.lock().await.insert(uuid, player); } pub async fn remove_player(&self, player: &Player) { self.current_players .lock() .await - .remove(&player.client.id) + .remove(&player.gameprofile.id) .unwrap(); let uuid = player.gameprofile.id; self.broadcast_packet_expect( - &[player.client.id], + &[player.gameprofile.id], &CRemovePlayerInfo::new(1.into(), &[uuid]), ) .await; diff --git a/pumpkin/src/world/player_chunker.rs b/pumpkin/src/world/player_chunker.rs index e42f520a5..77e6272ab 100644 --- a/pumpkin/src/world/player_chunker.rs +++ b/pumpkin/src/world/player_chunker.rs @@ -28,7 +28,7 @@ pub async fn player_join(world: &World, player: Arc) { assert_eq!(new_watched.x, chunk_pos.x); assert_eq!(new_watched.z, chunk_pos.z); - log::debug!("Sending center chunk to {}", player.client.id); + log::debug!("Sending center chunk to {}", player.gameprofile.name); player .client .send_packet(&CCenterChunk { @@ -40,7 +40,7 @@ pub async fn player_join(world: &World, player: Arc) { log::debug!( "Player {} ({}) joined with view distance: {}", player.gameprofile.name, - player.client.id, + player.gameprofile.name, view_distance );