Skip to content

Commit

Permalink
Add player join and quit messages. (#192)
Browse files Browse the repository at this point in the history
* pumpkin: Add player join and quit messages.

This implementation will send a 'joined the game' and 'left the game'
message akin to the vanilla server when a player joins or disconnects
respectively.

One caveat with this implementation is that it only broadcasts the
join/quit messages to players in the same world, unlike the vanilla
server, which broadcasts it to all online players (regardless of their
world).

I discussed this with Alex who suggested to keep it as per-world
(seemingly for now?) - [Discord conversation](https://discord.com/channels/1268592337445978193/1268611318617866261/1299668206734147597).

Regardless, this implementation works perfectly on my end. (yes, it has been tested)

* pumpkin: added logs for join/quit

* Move disconnect message code to world from player

Compiles and runs, sends join and quit messages in console with no
errors.

* Move join message from server to world
  • Loading branch information
lokka30 authored Oct 27, 2024
1 parent a6f3b3f commit 1a1a7e3
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
17 changes: 6 additions & 11 deletions pumpkin/src/entity/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ impl Player {
/// Removes the Player out of the current World
#[allow(unused_variables)]
pub async fn remove(&self) {
self.living_entity.entity.world.remove_player(self).await;
let world = &self.living_entity.entity.world;

world.remove_player(self).await;

let watched = self.watched_section.load();
let view_distance = i32::from(get_view_distance(self).await);
Expand Down Expand Up @@ -254,20 +256,13 @@ impl Player {
log::debug!("Done waiting for chunk batches");

// Decrement value of watched chunks
let chunks_to_clean = self
.living_entity
.entity
.world
.mark_chunks_as_not_watched(&watched_chunks);
let chunks_to_clean = world.mark_chunks_as_not_watched(&watched_chunks);

// Remove chunks with no watchers from the cache
self.living_entity
.entity
.world
.clean_chunks(&chunks_to_clean);
world.clean_chunks(&chunks_to_clean);

// Remove left over entries from all possiblily loaded chunks
self.living_entity.entity.world.clean_memory(&radial_chunks);
world.clean_memory(&radial_chunks);

log::debug!(
"Removed player id {} ({}) ({} chunks remain cached)",
Expand Down
1 change: 1 addition & 0 deletions pumpkin/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl Server {
self.server_listing.lock().await.add_player();
}
}

(player, world.clone())
}

Expand Down
23 changes: 22 additions & 1 deletion pumpkin/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use num_traits::ToPrimitive;
use pumpkin_config::BasicConfiguration;
use pumpkin_core::math::vector2::Vector2;
use pumpkin_core::math::{position::WorldPosition, vector3::Vector3};
use pumpkin_core::text::{color::NamedColor, TextComponent};
use pumpkin_entity::{entity_type::EntityType, EntityId};
use pumpkin_protocol::{
client::play::{CBlockUpdate, CSoundEffect, CWorldEvent},
Expand Down Expand Up @@ -482,7 +483,18 @@ impl World {
}

pub async fn add_player(&self, uuid: uuid::Uuid, player: Arc<Player>) {
self.current_players.lock().await.insert(uuid, player);
self.current_players
.lock()
.await
.insert(uuid, player.clone());

// Handle join message
let msg_txt = format!("{} joined the game.", player.gameprofile.name.as_str());
let msg_comp = TextComponent::text(msg_txt.as_str()).color_named(NamedColor::Yellow);
for player in self.current_players.lock().await.values() {
player.send_system_message(&msg_comp).await;
}
log::info!("{}", msg_comp.to_pretty_console());
}

pub async fn remove_player(&self, player: &Player) {
Expand All @@ -498,6 +510,15 @@ impl World {
)
.await;
self.remove_entity(&player.living_entity.entity).await;

// Send disconnect message / quit message to players in the same world
let disconn_msg_txt = format!("{} left the game.", player.gameprofile.name.as_str());
let disconn_msg_cmp =
TextComponent::text(disconn_msg_txt.as_str()).color_named(NamedColor::Yellow);
for player in self.current_players.lock().await.values() {
player.send_system_message(&disconn_msg_cmp).await;
}
log::info!("{}", disconn_msg_cmp.to_pretty_console());
}

pub async fn remove_entity(&self, entity: &Entity) {
Expand Down

0 comments on commit 1a1a7e3

Please sign in to comment.