Client disconnect

This commit is contained in:
Garen Tyler 2021-03-17 22:17:16 -06:00
parent a0e355ddde
commit c4c7e069b9
2 changed files with 56 additions and 1 deletions

View File

@ -254,11 +254,25 @@ impl NetworkClient {
}
}
NetworkClientState::Disconnected => {
self.connected = false;
if self.connected {
self.disconnect(None).await;
}
}
}
}
async fn disconnect(&mut self, reason: Option<&str>) {
self.connected = false;
self.state = NetworkClientState::Disconnected;
// Send 0x40 Disconnect.
let mut disconnect = Disconnect::new();
disconnect.reason.text = reason.unwrap_or("Disconnected").into();
disconnect.write(&mut self.stream).await.unwrap();
debug!("{:?}", disconnect);
// Give the client 10 seconds to disconnect before forcing it.
tokio::time::sleep(Duration::from_secs(10)).await;
}
/// Send a keep alive packet to the client.
async fn keep_alive(&mut self) {
// Keep alive ping to client.

View File

@ -469,3 +469,44 @@ impl KeepAlivePing {
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct Disconnect {
pub reason: MCChat,
}
impl Into<Vec<u8>> for Disconnect {
fn into(self) -> Vec<u8> {
let mut out = vec![];
let mut temp: Vec<u8> = MCVarInt::from(0x40).into(); // 0x40 Disconnect.
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.reason));
out.extend_from_slice(&Into::<Vec<u8>>::into(MCVarInt::from(temp.len() as i32)));
out.extend_from_slice(&temp);
out
}
}
impl TryFrom<Vec<u8>> for Disconnect {
type Error = &'static str;
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
Err("unimplemented")
}
}
impl Disconnect {
pub fn new() -> Self {
Disconnect {
reason: MCChat {
text: "Disconnected".into(),
},
}
}
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<Self> {
let mut keepalive = Disconnect::new();
keepalive.reason = MCChat::read(t).await?;
Ok(keepalive)
}
pub async fn write(&self, t: &mut TcpStream) -> tokio::io::Result<()> {
for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b).await?;
}
Ok(())
}
}