Add draft

This commit is contained in:
Vladislav Golub 2019-11-10 02:23:08 +03:00
parent d42dc7e5fe
commit c2348e7340
3 changed files with 128 additions and 0 deletions

View File

@ -14,3 +14,4 @@ readme = "README.md"
name = "mcpl"
[dependencies]
byteorder = "1"

27
src/lib.rs Normal file
View File

@ -0,0 +1,27 @@
use std::io;
use std::io::{Read, Write};
pub mod status;
/// Current supported protocol version.
pub const PROTOCOL_VERSION: usize = 498;
/// Possible errors while decoding packet.
pub enum DecodePacketError {
UnknownPacketType { type_id: u8 },
IOError { io_error: io::Error },
}
impl From<io::Error> for DecodePacketError {
fn from(io_error: io::Error) -> Self {
DecodePacketError::IOError { io_error }
}
}
trait Packet {
type Output;
fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error>;
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodePacketError>;
}

100
src/status.rs Normal file
View File

@ -0,0 +1,100 @@
use crate::{DecodePacketError, Packet};
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use std::io;
use std::io::{Read, Write};
pub enum StatusServerBoundPacket {
StatusRequest,
PingRequest(PingRequest),
}
pub enum StatusClientBoundPacket {
StatusResponse,
PingResponse(PingResponse),
}
impl StatusServerBoundPacket {
pub fn get_type_id(&self) -> u8 {
match self {
StatusServerBoundPacket::StatusRequest => 0x0,
StatusServerBoundPacket::PingRequest(_) => 0x1,
}
}
pub fn decode<R: Read>(&self, type_id: u8, reader: &mut R) -> Result<Self, DecodePacketError> {
match type_id {
0x0 => Ok(StatusServerBoundPacket::StatusRequest),
0x1 => {
let ping_request = PingRequest::decode(reader)?;
Ok(StatusServerBoundPacket::PingRequest(ping_request))
}
_ => Err(DecodePacketError::UnknownPacketType { type_id }),
}
}
}
impl StatusClientBoundPacket {
pub fn get_type_id(&self) -> u8 {
match self {
StatusClientBoundPacket::StatusResponse => 0x0,
StatusClientBoundPacket::PingResponse(_) => 0x1,
}
}
}
pub struct PingRequest {
time: u64,
}
impl PingRequest {
pub fn new(time: u64) -> StatusServerBoundPacket {
let ping_request = PingRequest { time };
StatusServerBoundPacket::PingRequest(ping_request)
}
}
impl Packet for PingRequest {
type Output = Self;
fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
writer.write_u64::<BigEndian>(self.time)?;
Ok(())
}
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodePacketError> {
let time = reader.read_u64::<BigEndian>()?;
Ok(PingRequest { time })
}
}
pub struct PingResponse {
time: u64,
}
impl PingResponse {
pub fn new(time: u64) -> StatusClientBoundPacket {
let ping_response = PingResponse { time };
StatusClientBoundPacket::PingResponse(ping_response)
}
}
impl Packet for PingResponse {
type Output = Self;
fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
writer.write_u64::<BigEndian>(self.time)?;
Ok(())
}
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodePacketError> {
let time = reader.read_u64::<BigEndian>()?;
Ok(PingResponse { time })
}
}