aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-20 15:22:02 -0600
committermat <github@matdoes.dev>2021-12-20 15:22:02 -0600
commit6ae94b96e6d51e3bf251d4a01f17fa7d41c9500f (patch)
tree3153984562016e703eefd71b4b1de4151d47fdde /azalea-protocol/src
parentcf88c7b7956398eba2e0d6ed86dbf3268fdb512b (diff)
downloadazalea-drasl-6ae94b96e6d51e3bf251d4a01f17fa7d41c9500f.tar.xz
start adding nbt to the protocol
Diffstat (limited to 'azalea-protocol/src')
-rw-r--r--azalea-protocol/src/mc_buf.rs42
-rw-r--r--azalea-protocol/src/packets/game/clientbound_login_packet.rs32
2 files changed, 60 insertions, 14 deletions
diff --git a/azalea-protocol/src/mc_buf.rs b/azalea-protocol/src/mc_buf.rs
index 84c602ec..3959560d 100644
--- a/azalea-protocol/src/mc_buf.rs
+++ b/azalea-protocol/src/mc_buf.rs
@@ -12,9 +12,10 @@ const MAX_STRING_LENGTH: u16 = 32767;
#[async_trait]
pub trait Writable {
- fn write_list<F, T>(&mut self, list: Vec<T>, writer: F) -> Result<(), std::io::Error>
+ fn write_list<F, T>(&mut self, list: &Vec<T>, writer: F) -> Result<(), std::io::Error>
where
- F: FnOnce(&mut Self, T) -> Result<(), std::io::Error> + Copy,
+ F: FnOnce(&mut Self, &T) -> Result<(), std::io::Error> + Copy,
+ T: Sized,
Self: Sized;
fn write_int_id_list(&mut self, list: Vec<i32>) -> Result<(), std::io::Error>;
fn write_map<KF, VF, KT, VT>(
@@ -36,13 +37,15 @@ pub trait Writable {
fn write_short(&mut self, n: u16) -> Result<(), std::io::Error>;
fn write_byte_array(&mut self, bytes: &[u8]) -> Result<(), std::io::Error>;
fn write_int(&mut self, n: i32) -> Result<(), std::io::Error>;
+ fn write_boolean(&mut self, b: bool) -> Result<(), std::io::Error>;
+ fn write_nbt(&mut self, nbt: &azalea_nbt::Tag) -> Result<(), std::io::Error>;
}
#[async_trait]
impl Writable for Vec<u8> {
- fn write_list<F, T>(&mut self, list: Vec<T>, writer: F) -> Result<(), std::io::Error>
+ fn write_list<F, T>(&mut self, list: &Vec<T>, writer: F) -> Result<(), std::io::Error>
where
- F: FnOnce(&mut Self, T) -> Result<(), std::io::Error> + Copy,
+ F: FnOnce(&mut Self, &T) -> Result<(), std::io::Error> + Copy,
Self: Sized,
{
self.write_varint(list.len() as i32)?;
@@ -53,7 +56,7 @@ impl Writable for Vec<u8> {
}
fn write_int_id_list(&mut self, list: Vec<i32>) -> Result<(), std::io::Error> {
- self.write_list(list, Self::write_varint)
+ self.write_list(&list, |buf, n| buf.write_varint(*n))
}
fn write_map<KF, VF, KT, VT>(
@@ -128,6 +131,15 @@ impl Writable for Vec<u8> {
fn write_int(&mut self, n: i32) -> Result<(), std::io::Error> {
WriteBytesExt::write_i32::<BigEndian>(self, n)
}
+
+ fn write_boolean(&mut self, b: bool) -> Result<(), std::io::Error> {
+ self.write_byte(if b { 1 } else { 0 })
+ }
+
+ fn write_nbt(&mut self, nbt: &azalea_nbt::Tag) -> Result<(), std::io::Error> {
+ nbt.write(self)
+ .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
+ }
}
#[async_trait]
@@ -142,6 +154,8 @@ pub trait Readable {
async fn read_utf_with_len(&mut self, max_length: u32) -> Result<String, String>;
async fn read_byte(&mut self) -> Result<u8, String>;
async fn read_int(&mut self) -> Result<i32, String>;
+ async fn read_boolean(&mut self) -> Result<bool, String>;
+ async fn read_nbt(&mut self) -> Result<azalea_nbt::Tag, String>;
}
#[async_trait]
@@ -261,6 +275,19 @@ where
Err(_) => Err("Error reading int".to_string()),
}
}
+
+ async fn read_boolean(&mut self) -> Result<bool, String> {
+ match self.read_byte().await {
+ Ok(0) => Ok(false),
+ Ok(1) => Ok(true),
+ _ => Err("Error reading boolean".to_string()),
+ }
+ }
+
+ async fn read_nbt(&mut self) -> Result<azalea_nbt::Tag, String> {
+ self.peek();
+ Ok(azalea_nbt::Tag::read(self).unwrap())
+ }
}
#[cfg(test)]
@@ -301,7 +328,7 @@ mod tests {
#[tokio::test]
async fn test_list() {
let mut buf = Vec::new();
- buf.write_list(vec!["a", "bc", "def"], Vec::write_utf)
+ buf.write_list(&vec!["a", "bc", "def"], |buf, s| buf.write_utf(s))
.unwrap();
// there's no read_list because idk how to do it in rust
@@ -319,7 +346,8 @@ mod tests {
#[tokio::test]
async fn test_int_id_list() {
let mut buf = Vec::new();
- buf.write_list(vec![1, 2, 3], Vec::write_varint).unwrap();
+ buf.write_list(&vec![1, 2, 3], |buf, i| buf.write_varint(*i))
+ .unwrap();
let mut buf = BufReader::new(Cursor::new(buf));
diff --git a/azalea-protocol/src/packets/game/clientbound_login_packet.rs b/azalea-protocol/src/packets/game/clientbound_login_packet.rs
index 0e23460e..54205c48 100644
--- a/azalea-protocol/src/packets/game/clientbound_login_packet.rs
+++ b/azalea-protocol/src/packets/game/clientbound_login_packet.rs
@@ -1,9 +1,8 @@
use super::GamePacket;
use crate::mc_buf::{Readable, Writable};
use azalea_core::{game_type::GameType, resource_location::ResourceLocation};
-use std::hash::Hash;
-#[derive(Hash, Clone, Debug)]
+#[derive(Clone, Debug)]
pub struct ClientboundLoginPacket {
// private final int playerId;
// private final boolean hardcore;
@@ -27,7 +26,17 @@ pub struct ClientboundLoginPacket {
pub game_type: GameType,
pub previous_game_type: Option<GameType>,
pub levels: Vec<ResourceLocation>,
- // pub registry_holder: azalea_core::registry::RegistryAccess,
+ pub registry_holder: azalea_nbt::Tag,
+ pub dimension_type: azalea_nbt::Tag,
+ pub dimension: ResourceLocation,
+ pub seed: i64,
+ pub max_players: i32,
+ pub chunk_radius: i32,
+ pub simulation_distance: i32,
+ pub reduced_debug_info: bool,
+ pub show_death_screen: bool,
+ pub is_debug: bool,
+ pub is_flat: bool,
}
impl ClientboundLoginPacket {
@@ -35,10 +44,19 @@ impl ClientboundLoginPacket {
GamePacket::ClientboundLoginPacket(self)
}
- pub fn write(&self, buf: &mut Vec<u8>) {
- buf.write_int(self.player_id);
- // buf.write_bool(self.hardcore);
- // buf.write_byte(self.game_type.
+ pub fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
+ buf.write_int(self.player_id)?;
+ buf.write_boolean(self.hardcore)?;
+ buf.write_byte(self.game_type.to_id())?;
+ buf.write_byte(GameType::to_optional_id(&self.previous_game_type) as u8)?;
+ buf.write_list(&self.levels, |buf, resource_location| {
+ buf.write_utf(&resource_location.to_string())
+ })?;
+ self.registry_holder
+ .write(buf)
+ .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "write registry holder"))?;
+
+ Ok(())
}
pub async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(