diff --git a/src/lib.rs b/src/lib.rs index 644195f..6653fdd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod parser; use serde::Deserialize; use std::io::Write; +use std::time::{SystemTime, UNIX_EPOCH}; use physis::race::{Gender, Race, Subrace}; use reqwest::Url; use zip::result::ZipError; @@ -120,6 +121,51 @@ impl From for JsValue { } } +// FIXME: this is stupid and also just copied from physis +fn convert_dat_race(x: i32) -> Race { + match x { + 1 => Race::Hyur, + 2 => Race::Elezen, + 3 => Race::Lalafell, + 4 => Race::Miqote, + 5 => Race::Roegadyn, + 6 => Race::AuRa, + 7 => Race::Hrothgar, + 8 => Race::Viera, + _ => Race::Hyur, + } +} + +fn convert_dat_gender(x: i32) -> Gender { + match x { + 0 => Gender::Male, + 1 => Gender::Female, + _ => Gender::Male, + } +} + +fn convert_dat_subrace(x: i32) -> Subrace { + match x { + 1 => Subrace::Midlander, + 2 => Subrace::Highlander, + 3 => Subrace::Wildwood, + 4 => Subrace::Duskwight, + 5 => Subrace::Plainsfolk, + 6 => Subrace::Dunesfolk, + 7 => Subrace::Seeker, + 8 => Subrace::Keeper, + 9 => Subrace::SeaWolf, + 10 => Subrace::Hellsguard, + 11 => Subrace::Raen, + 12 => Subrace::Xaela, + 13 => Subrace::Hellion, + 14 => Subrace::Lost, + 15 => Subrace::Rava, + 16 => Subrace::Veena, + _ => Subrace::Midlander, + } +} + /// Archives the character named `character_name` and gives a ZIP file as bytes that can be written to disk. pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Result, ArchiveError> { let lodestone_host = if cfg!(target_family = "wasm") { @@ -272,49 +318,57 @@ pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Resul zip.write_all(&*BASE64_STANDARD.decode(accent.trim_start_matches("data:image/png;base64,")).unwrap())?; } + let timestamp: u32 = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Failed to get UNIX timestamp!") + .as_secs() + .try_into() + .unwrap(); + + let char_dat = physis::chardat::CharacterData { + version: 7, + customize: physis::chardat::CustomizeData { + race: convert_dat_race(package.race), + gender: convert_dat_gender(package.gender), + age: package.model_type as u8, + height: package.height as u8, + subrace: convert_dat_subrace(package.tribe), + face: package.face_type as u8, + hair: package.hair_style as u8, + enable_highlights: package.has_highlights, + skin_tone: package.skin_color as u8, + right_eye_color: package.eye_color as u8, + hair_tone: package.hair_color as u8, + highlights: package.hair_color2 as u8, + facial_features: package.face_features as u8, + facial_feature_color: package.face_features_color as u8, + eyebrows: package.eyebrows as u8, + left_eye_color: package.eye_color2 as u8, + eyes: package.eye_shape as u8, + nose: package.nose_shape as u8, + jaw: package.jaw_shape as u8, + mouth: package.lip_style as u8, + lips_tone_fur_pattern: package.lip_color as u8, + race_feature_size: package.race_feature_size as u8, + race_feature_type: package.race_feature_type as u8, + bust: package.bust_size as u8, + face_paint: package.facepaint as u8, + face_paint_color: package.facepaint_color as u8, + voice: 0, // TODO: need to get from game + }, + timestamp, + comment: "Generated by Auracite".to_string(), + }; + + zip.start_file("FFXIV_CHARA_01.dat", options)?; + zip.write_all(&*char_dat.write_to_buffer().unwrap())?; + // Stop the HTTP server let stop_url = Url::parse(&"http://localhost:42072/stop").map_err(|_| ArchiveError::UnknownError)?; - download(&stop_url).await; + // I'm intentionally ignoring the message because it doesn't matter if it fails - and it usually does + let _ = download(&stop_url).await; } - let char_dat = physis::chardat::CharacterData { - version: 0, - customize: physis::chardat::CustomizeData { - race: Race::Hyur, - gender: Gender::Male, - age: 0, - height: 0, - subrace: Subrace::Midlander, - face: 0, - hair: 0, - enable_highlights: false, - skin_tone: 0, - right_eye_color: 0, - hair_tone: 0, - highlights: 0, - facial_features: 0, - facial_feature_color: 0, - eyebrows: 0, - left_eye_color: 0, - eyes: 0, - nose: 0, - jaw: 0, - mouth: 0, - lips_tone_fur_pattern: 0, - race_feature_size: 0, - race_feature_type: 0, - bust: 0, - face_paint: 0, - face_paint_color: 0, - voice: 0, - }, - timestamp: 0, - comment: "Generated by Auracite".to_string(), - }; - - zip.start_file("FFXIV_CHARA_01.dat", options)?; - zip.write_all(&*char_dat.write_to_buffer().unwrap())?; - zip.start_file("character.json", options)?; zip.write_all(serde_json::to_string(&char_data).unwrap().as_ref())?;