Send keep alive packets every 10s
This commit is contained in:
parent
6fa9ee968e
commit
a0e355ddde
@ -257,13 +257,7 @@ pub mod other {
|
|||||||
}
|
}
|
||||||
impl Display for MCPosition {
|
impl Display for MCPosition {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(
|
write!(f, "({}, {}, {})", self.x, self.y, self.z,)
|
||||||
f,
|
|
||||||
"({}, {}, {})",
|
|
||||||
self.x,
|
|
||||||
self.y,
|
|
||||||
self.z,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl TryFrom<Vec<u8>> for MCPosition {
|
impl TryFrom<Vec<u8>> for MCPosition {
|
||||||
@ -279,13 +273,10 @@ pub mod other {
|
|||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
let mut temp = vec![];
|
let mut temp = vec![];
|
||||||
temp.extend_from_slice(
|
temp.extend_from_slice(
|
||||||
&(
|
&((((Into::<i64>::into(self.x) & 0x3FFFFFF) << 38)
|
||||||
(
|
| ((Into::<i64>::into(self.y) & 0xFFF) << 26)
|
||||||
((Into::<i64>::into(self.x) & 0x3FFFFFF) << 38)
|
| (Into::<i64>::into(self.z) & 0x3FFFFFF)) as u64)
|
||||||
| ((Into::<i64>::into(self.y) & 0xFFF) << 26)
|
.to_be_bytes(),
|
||||||
| (Into::<i64>::into(self.z) & 0x3FFFFFF)
|
|
||||||
) as u64
|
|
||||||
).to_be_bytes()
|
|
||||||
);
|
);
|
||||||
// temp.extend_from_slice(&"{\"text\": \"".to_owned().into_bytes());
|
// temp.extend_from_slice(&"{\"text\": \"".to_owned().into_bytes());
|
||||||
// temp.extend_from_slice(&self.text.value.into_bytes());
|
// temp.extend_from_slice(&self.text.value.into_bytes());
|
||||||
|
@ -7,6 +7,7 @@ use log::{debug, info};
|
|||||||
use packets::*;
|
use packets::*;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::sync::mpsc::{self, Receiver, TryRecvError};
|
use std::sync::mpsc::{self, Receiver, TryRecvError};
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
use tokio::net::{TcpListener, TcpStream, ToSocketAddrs};
|
use tokio::net::{TcpListener, TcpStream, ToSocketAddrs};
|
||||||
|
|
||||||
/// The struct containing all the data and running all the updates.
|
/// The struct containing all the data and running all the updates.
|
||||||
@ -101,6 +102,7 @@ pub struct NetworkClient {
|
|||||||
pub state: NetworkClientState,
|
pub state: NetworkClientState,
|
||||||
pub uuid: Option<String>,
|
pub uuid: Option<String>,
|
||||||
pub username: Option<String>,
|
pub username: Option<String>,
|
||||||
|
pub last_keep_alive: Instant,
|
||||||
}
|
}
|
||||||
impl NetworkClient {
|
impl NetworkClient {
|
||||||
/// Create a new `NetworkClient`
|
/// Create a new `NetworkClient`
|
||||||
@ -112,6 +114,7 @@ impl NetworkClient {
|
|||||||
state: NetworkClientState::Handshake,
|
state: NetworkClientState::Handshake,
|
||||||
uuid: None,
|
uuid: None,
|
||||||
username: None,
|
username: None,
|
||||||
|
last_keep_alive: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,16 +240,35 @@ impl NetworkClient {
|
|||||||
let spawnposition = SpawnPosition::new();
|
let spawnposition = SpawnPosition::new();
|
||||||
spawnposition.write(&mut self.stream).await.unwrap();
|
spawnposition.write(&mut self.stream).await.unwrap();
|
||||||
debug!("{:?}", spawnposition);
|
debug!("{:?}", spawnposition);
|
||||||
|
// Send initial keep alive.
|
||||||
|
self.keep_alive().await;
|
||||||
// TODO: S->C Player Position and Look
|
// TODO: S->C Player Position and Look
|
||||||
// TODO: C->S Teleport Confirm
|
// TODO: C->S Teleport Confirm
|
||||||
// TODO: C->S Player Position and Look
|
// TODO: C->S Player Position and Look
|
||||||
// TODO: C->S Client Status
|
// TODO: C->S Client Status
|
||||||
// TODO: S->C inventories, entities, etc.
|
// TODO: S->C inventories, entities, etc.
|
||||||
}
|
}
|
||||||
NetworkClientState::Play => {}
|
NetworkClientState::Play => {
|
||||||
|
if self.last_keep_alive.elapsed() > Duration::from_secs(10) {
|
||||||
|
self.keep_alive().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
NetworkClientState::Disconnected => {
|
NetworkClientState::Disconnected => {
|
||||||
self.connected = false;
|
self.connected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send a keep alive packet to the client.
|
||||||
|
async fn keep_alive(&mut self) {
|
||||||
|
// Keep alive ping to client.
|
||||||
|
let clientboundkeepalive = KeepAlivePing::new();
|
||||||
|
clientboundkeepalive.write(&mut self.stream).await.unwrap();
|
||||||
|
debug!("{:?}", clientboundkeepalive);
|
||||||
|
// Keep alive pong to server.
|
||||||
|
let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap();
|
||||||
|
let serverboundkeepalive = KeepAlivePong::read(&mut self.stream).await.unwrap();
|
||||||
|
debug!("{:?}", serverboundkeepalive);
|
||||||
|
self.last_keep_alive = Instant::now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,29 +271,29 @@ impl HeldItemChange {
|
|||||||
pub struct EntityStatus {
|
pub struct EntityStatus {
|
||||||
entity_id: MCInt,
|
entity_id: MCInt,
|
||||||
entity_status: MCByte, // See table below.
|
entity_status: MCByte, // See table below.
|
||||||
// 1: Sent when resetting a mob spawn minecart's timer / Rabbit jump animation
|
// 1: Sent when resetting a mob spawn minecart's timer / Rabbit jump animation
|
||||||
// 2: Living Entity hurt
|
// 2: Living Entity hurt
|
||||||
// 3: Living Entity dead
|
// 3: Living Entity dead
|
||||||
// 4: Iron Golem throwing up arms
|
// 4: Iron Golem throwing up arms
|
||||||
// 6: Wolf/Ocelot/Horse taming — Spawn “heart” particles
|
// 6: Wolf/Ocelot/Horse taming — Spawn “heart” particles
|
||||||
// 7: Wolf/Ocelot/Horse tamed — Spawn “smoke” particles
|
// 7: Wolf/Ocelot/Horse tamed — Spawn “smoke” particles
|
||||||
// 8: Wolf shaking water — Trigger the shaking animation
|
// 8: Wolf shaking water — Trigger the shaking animation
|
||||||
// 9: (of self) Eating accepted by server
|
// 9: (of self) Eating accepted by server
|
||||||
// 10: Sheep eating grass
|
// 10: Sheep eating grass
|
||||||
// 10: Play TNT ignite sound
|
// 10: Play TNT ignite sound
|
||||||
// 11: Iron Golem handing over a rose
|
// 11: Iron Golem handing over a rose
|
||||||
// 12: Villager mating — Spawn “heart” particles
|
// 12: Villager mating — Spawn “heart” particles
|
||||||
// 13: Spawn particles indicating that a villager is angry and seeking revenge
|
// 13: Spawn particles indicating that a villager is angry and seeking revenge
|
||||||
// 14: Spawn happy particles near a villager
|
// 14: Spawn happy particles near a villager
|
||||||
// 15: Witch animation — Spawn “magic” particles
|
// 15: Witch animation — Spawn “magic” particles
|
||||||
// 16: Play zombie converting into a villager sound
|
// 16: Play zombie converting into a villager sound
|
||||||
// 17: Firework exploding
|
// 17: Firework exploding
|
||||||
// 18: Animal in love (ready to mate) — Spawn “heart” particles
|
// 18: Animal in love (ready to mate) — Spawn “heart” particles
|
||||||
// 19: Reset squid rotation
|
// 19: Reset squid rotation
|
||||||
// 20: Spawn explosion particle — works for some living entities
|
// 20: Spawn explosion particle — works for some living entities
|
||||||
// 21: Play guardian sound — works for only for guardians
|
// 21: Play guardian sound — works for only for guardians
|
||||||
// 22: Enables reduced debug for players
|
// 22: Enables reduced debug for players
|
||||||
// 23: Disables reduced debug for players
|
// 23: Disables reduced debug for players
|
||||||
}
|
}
|
||||||
impl Into<Vec<u8>> for EntityStatus {
|
impl Into<Vec<u8>> for EntityStatus {
|
||||||
fn into(self) -> Vec<u8> {
|
fn into(self) -> Vec<u8> {
|
||||||
@ -401,7 +401,7 @@ impl Into<Vec<u8>> for SpawnPosition {
|
|||||||
fn into(self) -> Vec<u8> {
|
fn into(self) -> Vec<u8> {
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
let mut temp: Vec<u8> = MCVarInt::from(0x05).into(); // 0x05 Spawn Position.
|
let mut temp: Vec<u8> = MCVarInt::from(0x05).into(); // 0x05 Spawn Position.
|
||||||
// temp.extend_from_slice(&Into::<Vec<u8>>::into(self.position));
|
// temp.extend_from_slice(&Into::<Vec<u8>>::into(self.position));
|
||||||
temp.extend_from_slice(&0u64.to_be_bytes());
|
temp.extend_from_slice(&0u64.to_be_bytes());
|
||||||
out.extend_from_slice(&Into::<Vec<u8>>::into(MCVarInt::from(temp.len() as i32)));
|
out.extend_from_slice(&Into::<Vec<u8>>::into(MCVarInt::from(temp.len() as i32)));
|
||||||
out.extend_from_slice(&temp);
|
out.extend_from_slice(&temp);
|
||||||
@ -432,3 +432,40 @@ impl SpawnPosition {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct KeepAlivePing {
|
||||||
|
payload: MCVarInt,
|
||||||
|
}
|
||||||
|
impl Into<Vec<u8>> for KeepAlivePing {
|
||||||
|
fn into(self) -> Vec<u8> {
|
||||||
|
let mut out = vec![];
|
||||||
|
let mut temp: Vec<u8> = MCVarInt::from(0x00).into(); // 0x00 Keep Alive.
|
||||||
|
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.payload));
|
||||||
|
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 KeepAlivePing {
|
||||||
|
type Error = &'static str;
|
||||||
|
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
|
||||||
|
Err("unimplemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl KeepAlivePing {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
KeepAlivePing { payload: 0.into() }
|
||||||
|
}
|
||||||
|
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<Self> {
|
||||||
|
let mut keepalive = KeepAlivePing::new();
|
||||||
|
keepalive.payload = MCVarInt::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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -225,3 +225,40 @@ impl ClientSettings {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct KeepAlivePong {
|
||||||
|
payload: MCVarInt,
|
||||||
|
}
|
||||||
|
impl Into<Vec<u8>> for KeepAlivePong {
|
||||||
|
fn into(self) -> Vec<u8> {
|
||||||
|
let mut out = vec![];
|
||||||
|
let mut temp: Vec<u8> = MCVarInt::from(0x00).into(); // 0x00 Keep Alive.
|
||||||
|
temp.extend_from_slice(&Into::<Vec<u8>>::into(self.payload));
|
||||||
|
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 KeepAlivePong {
|
||||||
|
type Error = &'static str;
|
||||||
|
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
|
||||||
|
Err("unimplemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl KeepAlivePong {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
KeepAlivePong { payload: 0.into() }
|
||||||
|
}
|
||||||
|
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<Self> {
|
||||||
|
let mut keepalive = KeepAlivePong::new();
|
||||||
|
keepalive.payload = MCVarInt::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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user