use connection::Packet;
use errors::Result;
use read::*;
use write::*;
use {ClientState, u128};
use std::collections::BTreeMap;
use std::fmt;
use std::io::Read;
include!("./.clientbound-enum.generated.rs");
include!("./.clientbound-packets.generated.rs");
impl Statistics {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&Statistics::PACKET_ID, &mut ret)?;
write_varint(&(self.values.len() as i32), &mut ret)?;
for (key, value) in self.values.iter() {
write_String(key, &mut ret)?;
write_varint(value, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let count = read_varint(r)?;
let mut tmp = BTreeMap::new();
for _ in 0..count {
tmp.insert(read_String(r)?, read_varint(r)?);
}
Ok(ClientboundPacket::Statistics(Statistics {
values: tmp,
}))
}
}
impl ClientboundTabComplete {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&ClientboundTabComplete::PACKET_ID, &mut ret)?;
write_varint(&(self.matches.len() as i32), &mut ret)?;
for value in &self.matches {
write_String(value, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let count = read_varint(r)?;
let mut tmp = Vec::with_capacity(count as usize);
for _ in 0..count {
tmp.push(read_String(r)?);
}
Ok(ClientboundPacket::ClientboundTabComplete(ClientboundTabComplete {
matches: tmp,
}))
}
}
impl MultiBlockChange {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&MultiBlockChange::PACKET_ID, &mut ret)?;
write_i32(&self.chunk_x, &mut ret)?;
write_i32(&self.chunk_z, &mut ret)?;
write_varint(&(self.changes.len() as i32), &mut ret)?;
for &(x, y, z, new_state) in &self.changes {
let xz: u8 = (x << 4) | z;
write_u8(&xz, &mut ret)?;
write_u8(&y, &mut ret)?;
write_varint(&new_state, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let chunk_x = read_i32(r)?;
let chunk_z = read_i32(r)?;
let count = read_varint(r)?;
let mut tmp: Vec<(u8, u8, u8, i32)> = Vec::with_capacity(count as
usize);
for _ in 0..count {
let hori_pos = read_u8(r)?;
let y = read_u8(r)?;
let block_state = read_varint(r)?;
let x = (hori_pos & 0xF0) >> 4;
let z = hori_pos & 0x0F;
tmp.push((x, y, z, block_state));
}
Ok(ClientboundPacket::MultiBlockChange(MultiBlockChange {
chunk_x: chunk_x,
chunk_z: chunk_z,
changes: tmp,
}))
}
}
impl OpenWindow {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&OpenWindow::PACKET_ID, &mut ret)?;
write_u8(&self.window_id, &mut ret)?;
write_String(&self.window_type, &mut ret)?;
write_String(&self.window_title, &mut ret)?;
write_u8(&self.number_of_slots, &mut ret)?;
if let Some(entity_id) = self.entity_id {
write_i32(&entity_id, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let window_id = read_u8(r)?;
let window_type = read_String(r)?;
let window_title = read_String(r)?;
let number_of_slots = read_u8(r)?;
let entity_id = match &*window_type {
"EntityHorse" => Some(read_i32(r)?),
_ => None,
};
Ok(ClientboundPacket::OpenWindow(OpenWindow {
window_id: window_id,
window_type: window_type,
window_title: window_title,
number_of_slots: number_of_slots,
entity_id: entity_id,
}))
}
}
impl Explosion {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&Explosion::PACKET_ID, &mut ret)?;
write_f32(&self.x, &mut ret)?;
write_f32(&self.y, &mut ret)?;
write_f32(&self.z, &mut ret)?;
write_f32(&self.radius, &mut ret)?;
write_i32(&(self.affected_blocks.len() as i32), &mut ret)?;
for &(x, y, z) in &self.affected_blocks {
write_i8(&x, &mut ret)?;
write_i8(&y, &mut ret)?;
write_i8(&z, &mut ret)?;
}
write_f32(&self.motion_x, &mut ret)?;
write_f32(&self.motion_y, &mut ret)?;
write_f32(&self.motion_z, &mut ret)?;
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let x = read_f32(r)?;
let y = read_f32(r)?;
let z = read_f32(r)?;
let radius = read_f32(r)?;
let count = read_i32(r)?;
let mut tmp: Vec<(i8, i8, i8)> = Vec::with_capacity(count as usize);
for _ in 0..count {
tmp.push((read_i8(r)?, read_i8(r)?, read_i8(r)?));
}
let motion_x = read_f32(r)?;
let motion_y = read_f32(r)?;
let motion_z = read_f32(r)?;
Ok(ClientboundPacket::Explosion(Explosion {
x: x,
y: y,
z: z,
radius: radius,
affected_blocks: tmp,
motion_x: motion_x,
motion_y: motion_y,
motion_z: motion_z,
}))
}
}
impl Particle {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&Particle::PACKET_ID, &mut ret)?;
write_i32(&self.particle_id, &mut ret)?;
write_bool(&self.use_long_distance, &mut ret)?;
write_f32(&self.x, &mut ret)?;
write_f32(&self.y, &mut ret)?;
write_f32(&self.z, &mut ret)?;
write_f32(&self.offset_x, &mut ret)?;
write_f32(&self.offset_y, &mut ret)?;
write_f32(&self.offset_z, &mut ret)?;
write_f32(&self.particle_data, &mut ret)?;
write_i32(&self.count, &mut ret)?;
if let Some(x) = self.id {
write_varint(&x, &mut ret)?;
}
if let Some(x) = self.crack_data {
write_varint(&x, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let particle_id = read_i32(r)?;
let long_distance = read_bool(r)?;
let x = read_f32(r)?;
let y = read_f32(r)?;
let z = read_f32(r)?;
let offset_x = read_f32(r)?;
let offset_y = read_f32(r)?;
let offset_z = read_f32(r)?;
let particle_data = read_f32(r)?;
let count = read_i32(r)?;
let id = match particle_id {
36 | 37 | 38 => Some(read_varint(r)?),
_ => None,
};
let crack_data = match particle_id {
36 | 37 => Some(read_varint(r)?),
_ => None,
};
Ok(ClientboundPacket::Particle(Particle {
particle_id: particle_id,
use_long_distance: long_distance,
x: x,
y: y,
z: z,
offset_x: offset_x,
offset_y: offset_y,
offset_z: offset_z,
particle_data: particle_data,
count: count,
id: id,
crack_data: crack_data,
}))
}
}
impl CombatEvent {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&CombatEvent::PACKET_ID, &mut ret)?;
write_varint(&self.event, &mut ret)?;
if let Some(x) = self.duration_playerid {
write_varint(&x, &mut ret)?;
}
if let Some(x) = self.entity_id {
write_i32(&x, &mut ret)?;
}
if let &Some(ref x) = &self.message {
write_String(x, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let event = read_varint(r)?;
let (duration_playerid, entity_id, message) = match event {
0 => (None, None, None),
1 => (Some(read_varint(r)?), Some(read_i32(r)?), None),
2 => {
(Some(read_varint(r)?),
Some(read_i32(r)?),
Some(read_String(r)?))
},
_ => bail!("Invalid event in CombatEvent"),
};
Ok(ClientboundPacket::CombatEvent(CombatEvent {
event: event,
duration_playerid:
duration_playerid,
entity_id: entity_id,
message: message,
}))
}
}
impl ScoreboardObjective {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&ScoreboardObjective::PACKET_ID, &mut ret)?;
write_String(&self.name, &mut ret)?;
write_u8(&self.mode, &mut ret)?;
if let &Some(ref x) = &self.value {
write_String(x, &mut ret)?;
}
if let &Some(ref x) = &self.objective_type {
write_String(x, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let name = read_String(r)?;
let mode = read_u8(r)?;
let (value, objective_type) = match mode {
0 | 2 => (Some(read_String(r)?), Some(read_String(r)?)),
_ => (None, None),
};
Ok(ClientboundPacket::ScoreboardObjective(ScoreboardObjective {
name: name,
mode: mode,
value: value,
objective_type:
objective_type,
}))
}
}
impl UpdateScore {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&UpdateScore::PACKET_ID, &mut ret)?;
write_String(&self.name, &mut ret)?;
write_u8(&self.action, &mut ret)?;
write_String(&self.objective_name, &mut ret)?;
if let Some(x) = self.value {
write_varint(&x, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let name = read_String(r)?;
let action = read_u8(r)?;
let objective_name = read_String(r)?;
let value = match action {
1 => Some(read_varint(r)?),
_ => None,
};
Ok(ClientboundPacket::UpdateScore(UpdateScore {
name: name,
action: action,
objective_name: objective_name,
value: value,
}))
}
}
impl Title {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&Title::PACKET_ID, &mut ret)?;
write_varint(&self.action, &mut ret)?;
if let &Some(ref x) = &self.text {
write_String(x, &mut ret)?;
} else if let Some((a, b, c)) = self.times {
write_i32(&a, &mut ret)?;
write_i32(&b, &mut ret)?;
write_i32(&c, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let action = read_varint(r)?;
let text = match action {
0 | 1 | 2 => Some(read_String(r)?),
_ => None,
};
let times = match action {
3 => Some((read_i32(r)?, read_i32(r)?, read_i32(r)?)),
_ => None,
};
Ok(ClientboundPacket::Title(Title {
action: action,
text: text,
times: times,
}))
}
}
impl PlayerAbilities {
pub fn is_invulnerable(&self) -> bool {
(self.flags & 0x01) != 0
}
pub fn is_flying(&self) -> bool {
(self.flags & 0x02) != 0
}
pub fn allow_flying(&self) -> bool {
(self.flags & 0x04) != 0
}
pub fn is_creative(&self) -> bool {
(self.flags & 0x08) != 0
}
}
impl UnlockRecipes {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&Self::PACKET_ID, &mut ret)?;
write_varint(&self.action, &mut ret)?;
write_bool(&self.crafting_book_open, &mut ret)?;
write_bool(&self.filter_craftable, &mut ret)?;
write_prefixed_varintarray(&self.recipes, &mut ret)?;
if self.action == 0 {
write_prefixed_varintarray(&self.recipes2, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let action = read_varint(r)?;
let crafting_book_open = read_bool(r)?;
let filter_craftable = read_bool(r)?;
let recipes = read_prefixed_varintarray(r)?;
let recipes2 = if let 0 = action {
read_prefixed_varintarray(r)?
} else {
Vec::new()
};
Ok(ClientboundPacket::UnlockRecipes(UnlockRecipes {
action,
crafting_book_open,
filter_craftable,
recipes,
recipes2,
}))
}
}
impl SelectAdvancementTab {
fn to_u8(&self) -> Result<Vec<u8>> {
let mut ret = Vec::new();
write_varint(&Self::PACKET_ID, &mut ret)?;
if let Some(ref identifier) = self.identifier {
if identifier.len() > 32767 {
bail!("SelectAdvancementTab identifier is too long, is {} bytes long",
identifier.len());
}
write_bool(&true, &mut ret)?;
write_String(identifier, &mut ret)?;
} else {
write_bool(&false, &mut ret)?;
}
Ok(ret)
}
fn deserialize<R: Read>(r: &mut R) -> Result<ClientboundPacket> {
let has_id = read_bool(r)?;
let identifier = if has_id {
let tmp = read_String(r)?;
if tmp.len() > 32767 {
bail!("SelectAdvancementTab identifier is too long, is {} bytes long",
tmp.len());
}
Some(tmp)
} else {
None
};
Ok(ClientboundPacket::SelectAdvancementTab(SelectAdvancementTab {
identifier,
}))
}
}