GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — feather/feather/server/src/lib.rs at develop · aheart/feather Expand file tree/ Copy pathlib.rsMore file actions 150 lines (129 loc) · 4.55 KB / Copy pathlib.rsFile metadata and controls150 lines (129 loc) · 4.55 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 #![allow(clippy::unnecessary_wraps)] // systems are required to return Results use std::{sync::Arc, time::Instant}; use base::Position; use chunk_subscriptions::ChunkSubscriptions; use common::Game; use ecs::SystemExecutor; use flume::Receiver; use initial_handler::NewPlayer; use listener::Listener; mod chunk_subscriptions; pub mod client; pub mod config; mod connection_worker; mod entities; pub mod favicon; mod initial_handler; mod listener; mod network_id_registry; mod options; mod packet_handlers; mod player_count; mod systems; pub use client::{Client, ClientId, Clients}; pub use network_id_registry::NetworkId; pub use options::Options; use player_count::PlayerCount; use systems::view::WaitingChunks; /// A Minecraft server. /// /// Call [`link_with_game`](Server::link_with_game) to register the server /// with a [`Game`](common::Game). This will /// cause the server to serve the game to players. /// /// Uses asynchronous IO with Tokio. pub struct Server { options: Arc<Options>, clients: Clients, new_players: Receiver<NewPlayer>, waiting_chunks: WaitingChunks, chunk_subscriptions: ChunkSubscriptions, last_keepalive_time: Instant, player_count: PlayerCount, } impl Server { /// Starts a server with the given `Options`. /// /// Must be called within the context of a Tokio runtime. pub async fn bind(options: Options) -> anyhow::Result<Self> { let options = Arc::new(options); let player_count = PlayerCount::new(options.max_players); let (new_players_tx, new_players) = flume::bounded(4); Listener::start(Arc::clone(&options), player_count.clone(), new_players_tx).await?; log::info!( "Server is listening on {}:{}", options.bind_address, options.port ); Ok(Self { options, clients: Clients::new(), new_players, waiting_chunks: WaitingChunks::default(), chunk_subscriptions: ChunkSubscriptions::default(), last_keepalive_time: Instant::now(), player_count, }) } /// Links this server with a `Game` so that players connecting /// to the server become part of this `Game`. pub fn link_with_game(self, game: &mut Game, systems: &mut SystemExecutor<Game>) { systems::register(self, game, systems); game.add_entity_spawn_callback(entities::add_entity_components); } /// Gets the number of online players. pub fn player_count(&self) -> u32 { self.player_count.get() } } /// Low-level functions, mostly used internally. /// You may find these useful for some custom functionality. impl Server { /// Polls for newly connected players. Returns the IDs of the new clients. pub fn accept_new_players(&mut self) -> Vec<ClientId> { let mut clients = Vec::new(); for player in self.new_players.clone().try_iter() { let id = self.create_client(player); clients.push(id); } clients } /// Removes a client. pub fn remove_client(&mut self, id: ClientId) { let client = self.clients.remove(id); if let Some(client) = client { log::debug!("Removed client for {}", client.username()); } } /// Allocates a `NetworkId` for an entity. pub fn create_network_id(&mut self) -> NetworkId { NetworkId::new() } fn create_client(&mut self, player: NewPlayer) -> ClientId { log::debug!("Creating client for {}", player.username); let network_id = self.create_network_id(); let client = Client::new(player, Arc::clone(&self.options), network_id); self.clients.insert(client) } /// Invokes a callback on all clients. pub fn broadcast_with(&self, mut callback: impl FnMut(&Client)) { for client in self.clients.iter() { callback(client); } } /// Sends a packet to all clients currently subscribed /// to the given position. This function should be /// used for entity updates, block updates, etc— /// any packets that need to be sent only to nearby players. pub fn broadcast_nearby_with(&self, position: Position, mut callback: impl FnMut(&Client)) { for &client_id in self.chunk_subscriptions.subscriptions_for(position.chunk()) { if let Some(client) = self.clients.get(client_id) { callback(client); } } } pub fn broadcast_keepalive(&mut self) { self.broadcast_with(|client| client.send_keepalive()); self.last_keepalive_time = Instant::now(); } } |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |