From c3df886685de3cee0022346f21ac2e872bc12eaf Mon Sep 17 00:00:00 2001 From: Mark Joaquim Date: Mon, 9 Mar 2020 09:35:34 -0400 Subject: [PATCH 1/2] tp to last position if we receive an OOB position --- src/interfaces/player.rs | 5 ++ src/services/patchwork.rs | 109 ++++++++++++++++++++------------------ src/services/player.rs | 25 +++++++++ 3 files changed, 86 insertions(+), 53 deletions(-) diff --git a/src/interfaces/player.rs b/src/interfaces/player.rs index fcdd950..d2a6aab 100644 --- a/src/interfaces/player.rs +++ b/src/interfaces/player.rs @@ -42,6 +42,11 @@ define_interface!( StatusResponse, status_response, [conn_id: Uuid, version: Version, description: Description] + ), + ( + TeleportToLastValidPos, + teleport_to_last_valid_pos, + [conn_id: Uuid] ) ); diff --git a/src/services/patchwork.rs b/src/services/patchwork.rs index 498c961..e89969f 100644 --- a/src/services/patchwork.rs +++ b/src/services/patchwork.rs @@ -50,59 +50,63 @@ pub fn start< map_index: 0, conn_id: None, }); - match &patchwork.maps[anchor.map_index].peer_connection { - Some(_) => match msg.packet { - Packet::Unknown => {} - _ => { - trace!( - "Routing packet from conn_id {:?} through anchor", - msg.conn_id - ); - player_state.anchored_move_and_look( - msg.conn_id, - extract_player_position((&msg.packet).clone()), - None, - ); - messenger.send_packet(anchor.conn_id.unwrap(), msg.packet.clone()); - } - }, - None => { - trace!("Routing packet from conn_id {:?} locally", msg.conn_id); - gameplay_router::route_packet( - msg.packet.clone(), - msg.conn_id, - player_state.clone(), - sender.clone(), - ); - } - } if let Some(position) = extract_map_position((&msg.packet).clone()) { - let new_map_index = patchwork_clone.position_map_index(position); - if new_map_index != anchor.map_index { - anchor.disconnect(messenger.clone()); - *anchor = match &patchwork.maps[new_map_index].peer_connection { - Some(peer_connection) => Anchor::connect( - peer_connection.peer.clone(), - msg.conn_id, - new_map_index, - patchwork.maps[new_map_index].position.x, - messenger.clone(), - player_state.clone(), - ) - .unwrap(), - None => { - gameplay_router::route_packet( - msg.packet.clone(), - msg.conn_id, - player_state.clone(), - sender.clone(), - ); - if patchwork.maps[anchor.map_index].peer_connection.is_some() { - player_state.reintroduce(msg.conn_id); + match patchwork_clone.position_map_index(position) { + None => player_state.teleport_to_last_valid_pos(msg.conn_id), + Some(new_map_index) => { + match &patchwork.maps[anchor.map_index].peer_connection { + Some(_) => match msg.packet { + Packet::Unknown => {} + _ => { + trace!( + "Routing packet from conn_id {:?} through anchor", + msg.conn_id + ); + player_state.anchored_move_and_look( + msg.conn_id, + extract_player_position((&msg.packet).clone()), + None, + ); + messenger.send_packet(anchor.conn_id.unwrap(), msg.packet.clone()); + } + }, + None => { + trace!("Routing packet from conn_id {:?} locally", msg.conn_id); + gameplay_router::route_packet( + msg.packet.clone(), + msg.conn_id, + player_state.clone(), + sender.clone(), + ); } - Anchor { - conn_id: None, - map_index: new_map_index, + } + if new_map_index != anchor.map_index { + anchor.disconnect(messenger.clone()); + *anchor = match &patchwork.maps[new_map_index].peer_connection { + Some(peer_connection) => Anchor::connect( + peer_connection.peer.clone(), + msg.conn_id, + new_map_index, + patchwork.maps[new_map_index].position.x, + messenger.clone(), + player_state.clone(), + ) + .unwrap(), + None => { + gameplay_router::route_packet( + msg.packet.clone(), + msg.conn_id, + player_state.clone(), + sender.clone(), + ); + if patchwork.maps[anchor.map_index].peer_connection.is_some() { + player_state.reintroduce(msg.conn_id); + } + Anchor { + conn_id: None, + map_index: new_map_index, + } + } } } } @@ -215,11 +219,10 @@ impl Patchwork { .push(Map::new(next_position, self.next_entity_id_block())); } - pub fn position_map_index(self, position: Position) -> usize { + pub fn position_map_index(self, position: Position) -> Option { self.maps .into_iter() .position(|map| map.position == position) - .expect("Could not find map for position") } pub fn connect_map( diff --git a/src/services/player.rs b/src/services/player.rs index 4d28f8d..06abe5b 100644 --- a/src/services/player.rs +++ b/src/services/player.rs @@ -203,6 +203,19 @@ fn handle_message { + trace!( + "Teleporting to last valid position for conn_id {:?}", + msg.conn_id + ); + let player = players + .get(&msg.conn_id) + .expect("Could not teleport to valid position: player not found"); + messenger.send_packet( + msg.conn_id, + Packet::ClientboundPlayerPositionAndLook(player.pos_and_look_last_valid_packet()) + ); + } } } @@ -247,6 +260,18 @@ impl Player { } } + pub fn pos_and_look_last_valid_packet(&self) -> ClientboundPlayerPositionAndLook { + ClientboundPlayerPositionAndLook { + x: self.position.x, + y: self.position.y, + z: self.position.z, + yaw: self.angle.yaw, + pitch: self.angle.pitch, + flags: 0, + teleport_id: 0 + } + } + pub fn pos_and_look_packet(&self) -> ClientboundPlayerPositionAndLook { ClientboundPlayerPositionAndLook { x: self.position.x, From 55b670fac6b7d1da78101bb6faba13c933d54113 Mon Sep 17 00:00:00 2001 From: Mark Joaquim Date: Mon, 9 Mar 2020 10:04:15 -0400 Subject: [PATCH 2/2] keep the look angle if we have it --- src/interfaces/player.rs | 2 +- src/services/patchwork.rs | 19 +++++++++++++++++-- src/services/player.rs | 8 ++++---- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/interfaces/player.rs b/src/interfaces/player.rs index d2a6aab..4685461 100644 --- a/src/interfaces/player.rs +++ b/src/interfaces/player.rs @@ -46,7 +46,7 @@ define_interface!( ( TeleportToLastValidPos, teleport_to_last_valid_pos, - [conn_id: Uuid] + [conn_id: Uuid, look: Option] ) ); diff --git a/src/services/patchwork.rs b/src/services/patchwork.rs index e89969f..9672220 100644 --- a/src/services/patchwork.rs +++ b/src/services/patchwork.rs @@ -1,7 +1,9 @@ use super::interfaces::messenger::Messenger; use super::interfaces::packet_processor::PacketProcessor; use super::interfaces::patchwork::Operations; -use super::interfaces::player::{PlayerState, Position as PlayerPosition}; +use super::interfaces::player::{ + PlayerState, Position as PlayerPosition, Angle as PlayerAngle +}; use super::map::{Map, Peer, PeerConnection, Position}; use super::packet; use super::packet::Packet; @@ -52,7 +54,10 @@ pub fn start< }); if let Some(position) = extract_map_position((&msg.packet).clone()) { match patchwork_clone.position_map_index(position) { - None => player_state.teleport_to_last_valid_pos(msg.conn_id), + None => { + let look = extract_player_look((&msg.packet).clone()); + player_state.teleport_to_last_valid_pos(msg.conn_id, look); + }, Some(new_map_index) => { match &patchwork.maps[anchor.map_index].peer_connection { Some(_) => match msg.packet { @@ -151,6 +156,16 @@ fn extract_player_position(packet: Packet) -> Option { } } +fn extract_player_look(packet: Packet) -> Option { + match packet { + Packet:: PlayerPositionAndLook(packet) => Some(PlayerAngle { + pitch: packet.pitch, + yaw: packet.yaw + }), + _=> None, + } +} + #[derive(Debug, Clone)] struct Anchor { map_index: usize, diff --git a/src/services/player.rs b/src/services/player.rs index 06abe5b..d4e90a5 100644 --- a/src/services/player.rs +++ b/src/services/player.rs @@ -213,7 +213,7 @@ fn handle_message ClientboundPlayerPositionAndLook { + pub fn pos_last_valid_packet(&self, look: Option) -> ClientboundPlayerPositionAndLook { ClientboundPlayerPositionAndLook { x: self.position.x, y: self.position.y, z: self.position.z, - yaw: self.angle.yaw, - pitch: self.angle.pitch, + yaw: look.unwrap_or(self.angle).yaw, + pitch: look.unwrap_or(self.angle).pitch, flags: 0, teleport_id: 0 }