diff --git a/examples/conway.rs b/examples/conway.rs index 0fd23e4..0ae82b0 100644 --- a/examples/conway.rs +++ b/examples/conway.rs @@ -98,14 +98,16 @@ impl Config for Game { fn update(&self, server: &Server, worlds: &mut Worlds) { let world = worlds.iter_mut().next().unwrap().1; + let spawn_pos = [ + SIZE_X as f64 / 2.0, + BOARD_Y as f64 + 1.0, + SIZE_Z as f64 / 2.0, + ]; + world.clients.retain(|_, client| { if client.created_tick() == server.current_tick() { client.set_game_mode(GameMode::Survival); - let spawn_pos = [ - SIZE_X as f64 / 2.0, - BOARD_Y as f64 + 1.0, - SIZE_Z as f64 / 2.0, - ]; + client.teleport(spawn_pos, 0.0, 0.0); world.meta.player_list_mut().insert( @@ -132,16 +134,24 @@ impl Config for Game { let State { board, board_buf } = &mut *self.state.lock().unwrap(); for (_, client) in world.clients.iter_mut() { - for event in client.events_mut().drain(..) { - if let Event::Digging(e) = event { - let pos = e.position; + while let Some(event) = client.pop_event() { + match event { + Event::Digging(e) => { + let pos = e.position; - if (0..SIZE_X as i32).contains(&pos.x) - && (0..SIZE_Z as i32).contains(&pos.z) - && pos.y == BOARD_Y - { - board[pos.x as usize + pos.z as usize * SIZE_X] = true; + if (0..SIZE_X as i32).contains(&pos.x) + && (0..SIZE_Z as i32).contains(&pos.z) + && pos.y == BOARD_Y + { + board[pos.x as usize + pos.z as usize * SIZE_X] = true; + } } + Event::Movement { position, .. } => { + if position.y <= 0.0 { + client.teleport(spawn_pos, 0.0, 0.0); + } + } + _ => {} } } } @@ -191,9 +201,9 @@ impl Config for Game { if cell_x < SIZE_X && cell_z < SIZE_Z { let b = if board[cell_x + cell_z * SIZE_X] { - BlockState::WHITE_WOOL + BlockState::GRASS_BLOCK } else { - BlockState::BLACK_WOOL + BlockState::DIRT }; chunk.set_block_state(x, (BOARD_Y - min_y) as usize, z, b); } diff --git a/src/client.rs b/src/client.rs index 3ea3e41..a2ae5e2 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,6 +1,6 @@ /// Contains the [`Event`] enum and related data types. mod event; -use std::collections::HashSet; +use std::collections::{HashSet, VecDeque}; use std::iter::FusedIterator; use std::time::Duration; @@ -119,7 +119,7 @@ pub struct Client { /// If spawn_position or spawn_position_yaw were modified this tick. modified_spawn_position: bool, death_location: Option<(DimensionId, BlockPos)>, - events: Vec, + events: VecDeque, /// The ID of the last keepalive sent. last_keepalive_id: i64, /// If the last sent keepalive got a response. @@ -167,7 +167,7 @@ impl Client { spawn_position_yaw: 0.0, modified_spawn_position: true, death_location: None, - events: Vec::new(), + events: VecDeque::new(), last_keepalive_id: 0, got_keepalive: true, new_max_view_distance: 16, @@ -289,12 +289,8 @@ impl Client { self.send.is_none() } - pub fn events(&self) -> &Vec { - &self.events - } - - pub fn events_mut(&mut self) -> &mut Vec { - &mut self.events + pub fn pop_event(&mut self) -> Option { + self.events.pop_front() } /// The current view distance of this client measured in chunks. @@ -381,7 +377,7 @@ impl Client { client.pitch = new_pitch; client.on_ground = new_on_ground; - client.events.push(event); + client.events.push_back(event); } } @@ -408,7 +404,7 @@ impl Client { C2sPlayPacket::BlockEntityTagQuery(_) => {} C2sPlayPacket::ChangeDifficulty(_) => {} C2sPlayPacket::ChatCommand(_) => {} - C2sPlayPacket::Chat(p) => self.events.push(Event::ChatMessage { + C2sPlayPacket::Chat(p) => self.events.push_back(Event::ChatMessage { message: p.message.0, timestamp: Duration::from_millis(p.timestamp), }), @@ -425,7 +421,7 @@ impl Client { allow_server_listings: p.allow_server_listings, }); - self.events.push(Event::SettingsChanged(old)); + self.events.push_back(Event::SettingsChanged(old)); } C2sPlayPacket::CommandSuggestion(_) => {} C2sPlayPacket::ContainerButtonClick(_) => {} @@ -438,7 +434,7 @@ impl Client { // TODO: verify that the client has line of sight to the targeted entity and // that the distance is <=4 blocks. - self.events.push(Event::InteractWithEntity { + self.events.push_back(Event::InteractWithEntity { id, sneaking: p.sneaking, typ: match p.typ { @@ -487,7 +483,7 @@ impl Client { handle_movement_packet(self, true, p.position, p.yaw, p.pitch, self.on_ground); } C2sPlayPacket::PaddleBoat(p) => { - self.events.push(Event::SteerBoat { + self.events.push_back(Event::SteerBoat { left_paddle_turning: p.left_paddle_turning, right_paddle_turning: p.right_paddle_turning, }); @@ -503,7 +499,7 @@ impl Client { self.dug_blocks.push(p.sequence.0); } - self.events.push(match p.status { + self.events.push_back(match p.status { DiggingStatus::StartedDigging => Event::Digging(Digging { status: event::DiggingStatus::Start, position: p.location,