From ca4f47c768cea595fcbbf463c48dd39bb71d684c Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Sat, 10 Sep 2022 16:02:12 -0700 Subject: [PATCH] Implement the player sample (#47) Verify that it works by hovering your mouse over the player count in the cow_sphere example. --- Cargo.toml | 2 +- examples/combat.rs | 3 ++- examples/conway.rs | 3 ++- examples/cow_sphere.rs | 18 ++++++++++++++++-- examples/raycast.rs | 3 ++- examples/terrain.rs | 3 ++- src/config.rs | 23 +++++++++++++++++++++-- src/server.rs | 3 ++- 8 files changed, 48 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 95c7ea9..9a2a790 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ sha1 = "0.10" sha2 = "0.10" thiserror = "1" url = { version = "2.2.2", features = ["serde"] } -uuid = "1" +uuid = { version = "1", features = ["serde"] } vek = "0.15" [dependencies.tokio] diff --git a/examples/combat.rs b/examples/combat.rs index 8fc59a6..a19074a 100644 --- a/examples/combat.rs +++ b/examples/combat.rs @@ -78,8 +78,9 @@ impl Config for Game { ServerListPing::Respond { online_players: self.player_count.load(Ordering::SeqCst) as i32, max_players: MAX_PLAYERS as i32, + player_sample: Default::default(), description: "Hello Valence!".color(Color::AQUA), - favicon_png: Some(include_bytes!("../assets/favicon.png")), + favicon_png: Some(include_bytes!("../assets/favicon.png").as_slice().into()), } } diff --git a/examples/conway.rs b/examples/conway.rs index 0e9e20f..e3bcda7 100644 --- a/examples/conway.rs +++ b/examples/conway.rs @@ -99,8 +99,9 @@ impl Config for Game { ServerListPing::Respond { online_players: self.player_count.load(Ordering::SeqCst) as i32, max_players: MAX_PLAYERS as i32, + player_sample: Default::default(), description: "Hello Valence!".color(Color::AQUA), - favicon_png: Some(include_bytes!("../assets/favicon.png")), + favicon_png: Some(include_bytes!("../assets/favicon.png").as_slice().into()), } } diff --git a/examples/cow_sphere.rs b/examples/cow_sphere.rs index a3c9527..d009f33 100644 --- a/examples/cow_sphere.rs +++ b/examples/cow_sphere.rs @@ -1,13 +1,15 @@ +use std::borrow::Cow; use std::f64::consts::TAU; use std::net::SocketAddr; use std::sync::atomic::{AtomicUsize, Ordering}; use log::LevelFilter; +use uuid::Uuid; use valence::async_trait; use valence::block::{BlockPos, BlockState}; use valence::chunk::UnloadedChunk; use valence::client::{default_client_event, GameMode}; -use valence::config::{Config, ServerListPing}; +use valence::config::{Config, PlayerSampleEntry, ServerListPing}; use valence::dimension::DimensionId; use valence::entity::{EntityId, EntityKind}; use valence::player_list::PlayerListId; @@ -66,11 +68,23 @@ impl Config for Game { _remote_addr: SocketAddr, _protocol_version: i32, ) -> ServerListPing { + const SAMPLE: &[PlayerSampleEntry] = &[ + PlayerSampleEntry { + name: Cow::Borrowed("§cFirst Entry"), + id: Uuid::nil(), + }, + PlayerSampleEntry { + name: Cow::Borrowed("§6§oSecond Entry"), + id: Uuid::nil(), + }, + ]; + ServerListPing::Respond { online_players: self.player_count.load(Ordering::SeqCst) as i32, max_players: MAX_PLAYERS as i32, + player_sample: SAMPLE.into(), description: "Hello Valence!".color(Color::AQUA), - favicon_png: Some(include_bytes!("../assets/favicon.png")), + favicon_png: Some(include_bytes!("../assets/favicon.png").as_slice().into()), } } diff --git a/examples/raycast.rs b/examples/raycast.rs index 8b42986..42069c6 100644 --- a/examples/raycast.rs +++ b/examples/raycast.rs @@ -67,8 +67,9 @@ impl Config for Game { ServerListPing::Respond { online_players: self.player_count.load(Ordering::SeqCst) as i32, max_players: MAX_PLAYERS as i32, + player_sample: Default::default(), description: "Hello Valence!".color(Color::AQUA), - favicon_png: Some(include_bytes!("../assets/favicon.png")), + favicon_png: Some(include_bytes!("../assets/favicon.png").as_slice().into()), } } diff --git a/examples/terrain.rs b/examples/terrain.rs index 8d109a1..905ed30 100644 --- a/examples/terrain.rs +++ b/examples/terrain.rs @@ -73,8 +73,9 @@ impl Config for Game { ServerListPing::Respond { online_players: self.player_count.load(Ordering::SeqCst) as i32, max_players: MAX_PLAYERS as i32, + player_sample: Default::default(), description: "Hello Valence!".color(Color::AQUA), - favicon_png: Some(include_bytes!("../assets/favicon.png")), + favicon_png: Some(include_bytes!("../assets/favicon.png").as_slice().into()), } } diff --git a/src/config.rs b/src/config.rs index 6705321..72a6e64 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,10 +1,13 @@ //! Configuration for the server. +use std::borrow::Cow; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::panic::{RefUnwindSafe, UnwindSafe}; use async_trait::async_trait; +use serde::Serialize; use tokio::runtime::Handle as TokioHandle; +use uuid::Uuid; use crate::biome::Biome; use crate::dimension::Dimension; @@ -229,7 +232,7 @@ pub trait Config: Sized + Send + Sync + UnwindSafe + RefUnwindSafe + 'static { /// The result of the [`server_list_ping`](Config::server_list_ping) callback. #[allow(clippy::large_enum_variant)] -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum ServerListPing<'a> { /// Responds to the server list ping with the given information. Respond { @@ -238,14 +241,30 @@ pub enum ServerListPing<'a> { /// Displayed as the maximum number of players allowed on the server at /// a time. max_players: i32, + /// The list of players visible by hovering over the player count. + /// + /// Has no effect if this list is empty. + player_sample: Cow<'a, [PlayerSampleEntry<'a>]>, /// A description of the server. description: Text, /// The server's icon as the bytes of a PNG image. /// The image must be 64x64 pixels. /// /// No icon is used if the value is `None`. - favicon_png: Option<&'a [u8]>, + favicon_png: Option>, }, /// Ignores the query and disconnects from the client. Ignore, } + +/// Represents an individual entry in the player sample. +#[derive(Clone, Debug, Serialize)] +pub struct PlayerSampleEntry<'a> { + /// The name of the player. + /// + /// This string can contain + /// [legacy formatting codes](https://minecraft.fandom.com/wiki/Formatting_codes). + pub name: Cow<'a, str>, + /// The player UUID. + pub id: Uuid, +} diff --git a/src/server.rs b/src/server.rs index 33c4a83..af605b1 100644 --- a/src/server.rs +++ b/src/server.rs @@ -584,6 +584,7 @@ async fn handle_status( ServerListPing::Respond { online_players, max_players, + player_sample, description, favicon_png, } => { @@ -595,7 +596,7 @@ async fn handle_status( "players": { "online": online_players, "max": max_players, - // TODO: player sample? + "sample": player_sample, }, "description": description, });