Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more fields to Motd and fix Motd Reader #60

Merged
merged 2 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ pub struct Client {
/// The receive queue is used internally to receive packets from the server.
/// This is read from before sending
recv_queue: Arc<Mutex<RecvQueue>>,
/// The network recieve channel is used to receive raw packets from the server.
/// The network receive channel is used to receive raw packets from the server.
network_recv: Option<Arc<Mutex<Receiver<Vec<u8>>>>>,
/// The internal channel that is used to dispatch packets to a higher level.
internal_recv: Receiver<Vec<u8>>,
Expand Down Expand Up @@ -573,7 +573,7 @@ impl Client {
match packet {
RakPacket::Offline(offline) => match offline {
OfflinePacket::UnconnectedPong(pong) => {
rakrs_debug!(true, "[CLIENT] Recieved pong packet!");
rakrs_debug!(true, "[CLIENT] Received pong packet!");
return Ok(pong);
}
_ => {}
Expand All @@ -582,7 +582,7 @@ impl Client {
}
}
Err(_) => {
rakrs_debug!(true, "[CLIENT] Failed to recieve anything on netowrk channel, is there a sender?");
rakrs_debug!(true, "[CLIENT] Failed to receive anything on network channel, is there a sender?");
continue;
}
}
Expand Down Expand Up @@ -628,19 +628,19 @@ impl Client {
($pk_recv: expr) => {
#[cfg(feature = "async_std")]
if let Err(_) = $pk_recv {
rakrs_debug!(true, "[CLIENT] (recv_task) Failed to recieve anything on netowrk channel, is there a sender?");
rakrs_debug!(true, "[CLIENT] (recv_task) Failed to receive anything on network channel, is there a sender?");
continue;
}

#[cfg(feature = "async_tokio")]
if let None = $pk_recv {
rakrs_debug!(true, "[CLIENT] (recv_task) Failed to recieve anything on netowrk channel, is there a sender?");
rakrs_debug!(true, "[CLIENT] (recv_task) Failed to receive anything on network channel, is there a sender?");
continue;
}

recv_time.store(current_epoch(), std::sync::atomic::Ordering::Relaxed);

rakrs_debug!(true, "[CLIENT] (recv_task) Recieved packet!");
rakrs_debug!(true, "[CLIENT] (recv_task) Received packet!");

let mut client_state = state.lock().await;

Expand Down Expand Up @@ -703,13 +703,13 @@ impl Client {
// todo: add ping time to client
rakrs_debug!(
true,
"[CLIENT] Recieved pong packet!"
"[CLIENT] Received pong packet!"
);
}
OnlinePacket::Disconnect(_) => {
rakrs_debug!(
true,
"[CLIENT] Recieved disconnect packet!"
"[CLIENT] Received disconnect packet!"
);
break 'task_loop;
}
Expand All @@ -727,7 +727,7 @@ impl Client {
}
},
RakPacket::Offline(_) => {
rakrs_debug!("[CLIENT] Recieved offline packet after handshake! In future versions this will kill the client.");
rakrs_debug!("[CLIENT] Received offline packet after handshake! In future versions this will kill the client.");
}
}
} else {
Expand Down
75 changes: 60 additions & 15 deletions src/protocol/mcpe/motd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use binary_util::interfaces::{Reader, Writer};
use binary_util::io::{ByteReader, ByteWriter};
use std::str::FromStr;

#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -33,12 +34,30 @@ impl std::fmt::Display for Gamemode {
}
}

impl FromStr for Gamemode {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Survival" => Ok(Gamemode::Survival),
"Creative" => Ok(Gamemode::Creative),
"Adventure" => Ok(Gamemode::Adventure),
"Spectator" => Ok(Gamemode::Spectator),
_ => Err(format!("Invalid gamemode {}", s)),
}
}
}

/// Protocol wise, motd is just a string
/// However we're using this struct to represent the motd
#[derive(Debug, Clone)]
pub struct Motd {
/// The edition of the server (MCPE or MCEE)
pub edition: String,
/// The name of the server
pub name: String,
/// The second line of the server MOTD
pub sub_name: String,
/// The protocol version
pub protocol: u16,
/// The version of the server
Expand All @@ -51,17 +70,21 @@ pub struct Motd {
pub gamemode: Gamemode,
/// The server's GUID
pub server_guid: u64,
/// The server's port
/// The server's IPv4 port
pub port: String,
/// The IPv6 port
// TODO: Implement this
pub ipv6_port: String,
/// Is Nintendo limited
pub nintendo_limited: bool,
}

impl Motd {
pub fn new<S: Into<String>>(server_guid: u64, port: S) -> Self {
Self {
edition: "MCPE".into(),
name: "Netrex Server".into(),
sub_name: "Netrex".into(),
player_count: 10,
player_max: 100,
protocol: 448,
Expand All @@ -70,23 +93,28 @@ impl Motd {
server_guid,
port: port.into(),
ipv6_port: "19133".into(),
nintendo_limited: false,
}
}

/// Takes the Motd and parses it into a valid MCPE
/// MOTD buffer.
pub fn write(&self) -> String {
let props: Vec<String> = vec![
"MCPE".into(),
self.edition.clone(),
self.name.clone(),
self.protocol.to_string(),
self.version.clone(),
self.player_count.to_string(),
self.player_max.to_string(),
self.server_guid.to_string(),
"Netrex".to_string(),
self.sub_name.clone(),
self.gamemode.as_str().to_string(),
"1".to_string(),
if self.nintendo_limited {
"0".into()
} else {
"1".into()
},
// TODO: Figure out why this is not working
// self.gamemode.to_string(),
self.port.to_string(),
Expand All @@ -110,6 +138,14 @@ impl Reader<Motd> for Motd {
.map(|c| c.to_string())
.collect::<Vec<String>>();

let edition = parts
.get(0)
.ok_or(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid motd edition",
))?
.clone();

let name = parts
.get(1)
.ok_or(std::io::Error::new(
Expand Down Expand Up @@ -158,6 +194,14 @@ impl Reader<Motd> for Motd {
))?
.clone();

let sub_name = parts
.get(7)
.ok_or(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid motd sub name",
))?
.clone();

let gamemode = parts
.get(8)
.ok_or(std::io::Error::new(
Expand All @@ -166,6 +210,14 @@ impl Reader<Motd> for Motd {
))?
.clone();

let nintendo_limited = parts
.get(9)
.ok_or(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid motd nintendo limited",
))?
.clone();

let port = parts
.get(10)
.ok_or(std::io::Error::new(
Expand All @@ -183,23 +235,16 @@ impl Reader<Motd> for Motd {
.clone();

Ok(Motd {
edition,
name,
protocol: protocol.as_str().parse().unwrap(),
version,
player_count: player_count.parse().unwrap(),
player_max: player_max.parse().unwrap(),
server_guid: server_guid.parse().unwrap(),
gamemode: match gamemode
.as_str()
.parse::<u8>()
.expect("Gamemode is not a byte")
{
0 => Gamemode::Survival,
1 => Gamemode::Creative,
2 => Gamemode::Adventure,
3 => Gamemode::Spectator,
_ => Gamemode::Survival,
},
sub_name,
gamemode: Gamemode::from_str(&gamemode).unwrap_or(Gamemode::Survival),
nintendo_limited: if nintendo_limited == "0" { true } else { false },
port,
ipv6_port,
})
Expand Down
Loading