Change update_duration to tick_rate and tweak favicon_png.

This commit is contained in:
Ryan 2022-04-30 18:01:41 -07:00
parent a0892faa72
commit 27e818d6cd
5 changed files with 34 additions and 58 deletions

View file

@ -1,6 +1,5 @@
use std::net::SocketAddr;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use log::LevelFilter;
use valence::client::GameMode;
@ -17,13 +16,11 @@ pub fn main() -> ShutdownResult {
.init();
valence::start_server(Game {
favicon: Arc::from(include_bytes!("favicon.png").as_slice()),
player_count: AtomicUsize::new(0),
})
}
struct Game {
favicon: Arc<[u8]>,
player_count: AtomicUsize,
}
@ -102,7 +99,7 @@ impl Config for Game {
online_players: self.player_count.load(Ordering::SeqCst) as i32,
max_players: MAX_PLAYERS as i32,
description: "Hello Valence!".color(Color::AQUA),
favicon_png: Some(self.favicon.clone()),
favicon_png: Some(include_bytes!("favicon.png")),
}
}

View file

@ -27,8 +27,8 @@ use crate::util::{chunks_in_view_distance, is_chunk_in_view_distance};
use crate::var_int::VarInt;
use crate::world::WorldId;
use crate::{
glm, ident, ChunkPos, ChunkStore, EntityId, EntityStore, Server, SharedServer, Text, Ticks,
WorldStore, LIBRARY_NAMESPACE,
glm, ident, ChunkPos, ChunkStore, EntityId, EntityStore, Server, Text, Ticks, WorldStore,
LIBRARY_NAMESPACE,
};
pub struct ClientStore {
@ -386,7 +386,7 @@ impl Client {
}
// Check if it's time to send another keepalive.
if other.last_keepalive == other.tick_start() {
if other.current_tick() % (other.tick_rate() * 8) == 0 {
if self.got_keepalive {
let id = rand::random();
self.send_packet(KeepAliveClientbound { id });

View file

@ -1,13 +1,11 @@
use std::any::Any;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::sync::Arc;
use std::time::Duration;
use async_trait::async_trait;
use tokio::runtime::Handle as TokioHandle;
use crate::{ident, Id, Identifier, NewClientData, Server, SharedServer, Text};
use crate::{ident, Id, Identifier, NewClientData, Server, SharedServer, Text, Ticks};
/// A trait containing callbacks which are invoked by the running Minecraft
/// server.
@ -41,20 +39,19 @@ pub trait Config: Any + Send + Sync + UnwindSafe + RefUnwindSafe {
SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 25565).into()
}
/// Called once at startup to get the duration of each game update.
/// Called once at startup to get the tick rate, which is the number of game
/// updates that should occur in one second.
///
/// On each game update (a.k.a. tick), the server is expected to update game
/// logic and respond to packets from clients. Once this is complete,
/// the server will sleep for any remaining time until the full update
/// duration has passed.
/// On each game update (tick), the server is expected to update game logic
/// and respond to packets from clients. Once this is complete, the server
/// will sleep for any remaining time until a full tick has passed.
///
/// The duration must be nonzero.
/// The tick rate must be greater than zero.
///
/// # Default Implementation
/// Returns 1/20th of a second, which is the same as Minecraft's official
/// server.
fn update_duration(&self) -> Duration {
Duration::from_secs_f64(1.0 / 20.0)
/// Returns `20`, which is the same as Minecraft's official server.
fn tick_rate(&self) -> Ticks {
20
}
/// Called once at startup to get the "online mode" option, which determines
@ -200,7 +197,7 @@ pub trait Config: Any + Send + Sync + UnwindSafe + RefUnwindSafe {
/// The result of the [`server_list_ping`](Handler::server_list_ping) callback.
#[derive(Debug)]
pub enum ServerListPing {
pub enum ServerListPing<'a> {
/// Responds to the server list ping with the given information.
Respond {
online_players: i32,
@ -210,7 +207,7 @@ pub enum ServerListPing {
/// The image must be 64x64 pixels.
///
/// No icon is used if the value is `None`.
favicon_png: Option<Arc<[u8]>>,
favicon_png: Option<&'a [u8]>,
},
/// Ignores the query and disconnects from the client.
Ignore,

View file

@ -67,8 +67,6 @@ pub struct Other {
tick_counter: Ticks,
/// The instant the current game tick began.
tick_start: Instant,
/// The time the last keep alive packet was sent to all players.
pub(crate) last_keepalive: Instant,
}
/// A server handle providing the subset of functionality which can be performed
@ -80,7 +78,7 @@ pub struct SharedServer(Arc<SharedServerInner>);
struct SharedServerInner {
cfg: Box<dyn Config>,
address: SocketAddr,
update_duration: Duration,
tick_rate: Ticks,
online_mode: bool,
max_connections: usize,
incoming_packet_capacity: usize,
@ -153,8 +151,8 @@ impl SharedServer {
self.0.address
}
pub fn update_duration(&self) -> Duration {
self.0.update_duration
pub fn tick_rate(&self) -> Ticks {
self.0.tick_rate
}
pub fn online_mode(&self) -> bool {
@ -277,12 +275,9 @@ pub fn start_server(config: impl Config) -> ShutdownResult {
fn setup_server(cfg: impl Config) -> anyhow::Result<Server> {
let max_connections = cfg.max_connections();
let address = cfg.address();
let update_duration = cfg.update_duration();
let tick_rate = cfg.tick_rate();
ensure!(
update_duration != Duration::ZERO,
"update duration must be nonzero"
);
ensure!(tick_rate > 0, "tick rate must be greater than zero");
let online_mode = cfg.online_mode();
@ -380,7 +375,7 @@ fn setup_server(cfg: impl Config) -> anyhow::Result<Server> {
let shared = SharedServer(Arc::new(SharedServerInner {
cfg: Box::new(cfg),
address,
update_duration,
tick_rate,
online_mode,
max_connections,
outgoing_packet_capacity,
@ -408,7 +403,6 @@ fn setup_server(cfg: impl Config) -> anyhow::Result<Server> {
tick_counter: 0,
tick_start: Instant::now(),
new_players_rx,
last_keepalive: Instant::now(),
},
})
}
@ -426,21 +420,14 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult {
join_player(server, msg);
}
const KEEPALIVE_FREQ: Duration = Duration::from_secs(8);
if server.tick_start().duration_since(server.last_keepalive) >= KEEPALIVE_FREQ {
server.last_keepalive = server.tick_start();
}
{
server.clients.par_iter_mut().for_each(|(_, client)| {
client.update(
&server.entities,
&server.worlds,
&server.chunks,
&server.other,
)
});
}
server.clients.par_iter_mut().for_each(|(_, client)| {
client.update(
&server.entities,
&server.worlds,
&server.chunks,
&server.other,
)
});
server.entities.update();
@ -451,7 +438,7 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult {
shared.config().update(server);
// Chunks modified this tick can have their changes applied immediately because
// Chunks created this tick can have their changes applied immediately because
// they have not been observed by clients yet.
server.chunks.par_iter_mut().for_each(|(_, chunk)| {
if chunk.created_this_tick() {
@ -461,14 +448,10 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult {
});
// Sleep for the remainder of the tick.
thread::sleep(
server
.0
.update_duration
.saturating_sub(server.tick_start.elapsed()),
);
server.tick_start = Instant::now();
let tick_duration = Duration::from_secs_f64((server.0.tick_rate as f64).recip());
thread::sleep(tick_duration.saturating_sub(server.tick_start.elapsed()));
server.tick_start = Instant::now();
server.tick_counter += 1;
}
}

View file

@ -59,7 +59,6 @@ impl<T> SlotMap<T> {
pub fn insert(&mut self, val: T) -> Key {
assert!(
// -1 so that NULL is always invalid.
self.count < u32::MAX,
"SlotMap: too many items inserted"
);