Skip to content

Commit

Permalink
bunger packets start
Browse files Browse the repository at this point in the history
  • Loading branch information
Shrecknt committed Feb 24, 2024
1 parent d204c52 commit e4a64df
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 0 deletions.
24 changes: 24 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = ["crates/*"]

[workspace.dependencies]
snowstorm = { version = "0.1.0", path = "crates/snowstorm" }
bunger = { version = "0.1.0", path = "crates/bunger" }
database = { version = "0.1.0", path = "crates/database" }
common = { version = "0.1.0", path = "crates/common" }
io = { version = "0.1.0", path = "crates/io" }
Expand Down Expand Up @@ -58,3 +59,4 @@ chrono = "0.4.34"
pretty-duration = "0.1.1"
toml = "0.8.10"
smart-default = "0.7.1"
flate2 = { version = "1.0.17", features = ["zlib"], default-features = false }
12 changes: 12 additions & 0 deletions crates/bunger/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "bunger"
version = "0.1.0"
edition = "2021"

[dependencies]
config = { workspace = true }
flate2 = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
eyre = { workspace = true }
71 changes: 71 additions & 0 deletions crates/bunger/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use flate2::read::ZlibDecoder;
use std::{
io::{Cursor, Read},
net::SocketAddrV4,
};
use tokio::{io::AsyncReadExt, net::TcpStream};

use crate::varint::AsyncVarint;

pub mod varint;

#[derive(Debug, Default)]
pub struct JoinData {
pub error: Option<String>,
}

impl JoinData {
pub fn new() -> Self {
Self::default()
}
}

pub async fn join(addr: SocketAddrV4) -> JoinData {
let mut join_data = JoinData::new();

let res = join_internal(addr, &mut join_data).await;
if let Err(err) = res {
join_data.error = Some(err.to_string());
}

join_data
}

async fn join_internal(addr: SocketAddrV4, join_data: &mut JoinData) -> eyre::Result<()> {
let mut stream = TcpStream::connect(addr).await?;

let packet = read_packet(&mut stream, false).await?;
println!("packet = {packet:?}");

Ok(())
}

async fn read_packet(stream: &mut TcpStream, compressed: bool) -> eyre::Result<(i32, Vec<u8>)> {
println!("a");
let packet_length = stream.read_varint().await?;

if compressed {
let (data_length_size, data_length) = stream.read_varint_len().await?;
if data_length != 0 {
let mut buf = Vec::with_capacity(data_length as usize);
stream.read_exact(&mut buf).await?;

let mut z = ZlibDecoder::new(Cursor::new(buf));
let mut buf = Vec::new();
z.read_to_end(&mut buf)?;

let mut buf = Cursor::new(buf);
let (packet_id_size, packet_id) = buf.read_varint_len().await?;
let mut packet = vec![0; packet_length as usize - packet_id_size as usize];
stream.read_exact(&mut packet).await?;

return Ok((packet_id, packet));
}
}

let (packet_id_size, packet_id) = stream.read_varint_len().await?;
let mut packet = vec![0; packet_length as usize - packet_id_size as usize];
stream.read_exact(&mut packet).await?;

Ok((packet_id, packet))
}
9 changes: 9 additions & 0 deletions crates/bunger/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use std::{net::SocketAddrV4, str::FromStr};

#[tokio::main]
async fn main() -> eyre::Result<()> {
let data = bunger::join(SocketAddrV4::from_str("130.61.123.184:25565").unwrap()).await;
println!("data = {data:?}");

Ok(())
}
50 changes: 50 additions & 0 deletions crates/bunger/src/varint/async.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use super::AsyncVarint;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

impl<T: AsyncReadExt + AsyncWriteExt + Send + Unpin + ?Sized> AsyncVarint for T {
type Error = tokio::io::Error;

async fn write_varint(&mut self, varint: i32) -> Result<(), Self::Error> {
let mut buffer = [0];
let mut value = varint;

if value == 0 {
self.write_all(&buffer).await?;
}

while value != 0 {
buffer[0] = (value & 0b0111_1111) as u8;
value = (value >> 7) & (i32::max_value() >> 6);
if value != 0 {
buffer[0] |= 0b1000_0000;
}
self.write_all(&buffer).await?;
}

Ok(())
}

async fn read_varint(&mut self) -> Result<i32, Self::Error> {
Ok(self.read_varint_len().await?.1)
}

async fn read_varint_len(&mut self) -> Result<(u32, i32), Self::Error> {
let mut buf = [0u8];
let mut res = 0;
let mut count = 0u32;

loop {
self.read_exact(&mut buf).await?;
res |= (buf[0] as i32 & (0b0111_1111_i32))
.checked_shl(7 * count)
.ok_or(tokio::io::ErrorKind::Other)?;

count += 1;
if count > 5 {
break Err(tokio::io::ErrorKind::Other.into());
} else if (buf[0] & (0b1000_0000_u8)) == 0 {
break Ok((count, res));
}
}
}
}
12 changes: 12 additions & 0 deletions crates/bunger/src/varint/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use std::future::Future;

pub mod r#async;

pub trait AsyncVarint {
type Error;

fn write_varint(&mut self, varint: i32)
-> impl Future<Output = Result<(), Self::Error>> + Send;
fn read_varint(&mut self) -> impl Future<Output = Result<i32, Self::Error>> + Send;
fn read_varint_len(&mut self) -> impl Future<Output = Result<(u32, i32), Self::Error>> + Send;
}

0 comments on commit e4a64df

Please sign in to comment.