aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-13 00:07:21 -0600
committermat <github@matdoes.dev>2021-12-13 00:07:21 -0600
commitc96ae8fce4e53ea9fad111ac7f479f2fa33ef859 (patch)
tree2d35061fa712464b225317f56a806d0dd269ca82
parent2c3bf3b79e133acd01580144771a7cf238ecc4ee (diff)
downloadazalea-drasl-c96ae8fce4e53ea9fad111ac7f479f2fa33ef859.tar.xz
start implementing joining servers
-rw-r--r--bot/src/main.rs10
-rw-r--r--minecraft-chat/src/text_component.rs4
-rw-r--r--minecraft-client/src/connect.rs49
-rw-r--r--minecraft-client/src/lib.rs3
-rw-r--r--minecraft-client/src/listeners/handshake.rs0
-rw-r--r--minecraft-client/src/listeners/mod.rs3
-rw-r--r--minecraft-client/src/ping.rs7
-rw-r--r--minecraft-protocol/src/connect.rs (renamed from minecraft-protocol/src/connection.rs)0
-rw-r--r--minecraft-protocol/src/lib.rs9
-rw-r--r--minecraft-protocol/src/mc_buf.rs23
-rw-r--r--minecraft-protocol/src/packets/game/mod.rs3
-rw-r--r--minecraft-protocol/src/packets/handshake/mod.rs5
-rw-r--r--minecraft-protocol/src/packets/login/clientbound_hello_packet.rs40
-rw-r--r--minecraft-protocol/src/packets/login/mod.rs7
-rw-r--r--minecraft-protocol/src/packets/login/serverbound_hello_packet.rs29
-rw-r--r--minecraft-protocol/src/packets/mod.rs177
-rw-r--r--minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs12
-rw-r--r--minecraft-protocol/src/packets/status/mod.rs78
-rw-r--r--minecraft-protocol/src/packets/status/serverbound_status_request_packet.rs14
19 files changed, 376 insertions, 97 deletions
diff --git a/bot/src/main.rs b/bot/src/main.rs
index 75a11dfd..2d62208d 100644
--- a/bot/src/main.rs
+++ b/bot/src/main.rs
@@ -1,11 +1,11 @@
-use minecraft_client::ping;
-use minecraft_protocol::ServerAddress;
+use minecraft_client::{connect::join_server, ping::ping_server};
use tokio::runtime::Runtime;
async fn bot() {
- let address = ServerAddress::parse(&"mc.hypixel.net".to_string()).unwrap();
- let response = ping::ping_server(&address).await.unwrap();
- println!("{}", response.description.to_ansi(None));
+ let address = "localhost:63425";
+ let response = join_server(&address.try_into().unwrap()).await.unwrap();
+ // println!("{}", response.description.to_ansi(None));
+ println!("connected");
}
fn main() {
diff --git a/minecraft-chat/src/text_component.rs b/minecraft-chat/src/text_component.rs
index a5030fa1..25341086 100644
--- a/minecraft-chat/src/text_component.rs
+++ b/minecraft-chat/src/text_component.rs
@@ -27,9 +27,7 @@ pub fn legacy_color_code_to_text_component(legacy_color_code: &str) -> TextCompo
if legacy_color_code.chars().nth(i).unwrap() == LEGACY_FORMATTING_CODE_SYMBOL {
let formatting_code = legacy_color_code.chars().nth(i + 1).unwrap();
if let Ok(formatter) = ChatFormatting::from_code(formatting_code) {
- if components.is_empty() {
- components.push(TextComponent::new("".to_string()));
- } else if !components.last().unwrap().text.is_empty() {
+ if components.is_empty() || !components.last().unwrap().text.is_empty() {
components.push(TextComponent::new("".to_string()));
}
diff --git a/minecraft-client/src/connect.rs b/minecraft-client/src/connect.rs
new file mode 100644
index 00000000..1d49fb89
--- /dev/null
+++ b/minecraft-client/src/connect.rs
@@ -0,0 +1,49 @@
+///! Connect to Minecraft servers.
+use minecraft_protocol::{
+ connect::Connection,
+ packets::{
+ handshake::client_intention_packet::ClientIntentionPacket,
+ login::serverbound_hello_packet::ServerboundHelloPacket,
+ status::clientbound_status_response_packet::ClientboundStatusResponsePacket,
+ ConnectionProtocol, Packet, PacketTrait, PROTOCOL_VERSION,
+ },
+ resolver, ServerAddress,
+};
+
+pub async fn join_server(address: &ServerAddress) -> Result<(), String> {
+ let username = "bot".to_string();
+
+ let resolved_address = resolver::resolve_address(address).await?;
+
+ let mut conn = Connection::new(&resolved_address).await?;
+
+ // handshake
+ conn.send_packet(
+ ClientIntentionPacket {
+ protocol_version: PROTOCOL_VERSION,
+ hostname: address.host.clone(),
+ port: address.port,
+ intention: ConnectionProtocol::Login,
+ }
+ .get(),
+ )
+ .await;
+ conn.switch_state(ConnectionProtocol::Login);
+
+ // login start
+ conn.send_packet(ServerboundHelloPacket { username }.get())
+ .await;
+
+ // encryption request
+ let packet = conn.read_packet().await.unwrap();
+ let encryption_request_packet = match packet {
+ Packet::ClientboundHelloPacket(p) => p,
+ _ => Err(format!("Invalid packet type: {:?}", packet))?,
+ };
+
+ // TODO: client auth
+
+ // TODO: encryption response
+
+ Ok(())
+}
diff --git a/minecraft-client/src/lib.rs b/minecraft-client/src/lib.rs
index 1fc97709..d4ceebde 100644
--- a/minecraft-client/src/lib.rs
+++ b/minecraft-client/src/lib.rs
@@ -1,3 +1,6 @@
+//! Significantly abstract minecraft-protocol so it's actually useable for bots.
+
+pub mod connect;
pub mod ping;
#[cfg(test)]
diff --git a/minecraft-client/src/listeners/handshake.rs b/minecraft-client/src/listeners/handshake.rs
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/minecraft-client/src/listeners/handshake.rs
diff --git a/minecraft-client/src/listeners/mod.rs b/minecraft-client/src/listeners/mod.rs
new file mode 100644
index 00000000..1f174453
--- /dev/null
+++ b/minecraft-client/src/listeners/mod.rs
@@ -0,0 +1,3 @@
+trait PacketListener {
+ handle(Packet)
+} \ No newline at end of file
diff --git a/minecraft-client/src/ping.rs b/minecraft-client/src/ping.rs
index 05aa84be..a7a01786 100644
--- a/minecraft-client/src/ping.rs
+++ b/minecraft-client/src/ping.rs
@@ -1,14 +1,13 @@
///! Ping Minecraft servers.
-
use minecraft_protocol::{
- connection::Connection,
+ connect::Connection,
packets::{
handshake::client_intention_packet::ClientIntentionPacket,
status::{
clientbound_status_response_packet::ClientboundStatusResponsePacket,
serverbound_status_request_packet::ServerboundStatusRequestPacket,
},
- ConnectionProtocol, Packet, PacketTrait,
+ ConnectionProtocol, Packet, PacketTrait, PROTOCOL_VERSION,
},
resolver, ServerAddress,
};
@@ -23,7 +22,7 @@ pub async fn ping_server(
// send the client intention packet and switch to the status state
conn.send_packet(
ClientIntentionPacket {
- protocol_version: 757,
+ protocol_version: PROTOCOL_VERSION,
hostname: address.host.clone(),
port: address.port,
intention: ConnectionProtocol::Status,
diff --git a/minecraft-protocol/src/connection.rs b/minecraft-protocol/src/connect.rs
index 5b750802..5b750802 100644
--- a/minecraft-protocol/src/connection.rs
+++ b/minecraft-protocol/src/connect.rs
diff --git a/minecraft-protocol/src/lib.rs b/minecraft-protocol/src/lib.rs
index 5d6c8330..31b50164 100644
--- a/minecraft-protocol/src/lib.rs
+++ b/minecraft-protocol/src/lib.rs
@@ -3,7 +3,7 @@
use std::net::IpAddr;
use std::str::FromStr;
-pub mod connection;
+pub mod connect;
pub mod mc_buf;
pub mod packets;
pub mod resolver;
@@ -20,9 +20,12 @@ pub struct ServerIpAddress {
pub port: u16,
}
-impl ServerAddress {
+// impl try_from for ServerAddress
+impl<'a> TryFrom<&'a str> for ServerAddress {
+ type Error = String;
+
/// Convert a Minecraft server address (host:port, the port is optional) to a ServerAddress
- pub fn parse(string: &str) -> Result<ServerAddress, String> {
+ fn try_from(string: &str) -> Result<Self, Self::Error> {
if string.is_empty() {
return Err("Empty string".to_string());
}
diff --git a/minecraft-protocol/src/mc_buf.rs b/minecraft-protocol/src/mc_buf.rs
index 6c812058..3490a66f 100644
--- a/minecraft-protocol/src/mc_buf.rs
+++ b/minecraft-protocol/src/mc_buf.rs
@@ -23,6 +23,17 @@ pub fn write_byte(buf: &mut Vec<u8>, n: u8) {
WriteBytesExt::write_u8(buf, n).unwrap();
}
+pub async fn read_bytes<T: AsyncRead + std::marker::Unpin>(
+ buf: &mut BufReader<T>,
+ n: usize,
+) -> Result<Vec<u8>, String> {
+ let mut bytes = vec![0; n];
+ match AsyncReadExt::read_exact(buf, &mut bytes).await {
+ Ok(_) => Ok(bytes),
+ Err(_) => Err("Error reading bytes".to_string()),
+ }
+}
+
pub fn write_bytes(buf: &mut Vec<u8>, bytes: &[u8]) {
buf.extend_from_slice(bytes);
}
@@ -159,3 +170,15 @@ pub fn write_utf(buf: &mut Vec<u8>, string: &str) {
pub fn write_short(buf: &mut Vec<u8>, n: u16) {
WriteBytesExt::write_u16::<BigEndian>(buf, n).unwrap();
}
+
+pub async fn read_byte_array<T: AsyncRead + std::marker::Unpin>(
+ buf: &mut BufReader<T>,
+) -> Result<Vec<u8>, String> {
+ let length = read_varint(buf).await?.0 as usize;
+ Ok(read_bytes(buf, length).await?)
+}
+
+pub fn write_byte_array(buf: &mut Vec<u8>, bytes: &[u8]) {
+ write_varint(buf, bytes.len() as i32);
+ write_bytes(buf, bytes);
+}
diff --git a/minecraft-protocol/src/packets/game/mod.rs b/minecraft-protocol/src/packets/game/mod.rs
index 8b137891..08444697 100644
--- a/minecraft-protocol/src/packets/game/mod.rs
+++ b/minecraft-protocol/src/packets/game/mod.rs
@@ -1 +1,2 @@
-
+#[derive(Clone, Debug)]
+pub enum GamePacket {}
diff --git a/minecraft-protocol/src/packets/handshake/mod.rs b/minecraft-protocol/src/packets/handshake/mod.rs
index 667b00f2..d2716299 100644
--- a/minecraft-protocol/src/packets/handshake/mod.rs
+++ b/minecraft-protocol/src/packets/handshake/mod.rs
@@ -1 +1,6 @@
pub mod client_intention_packet;
+
+#[derive(Clone, Debug)]
+pub enum HandshakePacket {
+ ClientIntentionPacket(client_intention_packet::ClientIntentionPacket),
+}
diff --git a/minecraft-protocol/src/packets/login/clientbound_hello_packet.rs b/minecraft-protocol/src/packets/login/clientbound_hello_packet.rs
new file mode 100644
index 00000000..878ca456
--- /dev/null
+++ b/minecraft-protocol/src/packets/login/clientbound_hello_packet.rs
@@ -0,0 +1,40 @@
+use async_trait::async_trait;
+use std::hash::Hash;
+use tokio::io::BufReader;
+
+use crate::{
+ mc_buf,
+ packets::{Packet, PacketTrait},
+};
+
+#[derive(Hash, Clone, Debug)]
+pub struct ClientboundHelloPacket {
+ pub server_id: String,
+ pub public_key: Vec<u8>,
+ pub nonce: Vec<u8>,
+}
+
+#[async_trait]
+impl PacketTrait for ClientboundHelloPacket {
+ fn get(self) -> Packet {
+ Packet::ClientboundHelloPacket(self)
+ }
+ fn write(&self, _buf: &mut Vec<u8>) {
+ panic!("ClientboundHelloPacket::write not implemented")
+ }
+
+ async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ buf: &mut BufReader<T>,
+ ) -> Result<Packet, String> {
+ let server_id = mc_buf::read_utf_with_len(buf, 20).await?;
+ let public_key = mc_buf::read_byte_array(buf).await?;
+ let nonce = mc_buf::read_byte_array(buf).await?;
+
+ Ok(ClientboundHelloPacket {
+ server_id,
+ public_key,
+ nonce,
+ }
+ .get())
+ }
+}
diff --git a/minecraft-protocol/src/packets/login/mod.rs b/minecraft-protocol/src/packets/login/mod.rs
index 8b137891..47193f92 100644
--- a/minecraft-protocol/src/packets/login/mod.rs
+++ b/minecraft-protocol/src/packets/login/mod.rs
@@ -1 +1,8 @@
+pub mod clientbound_hello_packet;
+pub mod serverbound_hello_packet;
+#[derive(Clone, Debug)]
+pub enum LoginPacket {
+ ServerboundHelloPacket(serverbound_hello_packet::ServerboundHelloPacket),
+ ClientboundHelloPacket(clientbound_hello_packet::ClientboundHelloPacket),
+}
diff --git a/minecraft-protocol/src/packets/login/serverbound_hello_packet.rs b/minecraft-protocol/src/packets/login/serverbound_hello_packet.rs
new file mode 100644
index 00000000..cadf9f7b
--- /dev/null
+++ b/minecraft-protocol/src/packets/login/serverbound_hello_packet.rs
@@ -0,0 +1,29 @@
+use async_trait::async_trait;
+use std::hash::Hash;
+use tokio::io::BufReader;
+
+use crate::{
+ mc_buf,
+ packets::{Packet, PacketTrait},
+};
+
+#[derive(Hash, Clone, Debug)]
+pub struct ServerboundHelloPacket {
+ pub username: String,
+}
+
+#[async_trait]
+impl PacketTrait for ServerboundHelloPacket {
+ fn get(self) -> Packet {
+ Packet::ServerboundHelloPacket(self)
+ }
+ fn write(&self, buf: &mut Vec<u8>) {
+ mc_buf::write_utf(buf, &self.username);
+ }
+
+ async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ _buf: &mut BufReader<T>,
+ ) -> Result<Packet, String> {
+ Err("ServerboundHelloPacket::read not implemented".to_string())
+ }
+}
diff --git a/minecraft-protocol/src/packets/mod.rs b/minecraft-protocol/src/packets/mod.rs
index bacd0c27..46caf02b 100644
--- a/minecraft-protocol/src/packets/mod.rs
+++ b/minecraft-protocol/src/packets/mod.rs
@@ -6,7 +6,9 @@ pub mod status;
use async_trait::async_trait;
use tokio::io::{AsyncRead, BufReader};
-use crate::connection::PacketFlow;
+use crate::connect::PacketFlow;
+
+pub const PROTOCOL_VERSION: u32 = 757;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ConnectionProtocol {
@@ -18,90 +20,123 @@ pub enum ConnectionProtocol {
#[derive(Clone, Debug)]
pub enum Packet {
- // game
-
- // handshake
- ClientIntentionPacket(handshake::client_intention_packet::ClientIntentionPacket),
-
- // login
-
- // status
- ServerboundStatusRequestPacket(
- status::serverbound_status_request_packet::ServerboundStatusRequestPacket,
- ),
- ClientboundStatusResponsePacket(
- status::clientbound_status_response_packet::ClientboundStatusResponsePacket,
- ),
+ Game(game::GamePacket),
+ Handshake(handshake::HandshakePacket),
+ Login(login::LoginPacket),
+ Status(status::StatusPacket),
}
-// 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,
- }
- }
+#[async_trait]
+pub trait ProtocolPacket {
+ fn get_inner<P: PacketTrait>(&self) -> &P;
+
+ fn id(&self) -> u32;
/// Read a packet by its id, ConnectionProtocol, and flow
- pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+ async fn read<
+ T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send,
+ P: ProtocolPacket,
+ >(
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);
- }
+ ) -> Result<P, String>
+ where
+ Self: Sized;
+
+ fn write(&self, buf: &mut Vec<u8>);
}
+// impl Packet {
+// fn get_inner_packet(&self) -> &dyn PacketTrait {
+// match self {
+// Packet::ClientIntentionPacket(packet) => packet,
+// Packet::ServerboundStatusRequestPacket(packet) => packet,
+// Packet::ClientboundStatusResponsePacket(packet) => packet,
+// Packet::ServerboundHelloPacket(packet) => packet,
+// Packet::ClientboundHelloPacket(packet) => packet,
+// }
+// }
+
+// pub fn id(&self) -> u32 {
+// match self {
+// Packet::ClientIntentionPacket(_packet) => 0x00,
+// Packet::ServerboundStatusRequestPacket(_packet) => 0x00,
+// Packet::ClientboundStatusResponsePacket(_packet) => 0x00,
+// Packet::ServerboundHelloPacket(_packet) => 0x00,
+// Packet::ClientboundHelloPacket(_packet) => 0x01,
+// }
+// }
+
+// /// 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 flow {
+// PacketFlow::ClientToServer => match id {
+// 0x00 => Ok(
+// handshake::client_intention_packet::ClientIntentionPacket::read(buf).await?,
+// ),
+// _ => Err(format!("Unknown ClientToServer handshake packet id: {}", id)),
+// }
+// PacketFlow::ServerToClient => Err("ServerToClient handshake packets not implemented".to_string()),
+// },
+
+// 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 ServerToClient status packet id: {}", id)),
+// },
+// PacketFlow::ClientToServer => match id {
+// 0x00 => Ok(
+// status::serverbound_status_request_packet::ServerboundStatusRequestPacket
+// ::read(buf)
+// .await?,
+// ),
+// _ => Err(format!("Unknown ClientToServer status packet id: {}", id)),
+// },
+// },
+
+// ConnectionProtocol::Login => match flow {
+// PacketFlow::ServerToClient => match id {
+// 0x01 => Ok(
+// login::clientbound_hello_packet::ClientboundHelloPacket::read(buf).await?,
+// ),
+// _ => Err(format!("Unknown ServerToClient login packet id: {}", id)),
+// },
+// PacketFlow::ClientToServer => match id {
+// 0x00 => Ok(
+// login::serverbound_hello_packet::ServerboundHelloPacket::read(buf).await?,
+// ),
+// _ => Err(format!("Unknown ClientToServer login packet id: {}", id)),
+// },
+// },
+// }
+// }
+
+// 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 get<P: ProtocolPacket>(self) -> P;
fn write(&self, buf: &mut Vec<u8>);
- async fn read<T: AsyncRead + std::marker::Unpin + std::marker::Send>(
+ async fn read<T: AsyncRead + std::marker::Unpin + std::marker::Send, P: ProtocolPacket>(
buf: &mut BufReader<T>,
- ) -> Result<Packet, String>
+ ) -> Result<P, String>
where
Self: Sized;
}
diff --git a/minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs b/minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs
index 99bef586..30b1403c 100644
--- a/minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs
+++ b/minecraft-protocol/src/packets/status/clientbound_status_response_packet.rs
@@ -9,9 +9,11 @@ use crate::{
packets::{Packet, PacketTrait},
};
+use super::StatusPacket;
+
#[derive(Clone, Debug, Deserialize)]
pub struct Version {
- pub name: String,
+ pub name: Component,
pub protocol: u32,
}
@@ -31,14 +33,16 @@ pub struct Players {
// the entire packet is just json, which is why it has deserialize
#[derive(Clone, Debug, Deserialize)]
pub struct ClientboundStatusResponsePacket {
- pub version: Version,
pub description: Component,
+ pub favicon: Option<String>,
+ pub players: Players,
+ pub version: Version,
}
#[async_trait]
impl PacketTrait for ClientboundStatusResponsePacket {
- fn get(self) -> Packet {
- Packet::ClientboundStatusResponsePacket(self)
+ fn get(self) -> StatusPacket {
+ StatusPacket::ClientboundStatusResponsePacket(self)
}
fn write(&self, _buf: &mut Vec<u8>) {}
diff --git a/minecraft-protocol/src/packets/status/mod.rs b/minecraft-protocol/src/packets/status/mod.rs
index efc03631..7e327ca7 100644
--- a/minecraft-protocol/src/packets/status/mod.rs
+++ b/minecraft-protocol/src/packets/status/mod.rs
@@ -1,2 +1,80 @@
pub mod clientbound_status_response_packet;
pub mod serverbound_status_request_packet;
+
+use async_trait::async_trait;
+use tokio::io::BufReader;
+
+use crate::connect::PacketFlow;
+
+use super::{ConnectionProtocol, PacketTrait, ProtocolPacket};
+
+#[derive(Clone, Debug)]
+pub enum StatusPacket {
+ ServerboundStatusRequestPacket(
+ serverbound_status_request_packet::ServerboundStatusRequestPacket,
+ ),
+ ClientboundStatusResponsePacket(
+ clientbound_status_response_packet::ClientboundStatusResponsePacket,
+ ),
+}
+
+// #[async_trait]
+// impl ProtocolPacket for StatusPacket {
+impl StatusPacket {
+ fn get_inner(self) -> impl PacketTrait {
+ match self {
+ StatusPacket::ServerboundStatusRequestPacket(packet) => packet,
+ StatusPacket::ClientboundStatusResponsePacket(packet) => packet,
+ }
+ }
+ // fn get_inner(&self) -> StatusPacket {
+ // match self {
+ // StatusPacket::ServerboundStatusRequestPacket(packet) => packet,
+ // StatusPacket::ClientboundStatusResponsePacket(packet) => packet,
+ // }
+ // }
+
+ fn id(&self) -> u32 {
+ match self {
+ StatusPacket::ServerboundStatusRequestPacket(_packet) => 0x00,
+ StatusPacket::ClientboundStatusResponsePacket(_packet) => 0x00,
+ }
+ }
+
+ fn write(&self, buf: &mut Vec<u8>) {
+ match self {
+ StatusPacket::ServerboundStatusRequestPacket(packet) => packet.write(buf),
+ StatusPacket::ClientboundStatusResponsePacket(packet) => packet.write(buf),
+ }
+ }
+
+ /// Read a packet by its id, ConnectionProtocol, and flow
+ async fn read<
+ T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send,
+ P: ProtocolPacket,
+ >(
+ id: u32,
+ flow: &PacketFlow,
+ buf: &mut BufReader<T>,
+ ) -> Result<P, String>
+ where
+ Self: Sized,
+ {
+ match flow {
+ PacketFlow::ServerToClient => match id {
+ 0x00 => Ok(
+ clientbound_status_response_packet::ClientboundStatusResponsePacket::read(buf)
+ .await?,
+ ),
+ _ => Err(format!("Unknown ServerToClient status packet id: {}", id)),
+ },
+ PacketFlow::ClientToServer => match id {
+ 0x00 => Ok(
+ serverbound_status_request_packet::ServerboundStatusRequestPacket::read(buf)
+ .await?,
+ ),
+ _ => Err(format!("Unknown ClientToServer status packet id: {}", id)),
+ },
+ }
+ }
+}
diff --git a/minecraft-protocol/src/packets/status/serverbound_status_request_packet.rs b/minecraft-protocol/src/packets/status/serverbound_status_request_packet.rs
index 56799677..066131cc 100644
--- a/minecraft-protocol/src/packets/status/serverbound_status_request_packet.rs
+++ b/minecraft-protocol/src/packets/status/serverbound_status_request_packet.rs
@@ -2,19 +2,21 @@ use async_trait::async_trait;
use std::hash::Hash;
use tokio::io::BufReader;
-use crate::{
- packets::{Packet, PacketTrait},
-};
+use crate::packets::{Packet, PacketTrait, ProtocolPacket};
+
+use super::StatusPacket;
#[derive(Hash, Clone, Debug)]
pub struct ServerboundStatusRequestPacket {}
#[async_trait]
impl PacketTrait for ServerboundStatusRequestPacket {
- fn get(self) -> Packet {
- Packet::ServerboundStatusRequestPacket(self)
+ fn get(self) -> StatusPacket {
+ StatusPacket::ServerboundStatusRequestPacket(self)
+ }
+ fn write(&self, _buf: &mut Vec<u8>) {
+ panic!("ServerboundStatusRequestPacket::write not implemented")
}
- fn write(&self, _buf: &mut Vec<u8>) {}
async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
_buf: &mut BufReader<T>,