Skip to content

Commit

Permalink
🎉 release: 0.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
john-bv authored Sep 18, 2023
2 parents 98f4081 + e36b868 commit 2af4c5a
Show file tree
Hide file tree
Showing 19 changed files with 385 additions and 150 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rak-rs"
version = "0.3.0"
version = "0.3.1"
authors = ["John Bergman <olybear9@gmail.com>"]
edition = "2021"
description = "A fully functional RakNet implementation in pure rust, asynchronously driven."
Expand Down
4 changes: 3 additions & 1 deletion examples/async-std/client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ use std::{net::ToSocketAddrs, vec};
#[async_std::main]
async fn main() {
let mut client = Client::new(10, DEFAULT_MTU);
let mut addr = "zeqa.net:19132".to_socket_addrs().unwrap();
let mut addr = "na.zeqa.net:19132".to_socket_addrs().unwrap();
if let Err(_) = client.connect(addr.next().unwrap()).await {
// here you could attempt to retry, but in this case, we'll just exit
println!("Failed to connect to server!");
return;
}

client.send_ord(&[254, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 ], 0).await.unwrap();

loop {
let pk = client.recv().await.unwrap();
println!("Received packet: {:?}", pk);
Expand Down
3 changes: 2 additions & 1 deletion examples/async-std/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ edition = "2021"
[dependencies]
async-std = { version = "1.12.0", features = [ "attributes" ] }
console-subscriber = "0.1.8"
rak-rs = { path = "../../../", features = [ "debug", "debug_all", "mcpe" ] }
# rak-rs = { path = "../../../", features = [ "debug", "debug_all", "mcpe" ] }
rak-rs = { path = "../../../", features = [ "mcpe" ] }
3 changes: 2 additions & 1 deletion examples/async-std/server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ async fn handle(mut conn: Connection) {
}
if let Ok(pk) = conn.recv().await {
println!("(RAKNET RECIEVE SIDE) Got a connection packet {:?} ", pk);
conn.send(&[254, 12, 143, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], true).await.unwrap();
}
}
}
}
127 changes: 123 additions & 4 deletions src/client/discovery.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::sync::Arc;
use std::sync::Mutex;
use std::time::Duration;

#[cfg(feature = "async_std")]
use async_std::{
future::timeout,
Expand All @@ -6,9 +10,11 @@ use async_std::{
task::{self, Context, Poll, Waker},
};

use binary_util::interfaces::Reader;
use binary_util::io::ByteReader;

#[cfg(feature = "async_tokio")]
use std::future::Future;
use std::sync::{Arc, Mutex};
#[cfg(feature = "async_tokio")]
use std::task::{Context, Poll, Waker};
#[cfg(feature = "async_tokio")]
Expand All @@ -18,14 +24,55 @@ use tokio::{
time::timeout,
};

use crate::match_ids;
use crate::protocol::packet::offline::IncompatibleProtocolVersion;
use crate::protocol::packet::offline::OpenConnectReply;
use crate::protocol::packet::offline::OpenConnectRequest;
use crate::rakrs_debug;

use super::util::send_packet;

macro_rules! update_state {
($done: expr, $shared_state: expr, $state: expr) => {{
let mut state = $shared_state.lock().unwrap();
state.status = $state;
state.done = true;
if let Some(waker) = state.waker.take() {
waker.wake();
}
return;
}};
($shared_state: expr, $state: expr) => {{
let mut state = $shared_state.lock().unwrap();
state.status = $state;
if let Some(waker) = state.waker.take() {
waker.wake();
}
}};
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum DiscoveryStatus {
/// The discovery has been initiated.
/// This only occurs when the discovery is first created.
Initiated,
Discovered,
/// The discovery has been completed.
/// We know the MTU size.
Discovered(u16),
/// We failed to discover the MTU size.
/// This is probably cause the server is offline.
Failed,
/// We're still trying to find the MTU size.
Undiscovered,
}

#[derive(Debug, Clone)]
pub struct MtuDiscoveryMeta {
pub id: i64,
pub version: u8,
pub mtu: u16,
}

struct DiscoveryState {
status: DiscoveryStatus,
waker: Option<Waker>,
Expand All @@ -35,15 +82,87 @@ pub struct MtuDiscovery {
state: Arc<Mutex<DiscoveryState>>,
}

impl MtuDiscovery {}
impl MtuDiscovery {
pub fn new(socket: Arc<UdpSocket>, discovery_info: MtuDiscoveryMeta) -> Self {
let state = Arc::new(Mutex::new(DiscoveryState {
status: DiscoveryStatus::Initiated,
waker: None,
}));

let shared_state = state.clone();

task::spawn(async move {
// try to use the mtu provided by the user
let valid_mtus: Vec<u16> = vec![discovery_info.mtu, 1506, 1492, 1400, 1200, 576];
for mtu in valid_mtus.iter() {
// send a connection request
let request = OpenConnectRequest {
protocol: discovery_info.version,
mtu_size: *mtu,
};

if !send_packet(&socket, request.into()).await {
rakrs_debug!(
true,
"[CLIENT] Failed sending OpenConnectRequest to server!"
);
update_state!(shared_state, DiscoveryStatus::Undiscovered);
// this is ok! we'll just try the next mtu
continue;
};

let reply = match_ids!(
socket.clone(),
// Open connect Reply
0x06,
// Incompatible protocol version
0x19
);

if reply.is_none() {
update_state!(shared_state, DiscoveryStatus::Undiscovered);
// break;
continue;
}

if let Ok(_) = IncompatibleProtocolVersion::read(&mut ByteReader::from(
&reply.clone().unwrap()[1..],
)) {
update_state!(shared_state, DiscoveryStatus::Failed);
break;
}

let open_reply =
OpenConnectReply::read(&mut ByteReader::from(&reply.unwrap()[1..]));

if open_reply.is_err() {
update_state!(shared_state, DiscoveryStatus::Failed);
return;
}

if let Ok(response) = open_reply {
rakrs_debug!(true, "[CLIENT] Received OpenConnectReply from server!");
update_state!(shared_state, DiscoveryStatus::Discovered(response.mtu_size));
return;
} else {
update_state!(shared_state, DiscoveryStatus::Undiscovered);
}
}

update_state!(shared_state, DiscoveryStatus::Failed);
});

Self { state }
}
}

impl Future for MtuDiscovery {
type Output = DiscoveryStatus;

fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut state = self.state.lock().unwrap();
match state.status {
DiscoveryStatus::Failed | DiscoveryStatus::Discovered => Poll::Ready(state.status),
DiscoveryStatus::Failed | DiscoveryStatus::Discovered(_) => Poll::Ready(state.status),
_ => {
state.waker = Some(cx.waker().clone());
Poll::Pending
Expand Down
Loading

0 comments on commit 2af4c5a

Please sign in to comment.