aboutsummaryrefslogtreecommitdiff
path: root/minecraft-protocol/src/packets/mod.rs
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-10 00:54:58 -0600
committermat <github@matdoes.dev>2021-12-10 00:54:58 -0600
commitbe762fc5d37ba48386996afb4c5ba0c94aaf5883 (patch)
treea7c96227c51e291e4e59eab7a66c6bc223973e06 /minecraft-protocol/src/packets/mod.rs
parentf64750afdd9b18379f706df66c32806b6d21bbe8 (diff)
downloadazalea-drasl-be762fc5d37ba48386996afb4c5ba0c94aaf5883.tar.xz
rust is driving me insane
Diffstat (limited to 'minecraft-protocol/src/packets/mod.rs')
-rw-r--r--minecraft-protocol/src/packets/mod.rs93
1 files changed, 80 insertions, 13 deletions
diff --git a/minecraft-protocol/src/packets/mod.rs b/minecraft-protocol/src/packets/mod.rs
index 5fb34743..76f9128e 100644
--- a/minecraft-protocol/src/packets/mod.rs
+++ b/minecraft-protocol/src/packets/mod.rs
@@ -1,10 +1,12 @@
-mod game;
-mod handshake;
-mod login;
-mod status;
+pub mod game;
+pub mod handshake;
+pub mod login;
+pub mod status;
use async_trait::async_trait;
-use tokio::io::AsyncRead;
+use tokio::io::{AsyncRead, BufReader};
+
+use crate::connection::PacketFlow;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ConnectionProtocol {
@@ -16,24 +18,89 @@ pub enum ConnectionProtocol {
pub enum Packet<'a> {
// game
+
// handshake
- ClientIntentionPacket(&'a handshake::client_intention_packet::ClientIntentionPacket<'a>),
+ ClientIntentionPacket(handshake::client_intention_packet::ClientIntentionPacket<'a>),
+
// login
+
// status
ServerboundStatusRequestPacket(
- &'a status::serverbound_status_request_packet::ServerboundStatusRequestPacket,
+ status::serverbound_status_request_packet::ServerboundStatusRequestPacket,
),
- ClientboundStatusRequestPacket(
- &'a status::clientbound_status_response_packet::ClientboundStatusRequestPacket,
+ ClientboundStatusResponsePacket(
+ status::clientbound_status_response_packet::ClientboundStatusResponsePacket,
),
}
+// TODO: do all this with macros so it's less repetitive
+impl Packet<'_> {
+ fn get_inner_packet(&self) -> &dyn PacketTrait {
+ match self {
+ Packet::ClientIntentionPacket(packet) => packet,
+ Packet::ServerboundStatusRequestPacket(packet) => packet,
+ Packet::ClientboundStatusResponsePacket(packet) => packet,
+ }
+ }
+
+ pub fn id(&self) -> u32 {
+ match self {
+ Packet::ClientIntentionPacket(packet) => 0x00,
+ Packet::ServerboundStatusRequestPacket(packet) => 0x00,
+ Packet::ClientboundStatusResponsePacket(packet) => 0x00,
+ }
+ }
+
+ /// Read a packet by its id, ConnectionProtocol, and flow
+ pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ id: u32,
+ protocol: ConnectionProtocol,
+ flow: PacketFlow,
+ buf: &mut BufReader<T>,
+ ) -> Result<Packet<'_>, String> {
+ match protocol {
+ ConnectionProtocol::Handshake => match id {
+ 0x00 => Ok(
+ handshake::client_intention_packet::ClientIntentionPacket::read(buf).await?,
+ ),
+ _ => Err(format!("Unknown packet id: {}", id)),
+ },
+ ConnectionProtocol::Game => Err("Game protocol not implemented yet".to_string()),
+ ConnectionProtocol::Status => match flow {
+ PacketFlow::ServerToClient => match id {
+ 0x00 => Ok(
+ status::clientbound_status_response_packet::ClientboundStatusResponsePacket
+ ::read(buf)
+ .await?,
+ ),
+ _ => Err(format!("Unknown packet id: {}", id)),
+ },
+ PacketFlow::ClientToServer => match id {
+ 0x00 => Ok(
+ status::serverbound_status_request_packet::ServerboundStatusRequestPacket
+ ::read(buf)
+ .await?,
+ ),
+ _ => Err(format!("Unknown packet id: {}", id)),
+ },
+ },
+ ConnectionProtocol::Login => Err("Login protocol not implemented yet".to_string()),
+ }
+ }
+
+ pub fn write(&self, buf: &mut Vec<u8>) {
+ self.get_inner_packet().write(buf);
+ }
+}
+
+#[async_trait]
pub trait PacketTrait {
/// Return a version of the packet that you can actually use for stuff
fn get(&self) -> Packet;
fn write(&self, buf: &mut Vec<u8>) -> ();
- fn parse<T: AsyncRead + std::marker::Unpin>(
- buf: &mut T,
- // is using a static lifetime here a good idea? idk
- ) -> Result<Packet<'_>, String>;
+ async fn read<T: AsyncRead + std::marker::Unpin + std::marker::Send>(
+ buf: &mut BufReader<T>,
+ ) -> Result<Packet<'_>, String>
+ where
+ Self: Sized;
}