mirror of
https://github.com/italicsjenga/valence.git
synced 2024-12-23 22:41:30 +11:00
Change update_duration to tick_rate and tweak favicon_png.
This commit is contained in:
parent
a0892faa72
commit
27e818d6cd
|
@ -1,6 +1,5 @@
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use valence::client::GameMode;
|
use valence::client::GameMode;
|
||||||
|
@ -17,13 +16,11 @@ pub fn main() -> ShutdownResult {
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
valence::start_server(Game {
|
valence::start_server(Game {
|
||||||
favicon: Arc::from(include_bytes!("favicon.png").as_slice()),
|
|
||||||
player_count: AtomicUsize::new(0),
|
player_count: AtomicUsize::new(0),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Game {
|
struct Game {
|
||||||
favicon: Arc<[u8]>,
|
|
||||||
player_count: AtomicUsize,
|
player_count: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +99,7 @@ impl Config for Game {
|
||||||
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,
|
||||||
description: "Hello Valence!".color(Color::AQUA),
|
description: "Hello Valence!".color(Color::AQUA),
|
||||||
favicon_png: Some(self.favicon.clone()),
|
favicon_png: Some(include_bytes!("favicon.png")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,8 @@ use crate::util::{chunks_in_view_distance, is_chunk_in_view_distance};
|
||||||
use crate::var_int::VarInt;
|
use crate::var_int::VarInt;
|
||||||
use crate::world::WorldId;
|
use crate::world::WorldId;
|
||||||
use crate::{
|
use crate::{
|
||||||
glm, ident, ChunkPos, ChunkStore, EntityId, EntityStore, Server, SharedServer, Text, Ticks,
|
glm, ident, ChunkPos, ChunkStore, EntityId, EntityStore, Server, Text, Ticks, WorldStore,
|
||||||
WorldStore, LIBRARY_NAMESPACE,
|
LIBRARY_NAMESPACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct ClientStore {
|
pub struct ClientStore {
|
||||||
|
@ -386,7 +386,7 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if it's time to send another keepalive.
|
// 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 {
|
if self.got_keepalive {
|
||||||
let id = rand::random();
|
let id = rand::random();
|
||||||
self.send_packet(KeepAliveClientbound { id });
|
self.send_packet(KeepAliveClientbound { id });
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||||
use std::panic::{RefUnwindSafe, UnwindSafe};
|
use std::panic::{RefUnwindSafe, UnwindSafe};
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use tokio::runtime::Handle as TokioHandle;
|
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
|
/// A trait containing callbacks which are invoked by the running Minecraft
|
||||||
/// server.
|
/// server.
|
||||||
|
@ -41,20 +39,19 @@ pub trait Config: Any + Send + Sync + UnwindSafe + RefUnwindSafe {
|
||||||
SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 25565).into()
|
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
|
/// On each game update (tick), the server is expected to update game logic
|
||||||
/// logic and respond to packets from clients. Once this is complete,
|
/// and respond to packets from clients. Once this is complete, the server
|
||||||
/// the server will sleep for any remaining time until the full update
|
/// will sleep for any remaining time until a full tick has passed.
|
||||||
/// duration has passed.
|
|
||||||
///
|
///
|
||||||
/// The duration must be nonzero.
|
/// The tick rate must be greater than zero.
|
||||||
///
|
///
|
||||||
/// # Default Implementation
|
/// # Default Implementation
|
||||||
/// Returns 1/20th of a second, which is the same as Minecraft's official
|
/// Returns `20`, which is the same as Minecraft's official server.
|
||||||
/// server.
|
fn tick_rate(&self) -> Ticks {
|
||||||
fn update_duration(&self) -> Duration {
|
20
|
||||||
Duration::from_secs_f64(1.0 / 20.0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called once at startup to get the "online mode" option, which determines
|
/// 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.
|
/// The result of the [`server_list_ping`](Handler::server_list_ping) callback.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ServerListPing {
|
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 {
|
||||||
online_players: i32,
|
online_players: i32,
|
||||||
|
@ -210,7 +207,7 @@ pub enum ServerListPing {
|
||||||
/// 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<Arc<[u8]>>,
|
favicon_png: Option<&'a [u8]>,
|
||||||
},
|
},
|
||||||
/// Ignores the query and disconnects from the client.
|
/// Ignores the query and disconnects from the client.
|
||||||
Ignore,
|
Ignore,
|
||||||
|
|
|
@ -67,8 +67,6 @@ pub struct Other {
|
||||||
tick_counter: Ticks,
|
tick_counter: Ticks,
|
||||||
/// The instant the current game tick began.
|
/// The instant the current game tick began.
|
||||||
tick_start: Instant,
|
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
|
/// A server handle providing the subset of functionality which can be performed
|
||||||
|
@ -80,7 +78,7 @@ pub struct SharedServer(Arc<SharedServerInner>);
|
||||||
struct SharedServerInner {
|
struct SharedServerInner {
|
||||||
cfg: Box<dyn Config>,
|
cfg: Box<dyn Config>,
|
||||||
address: SocketAddr,
|
address: SocketAddr,
|
||||||
update_duration: Duration,
|
tick_rate: Ticks,
|
||||||
online_mode: bool,
|
online_mode: bool,
|
||||||
max_connections: usize,
|
max_connections: usize,
|
||||||
incoming_packet_capacity: usize,
|
incoming_packet_capacity: usize,
|
||||||
|
@ -153,8 +151,8 @@ impl SharedServer {
|
||||||
self.0.address
|
self.0.address
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_duration(&self) -> Duration {
|
pub fn tick_rate(&self) -> Ticks {
|
||||||
self.0.update_duration
|
self.0.tick_rate
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn online_mode(&self) -> bool {
|
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> {
|
fn setup_server(cfg: impl Config) -> anyhow::Result<Server> {
|
||||||
let max_connections = cfg.max_connections();
|
let max_connections = cfg.max_connections();
|
||||||
let address = cfg.address();
|
let address = cfg.address();
|
||||||
let update_duration = cfg.update_duration();
|
let tick_rate = cfg.tick_rate();
|
||||||
|
|
||||||
ensure!(
|
ensure!(tick_rate > 0, "tick rate must be greater than zero");
|
||||||
update_duration != Duration::ZERO,
|
|
||||||
"update duration must be nonzero"
|
|
||||||
);
|
|
||||||
|
|
||||||
let online_mode = cfg.online_mode();
|
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 {
|
let shared = SharedServer(Arc::new(SharedServerInner {
|
||||||
cfg: Box::new(cfg),
|
cfg: Box::new(cfg),
|
||||||
address,
|
address,
|
||||||
update_duration,
|
tick_rate,
|
||||||
online_mode,
|
online_mode,
|
||||||
max_connections,
|
max_connections,
|
||||||
outgoing_packet_capacity,
|
outgoing_packet_capacity,
|
||||||
|
@ -408,7 +403,6 @@ fn setup_server(cfg: impl Config) -> anyhow::Result<Server> {
|
||||||
tick_counter: 0,
|
tick_counter: 0,
|
||||||
tick_start: Instant::now(),
|
tick_start: Instant::now(),
|
||||||
new_players_rx,
|
new_players_rx,
|
||||||
last_keepalive: Instant::now(),
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -426,12 +420,6 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult {
|
||||||
join_player(server, msg);
|
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)| {
|
server.clients.par_iter_mut().for_each(|(_, client)| {
|
||||||
client.update(
|
client.update(
|
||||||
&server.entities,
|
&server.entities,
|
||||||
|
@ -440,7 +428,6 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult {
|
||||||
&server.other,
|
&server.other,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
server.entities.update();
|
server.entities.update();
|
||||||
|
|
||||||
|
@ -451,7 +438,7 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult {
|
||||||
|
|
||||||
shared.config().update(server);
|
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.
|
// they have not been observed by clients yet.
|
||||||
server.chunks.par_iter_mut().for_each(|(_, chunk)| {
|
server.chunks.par_iter_mut().for_each(|(_, chunk)| {
|
||||||
if chunk.created_this_tick() {
|
if chunk.created_this_tick() {
|
||||||
|
@ -461,14 +448,10 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sleep for the remainder of the tick.
|
// Sleep for the remainder of the tick.
|
||||||
thread::sleep(
|
let tick_duration = Duration::from_secs_f64((server.0.tick_rate as f64).recip());
|
||||||
server
|
thread::sleep(tick_duration.saturating_sub(server.tick_start.elapsed()));
|
||||||
.0
|
|
||||||
.update_duration
|
|
||||||
.saturating_sub(server.tick_start.elapsed()),
|
|
||||||
);
|
|
||||||
server.tick_start = Instant::now();
|
|
||||||
|
|
||||||
|
server.tick_start = Instant::now();
|
||||||
server.tick_counter += 1;
|
server.tick_counter += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,6 @@ impl<T> SlotMap<T> {
|
||||||
|
|
||||||
pub fn insert(&mut self, val: T) -> Key {
|
pub fn insert(&mut self, val: T) -> Key {
|
||||||
assert!(
|
assert!(
|
||||||
// -1 so that NULL is always invalid.
|
|
||||||
self.count < u32::MAX,
|
self.count < u32::MAX,
|
||||||
"SlotMap: too many items inserted"
|
"SlotMap: too many items inserted"
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue