From a442d0b3b8ad68885a59604b168bc45269ded62e Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Sun, 22 Dec 2019 16:29:47 +0100 Subject: use byteorder for chatlink parsing --- Cargo.toml | 1 + src/bt.rs | 36 +++++++++++++++++++----------------- src/main.rs | 1 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8949851..81bda2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,3 +21,4 @@ base64 = "0.11" termcolor = "1.0" num_enum = "0.4" num-traits = "0.2" +byteorder = "1.3" diff --git a/src/bt.rs b/src/bt.rs index c348fca..97fb8c5 100644 --- a/src/bt.rs +++ b/src/bt.rs @@ -1,6 +1,7 @@ use super::api::{Api, ApiError, Profession, Skill, Specialization}; +use byteorder::{ReadBytesExt, WriteBytesExt, LE}; use num_enum::{IntoPrimitive, TryFromPrimitive}; -use std::{convert::TryFrom, error::Error, fmt, str::FromStr}; +use std::{convert::TryFrom, error::Error, fmt, io::Cursor, str::FromStr}; #[derive(Debug)] pub enum ChatlinkError { @@ -15,6 +16,12 @@ error_froms! { ChatlinkError, _err: num_enum::TryFromPrimitiveError => ChatlinkError::MalformedInput, } +impl From for ChatlinkError { + fn from(_err: std::io::Error) -> Self { + panic!("The reading cursor should never return an error!"); + } +} + impl fmt::Display for ChatlinkError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -137,7 +144,7 @@ pub const LEGEND_COUNT: usize = 4; pub const CODE_REVENANT: u32 = 9; pub const EMPTY_SKILLS: [Option; SKILL_COUNT] = [None, None, None, None, None]; -pub const EMPTY_TRAITLINES: [Option; TRAITLINE_COUNT] = [None,None, None]; +pub const EMPTY_TRAITLINES: [Option; TRAITLINE_COUNT] = [None, None, None]; /// Represents a build template. /// @@ -258,12 +265,8 @@ impl BuildTemplate { bytes.push(0); } Some(s) => { - let palette_id = self - .profession() - .skill_id_to_palette_id(s.id) - .unwrap_or(0); - bytes.push((palette_id & 0xFF) as u8); - bytes.push(((palette_id >> 8) & 0xFF) as u8); + let palette_id = self.profession().skill_id_to_palette_id(s.id).unwrap_or(0); + bytes.write_u16::(palette_id as u16).unwrap(); } } // Aquatic @@ -307,12 +310,14 @@ impl BuildTemplate { } bytes.remove(0); - let profession = code_to_profession(api, bytes.remove(0) as u32)?; + let mut reader = Cursor::new(bytes); + + let profession = code_to_profession(api, reader.read_u8()? as u32)?; let mut traitlines = EMPTY_TRAITLINES; for i in traitlines.iter_mut() { - let spec_id = bytes.remove(0); - let trait_choices = bytes.remove(0); + let spec_id = reader.read_u8()?; + let trait_choices = reader.read_u8()?; if spec_id == 0 { continue; } @@ -327,9 +332,7 @@ impl BuildTemplate { let mut skills = EMPTY_SKILLS; for i in skills.iter_mut() { // Terrestrial - let byte_1 = bytes.remove(0); - let byte_2 = bytes.remove(0); - let palette_id = byte_1 as u32 | (byte_2 as u32) << 8; + let palette_id = reader.read_u16::()? as u32; if palette_id != 0 { let skill_id = profession .palette_id_to_skill_id(palette_id) @@ -339,15 +342,14 @@ impl BuildTemplate { } // Aquatic - bytes.remove(0); - bytes.remove(0); + reader.read_u16::()?; } let extra_data = match profession.code { CODE_REVENANT => { let mut legends = [Legend::None; LEGEND_COUNT]; for i in legends.iter_mut() { - *i = Legend::try_from(bytes.remove(0))?; + *i = Legend::try_from(reader.read_u8()?)?; } ExtraData::Legends(legends) } diff --git a/src/main.rs b/src/main.rs index 47ccabd..eb5ef06 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ extern crate base64; +extern crate byteorder; extern crate clap; extern crate image; extern crate imageproc; -- cgit v1.2.3