1
Fork 0
mirror of https://github.com/redstrate/Auracite.git synced 2025-06-07 16:07:45 +00:00

Extract current class/job levels from the Lodestone

This commit is contained in:
Joshua Goins 2025-03-31 17:21:13 -04:00
parent 90a2eeda8a
commit 3210f31763
3 changed files with 40 additions and 2 deletions

View file

@ -1,7 +1,8 @@
use serde::Serialize; use serde::Serialize;
use crate::value::{ use crate::value::{
CityStateValue, GenderValue, GuardianValue, NamedayValue, RaceValue, TribeValue, WorldValue, CityStateValue, ClassJobValue, GenderValue, GuardianValue, NamedayValue, RaceValue, TribeValue,
WorldValue,
}; };
#[derive(Default, Serialize)] #[derive(Default, Serialize)]
@ -50,6 +51,8 @@ pub struct CharacterData {
pub race: RaceValue, pub race: RaceValue,
pub gender: GenderValue, pub gender: GenderValue,
pub tribe: TribeValue, pub tribe: TribeValue,
pub classjob_levels: Vec<ClassJobValue>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub currencies: Option<Currencies>, pub currencies: Option<Currencies>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]

View file

@ -1,7 +1,8 @@
use crate::{ use crate::{
data::CharacterData, data::CharacterData,
value::{ value::{
CityStateValue, GenderValue, GuardianValue, NamedayValue, RaceValue, TribeValue, WorldValue, CityStateValue, ClassJobValue, GenderValue, GuardianValue, NamedayValue, RaceValue,
TribeValue, WorldValue,
}, },
}; };
use regex::Regex; use regex::Regex;
@ -40,6 +41,7 @@ const CHARACTER_BLOCK_NAME_SELECTOR: &str = ".character-block__name";
const FACE_IMG_SELECTOR: &str = ".frame__chara__face > img"; const FACE_IMG_SELECTOR: &str = ".frame__chara__face > img";
const PORTRAIT_IMG_SELECTOR: &str = ".character__detail__image > a > img"; const PORTRAIT_IMG_SELECTOR: &str = ".character__detail__image > a > img";
const NAMEDAY_SELECTOR: &str = ".character-block__birth"; const NAMEDAY_SELECTOR: &str = ".character-block__birth";
const CLASSJOB_SELECTOR: &str = ".character__level__list > ul > li";
/// Parses the HTML from `data` and returns `CharacterData`. The data may be incomplete. /// Parses the HTML from `data` and returns `CharacterData`. The data may be incomplete.
pub fn parse_lodestone(data: &str) -> CharacterData { pub fn parse_lodestone(data: &str) -> CharacterData {
@ -118,5 +120,30 @@ pub fn parse_lodestone(data: &str) -> CharacterData {
char_data.portrait_url = element.attr("src").unwrap().parse().unwrap(); char_data.portrait_url = element.attr("src").unwrap().parse().unwrap();
} }
for element in document.select(&Selector::parse(CLASSJOB_SELECTOR).unwrap()) {
let img = element.first_child().unwrap();
let name = img
.value()
.as_element()
.unwrap()
.attr("data-tooltip")
.unwrap();
// ignore "-" and other invalid level values
if let Ok(level) = element
.last_child()
.unwrap()
.value()
.as_text()
.unwrap()
.parse::<i32>()
{
char_data.classjob_levels.push(ClassJobValue {
name: name.to_string(),
level,
});
}
}
char_data char_data
} }

View file

@ -292,3 +292,11 @@ impl TryFrom<&str> for NamedayValue {
}) })
} }
} }
#[derive(Default, Serialize)]
pub struct ClassJobValue {
/// Name of the class or job.
pub name: String,
/// Level of the class or job.
pub level: i32,
}