1919
2020use std:: { sync:: Arc , time:: Duration } ;
2121
22- use color_eyre:: eyre:: Result ;
22+ use color_eyre:: eyre:: { bail , Result } ;
2323use rand:: Rng ;
2424use serde_json:: json;
2525use thiserror:: Error ;
@@ -50,7 +50,7 @@ use crate::{
5050#[ cfg( feature = "encryption" ) ]
5151use crate :: protocol:: { datatypes:: Bytes , packets:: login:: PluginRequestC } ;
5252
53- use super :: io:: NetIo ;
53+ use super :: { entity :: Entity , io:: NetIo } ;
5454
5555#[ derive( Debug ) ]
5656pub struct Player {
@@ -62,14 +62,16 @@ pub struct Player {
6262 packet_state : RwLock < PacketState > ,
6363
6464 uuid : RwLock < Option < Uuid > > ,
65- tp_state : Mutex < TeleportState > ,
65+ tp_state : RwLock < TeleportState > ,
6666
6767 last_keepalive : RwLock < Instant > ,
68+
69+ entity : RwLock < Entity > ,
6870}
6971
70- #[ derive( Debug ) ]
72+ #[ derive( Debug , PartialEq ) ]
7173enum TeleportState {
72- Pending ( i32 ) ,
74+ Pending ( i32 , Instant ) ,
7375 Clear ,
7476}
7577
@@ -92,10 +94,12 @@ impl SharedPlayer {
9294 crawlstate,
9395 packet_state : RwLock :: new ( PacketState :: Handshaking ) ,
9496
95- tp_state : Mutex :: new ( TeleportState :: Clear ) ,
9697 uuid : RwLock :: new ( None ) ,
98+ tp_state : RwLock :: new ( TeleportState :: Clear ) ,
9799
98100 last_keepalive : RwLock :: new ( Instant :: now ( ) ) ,
101+
102+ entity : RwLock :: new ( Entity :: default ( ) ) ,
99103 } ) )
100104 }
101105
@@ -339,7 +343,6 @@ impl SharedPlayer {
339343 // thread but realistically who knows burhhhh
340344 state. player_send . send ( self . clone ( ) ) . await ?;
341345
342- state. shutdown_token . cancelled ( ) . await ;
343346 Ok ( ( ) )
344347 }
345348
@@ -392,17 +395,6 @@ impl SharedPlayer {
392395 Ok ( ( ) )
393396 }
394397
395- async fn confirm_teleport ( & self , id : i32 ) -> Result < ( ) , TeleportError > {
396- let tp_state = self . 0 . tp_state . lock ( ) . await ;
397- match * tp_state {
398- TeleportState :: Clear => Err ( TeleportError :: Unexpected ) ,
399- TeleportState :: Pending ( expected) => match id == expected {
400- true => Ok ( ( ) ) ,
401- false => Err ( TeleportError :: WrongId ( expected, id) ) ,
402- } ,
403- }
404- }
405-
406398 pub async fn uuid ( & self ) -> Uuid {
407399 let uuid = self . 0 . uuid . read ( ) . await ;
408400 uuid. expect ( "uuid() called on uninitialized player - only call this after login!" )
@@ -416,20 +408,30 @@ impl SharedPlayer {
416408 yaw : f32 ,
417409 pitch : f32 ,
418410 ) -> Result < ( ) > {
411+ {
412+ let tp_state = self . 0 . tp_state . read ( ) . await ;
413+ if * tp_state != TeleportState :: Clear {
414+ bail ! ( "Player {} already has a teleport pending" , self . 0 . id) ;
415+ } ;
416+ }
417+
419418 let mut io = self . 0 . io . lock ( ) . await ;
420419
421420 let tp = SynchronisePositionC :: new ( x, y, z, yaw, pitch) ;
422421 {
423- let mut tp_state = self . 0 . tp_state . lock ( ) . await ;
422+ let mut tp_state = self . 0 . tp_state . write ( ) . await ;
424423 // player will be given 5 (FIVE) SECONDS TO ACK!!!!!
425- * tp_state = TeleportState :: Pending ( tp. id ) ;
424+ * tp_state = TeleportState :: Pending ( tp. id , Instant :: now ( ) ) ;
426425 }
427426 io. tx ( & tp) . await ?;
428427
429428 let tp_ack = io. rx :: < ConfirmTeleportS > ( ) . await ?;
430429
431430 match tokio:: time:: timeout ( Duration :: from_secs ( 5 ) , self . confirm_teleport ( tp_ack. id ) ) . await {
432- Ok ( Ok ( ( ) ) ) => ( ) ,
431+ Ok ( Ok ( ( ) ) ) => {
432+ let mut tp_state = self . 0 . tp_state . write ( ) . await ;
433+ * tp_state = TeleportState :: Clear ;
434+ }
433435 Ok ( Err ( why) ) => {
434436 warn ! ( "Spawning player {} failed: {why}" , self . 0 . id) ;
435437 Err ( why) ?;
@@ -442,23 +444,66 @@ impl SharedPlayer {
442444 Ok ( ( ) )
443445 }
444446
447+ async fn confirm_teleport ( & self , id : i32 ) -> Result < ( ) , TeleportError > {
448+ let tp_state = self . 0 . tp_state . read ( ) . await ;
449+ match * tp_state {
450+ TeleportState :: Clear => Err ( TeleportError :: Unexpected ) ,
451+ TeleportState :: Pending ( expected, _) if id == expected => Ok ( ( ) ) ,
452+ TeleportState :: Pending ( expected, _) => Err ( TeleportError :: WrongId ( expected, id) ) ,
453+ }
454+ }
455+
456+ pub async fn check_teleports (
457+ & self ,
458+ ack : Option < ConfirmTeleportS > ,
459+ ) -> Result < ( ) , TeleportError > {
460+ let tp_state = self . 0 . tp_state . read ( ) . await ;
461+
462+ match * tp_state {
463+ TeleportState :: Pending ( pending_id, sent_at) => {
464+ if Instant :: now ( ) - sent_at > Duration :: from_secs ( 5 ) {
465+ return Err ( TeleportError :: TimedOut ) ;
466+ }
467+
468+ match ack {
469+ Some ( ack) if ack. id == pending_id => {
470+ drop ( tp_state) ;
471+ let mut tp_state = self . 0 . tp_state . write ( ) . await ;
472+ * tp_state = TeleportState :: Clear ;
473+ Ok ( ( ) )
474+ }
475+ Some ( ack) => Err ( TeleportError :: WrongId ( ack. id , pending_id) ) ,
476+ None => Err ( TeleportError :: Pending ( pending_id) ) ,
477+ }
478+ }
479+ TeleportState :: Clear => match ack {
480+ None => Ok ( ( ) ) ,
481+ Some ( _) => Err ( TeleportError :: Unexpected ) ,
482+ } ,
483+ }
484+ }
485+
445486 async fn handle_frames ( & self , frames : Vec < Frame > ) -> Result < ( ) > {
446487 for frame in frames {
447488 match frame. id {
448489 SetPlayerPositionS :: ID => {
449490 let packet: SetPlayerPositionS = frame. decode ( ) ?;
450- debug ! (
451- "Player {} moved to {}, {}, {}" ,
452- self . 0 . id, packet. x, packet. feet_y, packet. z
453- ) ;
491+
492+ let mut entity = self . 0 . entity . write ( ) . await ;
493+ entity. reposition ( packet. x , packet. feet_y , packet. z ) ;
454494 }
455495
456496 SetPlayerPositionAndRotationS :: ID => {
457497 let packet: SetPlayerPositionAndRotationS = frame. decode ( ) ?;
458- debug ! (
459- "Player {} moved to {}, {}, {} rotated {} {}" ,
460- self . 0 . id, packet. x, packet. feet_y, packet. z, packet. pitch, packet. yaw
461- ) ;
498+
499+ let mut entity = self . 0 . entity . write ( ) . await ;
500+ entity. reposition ( packet. x , packet. feet_y , packet. z ) ;
501+ entity. rotate ( packet. yaw , packet. pitch ) ;
502+ }
503+
504+ ConfirmTeleportS :: ID => {
505+ let packet: ConfirmTeleportS = frame. decode ( ) ?;
506+ self . check_teleports ( Some ( packet) ) . await ?;
462507 }
463508
464509 id => {
@@ -475,9 +520,13 @@ impl SharedPlayer {
475520}
476521
477522#[ derive( Debug , Error ) ]
478- enum TeleportError {
523+ pub enum TeleportError {
479524 #[ error( "Client was not expecting a teleport acknowledgement" ) ]
480525 Unexpected ,
481526 #[ error( "Teleport ack has wrong ID (expected {0}, got {1})" ) ]
482527 WrongId ( i32 , i32 ) ,
528+ #[ error( "Teleport timed out" ) ]
529+ TimedOut ,
530+ #[ error( "Waiting for teleport acknowledgement for id {0}" ) ]
531+ Pending ( i32 ) ,
483532}
0 commit comments