mirror of
https://github.com/redstrate/Auracite.git
synced 2025-04-21 20:27:46 +00:00
Write actual appearance data to the .dat file
It actually loads in-game, cool! Auracite does not yet extract the voice, that will have to be done eventually.
This commit is contained in:
parent
e18ddec008
commit
fbec3dcd11
1 changed files with 93 additions and 39 deletions
120
src/lib.rs
120
src/lib.rs
|
@ -5,6 +5,7 @@ pub mod parser;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use physis::race::{Gender, Race, Subrace};
|
use physis::race::{Gender, Race, Subrace};
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
use zip::result::ZipError;
|
use zip::result::ZipError;
|
||||||
|
@ -120,6 +121,51 @@ impl From<ArchiveError> 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.
|
/// 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<Vec<u8>, ArchiveError> {
|
pub async fn archive_character(character_name: &str, use_dalamud: bool) -> Result<Vec<u8>, ArchiveError> {
|
||||||
let lodestone_host = if cfg!(target_family = "wasm") {
|
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())?;
|
zip.write_all(&*BASE64_STANDARD.decode(accent.trim_start_matches("data:image/png;base64,")).unwrap())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the HTTP server
|
let timestamp: u32 = SystemTime::now()
|
||||||
let stop_url = Url::parse(&"http://localhost:42072/stop").map_err(|_| ArchiveError::UnknownError)?;
|
.duration_since(UNIX_EPOCH)
|
||||||
download(&stop_url).await;
|
.expect("Failed to get UNIX timestamp!")
|
||||||
}
|
.as_secs()
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let char_dat = physis::chardat::CharacterData {
|
let char_dat = physis::chardat::CharacterData {
|
||||||
version: 0,
|
version: 7,
|
||||||
customize: physis::chardat::CustomizeData {
|
customize: physis::chardat::CustomizeData {
|
||||||
race: Race::Hyur,
|
race: convert_dat_race(package.race),
|
||||||
gender: Gender::Male,
|
gender: convert_dat_gender(package.gender),
|
||||||
age: 0,
|
age: package.model_type as u8,
|
||||||
height: 0,
|
height: package.height as u8,
|
||||||
subrace: Subrace::Midlander,
|
subrace: convert_dat_subrace(package.tribe),
|
||||||
face: 0,
|
face: package.face_type as u8,
|
||||||
hair: 0,
|
hair: package.hair_style as u8,
|
||||||
enable_highlights: false,
|
enable_highlights: package.has_highlights,
|
||||||
skin_tone: 0,
|
skin_tone: package.skin_color as u8,
|
||||||
right_eye_color: 0,
|
right_eye_color: package.eye_color as u8,
|
||||||
hair_tone: 0,
|
hair_tone: package.hair_color as u8,
|
||||||
highlights: 0,
|
highlights: package.hair_color2 as u8,
|
||||||
facial_features: 0,
|
facial_features: package.face_features as u8,
|
||||||
facial_feature_color: 0,
|
facial_feature_color: package.face_features_color as u8,
|
||||||
eyebrows: 0,
|
eyebrows: package.eyebrows as u8,
|
||||||
left_eye_color: 0,
|
left_eye_color: package.eye_color2 as u8,
|
||||||
eyes: 0,
|
eyes: package.eye_shape as u8,
|
||||||
nose: 0,
|
nose: package.nose_shape as u8,
|
||||||
jaw: 0,
|
jaw: package.jaw_shape as u8,
|
||||||
mouth: 0,
|
mouth: package.lip_style as u8,
|
||||||
lips_tone_fur_pattern: 0,
|
lips_tone_fur_pattern: package.lip_color as u8,
|
||||||
race_feature_size: 0,
|
race_feature_size: package.race_feature_size as u8,
|
||||||
race_feature_type: 0,
|
race_feature_type: package.race_feature_type as u8,
|
||||||
bust: 0,
|
bust: package.bust_size as u8,
|
||||||
face_paint: 0,
|
face_paint: package.facepaint as u8,
|
||||||
face_paint_color: 0,
|
face_paint_color: package.facepaint_color as u8,
|
||||||
voice: 0,
|
voice: 0, // TODO: need to get from game
|
||||||
},
|
},
|
||||||
timestamp: 0,
|
timestamp,
|
||||||
comment: "Generated by Auracite".to_string(),
|
comment: "Generated by Auracite".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
zip.start_file("FFXIV_CHARA_01.dat", options)?;
|
zip.start_file("FFXIV_CHARA_01.dat", options)?;
|
||||||
zip.write_all(&*char_dat.write_to_buffer().unwrap())?;
|
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)?;
|
||||||
|
// I'm intentionally ignoring the message because it doesn't matter if it fails - and it usually does
|
||||||
|
let _ = download(&stop_url).await;
|
||||||
|
}
|
||||||
|
|
||||||
zip.start_file("character.json", options)?;
|
zip.start_file("character.json", options)?;
|
||||||
zip.write_all(serde_json::to_string(&char_data).unwrap().as_ref())?;
|
zip.write_all(serde_json::to_string(&char_data).unwrap().as_ref())?;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue