Implement the player sample (#47)

Verify that it works by hovering your mouse over the player count in the
cow_sphere example.
This commit is contained in:
Ryan Johnson 2022-09-10 16:02:12 -07:00 committed by GitHub
parent 49fdeb6be4
commit ca4f47c768
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 48 additions and 10 deletions

View file

@ -41,7 +41,7 @@ sha1 = "0.10"
sha2 = "0.10" sha2 = "0.10"
thiserror = "1" thiserror = "1"
url = { version = "2.2.2", features = ["serde"] } url = { version = "2.2.2", features = ["serde"] }
uuid = "1" uuid = { version = "1", features = ["serde"] }
vek = "0.15" vek = "0.15"
[dependencies.tokio] [dependencies.tokio]

View file

@ -78,8 +78,9 @@ impl Config for Game {
ServerListPing::Respond { ServerListPing::Respond {
online_players: self.player_count.load(Ordering::SeqCst) as i32, online_players: self.player_count.load(Ordering::SeqCst) as i32,
max_players: MAX_PLAYERS as i32, max_players: MAX_PLAYERS as i32,
player_sample: Default::default(),
description: "Hello Valence!".color(Color::AQUA), 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()),
} }
} }

View file

@ -99,8 +99,9 @@ impl Config for Game {
ServerListPing::Respond { ServerListPing::Respond {
online_players: self.player_count.load(Ordering::SeqCst) as i32, online_players: self.player_count.load(Ordering::SeqCst) as i32,
max_players: MAX_PLAYERS as i32, max_players: MAX_PLAYERS as i32,
player_sample: Default::default(),
description: "Hello Valence!".color(Color::AQUA), 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()),
} }
} }

View file

@ -1,13 +1,15 @@
use std::borrow::Cow;
use std::f64::consts::TAU; use std::f64::consts::TAU;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use log::LevelFilter; use log::LevelFilter;
use uuid::Uuid;
use valence::async_trait; use valence::async_trait;
use valence::block::{BlockPos, BlockState}; use valence::block::{BlockPos, BlockState};
use valence::chunk::UnloadedChunk; use valence::chunk::UnloadedChunk;
use valence::client::{default_client_event, GameMode}; use valence::client::{default_client_event, GameMode};
use valence::config::{Config, ServerListPing}; use valence::config::{Config, PlayerSampleEntry, ServerListPing};
use valence::dimension::DimensionId; use valence::dimension::DimensionId;
use valence::entity::{EntityId, EntityKind}; use valence::entity::{EntityId, EntityKind};
use valence::player_list::PlayerListId; use valence::player_list::PlayerListId;
@ -66,11 +68,23 @@ impl Config for Game {
_remote_addr: SocketAddr, _remote_addr: SocketAddr,
_protocol_version: i32, _protocol_version: i32,
) -> ServerListPing { ) -> 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 { ServerListPing::Respond {
online_players: self.player_count.load(Ordering::SeqCst) as i32, online_players: self.player_count.load(Ordering::SeqCst) as i32,
max_players: MAX_PLAYERS as i32, max_players: MAX_PLAYERS as i32,
player_sample: SAMPLE.into(),
description: "Hello Valence!".color(Color::AQUA), 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()),
} }
} }

View file

@ -67,8 +67,9 @@ impl Config for Game {
ServerListPing::Respond { ServerListPing::Respond {
online_players: self.player_count.load(Ordering::SeqCst) as i32, online_players: self.player_count.load(Ordering::SeqCst) as i32,
max_players: MAX_PLAYERS as i32, max_players: MAX_PLAYERS as i32,
player_sample: Default::default(),
description: "Hello Valence!".color(Color::AQUA), 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()),
} }
} }

View file

@ -73,8 +73,9 @@ impl Config for Game {
ServerListPing::Respond { ServerListPing::Respond {
online_players: self.player_count.load(Ordering::SeqCst) as i32, online_players: self.player_count.load(Ordering::SeqCst) as i32,
max_players: MAX_PLAYERS as i32, max_players: MAX_PLAYERS as i32,
player_sample: Default::default(),
description: "Hello Valence!".color(Color::AQUA), 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()),
} }
} }

View file

@ -1,10 +1,13 @@
//! Configuration for the server. //! Configuration for the server.
use std::borrow::Cow;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::panic::{RefUnwindSafe, UnwindSafe}; use std::panic::{RefUnwindSafe, UnwindSafe};
use async_trait::async_trait; use async_trait::async_trait;
use serde::Serialize;
use tokio::runtime::Handle as TokioHandle; use tokio::runtime::Handle as TokioHandle;
use uuid::Uuid;
use crate::biome::Biome; use crate::biome::Biome;
use crate::dimension::Dimension; 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. /// The result of the [`server_list_ping`](Config::server_list_ping) callback.
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Debug)] #[derive(Clone, Debug)]
pub enum ServerListPing<'a> { pub enum ServerListPing<'a> {
/// Responds to the server list ping with the given information. /// Responds to the server list ping with the given information.
Respond { Respond {
@ -238,14 +241,30 @@ pub enum ServerListPing<'a> {
/// Displayed as the maximum number of players allowed on the server at /// Displayed as the maximum number of players allowed on the server at
/// a time. /// a time.
max_players: i32, 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. /// A description of the server.
description: Text, description: Text,
/// The server's icon as the bytes of a PNG image. /// The server's icon as the bytes of a PNG image.
/// The image must be 64x64 pixels. /// The image must be 64x64 pixels.
/// ///
/// No icon is used if the value is `None`. /// No icon is used if the value is `None`.
favicon_png: Option<&'a [u8]>, favicon_png: Option<Cow<'a, [u8]>>,
}, },
/// Ignores the query and disconnects from the client. /// Ignores the query and disconnects from the client.
Ignore, 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,
}

View file

@ -584,6 +584,7 @@ async fn handle_status<C: Config>(
ServerListPing::Respond { ServerListPing::Respond {
online_players, online_players,
max_players, max_players,
player_sample,
description, description,
favicon_png, favicon_png,
} => { } => {
@ -595,7 +596,7 @@ async fn handle_status<C: Config>(
"players": { "players": {
"online": online_players, "online": online_players,
"max": max_players, "max": max_players,
// TODO: player sample? "sample": player_sample,
}, },
"description": description, "description": description,
}); });