|
| 1 | +use base64::prelude::BASE64_STANDARD; |
| 2 | +use base64::Engine; |
| 3 | +use reliquary::resource::excel::{ |
| 4 | + AvatarConfigMap, AvatarSkillTreeConfigMap, EquipmentConfigMap, MultiplePathAvatarConfigMap, |
| 5 | + RelicConfigMap, RelicMainAffixConfigMap, RelicSetConfigMap, RelicSubAffixConfigMap, |
| 6 | +}; |
| 7 | +use reliquary::resource::text_map::TextMap; |
| 8 | +use serde::de::DeserializeOwned; |
| 9 | +use std::collections::HashMap; |
| 10 | +use tracing::{info, instrument}; |
| 11 | + |
| 12 | +pub struct Database { |
| 13 | + pub avatar_config: AvatarConfigMap, |
| 14 | + pub avatar_skill_tree_config: AvatarSkillTreeConfigMap, |
| 15 | + pub equipment_config: EquipmentConfigMap, |
| 16 | + pub multipath_avatar_config: MultiplePathAvatarConfigMap, |
| 17 | + pub relic_config: RelicConfigMap, |
| 18 | + pub relic_set_config: RelicSetConfigMap, |
| 19 | + pub relic_main_affix_config: RelicMainAffixConfigMap, |
| 20 | + pub relic_sub_affix_config: RelicSubAffixConfigMap, |
| 21 | + pub text_map: TextMap, |
| 22 | + pub keys: HashMap<u32, Vec<u8>>, |
| 23 | +} |
| 24 | + |
| 25 | +impl Database { |
| 26 | + #[instrument(name = "config_map")] |
| 27 | + pub fn new() -> Self { |
| 28 | + info!("using local database"); |
| 29 | + |
| 30 | + // config files are downloaded by the build script |
| 31 | + // |
| 32 | + // i *would* create a fn load_local_config<T: ResourceMap + DeserializeOwned>() |
| 33 | + // to avoid duplicating the json file names by using T::get_json_name, |
| 34 | + // but concat!() only takes string literals. it doesn't even take `&'static str`!! |
| 35 | + Database { |
| 36 | + avatar_config: Self::parse_json(include_str!(concat!( |
| 37 | + env!("OUT_DIR"), |
| 38 | + "/AvatarConfig.json" |
| 39 | + ))), |
| 40 | + avatar_skill_tree_config: Self::parse_json(include_str!(concat!( |
| 41 | + env!("OUT_DIR"), |
| 42 | + "/AvatarSkillTreeConfig.json" |
| 43 | + ))), |
| 44 | + equipment_config: Self::parse_json(include_str!(concat!( |
| 45 | + env!("OUT_DIR"), |
| 46 | + "/EquipmentConfig.json" |
| 47 | + ))), |
| 48 | + multipath_avatar_config: Self::parse_json(include_str!(concat!( |
| 49 | + env!("OUT_DIR"), |
| 50 | + "/MultiplePathAvatarConfig.json" |
| 51 | + ))), |
| 52 | + relic_config: Self::parse_json(include_str!(concat!( |
| 53 | + env!("OUT_DIR"), |
| 54 | + "/RelicConfig.json" |
| 55 | + ))), |
| 56 | + relic_set_config: Self::parse_json(include_str!(concat!( |
| 57 | + env!("OUT_DIR"), |
| 58 | + "/RelicSetConfig.json" |
| 59 | + ))), |
| 60 | + relic_main_affix_config: Self::parse_json(include_str!(concat!( |
| 61 | + env!("OUT_DIR"), |
| 62 | + "/RelicMainAffixConfig.json" |
| 63 | + ))), |
| 64 | + relic_sub_affix_config: Self::parse_json(include_str!(concat!( |
| 65 | + env!("OUT_DIR"), |
| 66 | + "/RelicSubAffixConfig.json" |
| 67 | + ))), |
| 68 | + text_map: Self::parse_json(include_str!(concat!(env!("OUT_DIR"), "/TextMapEN.json"))), |
| 69 | + keys: Self::load_local_keys(), |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + fn parse_json<T: DeserializeOwned>(str: &'static str) -> T { |
| 74 | + serde_json::de::from_str(str).unwrap() |
| 75 | + } |
| 76 | + |
| 77 | + fn load_local_keys() -> HashMap<u32, Vec<u8>> { |
| 78 | + let keys: HashMap<u32, String> = |
| 79 | + Self::parse_json(include_str!(concat!(env!("OUT_DIR"), "/keys.json"))); |
| 80 | + let mut keys_bytes = HashMap::new(); |
| 81 | + |
| 82 | + for (k, v) in keys { |
| 83 | + keys_bytes.insert(k, BASE64_STANDARD.decode(v).unwrap()); |
| 84 | + } |
| 85 | + |
| 86 | + keys_bytes |
| 87 | + } |
| 88 | + |
| 89 | + pub(crate) fn lookup_avatar_name(&self, avatar_id: u32) -> Option<String> { |
| 90 | + if avatar_id == 0 { |
| 91 | + return None; |
| 92 | + } |
| 93 | + |
| 94 | + if avatar_id >= 8000 { |
| 95 | + Some("Trailblazer".to_owned()) |
| 96 | + } else { |
| 97 | + let cfg = self.avatar_config.get(&avatar_id)?; |
| 98 | + cfg.AvatarName.lookup(&self.text_map).map(|s| s.to_string()) |
| 99 | + } |
| 100 | + } |
| 101 | +} |
0 commit comments