Skip to content

Commit

Permalink
feat: add keep alive (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewgazelka authored Mar 21, 2024
1 parent 25eaf2c commit e5e9221
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 12 deletions.
36 changes: 31 additions & 5 deletions server/src/handshake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ fn offline_uuid(username: &str) -> anyhow::Result<Uuid> {
Uuid::from_slice(&sha2::Sha256::digest(username)[..16]).map_err(Into::into)
}

pub struct ClientConnection {
pub packets: Packets,
pub name: Box<str>,
}

pub struct Io {
stream: TcpStream,
dec: PacketDecoder,
Expand Down Expand Up @@ -101,6 +106,18 @@ impl WriterComm {
Ok(())
}

pub fn send_keep_alive(&mut self) -> anyhow::Result<()> {
// todo: handle error
let pkt = valence_protocol::packets::play::KeepAliveS2c {
// todo: this might be inefficient
id: rand::random(),
};

self.send_packet(&pkt)?;

Ok(())
}

pub fn send_game_join_packet(&mut self) -> anyhow::Result<()> {
// recv ack

Expand Down Expand Up @@ -262,7 +279,11 @@ impl Io {
Ok(())
}

async fn server_process(mut self, id: usize, tx: flume::Sender<Packets>) -> anyhow::Result<()> {
async fn server_process(
mut self,
id: usize,
tx: flume::Sender<ClientConnection>,
) -> anyhow::Result<()> {
// self.stream.set_nodelay(true)?;

info!("connection id {id}");
Expand Down Expand Up @@ -294,7 +315,7 @@ impl Io {
Ok(())
}

async fn server_login(mut self, tx: flume::Sender<Packets>) -> anyhow::Result<()> {
async fn server_login(mut self, tx: flume::Sender<ClientConnection>) -> anyhow::Result<()> {
debug!("[[start login phase]]");

// first
Expand Down Expand Up @@ -358,7 +379,12 @@ impl Io {
reader: reader_comm,
};

tx.send(packets).unwrap();
let conn = ClientConnection {
packets,
name: username,
};

tx.send(conn).unwrap();

Ok(())
}
Expand Down Expand Up @@ -410,7 +436,7 @@ async fn print_errors(future: impl core::future::Future<Output = anyhow::Result<
}
}

async fn run(tx: flume::Sender<Packets>) {
async fn run(tx: flume::Sender<ClientConnection>) {
// start socket 25565
// todo: remove unwrap
let addr = "0.0.0.0:25565";
Expand Down Expand Up @@ -448,7 +474,7 @@ async fn run(tx: flume::Sender<Packets>) {
}
}

pub fn server(shutdown: flume::Receiver<()>) -> flume::Receiver<Packets> {
pub fn server(shutdown: flume::Receiver<()>) -> flume::Receiver<ClientConnection> {
let (tx, rx) = flume::unbounded();

std::thread::spawn(move || {
Expand Down
16 changes: 12 additions & 4 deletions server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use signal_hook::iterator::Signals;
use tracing::{info, warn};
use valence_protocol::math::DVec3;

use crate::handshake::{server, Packets};
use crate::handshake::{server, ClientConnection, Packets};

mod global;
mod handshake;
Expand All @@ -28,13 +28,16 @@ mod system;
#[derive(Component)]
struct Player {
packets: Packets,
name: Box<str>,
last_keep_alive_sent: Instant,
locale: Option<String>,
}

#[derive(Event)]
struct InitPlayer {
entity: EntityId,
io: Packets,
name: Box<str>,
pos: FullEntityPose,
}

Expand All @@ -60,17 +63,20 @@ static GLOBAL: global::Global = global::Global {

struct Game {
world: World,
incoming: flume::Receiver<Packets>,
incoming: flume::Receiver<ClientConnection>,
}

impl Game {
fn tick(&mut self) {
while let Ok(io) = self.incoming.try_recv() {
while let Ok(connection) = self.incoming.try_recv() {
let ClientConnection { packets, name } = connection;

let player = self.world.spawn();

let event = InitPlayer {
entity: player,
io,
io: packets,
name,
pos: FullEntityPose {
position: DVec3::new(0.0, 2.0, 0.0),
yaw: 0.0,
Expand Down Expand Up @@ -140,6 +146,8 @@ fn main() {
world.add_handler(system::init_player);
world.add_handler(system::player_join_world);
world.add_handler(system::player_kick);

world.add_handler(system::keep_alive);
world.add_handler(process_packets);

let mut game = Game {
Expand Down
2 changes: 1 addition & 1 deletion server/src/packets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub fn switch(
play::ClientCommandC2s::ID => player_command(data)?,
play::UpdatePlayerAbilitiesC2s::ID => update_player_abilities(data)?,
play::UpdateSelectedSlotC2s::ID => update_selected_slot(data)?,
_ => warn!("unknown packet id: 0x{:X}", id),
_ => warn!("unknown packet id: 0x{:02X}", id),
}

Ok(())
Expand Down
2 changes: 2 additions & 0 deletions server/src/system.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod init_player;
mod keep_alive;
mod player_join_world;
mod player_kick;

pub use init_player::init_player;
pub use keep_alive::keep_alive;
pub use player_join_world::player_join_world;
pub use player_kick::player_kick;
9 changes: 8 additions & 1 deletion server/src/system/init_player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@ pub fn init_player(
// take ownership
let event = EventMut::take(r.event);

let InitPlayer { entity, io, pos } = event;
let InitPlayer {
entity,
io,
name,
pos,
} = event;

s.insert(entity, pos);
s.insert(entity, Player {
packets: io,
last_keep_alive_sent: std::time::Instant::now(),
name,
locale: None,
});

Expand Down
19 changes: 19 additions & 0 deletions server/src/system/keep_alive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use std::time::Instant;

use evenio::{prelude::*, rayon::prelude::*};
use tracing::debug;

use crate::{Gametick, Player};

pub fn keep_alive(_: Receiver<Gametick>, mut fetcher: Fetcher<&mut Player>) {
fetcher.par_iter_mut().for_each(|player| {
// if we haven't sent a keep alive packet in 5 seconds, send one
if player.last_keep_alive_sent.elapsed().as_secs() >= 5 {
player.last_keep_alive_sent = Instant::now();
// todo: handle and disconnect
let name = &player.name;
debug!("sending keep alive to {name}");
let _ = player.packets.writer.send_keep_alive();
}
});
}
2 changes: 1 addition & 1 deletion server/src/system/player_join_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn player_join_world(
) {
let (id, player) = r.query;

info!("Player {:?} joined the world", id);
info!("Player {} joined the world", player.name);

if let Err(e) = inner(player) {
s.send(KickPlayer {
Expand Down

0 comments on commit e5e9221

Please sign in to comment.