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

Registry data #8

Merged
merged 8 commits into from
Nov 30, 2023
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
4 changes: 3 additions & 1 deletion mclib/main/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub use mclib_protocol::types::base::MCType;
pub mod packets {
pub mod server {
pub use mclib_protocol::packets::server::handshake::{Handshake, HandshakeNextState};
pub use mclib_protocol::packets::server::login_acknowledged::LoginAcknowledged;
pub use mclib_protocol::packets::server::login_start::LoginStart;
pub use mclib_protocol::packets::server::ping::PingRequest;
pub use mclib_protocol::packets::server::status_request::StatusRequest;
Expand All @@ -26,7 +27,7 @@ pub mod types {
pub use mclib_protocol::types::varint::MCVarInt;
}
pub mod nbt {
pub use mclib_protocol::nbt::tags::base::NBTTag;
pub use mclib_protocol::nbt::tags::base::{IntoNBTTag, NBTTag};
pub use mclib_protocol::nbt::tags::byte::TagByte;
pub use mclib_protocol::nbt::tags::byte_array::TagByteArray;
pub use mclib_protocol::nbt::tags::compound::TagCompound;
Expand All @@ -37,4 +38,5 @@ pub mod nbt {
pub use mclib_protocol::nbt::tags::long::TagLong;
pub use mclib_protocol::nbt::tags::short::TagShort;
pub use mclib_protocol::nbt::tags::string::TagString;
pub use mclib_protocol::nbt::NBT;
}
1 change: 1 addition & 0 deletions mclib/protocol/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod nbt;
pub mod packets;
pub mod types;
pub mod utils;
39 changes: 35 additions & 4 deletions mclib/protocol/src/nbt.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
use crate::nbt::tags::base::NBTTag;
use crate::nbt::tags::base::{unpack_by_ty_id, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

pub mod tags;

pub struct NBT(Option<String>, Box<dyn NBTTag>);
#[derive(Debug)]
pub struct NBT(pub Option<String>, pub Box<dyn NBTTag>);

impl Clone for NBT {
// TODO
fn clone(&self) -> Self {
let bin = self.pack();
Self::unpack(&mut std::io::Cursor::new(bin), self.0.is_some())
}
}

impl NBT {
pub fn pack(&self) -> Vec<u8> {
Expand All @@ -16,6 +27,22 @@ impl NBT {
result.extend(self.1.pack());
result
}

pub fn unpack(src: &mut dyn Read, read_name: bool) -> Self {
let ty_id = src.read_byte();
let name = if read_name {
let name_length = i16::from_be_bytes([src.read_byte(), src.read_byte()]);
let mut name = Vec::new();
for _ in 0..name_length {
name.push(src.read_byte());
}
Some(String::from_utf8(name).unwrap())
} else {
None
};
let inner = unpack_by_ty_id(ty_id, src);
Self(name, inner)
}
}

#[cfg(test)]
Expand Down Expand Up @@ -129,8 +156,12 @@ mod tests {
let mut decoder = flate2::read::GzDecoder::new(std::io::Cursor::new(result));
let mut result = Vec::new();
decoder.read_to_end(&mut result).unwrap();
let p = nbt.pack();
assert_eq!(p[..p.len() - 1], result[..p.len() - 1]);
assert_eq!(nbt.pack(), result);

assert_eq!(
NBT::unpack(&mut std::io::Cursor::new(result.clone()), true).pack(),
result
)
}

#[test]
Expand Down
38 changes: 38 additions & 0 deletions mclib/protocol/src/nbt/tags/base.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,48 @@
use crate::nbt::tags::byte::TagByte;
use crate::nbt::tags::byte_array::TagByteArray;
use crate::nbt::tags::compound::TagCompound;
use crate::nbt::tags::double::TagDouble;
use crate::nbt::tags::float::TagFloat;
use crate::nbt::tags::int::TagInt;
use crate::nbt::tags::list::TagList;
use crate::nbt::tags::long::TagLong;
use crate::nbt::tags::short::TagShort;
use crate::nbt::tags::string::TagString;
use std::fmt::Debug;
use std::io::Read;

pub trait NBTTag: Debug {
fn ty_id(&self) -> u8;
fn pack(&self) -> Vec<u8>;
fn unpack(src: &mut dyn Read) -> Self
where
Self: Sized;
}

pub trait IntoNBTTag {
fn to_nbt(self) -> Box<dyn NBTTag>;
}

pub fn unpack_by_ty_id(ty_id: u8, src: &mut dyn Read) -> Box<dyn NBTTag> {
match ty_id {
1 => Box::new(TagByte::unpack(src)),
2 => Box::new(TagShort::unpack(src)),
3 => Box::new(TagInt::unpack(src)),
4 => Box::new(TagLong::unpack(src)),
5 => Box::new(TagFloat::unpack(src)),
6 => Box::new(TagDouble::unpack(src)),
7 => Box::new(TagByteArray::unpack(src)),
8 => Box::new(TagString::unpack(src)),
9 => Box::new(TagList::unpack(src)),
10 => Box::new(TagCompound::unpack(src)),
11 => {
todo!()
}
12 => {
todo!()
}
_ => {
todo!()
}
}
}
6 changes: 6 additions & 0 deletions mclib/protocol/src/nbt/tags/byte.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagByte(i8);
Expand All @@ -17,4 +19,8 @@ impl NBTTag for TagByte {
fn pack(&self) -> Vec<u8> {
vec![self.0 as u8]
}

fn unpack(src: &mut dyn Read) -> Self {
Self(src.read_byte() as i8)
}
}
18 changes: 17 additions & 1 deletion mclib/protocol/src/nbt/tags/byte_array.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagByteArray(Vec<i8>);
Expand All @@ -16,10 +18,24 @@ impl NBTTag for TagByteArray {

fn pack(&self) -> Vec<u8> {
let mut result = Vec::new();
result.extend((1000i32).to_be_bytes());
result.extend((self.0.len() as i32).to_be_bytes());
for b in &self.0 {
result.push(*b as u8);
}
result
}

fn unpack(src: &mut dyn Read) -> Self {
let length = i32::from_be_bytes([
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
]);
let mut result = Vec::new();
for _ in 0..length {
result.push(src.read_byte() as i8);
}
Self(result)
}
}
24 changes: 23 additions & 1 deletion mclib/protocol/src/nbt/tags/compound.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::nbt::tags::base::{unpack_by_ty_id, IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagCompound(Vec<(String, Box<dyn NBTTag>)>);
Expand Down Expand Up @@ -30,4 +32,24 @@ impl NBTTag for TagCompound {
result.push(0x00);
result
}

fn unpack(src: &mut dyn Read) -> Self {
let mut result = Vec::<(String, Box<dyn NBTTag>)>::new();
let read_name = |src: &mut dyn Read| {
let name_len = u16::from_be_bytes([src.read_byte(), src.read_byte()]);
let mut name_bytes = Vec::new();
for _ in 0..name_len {
name_bytes.push(src.read_byte());
}
String::from_utf8(name_bytes).unwrap()
};
loop {
let ty_id = src.read_byte();
if ty_id == 0 {
break;
}
result.push((read_name(src), unpack_by_ty_id(ty_id, src)));
}
Self(result)
}
}
15 changes: 15 additions & 0 deletions mclib/protocol/src/nbt/tags/double.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagDouble(f64);
Expand All @@ -17,4 +19,17 @@ impl NBTTag for TagDouble {
fn pack(&self) -> Vec<u8> {
self.0.to_be_bytes().to_vec()
}

fn unpack(src: &mut dyn Read) -> Self {
Self(f64::from_be_bytes([
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
]))
}
}
11 changes: 11 additions & 0 deletions mclib/protocol/src/nbt/tags/float.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagFloat(f32);
Expand All @@ -17,4 +19,13 @@ impl NBTTag for TagFloat {
fn pack(&self) -> Vec<u8> {
self.0.to_be_bytes().to_vec()
}

fn unpack(src: &mut dyn Read) -> Self {
Self(f32::from_be_bytes([
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
]))
}
}
11 changes: 11 additions & 0 deletions mclib/protocol/src/nbt/tags/int.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagInt(i32);
Expand All @@ -17,4 +19,13 @@ impl NBTTag for TagInt {
fn pack(&self) -> Vec<u8> {
self.0.to_be_bytes().to_vec()
}

fn unpack(src: &mut dyn Read) -> Self {
Self(i32::from_be_bytes([
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
]))
}
}
19 changes: 18 additions & 1 deletion mclib/protocol/src/nbt/tags/list.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::nbt::tags::base::{unpack_by_ty_id, IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagList(Vec<Box<dyn NBTTag>>);
Expand Down Expand Up @@ -29,4 +31,19 @@ impl NBTTag for TagList {
result.extend(elements);
result
}

fn unpack(src: &mut dyn Read) -> Self {
let mut result = Vec::<Box<dyn NBTTag>>::new();
let ty_id = src.read_byte();
let length = i32::from_be_bytes([
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
]);
for _ in 0..length {
result.push(unpack_by_ty_id(ty_id, src));
}
Self(result)
}
}
15 changes: 15 additions & 0 deletions mclib/protocol/src/nbt/tags/long.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagLong(i64);
Expand All @@ -17,4 +19,17 @@ impl NBTTag for TagLong {
fn pack(&self) -> Vec<u8> {
self.0.to_be_bytes().to_vec()
}

fn unpack(src: &mut dyn Read) -> Self {
Self(i64::from_be_bytes([
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
src.read_byte(),
]))
}
}
6 changes: 6 additions & 0 deletions mclib/protocol/src/nbt/tags/short.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagShort(i16);
Expand All @@ -17,4 +19,8 @@ impl NBTTag for TagShort {
fn pack(&self) -> Vec<u8> {
self.0.to_be_bytes().to_vec()
}

fn unpack(src: &mut dyn Read) -> Self {
Self(i16::from_be_bytes([src.read_byte(), src.read_byte()]))
}
}
11 changes: 11 additions & 0 deletions mclib/protocol/src/nbt/tags/string.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::nbt::tags::base::{IntoNBTTag, NBTTag};
use crate::utils::TcpUtils;
use std::io::Read;

#[derive(Debug)]
pub struct TagString(Vec<u8>);
Expand Down Expand Up @@ -26,4 +28,13 @@ impl NBTTag for TagString {
result.extend(&self.0);
result
}

fn unpack(src: &mut dyn Read) -> Self {
let length = u16::from_be_bytes([src.read_byte(), src.read_byte()]);
let mut result = Vec::new();
for _ in 0..length {
result.push(src.read_byte());
}
Self(result)
}
}
1 change: 1 addition & 0 deletions mclib/protocol/src/packets/client.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod login_success;
pub mod registry_data;
pub mod status_response;
11 changes: 11 additions & 0 deletions mclib/protocol/src/packets/client/registry_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use crate::packets::base::MCPacket;
use crate::types::base::MCType;
use crate::types::nbt::MCNBT;
use crate::types::varint::MCVarInt;
use mclib_macros::MCPacket;

#[derive(MCPacket, Debug, Clone)]
#[packet(packet_id = 0x05)]
pub struct RegistryData {
registry_codec: MCNBT,
}
1 change: 1 addition & 0 deletions mclib/protocol/src/packets/server.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod handshake;
pub mod login_acknowledged;
pub mod login_start;
pub mod ping;
pub mod status_request;
Loading