2025-03-13 00:02:37 -04:00
|
|
|
use binrw::binrw;
|
2025-03-09 09:40:11 -04:00
|
|
|
use serde_json::{Value, json};
|
|
|
|
|
2025-03-13 00:02:37 -04:00
|
|
|
#[binrw]
|
|
|
|
#[derive(Debug, Clone, Default)]
|
2025-03-09 09:40:11 -04:00
|
|
|
pub struct ClientCustomizeData {
|
|
|
|
pub race: i32,
|
|
|
|
pub gender: i32,
|
|
|
|
pub height: i32,
|
|
|
|
pub subrace: i32,
|
|
|
|
pub face: i32,
|
|
|
|
pub hair: i32,
|
|
|
|
pub enable_highlights: i32,
|
|
|
|
pub skin_tone: i32,
|
|
|
|
pub right_eye_color: i32,
|
|
|
|
pub hair_tone: i32,
|
|
|
|
pub highlights: i32,
|
|
|
|
pub facial_features: i32,
|
|
|
|
pub facial_feature_color: i32,
|
|
|
|
pub eyebrows: i32,
|
|
|
|
pub left_eye_color: i32,
|
|
|
|
pub eyes: i32,
|
|
|
|
pub nose: i32,
|
|
|
|
pub jaw: i32,
|
|
|
|
pub mouth: i32,
|
|
|
|
pub lips_tone_fur_pattern: i32,
|
|
|
|
pub race_feature_size: i32,
|
|
|
|
pub race_feature_type: i32,
|
|
|
|
pub bust: i32,
|
|
|
|
pub face_paint: i32,
|
|
|
|
pub face_paint_color: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ClientCustomizeData {
|
|
|
|
pub fn to_json(&self) -> Value {
|
|
|
|
json!([
|
|
|
|
self.race.to_string(),
|
|
|
|
self.gender.to_string(),
|
|
|
|
self.height.to_string(),
|
|
|
|
self.subrace.to_string(),
|
|
|
|
self.face.to_string(),
|
|
|
|
self.enable_highlights.to_string(),
|
|
|
|
self.skin_tone.to_string(),
|
|
|
|
self.right_eye_color.to_string(),
|
|
|
|
self.hair_tone.to_string(),
|
|
|
|
self.highlights.to_string(),
|
|
|
|
self.facial_features.to_string(),
|
|
|
|
self.facial_feature_color.to_string(),
|
|
|
|
self.eyebrows.to_string(),
|
|
|
|
self.left_eye_color.to_string(),
|
|
|
|
self.eyes.to_string(),
|
|
|
|
self.nose.to_string(),
|
|
|
|
self.jaw.to_string(),
|
|
|
|
self.mouth.to_string(),
|
|
|
|
self.lips_tone_fur_pattern.to_string(),
|
|
|
|
self.race_feature_size.to_string(),
|
|
|
|
self.race_feature_type.to_string(),
|
|
|
|
self.bust.to_string(),
|
|
|
|
self.face_paint.to_string(),
|
|
|
|
self.face_paint_color.to_string(),
|
|
|
|
])
|
|
|
|
}
|
2025-03-13 23:30:48 -04:00
|
|
|
|
|
|
|
pub fn from_json(json: &Value) -> Self {
|
|
|
|
Self {
|
|
|
|
race: json[0].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
gender: json[1].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
height: json[2].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
subrace: json[3].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
face: json[4].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
hair: json[5].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
enable_highlights: json[6].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
skin_tone: json[7].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
right_eye_color: json[8].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
hair_tone: json[9].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
highlights: json[10].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
facial_features: json[11].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
facial_feature_color: json[12].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
eyebrows: json[13].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
left_eye_color: json[14].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
eyes: json[15].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
nose: json[16].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
jaw: json[17].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
mouth: json[18].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
lips_tone_fur_pattern: json[19].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
race_feature_size: json[20].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
race_feature_type: json[21].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
bust: json[22].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
face_paint: json[23].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
face_paint_color: json[24].as_str().unwrap().parse::<i32>().unwrap(),
|
|
|
|
}
|
|
|
|
}
|
2025-03-09 09:40:11 -04:00
|
|
|
}
|
2025-03-09 10:13:47 -04:00
|
|
|
/// See https://github.com/aers/FFXIVClientStructs/blob/main/FFXIVClientStructs/FFXIV/Application/Network/WorkDefinitions/ClientSelectData.cs
|
2025-03-09 09:40:11 -04:00
|
|
|
pub struct ClientSelectData {
|
|
|
|
pub game_name_unk: String,
|
2025-03-09 10:13:47 -04:00
|
|
|
pub current_class: i32,
|
|
|
|
pub class_levels: [i32; 30],
|
|
|
|
pub race: i32,
|
|
|
|
pub subrace: i32,
|
|
|
|
pub gender: i32,
|
|
|
|
pub birth_month: i32,
|
|
|
|
pub birth_day: i32,
|
|
|
|
pub guardian: i32,
|
2025-03-09 09:40:11 -04:00
|
|
|
pub unk8: i32,
|
|
|
|
pub unk9: i32,
|
2025-03-09 10:13:47 -04:00
|
|
|
pub zone_id: i32,
|
2025-03-09 09:40:11 -04:00
|
|
|
pub unk11: i32,
|
|
|
|
pub customize: ClientCustomizeData,
|
|
|
|
pub unk12: i32,
|
|
|
|
pub unk13: i32,
|
|
|
|
pub unk14: [i32; 10],
|
|
|
|
pub unk15: i32,
|
|
|
|
pub unk16: i32,
|
2025-03-09 10:13:47 -04:00
|
|
|
/// If set to 1, the user is granted one opportunity to edit their character and are prompted to re-choose their class.
|
|
|
|
pub legacy_character: i32,
|
2025-03-09 09:40:11 -04:00
|
|
|
pub unk18: i32,
|
|
|
|
pub unk19: i32,
|
|
|
|
pub unk20: i32,
|
|
|
|
pub unk21: String,
|
|
|
|
pub unk22: i32,
|
|
|
|
pub unk23: i32,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ClientSelectData {
|
|
|
|
pub fn to_json(&self) -> String {
|
|
|
|
let content = json!([
|
|
|
|
self.game_name_unk,
|
2025-03-09 10:13:47 -04:00
|
|
|
self.current_class.to_string(),
|
|
|
|
self.class_levels.map(|x| x.to_string()),
|
|
|
|
self.race.to_string(),
|
|
|
|
self.subrace.to_string(),
|
|
|
|
self.gender.to_string(),
|
|
|
|
self.birth_month.to_string(),
|
|
|
|
self.birth_day.to_string(),
|
|
|
|
self.guardian.to_string(),
|
2025-03-09 09:40:11 -04:00
|
|
|
self.unk8.to_string(),
|
|
|
|
self.unk9.to_string(),
|
2025-03-09 10:13:47 -04:00
|
|
|
self.zone_id.to_string(),
|
2025-03-09 09:40:11 -04:00
|
|
|
self.unk11.to_string(),
|
|
|
|
self.customize.to_json(),
|
|
|
|
self.unk12.to_string(),
|
|
|
|
self.unk13.to_string(),
|
|
|
|
self.unk14.map(|x| x.to_string()),
|
|
|
|
self.unk15.to_string(),
|
|
|
|
self.unk16.to_string(),
|
2025-03-09 10:13:47 -04:00
|
|
|
self.legacy_character.to_string(),
|
2025-03-09 09:40:11 -04:00
|
|
|
self.unk18.to_string(),
|
|
|
|
self.unk19.to_string(),
|
|
|
|
self.unk20.to_string(),
|
|
|
|
self.unk21,
|
|
|
|
self.unk22.to_string(),
|
|
|
|
self.unk23.to_string(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
let obj = json!({
|
|
|
|
"content": content,
|
|
|
|
"classname": "ClientSelectData",
|
|
|
|
"classid": 116,
|
|
|
|
});
|
|
|
|
|
|
|
|
serde_json::to_string_pretty(&obj).unwrap()
|
|
|
|
}
|
|
|
|
}
|