Compare commits

..

No commits in common. "lazymc-multiver" and "master" have entirely different histories.

19 changed files with 12 additions and 536 deletions

View File

@ -8,7 +8,6 @@ pub struct ServerStatus {
pub version: ServerVersion,
pub players: OnlinePlayers,
pub description: Message,
pub favicon: Option<String>,
}
#[derive(Clone, Serialize, Deserialize, Debug)]

View File

@ -222,41 +222,6 @@ impl Decoder for Vec<CompoundTag> {
}
}
// TODO(timvisee): identifier decoder, we might want a custom type
impl Decoder for Vec<String> {
type Output = Self;
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodeError> {
let length = reader.read_var_i32()? as usize;
let mut vec = Vec::with_capacity(length);
for _ in 0..length {
let identifier = reader.read_string(32767)?;
vec.push(identifier);
}
Ok(vec)
}
}
// TODO(timvisee): forge mod channel decoder, we might want a custom type
impl Decoder for Vec<(String, String)> {
type Output = Self;
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodeError> {
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;
@ -296,17 +261,8 @@ pub mod uuid_hyp_str {
use uuid::Uuid;
pub fn decode<R: Read>(reader: &mut R) -> Result<Uuid, DecodeError> {
// TODO(timvisee): use custom encoder for this, rather than putting this in uuid_hyp_str
let data = [reader.read_var_i64()?, reader.read_var_i64()?];
// TODO(timvisee): remove unsafe
let raw = unsafe { std::mem::transmute(data) };
let uuid = Uuid::from_bytes(raw);
// let uuid_hyphenated_string = reader.read_string(36)?;
// let uuid = Uuid::parse_str(&uuid_hyphenated_string)?;
let uuid_hyphenated_string = reader.read_string(36)?;
let uuid = Uuid::parse_str(&uuid_hyphenated_string)?;
Ok(uuid)
}

View File

@ -183,33 +183,6 @@ impl Encoder for Vec<CompoundTag> {
}
}
// TODO(timvisee): identifier encoder, we might want a custom type
impl Encoder for Vec<String> {
fn encode<W: Write>(&self, writer: &mut W) -> Result<(), EncodeError> {
writer.write_var_i32(self.len() as i32)?;
for s in self {
writer.write_string(&s, 32767)?;
}
Ok(())
}
}
// TODO(timvisee): forge mod channel encoder, we might want a custom type
impl Encoder for Vec<(String, String)> {
fn encode<W: Write>(&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;
@ -249,19 +222,11 @@ pub mod uuid_hyp_str {
use crate::encoder::EncoderWriteExt;
use crate::error::EncodeError;
use std::io::Write;
use uuid::{Uuid, Version};
use uuid::Uuid;
pub fn encode<W: Write>(value: &Uuid, writer: &mut W) -> Result<(), EncodeError> {
// TODO(timvisee): use custom encoder for this, rather than putting this in uuid_hyp_str
match value.get_version() {
Some(Version::Md5) => {
writer.write_all(value.as_bytes())?;
}
_ => {
let uuid_hyphenated_string = value.to_hyphenated().to_string();
writer.write_string(&uuid_hyphenated_string, 36)?;
}
}
let uuid_hyphenated_string = value.to_hyphenated().to_string();
writer.write_string(&uuid_hyphenated_string, 36)?;
Ok(())
}

View File

@ -1,62 +0,0 @@
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<u8>,
}
#[derive(Encoder, Decoder, Debug)]
pub struct ModList {
pub mod_names: Vec<String>,
pub channels: Vec<(String, String)>,
pub registries: Vec<String>,
}
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<String>,
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<u8>,
}
#[derive(Encoder, Decoder, Debug)]
pub struct ConfigurationData {
pub file_name: String,
pub data: Vec<u8>,
}
#[derive(Encoder, Decoder, Debug)]
pub struct Acknowledgement {}

View File

@ -1 +0,0 @@
pub mod login;

View File

@ -1,27 +1 @@
pub mod forge_v1_13;
pub mod v1_14_4;
pub mod v1_16_3;
pub mod v1_16_4;
pub mod v1_17;
pub mod v1_17_1;
/// Trait to obtain packet ID from packet data.
pub trait PacketId {
/// Get protcol packet ID.
fn packet_id(&self) -> u8;
}
#[macro_export]
macro_rules! set_packet_id (
($type: ident, $id: expr) => (
impl $type {
pub const PACKET_ID: u8 = $id;
}
impl PacketId for $type {
fn packet_id(&self) -> u8 {
Self::PACKET_ID
}
}
)
);

View File

@ -3,25 +3,12 @@ use crate::decoder::Decoder;
use crate::decoder::DecoderReadExt;
use crate::encoder::EncoderWriteExt;
use crate::error::DecodeError;
use crate::{set_packet_id, version::PacketId};
use byteorder::{ReadBytesExt, WriteBytesExt};
use minecraft_protocol_derive::{Decoder, Encoder};
use nbt::CompoundTag;
use std::io::Read;
use uuid::Uuid;
set_packet_id!(ServerBoundChatMessage, 0x03);
set_packet_id!(ServerBoundKeepAlive, 0x0F);
set_packet_id!(ServerBoundAbilities, 0x19);
set_packet_id!(ClientBoundChatMessage, 0x0F);
set_packet_id!(GameDisconnect, 0x1A);
set_packet_id!(ClientBoundKeepAlive, 0x21);
set_packet_id!(ChunkData, 0x21);
set_packet_id!(JoinGame, 0x25);
set_packet_id!(BossBar, 0x0D);
set_packet_id!(EntityAction, 0x1B);
pub enum GameServerBoundPacket {
ServerBoundChatMessage(ServerBoundChatMessage),
ServerBoundKeepAlive(ServerBoundKeepAlive),
@ -67,11 +54,11 @@ impl GameServerBoundPacket {
impl GameClientBoundPacket {
pub fn get_type_id(&self) -> u8 {
match self {
GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0F,
GameClientBoundPacket::ClientBoundChatMessage(_) => 0x0E,
GameClientBoundPacket::GameDisconnect(_) => 0x1A,
GameClientBoundPacket::ClientBoundKeepAlive(_) => 0x20,
GameClientBoundPacket::ChunkData(_) => 0x21,
GameClientBoundPacket::JoinGame(_) => 0x26,
GameClientBoundPacket::JoinGame(_) => 0x25,
GameClientBoundPacket::BossBar(_) => 0x0D,
GameClientBoundPacket::EntityAction(_) => 0x1B,
}
@ -203,7 +190,7 @@ impl ServerBoundKeepAlive {
}
}
#[derive(Encoder, Decoder, Debug)]
#[derive(Encoder, Decoder)]
pub struct ClientBoundKeepAlive {
pub id: u64,
}

View File

@ -1,11 +1,8 @@
use crate::decoder::Decoder;
use crate::error::DecodeError;
use crate::{set_packet_id, version::PacketId};
use minecraft_protocol_derive::{Decoder, Encoder};
use std::io::Read;
set_packet_id!(Handshake, 0x00);
pub enum HandshakeServerBoundPacket {
Handshake(Handshake),
}
@ -28,7 +25,7 @@ impl HandshakeServerBoundPacket {
}
}
#[derive(Clone, Encoder, Decoder, Debug)]
#[derive(Encoder, Decoder, Debug)]
pub struct Handshake {
#[data_type(with = "var_int")]
pub protocol_version: i32,

View File

@ -4,19 +4,8 @@ use uuid::Uuid;
use crate::data::chat::Message;
use crate::decoder::Decoder;
use crate::error::DecodeError;
use crate::{set_packet_id, version::PacketId};
use minecraft_protocol_derive::{Decoder, Encoder};
set_packet_id!(LoginStart, 0x00);
set_packet_id!(EncryptionResponse, 0x01);
set_packet_id!(LoginPluginResponse, 0x02);
set_packet_id!(LoginDisconnect, 0x00);
set_packet_id!(EncryptionRequest, 0x01);
set_packet_id!(LoginSuccess, 0x02);
set_packet_id!(SetCompression, 0x03);
set_packet_id!(LoginPluginRequest, 0x04);
pub enum LoginServerBoundPacket {
LoginStart(LoginStart),
EncryptionResponse(EncryptionResponse),

View File

@ -1,9 +1,4 @@
// Spec: https://wiki.vg/index.php?title=Protocol&oldid=15346
pub mod game;
pub mod handshake;
pub mod login;
pub mod status;
/// Minecraft protocol version.
pub const PROTOCOL: u32 = 498;

View File

@ -1,18 +1,11 @@
use crate::data::server_status::*;
use crate::decoder::Decoder;
use crate::error::DecodeError;
use crate::{set_packet_id, version::PacketId};
use minecraft_protocol_derive::{Decoder, Encoder};
use std::io::Read;
set_packet_id!(StatusRequest, 0x00);
set_packet_id!(PingRequest, 0x01);
set_packet_id!(StatusResponse, 0x00);
set_packet_id!(PingResponse, 0x01);
pub enum StatusServerBoundPacket {
StatusRequest(StatusRequest),
StatusRequest,
PingRequest(PingRequest),
}
@ -24,14 +17,14 @@ pub enum StatusClientBoundPacket {
impl StatusServerBoundPacket {
pub fn get_type_id(&self) -> u8 {
match self {
StatusServerBoundPacket::StatusRequest(_) => 0x00,
StatusServerBoundPacket::StatusRequest => 0x00,
StatusServerBoundPacket::PingRequest(_) => 0x01,
}
}
pub fn decode<R: Read>(type_id: u8, reader: &mut R) -> Result<Self, DecodeError> {
match type_id {
0x00 => Ok(StatusServerBoundPacket::StatusRequest(StatusRequest {})),
0x00 => Ok(StatusServerBoundPacket::StatusRequest),
0x01 => {
let ping_request = PingRequest::decode(reader)?;
@ -77,15 +70,6 @@ impl PingResponse {
}
}
#[derive(Encoder, Decoder, Debug)]
pub struct StatusRequest {}
impl StatusRequest {
pub fn new() -> StatusServerBoundPacket {
StatusServerBoundPacket::StatusRequest(StatusRequest {})
}
}
#[derive(Encoder, Decoder, Debug)]
pub struct StatusResponse {
pub server_status: ServerStatus,

View File

@ -1,139 +0,0 @@
use crate::data::chat::Message;
use crate::error::DecodeError;
use crate::{set_packet_id, version::PacketId};
use byteorder::{ReadBytesExt, WriteBytesExt};
use minecraft_protocol_derive::{Decoder, Encoder};
use nbt::CompoundTag;
set_packet_id!(ServerBoundPluginMessage, 0x0B);
set_packet_id!(ServerBoundKeepAlive, 0x10);
set_packet_id!(ClientBoundPluginMessage, 0x17);
set_packet_id!(NamedSoundEffect, 0x18);
set_packet_id!(JoinGame, 0x24);
set_packet_id!(PlayerPositionAndLook, 0x34);
set_packet_id!(Respawn, 0x39);
set_packet_id!(TimeUpdate, 0x4E);
set_packet_id!(Title, 0x4F);
set_packet_id!(ClientBoundKeepAlive, 0x1F);
#[derive(Encoder, Decoder, Debug)]
pub struct ServerBoundPluginMessage {
#[data_type(max_length = 32767)]
pub channel: String,
pub data: Vec<u8>,
}
#[derive(Encoder, Decoder)]
pub struct ServerBoundKeepAlive {
pub id: u64,
}
#[derive(Encoder, Decoder, Debug)]
pub struct ClientBoundPluginMessage {
#[data_type(max_length = 32767)]
pub channel: String,
pub data: Vec<u8>,
}
// TODO(timvisee): remove clone?
#[derive(Clone, Encoder, Decoder, Debug)]
pub struct NamedSoundEffect {
#[data_type(max_length = 32767)]
pub sound_name: String,
#[data_type(with = "var_int")]
pub sound_category: i32,
// Mulitplied by 8
pub effect_pos_x: i32,
// Mulitplied by 8
pub effect_pos_y: i32,
// Mulitplied by 8
pub effect_pos_z: i32,
pub volume: f32,
pub pitch: f32,
}
// TODO(timvisee): remove clone?
#[derive(Clone, Encoder, Decoder, Debug)]
pub struct JoinGame {
pub entity_id: u32,
pub hardcore: bool,
pub game_mode: u8,
pub previous_game_mode: u8,
// TODO: max string length: 32767
pub world_names: Vec<String>,
pub dimension_codec: CompoundTag,
pub dimension: CompoundTag,
#[data_type(max_length = 32767)]
pub world_name: String,
pub hashed_seed: i64,
#[data_type(with = "var_int")]
pub max_players: i32,
#[data_type(with = "var_int")]
pub view_distance: i32,
pub reduced_debug_info: bool,
pub enable_respawn_screen: bool,
pub is_debug: bool,
pub is_flat: bool,
}
#[derive(Encoder, Decoder, Debug)]
pub struct PlayerPositionAndLook {
pub x: f64,
pub y: f64,
pub z: f64,
pub yaw: f32,
pub pitch: f32,
pub flags: u8,
#[data_type(with = "var_int")]
pub teleport_id: i32,
}
#[derive(Encoder, Decoder, Debug)]
pub struct Respawn {
pub dimension: CompoundTag,
#[data_type(max_length = 32767)]
pub world_name: String,
pub hashed_seed: i64,
pub game_mode: u8,
pub previous_game_mode: u8,
pub is_debug: bool,
pub is_flat: bool,
pub copy_metadata: bool,
}
#[derive(Encoder, Decoder, Debug)]
pub struct TimeUpdate {
pub world_age: i64,
pub time_of_day: i64,
}
#[derive(Encoder, Decoder, Debug)]
pub struct Title {
pub action: TitleAction,
}
#[derive(Encoder, Decoder, Debug)]
pub enum TitleAction {
SetTitle {
text: Message,
},
SetSubtitle {
text: Message,
},
SetActionBar {
text: Message,
},
SetTimesAndDisplay {
fade_in: i32,
stay: i32,
fade_out: i32,
},
Hide,
Reset,
}
#[derive(Encoder, Decoder, Debug)]
pub struct ClientBoundKeepAlive {
pub id: u64,
}

View File

@ -1,6 +0,0 @@
// Spec: https://wiki.vg/index.php?title=Protocol&oldid=16091
pub mod game;
/// Minecraft protocol version.
pub const PROTOCOL: u32 = 753;

View File

@ -1,6 +0,0 @@
// Re-export
pub use crate::version::v1_16_3::game::{
ClientBoundKeepAlive, ClientBoundPluginMessage, JoinGame, NamedSoundEffect,
PlayerPositionAndLook, Respawn, ServerBoundKeepAlive, ServerBoundPluginMessage, TimeUpdate,
Title,
};

View File

@ -1,6 +0,0 @@
// Spec: https://wiki.vg/index.php?title=Protocol&oldid=16317
pub mod game;
/// Minecraft protocol version.
pub const PROTOCOL: u32 = 754;

View File

@ -1,132 +0,0 @@
use crate::data::chat::Message;
use crate::{set_packet_id, version::PacketId};
use minecraft_protocol_derive::{Decoder, Encoder};
use nbt::CompoundTag;
set_packet_id!(ServerBoundPluginMessage, 0x0A);
set_packet_id!(ServerBoundKeepAlive, 0x0F);
set_packet_id!(ClientBoundPluginMessage, 0x18);
set_packet_id!(NamedSoundEffect, 0x19);
set_packet_id!(JoinGame, 0x26);
set_packet_id!(PlayerPositionAndLook, 0x38);
set_packet_id!(Respawn, 0x3D);
set_packet_id!(SetTitleSubtitle, 0x57);
set_packet_id!(TimeUpdate, 0x58);
set_packet_id!(SetTitleText, 0x59);
set_packet_id!(SetTitleTimes, 0x5A);
set_packet_id!(ClientBoundKeepAlive, 0x21);
#[derive(Encoder, Decoder, Debug)]
pub struct ServerBoundPluginMessage {
#[data_type(max_length = 32767)]
pub channel: String,
pub data: Vec<u8>,
}
#[derive(Encoder, Decoder)]
pub struct ServerBoundKeepAlive {
pub id: u64,
}
#[derive(Encoder, Decoder, Debug)]
pub struct ClientBoundPluginMessage {
#[data_type(max_length = 32767)]
pub channel: String,
pub data: Vec<u8>,
}
// TODO(timvisee): remove clone?
#[derive(Clone, Encoder, Decoder, Debug)]
pub struct NamedSoundEffect {
#[data_type(max_length = 32767)]
pub sound_name: String,
#[data_type(with = "var_int")]
pub sound_category: i32,
// Mulitplied by 8
pub effect_pos_x: i32,
// Mulitplied by 8
pub effect_pos_y: i32,
// Mulitplied by 8
pub effect_pos_z: i32,
pub volume: f32,
pub pitch: f32,
}
// TODO(timvisee): remove clone?
#[derive(Clone, Encoder, Decoder, Debug)]
pub struct JoinGame {
pub entity_id: u32,
pub hardcore: bool,
pub game_mode: u8,
pub previous_game_mode: u8,
// TODO: max string length: 32767
pub world_names: Vec<String>,
pub dimension_codec: CompoundTag,
pub dimension: CompoundTag,
#[data_type(max_length = 32767)]
pub world_name: String,
pub hashed_seed: i64,
#[data_type(with = "var_int")]
pub max_players: i32,
#[data_type(with = "var_int")]
pub view_distance: i32,
pub reduced_debug_info: bool,
pub enable_respawn_screen: bool,
pub is_debug: bool,
pub is_flat: bool,
}
#[derive(Encoder, Decoder, Debug)]
pub struct Respawn {
pub dimension: CompoundTag,
#[data_type(max_length = 32767)]
pub world_name: String,
pub hashed_seed: i64,
pub game_mode: u8,
pub previous_game_mode: u8,
pub is_debug: bool,
pub is_flat: bool,
pub copy_metadata: bool,
}
#[derive(Encoder, Decoder, Debug)]
pub struct PlayerPositionAndLook {
pub x: f64,
pub y: f64,
pub z: f64,
pub yaw: f32,
pub pitch: f32,
pub flags: u8,
#[data_type(with = "var_int")]
pub teleport_id: i32,
pub dismount_vehicle: bool,
}
#[derive(Encoder, Decoder, Debug)]
pub struct TimeUpdate {
pub world_age: i64,
pub time_of_day: i64,
}
#[derive(Encoder, Decoder, Debug)]
pub struct SetTitleText {
pub text: Message,
}
#[derive(Encoder, Decoder, Debug)]
pub struct SetTitleSubtitle {
pub text: Message,
}
#[derive(Encoder, Decoder, Debug)]
pub struct SetTitleTimes {
pub fade_in: i32,
pub stay: i32,
pub fade_out: i32,
}
#[derive(Encoder, Decoder, Debug)]
pub struct ClientBoundKeepAlive {
pub id: u64,
}

View File

@ -1,6 +0,0 @@
// Spec: https://wiki.vg/index.php?title=Protocol&oldid=16866
pub mod game;
/// Minecraft protocol version.
pub const PROTOCOL: u32 = 755;

View File

@ -1,6 +0,0 @@
// Re-export
pub use crate::version::v1_17::game::{
ClientBoundKeepAlive, ClientBoundPluginMessage, JoinGame, NamedSoundEffect,
PlayerPositionAndLook, Respawn, ServerBoundKeepAlive, ServerBoundPluginMessage,
SetTitleSubtitle, SetTitleText, SetTitleTimes, TimeUpdate,
};

View File

@ -1,6 +0,0 @@
// Spec: https://wiki.vg/index.php?title=Protocol&oldid=16918
pub mod game;
/// Minecraft protocol version.
pub const PROTOCOL: u32 = 756;