1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
use std::fmt; use std::fs::File; use std::io::{self, Read}; use std::path::PathBuf; use crate::dh; use super::address::Address; use super::data::{ Attr, Buff, Effect, FighterAbil, Item, ItemAttrs, ItemEffects, ItemFighterAbils, ItemGroup, ItemSkillMap, Metadata, MutaAttrMods, MutaItemConvs, }; use super::error::{Error, FromPath, Result}; use super::fsd; pub struct PhobosHandler { base_path: PathBuf, } impl PhobosHandler { pub fn new<T: Into<PathBuf>>(path: T) -> PhobosHandler { PhobosHandler { base_path: path.into() } } fn read_file(&self, addr: &Address) -> io::Result<Vec<u8>> { let full_path = addr.get_full_path(&self.base_path); let mut bytes = Vec::new(); File::open(full_path)?.read_to_end(&mut bytes)?; Ok(bytes) } fn read_json(&self, addr: &Address) -> Result<serde_json::Value> { let bytes = self .read_file(addr) .map_err(|e| Error::from_path(e, addr.get_part_str()))?; let data = serde_json::from_slice(&bytes).map_err(|e| Error::from_path(e, addr.get_part_str()))?; Ok(data) } fn process_fsd<T, U>(&self, folder: &'static str, file: &'static str) -> dh::Result<dh::Container<U>> where T: serde::de::DeserializeOwned + fsd::FsdMerge<U>, { let addr = Address::new(folder, file); let json = self.read_json(&addr)?; fsd::handle::<T, U>(json) } } impl fmt::Debug for PhobosHandler { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "PhobosHandler(\"{}\")", self.base_path.to_str().unwrap_or("<error>")) } } impl dh::DataHandler for PhobosHandler { fn get_items(&self) -> dh::Result<dh::Container<dh::Item>> { self.process_fsd::<Item, dh::Item>("fsd_lite", "evetypes") } fn get_item_groups(&self) -> dh::Result<dh::Container<dh::ItemGroup>> { self.process_fsd::<ItemGroup, dh::ItemGroup>("fsd_lite", "evegroups") } fn get_attrs(&self) -> dh::Result<dh::Container<dh::Attr>> { self.process_fsd::<Attr, dh::Attr>("fsd_binary", "dogmaattributes") } fn get_item_attrs(&self) -> dh::Result<dh::Container<dh::ItemAttr>> { self.process_fsd::<ItemAttrs, dh::ItemAttr>("fsd_binary", "typedogma") } fn get_effects(&self) -> dh::Result<dh::Container<dh::Effect>> { self.process_fsd::<Effect, dh::Effect>("fsd_binary", "dogmaeffects") } fn get_item_effects(&self) -> dh::Result<dh::Container<dh::ItemEffect>> { self.process_fsd::<ItemEffects, dh::ItemEffect>("fsd_binary", "typedogma") } fn get_fighter_abils(&self) -> dh::Result<dh::Container<dh::FighterAbil>> { self.process_fsd::<FighterAbil, dh::FighterAbil>("fsd_lite", "fighterabilities") } fn get_item_fighter_abils(&self) -> dh::Result<dh::Container<dh::ItemFighterAbil>> { self.process_fsd::<ItemFighterAbils, dh::ItemFighterAbil>("fsd_lite", "fighterabilitiesbytype") } fn get_buffs(&self) -> dh::Result<dh::Container<dh::Buff>> { self.process_fsd::<Buff, dh::Buff>("fsd_lite", "dbuffcollections") } fn get_item_skill_reqs(&self) -> dh::Result<dh::Container<dh::ItemSkillReq>> { self.process_fsd::<ItemSkillMap, dh::ItemSkillReq>("fsd_binary", "requiredskillsfortypes") } fn get_muta_item_convs(&self) -> dh::Result<dh::Container<dh::MutaItemConv>> { self.process_fsd::<MutaItemConvs, dh::MutaItemConv>("fsd_binary", "dynamicitemattributes") } fn get_muta_attr_mods(&self) -> dh::Result<dh::Container<dh::MutaAttrMod>> { self.process_fsd::<MutaAttrMods, dh::MutaAttrMod>("fsd_binary", "dynamicitemattributes") } fn get_version(&self) -> dh::Result<String> { let addr = Address::new("phobos", "metadata"); let unprocessed = self.read_json(&addr)?; let metadatas: Vec<Metadata> = serde_json::from_value(unprocessed).map_err(|e| Error::from_path(e, addr.get_part_str()))?; for metadata in metadatas { if metadata.field_name == "client_build" { return Ok(metadata.field_value.to_string()); } } Err(Error::new("unable to find client build").into()) } }