From 555b64669612745f3d83980cdbe2df7207672c44 Mon Sep 17 00:00:00 2001 From: Techcable Date: Sun, 10 Jul 2016 04:23:59 -0700 Subject: [PATCH] Update to minecraft 1.10.2 --- .gitignore | 8 +++++ src/format.rs | 14 +++++++++ src/nbt/mod.rs | 4 +-- src/protocol/mod.rs | 2 +- src/protocol/packet.rs | 14 ++------- src/resources.rs | 8 ++--- src/server/mod.rs | 66 +++++++++++++++++++++++++++++++++--------- 7 files changed, 84 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index f778df6..7661067 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ target/ .rust/ working/ + +# Steven Data +conf.cfg +index +objects +resources-* +servers.json +skin-cache diff --git a/src/format.rs b/src/format.rs index 6b4ba38..1b1bad9 100644 --- a/src/format.rs +++ b/src/format.rs @@ -22,6 +22,20 @@ pub enum Component { } impl Component { + + pub fn from_string(str: &str) -> Self { + let mut component; + match serde_json::from_str::(str) { + Ok(value) => component = Component::from_value(&value), + // Sometimes mojang sends a literal string, so we should interpret it literally + Err(_) => { + component = Component::Text(TextComponent::new(str)); + convert_legacy(&mut component); + }, + } + return component; + } + pub fn from_value(v: &serde_json::Value) -> Self { let mut modifier = Modifier::from_value(v); if let Some(val) = v.as_string() { diff --git a/src/nbt/mod.rs b/src/nbt/mod.rs index 5883c9e..ecd9495 100644 --- a/src/nbt/mod.rs +++ b/src/nbt/mod.rs @@ -20,7 +20,7 @@ use super::protocol::Serializable; use super::protocol; use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt}; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Tag { End, Byte(i8), @@ -36,7 +36,7 @@ pub enum Tag { IntArray(Vec), } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct NamedTag(pub String, pub Tag); impl Tag { diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index c831552..d1b3d02 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -34,7 +34,7 @@ use flate2; use time; use shared::Position; -pub const SUPPORTED_PROTOCOL: i32 = 109; +pub const SUPPORTED_PROTOCOL: i32 = 210; /// Helper macro for defining packets diff --git a/src/protocol/packet.rs b/src/protocol/packet.rs index 5dc47c6..2b5f8aa 100644 --- a/src/protocol/packet.rs +++ b/src/protocol/packet.rs @@ -196,7 +196,6 @@ state_packets!( /// ResourcePackStatus informs the server of the client's current progress /// in activating the requested resource pack packet ResourcePackStatus { - field hash: String =, field result: VarInt =, } /// HeldItemChange is sent when the player changes the currently active @@ -448,7 +447,7 @@ state_packets!( field y: i32 =, field z: i32 =, field volume: f32 =, - field pitch: u8 =, + field pitch: f32 =, } /// Disconnect causes the client to disconnect displaying the passed reason. packet Disconnect { @@ -499,6 +498,7 @@ state_packets!( field new: bool =, field bitmask: VarInt =, field data: LenPrefixedBytes =, + field block_entities: LenPrefixed> =, } /// Effect plays a sound effect or particle at the target location with the /// volume (of sounds) being relative to the player's position unless @@ -784,14 +784,6 @@ state_packets!( field fade_stay: Option = when(|p: &Title| p.action.0 == 2), field fade_out: Option = when(|p: &Title| p.action.0 == 2), } - /// UpdateSign sets or changes the text on a sign. - packet UpdateSign { - field location: Position =, - field line1: format::Component =, - field line2: format::Component =, - field line3: format::Component =, - field line4: format::Component =, - } /// SoundEffect plays the named sound at the target location. packet SoundEffect { field name: VarInt =, @@ -800,7 +792,7 @@ state_packets!( field y: i32 =, field z: i32 =, field volume: f32 =, - field pitch: u8 =, + field pitch: f32 =, } /// PlayerListHeaderFooter updates the header/footer of the player list. packet PlayerListHeaderFooter { diff --git a/src/resources.rs b/src/resources.rs index 4cbcc0c..be1914e 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -30,10 +30,10 @@ use zip; use types::hash::FNVHash; use ui; -const RESOURCES_VERSION: &'static str = "1.9.2"; -const VANILLA_CLIENT_URL: &'static str = "https://launcher.mojang.com/mc/game/1.9.2/client/19106fd5e222dca0f2dde9f66db8384c9a7db957/client.jar"; -const ASSET_VERSION: &'static str = "1.9"; -const ASSET_INDEX_URL: &'static str = "https://launchermeta.mojang.com/mc-staging/assets/1.9/13f566a82f5a8a1b5a5552d968a93c2d9b86df66/1.9.json"; +const RESOURCES_VERSION: &'static str = "1.10.2"; +const VANILLA_CLIENT_URL: &'static str = "https://launcher.mojang.com/mc/game/1.10.2/client/dc8e75ac7274ff6af462b0dcec43c307de668e40/client.jar"; +const ASSET_VERSION: &'static str = "1.10.2"; +const ASSET_INDEX_URL: &'static str = "https://launchermeta.mojang.com/mc/assets/1.10/d3bfc4ffba1ea334c725dd91eaf4ecd402d641f7/1.10.json"; pub trait Pack: Sync + Send { fn open(&self, name: &str) -> Option>; diff --git a/src/server/mod.rs b/src/server/mod.rs index a352010..a3e9709 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -381,7 +381,7 @@ impl Server { TeleportPlayer => on_teleport, TimeUpdate => on_time_update, ChangeGameState => on_game_state_change, - UpdateSign => on_sign_update, + UpdateBlockEntity => on_block_entity_update, PlayerInfo => on_player_info, Disconnect => on_disconnect, // Entities @@ -712,19 +712,34 @@ impl Server { } } - fn on_sign_update(&mut self, mut update_sign: packet::play::clientbound::UpdateSign) { - use format; - format::convert_legacy(&mut update_sign.line1); - format::convert_legacy(&mut update_sign.line2); - format::convert_legacy(&mut update_sign.line3); - format::convert_legacy(&mut update_sign.line4); - self.world.add_block_entity_action(world::BlockEntityAction::UpdateSignText( - update_sign.location, - update_sign.line1, - update_sign.line2, - update_sign.line3, - update_sign.line4, - )); + fn on_block_entity_update(&mut self, block_update: packet::play::clientbound::UpdateBlockEntity) { + match block_update.nbt { + None => { + // NBT is null, so we need to remove the block entity + self.world.add_block_entity_action(world::BlockEntityAction::Remove( + block_update.location, + )); + }, + Some(nbt) => { + match block_update.action { + 9 => { + use format; + let line1 = format::Component::from_string(nbt.1.get("Text1").unwrap().as_string().unwrap()); + let line2 = format::Component::from_string(nbt.1.get("Text2").unwrap().as_string().unwrap()); + let line3 = format::Component::from_string(nbt.1.get("Text3").unwrap().as_string().unwrap()); + let line4 = format::Component::from_string(nbt.1.get("Text4").unwrap().as_string().unwrap()); + self.world.add_block_entity_action(world::BlockEntityAction::UpdateSignText( + block_update.location, + line1, + line2, + line3, + line4, + )); + }, + _ => {} // Ignore it + } + } + } } fn on_player_info(&mut self, player_info: packet::play::clientbound::PlayerInfo) { @@ -817,6 +832,29 @@ impl Server { chunk_data.bitmask.0 as u16, chunk_data.data.data ).unwrap(); + for optional_block_entity in chunk_data.block_entities.data { + match optional_block_entity { + Some(block_entity) => { + let x = block_entity.1.get("x").unwrap().as_int().unwrap(); + let y = block_entity.1.get("y").unwrap().as_int().unwrap(); + let z = block_entity.1.get("z").unwrap().as_int().unwrap(); + let tile_id = block_entity.1.get("id").unwrap().as_string().unwrap(); + let action; + match tile_id { + // Fake a sign update + "Sign" => action = 9, + // Not something we care about, so break the loop + _ => continue, + } + self.on_block_entity_update(packet::play::clientbound::UpdateBlockEntity { + location: Position::new(x, y, z), + action: action, + nbt: Some(block_entity.clone()), + }); + }, + None => {} // Ignore + } + } } fn on_chunk_unload(&mut self, chunk_unload: packet::play::clientbound::ChunkUnload) {