diff --git a/protocol/src/decoder.rs b/protocol/src/decoder.rs index 503db3b..5b756c9 100644 --- a/protocol/src/decoder.rs +++ b/protocol/src/decoder.rs @@ -239,6 +239,24 @@ impl Decoder for Vec { } } +// TODO(timvisee): forge mod channel decoder, we might want a custom type +impl Decoder for Vec<(String, String)> { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + let length = reader.read_var_i32()? as usize; + let mut vec = Vec::with_capacity(length); + + for _ in 0..length { + let a = reader.read_string(32767)?; + let b = reader.read_string(32767)?; + vec.push((a, b)); + } + + Ok(vec) + } +} + pub mod var_int { use crate::decoder::DecoderReadExt; use crate::error::DecodeError; diff --git a/protocol/src/encoder.rs b/protocol/src/encoder.rs index 8c43c45..a1e5a58 100644 --- a/protocol/src/encoder.rs +++ b/protocol/src/encoder.rs @@ -196,6 +196,20 @@ impl Encoder for Vec { } } +// TODO(timvisee): forge mod channel encoder, we might want a custom type +impl Encoder for Vec<(String, String)> { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + writer.write_var_i32(self.len() as i32)?; + + for (a, b) in self { + writer.write_string(&a, 32767)?; + writer.write_string(&b, 32767)?; + } + + Ok(()) + } +} + pub mod var_int { use crate::encoder::EncoderWriteExt; use crate::error::EncodeError; diff --git a/protocol/src/version/forge_v1_13/login.rs b/protocol/src/version/forge_v1_13/login.rs new file mode 100644 index 0000000..5715e36 --- /dev/null +++ b/protocol/src/version/forge_v1_13/login.rs @@ -0,0 +1,62 @@ +use crate::{set_packet_id, version::PacketId}; +use minecraft_protocol_derive::Decoder; +use minecraft_protocol_derive::Encoder; + +set_packet_id!(ModList, 1); +set_packet_id!(ModListReply, 2); +set_packet_id!(ServerRegistry, 3); +set_packet_id!(ConfigurationData, 4); +set_packet_id!(Acknowledgement, 99); + +#[derive(Encoder, Decoder, Debug)] +pub struct LoginWrapper { + pub channel: String, + pub packet: Vec, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct ModList { + pub mod_names: Vec, + pub channels: Vec<(String, String)>, + pub registries: Vec, +} + +impl ModList { + /// Transform this into a `ModListReply` with empty registry markers. + pub fn into_reply(self) -> ModListReply { + ModListReply { + mod_names: self.mod_names, + channels: self.channels, + registries: self + .registries + .into_iter() + .map(|r| (r, "".into())) + .collect(), + } + } +} + +#[derive(Encoder, Decoder, Debug)] +pub struct ModListReply { + pub mod_names: Vec, + pub channels: Vec<(String, String)>, + pub registries: Vec<(String, String)>, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct ServerRegistry { + pub registry_name: String, + pub snapshot_present: bool, + // TODO: implement this snapshot type! + // TODO: add dummy data here, 5x 0 ? + pub snapshot: Vec, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct ConfigurationData { + pub file_name: String, + pub data: Vec, +} + +#[derive(Encoder, Decoder, Debug)] +pub struct Acknowledgement {} diff --git a/protocol/src/version/forge_v1_13/mod.rs b/protocol/src/version/forge_v1_13/mod.rs new file mode 100644 index 0000000..320cbbb --- /dev/null +++ b/protocol/src/version/forge_v1_13/mod.rs @@ -0,0 +1 @@ +pub mod login; diff --git a/protocol/src/version/mod.rs b/protocol/src/version/mod.rs index cace214..939b6df 100644 --- a/protocol/src/version/mod.rs +++ b/protocol/src/version/mod.rs @@ -1,3 +1,4 @@ +pub mod forge_v1_13; pub mod v1_14_4; pub mod v1_16_5; pub mod v1_17;