aboutsummaryrefslogtreecommitdiff
path: root/minecraft-protocol/src/connect.rs
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-15 13:43:57 -0600
committermat <github@matdoes.dev>2021-12-15 13:43:57 -0600
commit732de94d7b9f1bf2bc9239c8138a37c53242b470 (patch)
treeeaeaddbf73bf5379fbb1924e57a28b8dad5be48b /minecraft-protocol/src/connect.rs
parentace140500734d33fe53126086a8d9278fa861e21 (diff)
downloadazalea-drasl-732de94d7b9f1bf2bc9239c8138a37c53242b470.tar.xz
oh yeah it compiles
Diffstat (limited to 'minecraft-protocol/src/connect.rs')
-rw-r--r--minecraft-protocol/src/connect.rs121
1 files changed, 71 insertions, 50 deletions
diff --git a/minecraft-protocol/src/connect.rs b/minecraft-protocol/src/connect.rs
index 5b750802..7c6a5f18 100644
--- a/minecraft-protocol/src/connect.rs
+++ b/minecraft-protocol/src/connect.rs
@@ -1,6 +1,12 @@
//! parse sending and receiving packets with a server.
-use crate::packets::ConnectionProtocol;
+use crate::packets::game::GamePacket;
+use crate::packets::handshake::HandshakePacket;
+use crate::packets::login::LoginPacket;
+use crate::packets::status::StatusPacket;
+use crate::packets::{ConnectionProtocol, ProtocolPacket};
+use crate::read::read_packet;
+use crate::write::write_packet;
use crate::{mc_buf, packets::Packet, ServerIpAddress};
use tokio::io::AsyncWriteExt;
use tokio::{
@@ -13,15 +19,32 @@ pub enum PacketFlow {
ServerToClient,
}
-pub struct Connection {
- pub state: ConnectionProtocol,
+pub struct HandshakeConnection {
pub flow: PacketFlow,
/// The buffered writer
pub stream: TcpStream,
}
-impl Connection {
- pub async fn new(address: &ServerIpAddress) -> Result<Connection, String> {
+pub struct GameConnection {
+ pub flow: PacketFlow,
+ /// The buffered writer
+ pub stream: TcpStream,
+}
+
+pub struct StatusConnection {
+ pub flow: PacketFlow,
+ /// The buffered writer
+ pub stream: TcpStream,
+}
+
+pub struct LoginConnection {
+ pub flow: PacketFlow,
+ /// The buffered writer
+ pub stream: TcpStream,
+}
+
+impl HandshakeConnection {
+ pub async fn new(address: &ServerIpAddress) -> Result<HandshakeConnection, String> {
let ip = address.ip;
let port = address.port;
@@ -34,67 +57,65 @@ impl Connection {
.set_nodelay(true)
.expect("Error enabling tcp_nodelay");
- Ok(Connection {
- state: ConnectionProtocol::Handshake,
+ Ok(HandshakeConnection {
flow: PacketFlow::ServerToClient,
stream,
})
}
- pub fn switch_state(&mut self, state: ConnectionProtocol) {
- self.state = state;
+ pub fn login(self) -> LoginConnection {
+ LoginConnection {
+ flow: self.flow,
+ stream: self.stream,
+ }
}
- pub async fn read_packet(&mut self) -> Result<Packet, String> {
- // what this does:
- // 1. reads the first 5 bytes, probably only some of this will be used to get the packet length
- // 2. how much we should read = packet length - 5
- // 3. read the rest of the packet and add it to the cursor
- // 4. figure out what packet this is and parse it
-
- // the first thing minecraft sends us is the length as a varint, which can be up to 5 bytes long
- let mut buf = BufReader::with_capacity(4 * 1024 * 1024, &mut self.stream);
-
- let (_packet_size, _packet_size_varint_size) = mc_buf::read_varint(&mut buf).await?;
-
- // then, minecraft tells us the packet id as a varint
- let (packet_id, _packet_id_size) = mc_buf::read_varint(&mut buf).await?;
+ pub fn status(self) -> StatusConnection {
+ StatusConnection {
+ flow: self.flow,
+ stream: self.stream,
+ }
+ }
- // if we recognize the packet id, parse it
+ pub async fn read(&mut self) -> Result<HandshakePacket, String> {
+ read_packet::<HandshakePacket>(&self.flow, &mut self.stream).await
+ }
- let packet = Packet::read(
- packet_id.try_into().unwrap(),
- &self.state,
- &self.flow,
- &mut buf,
- )
- .await?;
+ /// Write a packet to the server
+ pub async fn write(&mut self, packet: HandshakePacket) {
+ write_packet(packet, &mut self.stream).await;
+ }
+}
- Ok(packet)
+impl GameConnection {
+ pub async fn read(&mut self) -> Result<GamePacket, String> {
+ read_packet::<GamePacket>(&self.flow, &mut self.stream).await
}
/// Write a packet to the server
- pub async fn send_packet(&mut self, packet: Packet) {
- // TODO: implement compression
-
- // packet structure:
- // length (varint) + id (varint) + data
+ pub async fn write(&mut self, packet: GamePacket) {
+ write_packet(packet, &mut self.stream).await;
+ }
+}
- // write the packet id
- let mut id_and_data_buf = vec![];
- mc_buf::write_varint(&mut id_and_data_buf, packet.id() as i32);
- packet.write(&mut id_and_data_buf);
+impl StatusConnection {
+ pub async fn read(&mut self) -> Result<StatusPacket, String> {
+ read_packet::<StatusPacket>(&self.flow, &mut self.stream).await
+ }
- // write the packet data
+ /// Write a packet to the server
+ pub async fn write(&mut self, packet: StatusPacket) {
+ write_packet(packet, &mut self.stream).await;
+ }
+}
- // make a new buffer that has the length at the beginning
- // and id+data at the end
- let mut complete_buf: Vec<u8> = Vec::new();
- mc_buf::write_varint(&mut complete_buf, id_and_data_buf.len() as i32);
- complete_buf.append(&mut id_and_data_buf);
+impl LoginConnection {
+ pub async fn read(&mut self) -> Result<LoginPacket, String> {
+ read_packet::<LoginPacket>(&self.flow, &mut self.stream).await
+ }
- // finally, write and flush to the stream
- self.stream.write_all(&complete_buf).await.unwrap();
- self.stream.flush().await.unwrap();
+ /// Write a packet to the server
+ pub async fn write(&mut self, packet: LoginPacket) {
+ write_packet(packet, &mut self.stream).await;
}
}