Skip to content

Commit

Permalink
Server list ping callback improvements (#408)
Browse files Browse the repository at this point in the history
# Objective

- Improve the server list ping callback to make it more customizable and
powerful.

# Solution

- Pass all handshake data (except for `next_state` which is always
`status`) to the callback instead of just protocol version.
- Allow the callback to set the version name and protocol of the
response.
  • Loading branch information
PonasKovas authored Jul 13, 2023
1 parent a5101ce commit 32bd4dd
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 19 deletions.
30 changes: 20 additions & 10 deletions crates/valence_network/src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use valence_core::protocol::raw::RawBytes;
use valence_core::protocol::var_int::VarInt;
use valence_core::protocol::Decode;
use valence_core::text::Text;
use valence_core::{ident, translation_key, MINECRAFT_VERSION, PROTOCOL_VERSION};
use valence_core::{ident, translation_key, PROTOCOL_VERSION};

use crate::legacy_ping::try_handle_legacy_ping;
use crate::packet::{
Expand Down Expand Up @@ -110,10 +110,16 @@ async fn handle_connection(
}
}

struct HandshakeData {
protocol_version: i32,
server_address: String,
next_state: HandshakeNextState,
/// Basic information about a client, provided at the beginning of the
/// connection
#[derive(Default, Debug)]
pub struct HandshakeData {
/// The protocol version of the client.
pub protocol_version: i32,
/// The address that the client used to connect.
pub server_address: String,
/// The port that the client used to connect.
pub server_port: u16,
}

async fn handle_handshake(
Expand All @@ -123,10 +129,12 @@ async fn handle_handshake(
) -> anyhow::Result<()> {
let handshake = io.recv_packet::<HandshakeC2s>().await?;

let next_state = handshake.next_state;

let handshake = HandshakeData {
protocol_version: handshake.protocol_version.0,
server_address: handshake.server_address.to_owned(),
next_state: handshake.next_state,
server_port: handshake.server_port,
};

ensure!(
Expand All @@ -135,7 +143,7 @@ async fn handle_handshake(
"handshake server address is too long"
);

match handshake.next_state {
match next_state {
HandshakeNextState::Status => handle_status(shared, io, remote_addr, handshake)
.await
.context("error handling status"),
Expand Down Expand Up @@ -174,7 +182,7 @@ async fn handle_status(
.0
.callbacks
.inner
.server_list_ping(&shared, remote_addr, handshake.protocol_version)
.server_list_ping(&shared, remote_addr, &handshake)
.await
{
ServerListPing::Respond {
Expand All @@ -183,11 +191,13 @@ async fn handle_status(
player_sample,
description,
favicon_png,
version_name,
protocol,
} => {
let mut json = json!({
"version": {
"name": MINECRAFT_VERSION,
"protocol": PROTOCOL_VERSION
"name": version_name,
"protocol": protocol,
},
"players": {
"online": online_players,
Expand Down
38 changes: 31 additions & 7 deletions crates/valence_network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub use async_trait::async_trait;
use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use connect::do_accept_loop;
pub use connect::HandshakeData;
use flume::{Receiver, Sender};
pub use legacy_ping::{ServerListLegacyPingPayload, ServerListLegacyPingResponse};
use rand::rngs::OsRng;
Expand Down Expand Up @@ -336,7 +337,7 @@ pub trait NetworkCallbacks: Send + Sync + 'static {
&self,
shared: &SharedNetworkState,
remote_addr: SocketAddr,
protocol_version: i32,
handshake_data: &HandshakeData,
) -> ServerListPing {
#![allow(unused_variables)]

Expand All @@ -346,6 +347,8 @@ pub trait NetworkCallbacks: Send + Sync + 'static {
player_sample: vec![],
description: "A Valence Server".into(),
favicon_png: &[],
version_name: MINECRAFT_VERSION.to_owned(),
protocol: PROTOCOL_VERSION,
}
}

Expand All @@ -365,21 +368,34 @@ pub trait NetworkCallbacks: Send + Sync + 'static {
) -> ServerListLegacyPing {
#![allow(unused_variables)]

let protocol = match payload {
ServerListLegacyPingPayload::Pre1_7 { protocol, .. } => protocol,
_ => 0,
let handshake_data = match payload {
ServerListLegacyPingPayload::Pre1_7 {
protocol,
hostname,
port,
} => HandshakeData {
protocol_version: protocol,
server_address: hostname,
server_port: port,
},
_ => HandshakeData::default(),
};

match self.server_list_ping(shared, remote_addr, protocol).await {
match self
.server_list_ping(shared, remote_addr, &handshake_data)
.await
{
ServerListPing::Respond {
online_players,
max_players,
player_sample,
description,
favicon_png,
version_name,
protocol,
} => ServerListLegacyPing::Respond(
ServerListLegacyPingResponse::new(PROTOCOL_VERSION, online_players, max_players)
.version(format!("§dValence §5{MINECRAFT_VERSION}"))
ServerListLegacyPingResponse::new(protocol, online_players, max_players)
.version(version_name)
.description(description.to_legacy_lossy()),
),
ServerListPing::Ignore => ServerListLegacyPing::Ignore,
Expand Down Expand Up @@ -598,6 +614,14 @@ pub enum ServerListPing<'a> {
///
/// No icon is used if the slice is empty.
favicon_png: &'a [u8],
/// The version name of the server. Displayed when client is using a
/// different protocol.
///
/// Can be formatted using `§` and format codes. Or use
/// [`valence_core::text::Text::to_legacy_lossy`].
version_name: String,
/// The protocol version of the server.
protocol: i32,
},
/// Ignores the query and disconnects from the client.
#[default]
Expand Down
9 changes: 7 additions & 2 deletions examples/server_list_ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use valence::network::{
async_trait, BroadcastToLan, CleanupFn, ConnectionMode, PlayerSampleEntry, ServerListPing,
};
use valence::prelude::*;
use valence_core::MINECRAFT_VERSION;
use valence_network::HandshakeData;

pub fn main() {
App::new()
Expand All @@ -27,7 +29,7 @@ impl NetworkCallbacks for MyCallbacks {
&self,
_shared: &SharedNetworkState,
remote_addr: SocketAddr,
_protocol_version: i32,
handshake_data: &HandshakeData,
) -> ServerListPing {
let max_players = 420;

Expand All @@ -39,8 +41,11 @@ impl NetworkCallbacks for MyCallbacks {
id: Uuid::from_u128(12345),
}],
description: "Your IP address is ".into_text()
+ remote_addr.to_string().color(Color::GOLD),
+ remote_addr.to_string().color(Color::DARK_GRAY),
favicon_png: include_bytes!("../assets/logo-64x64.png"),
version_name: ("Valence ".color(Color::GOLD) + MINECRAFT_VERSION.color(Color::RED))
.to_legacy_lossy(),
protocol: handshake_data.protocol_version,
}
}

Expand Down

0 comments on commit 32bd4dd

Please sign in to comment.