use std::collections::HashSet;
use serde::Deserialize;
use strum::{EnumIter, IntoEnumIterator, EnumProperty};
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct RawStamp {
id: usize,
seq: usize,
name: String,
description: Option<String>,
stamp_type: String,
assetbundle_name: String,
balloon_assetbundle_name: String,
// ignored by us, used in sekai-viewer UI
archive_published_at: usize,
// ignored by us, used in sekai-viewer UI
archive_display_type: Option<String>,
character_id_1: Option<Character>,
character_id_2: Option<Character>,
game_character_unit_id: Option<Character>
}
impl RawStamp {
pub fn to_stamp(self) -> Stamp {
use StampCharacter::*;
let RawStamp { id, seq,
name, description, stamp_type,
assetbundle_name, balloon_assetbundle_name,
character_id_1, character_id_2, game_character_unit_id, .. } = self;
let character = match (character_id_1, character_id_2, game_character_unit_id) {
(None, None, None)
=> Nobody,
(Some(character_id), None, None)
=> Solo{character_id},
(Some(character_id_1), Some(character_id_2), None)
=> Duo{character_id_1, character_id_2},
(Some(character_id), None, Some(game_character_unit_id))
=> SoloExtra{character_id, game_character_unit_id},
(None, None, Some(game_character_unit_id))
=> GCUID{game_character_unit_id},
x => { panic!("They added a new character format: {x:?}"); }
};
Stamp { id, seq,
name, description, stamp_type,
assetbundle_name, balloon_assetbundle_name,
character }
}
}
#[derive(Clone, Debug, Default)]
pub struct Stamp {
pub id: usize,
pub seq: usize,
pub name: String,
pub description: Option<String>,
pub stamp_type: String,
pub assetbundle_name: String,
pub balloon_assetbundle_name: String,
pub character: StampCharacter
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Hash)]
pub enum StampCharacter {
#[default]
Nobody,
Solo{character_id: Character},
Duo{character_id_1: Character, character_id_2: Character},
SoloExtra{character_id: Character, game_character_unit_id: Character},
GCUID{game_character_unit_id: Character},
}
impl std::fmt::Display for StampCharacter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
Self::Nobody => write!(f, "text"),
Self::Solo{character_id} => write!(f, "{}", character_id.get_str("prefix").unwrap()),
Self::Duo{character_id_1, character_id_2} => write!(f, "{}_{}", character_id_1.get_str("prefix").unwrap(), character_id_2.get_str("prefix").unwrap()),
Self::SoloExtra{game_character_unit_id, ..} => write!(f, "{}", game_character_unit_id.get_str("prefix").unwrap()),
Self::GCUID{game_character_unit_id} => write!(f, "text_{}", game_character_unit_id.get_str("prefix").unwrap())
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Deserialize, Hash, EnumIter, EnumProperty)]
#[repr(u8)]
#[serde(from = "u8")]
pub enum Character {
// Leo / Need
#[strum(props(prefix = "ichika"))]
Ichika = 1,
#[strum(props(prefix = "saki"))]
Saki = 2,
#[strum(props(prefix = "honami"))]
Honami = 3,
#[strum(props(prefix = "shiho"))]
Shiho = 4,
// MORE MORE JUMP!
#[strum(props(prefix = "minori"))]
Minori = 5,
#[strum(props(prefix = "haruka"))]
Haruka = 6,
#[strum(props(prefix = "airi"))]
Airi = 7,
#[strum(props(prefix = "shizuku"))]
Shizuku = 8,
// Vivid BAD SQUAD
#[strum(props(prefix = "kohane"))]
Kohane = 9,
#[strum(props(prefix = "an"))]
An = 10,
#[strum(props(prefix = "akito"))]
Akito = 11,
#[strum(props(prefix = "toya"))]
Toya = 12,
// Wonderlands x Showtime
#[strum(props(prefix = "tsukasa"))]
Tsukasa = 13,
#[strum(props(prefix = "emu"))]
Emu = 14,
#[strum(props(prefix = "nene"))]
Nene = 15,
#[strum(props(prefix = "rui"))]
Rui = 16,
// Nightcord at 25:00
#[strum(props(prefix = "kanade"))]
Kanade = 17,
#[strum(props(prefix = "mafuyu"))]
Mafuyu = 18,
#[strum(props(prefix = "ena"))]
Ena = 19,
#[strum(props(prefix = "mizuki"))]
Mizuki = 20,
// VOCALOID
#[strum(props(prefix = "miku"))]
Miku = 21,
#[strum(props(prefix = "rin"))]
Rin = 22,
#[strum(props(prefix = "len"))]
Len = 23,
#[strum(props(prefix = "luka"))]
Luka = 24,
#[strum(props(prefix = "meiko"))]
MEIKO = 25,
#[strum(props(prefix = "kaito"))]
KAITO = 26,
// "Game Character Unit ID"
// Basically just, character IDs associated to a particular group
// - Miku
#[strum(props(prefix = "ln_miku"))]
LnMiku = 27,
#[strum(props(prefix = "mmj_miku"))]
MmjMiku = 28,
#[strum(props(prefix = "vbs_miku"))]
VbsMiku = 29,
#[strum(props(prefix = "wxs_miku"))]
WxsMiku = 30,
#[strum(props(prefix = "n25_miku"))]
N25Miku = 31,
// - Rin
#[strum(props(prefix = "ln_rin"))]
LnRin = 32,
#[strum(props(prefix = "mmj_rin"))]
MmjRin = 33,
#[strum(props(prefix = "vbs_rin"))]
VbsRin = 34,
#[strum(props(prefix = "wxs_rin"))]
WxsRin = 35,
#[strum(props(prefix = "n25_rin"))]
N25Rin = 36,
// - Len
#[strum(props(prefix = "ln_len"))]
LnLen = 37,
#[strum(props(prefix = "mmj_len"))]
MmjLen = 38,
#[strum(props(prefix = "vbs_len"))]
VbsLen = 39,
#[strum(props(prefix = "wxs_len"))]
WxsLen = 40,
#[strum(props(prefix = "n25_len"))]
N25Len = 41,
// - Luka
#[strum(props(prefix = "ln_luka"))]
LnLuka = 42,
#[strum(props(prefix = "mmj_luka"))]
MmjLuka = 43,
#[strum(props(prefix = "vbs_luka"))]
VbsLuka = 44,
#[strum(props(prefix = "wxs_luka"))]
WxsLuka = 45,
#[strum(props(prefix = "n25_luka"))]
N25Luka = 46,
// - MEIKO
#[strum(props(prefix = "ln_meiko"))]
LnMEIKO = 47,
#[strum(props(prefix = "mmj_meiko"))]
MmjMEIKO = 48,
#[strum(props(prefix = "vbs_meiko"))]
VbsMEIKO = 49,
#[strum(props(prefix = "wxs_meiko"))]
WxsMEIKO = 50,
#[strum(props(prefix = "n25_meiko"))]
N25MEIKO = 51,
// - KAITO
#[strum(props(prefix = "ln_kaito"))]
LnKAITO = 52,
#[strum(props(prefix = "mmj_kaito"))]
MmjKAITO = 53,
#[strum(props(prefix = "vbs_kaito"))]
VbsKAITO = 54,
#[strum(props(prefix = "wxs_kaito"))]
WxsKAITO = 55,
#[strum(props(prefix = "n25_kaito"))]
N25KAITO = 56,
}
impl From<u8> for Character {
fn from(val: u8) -> Self {
for var in Self::iter() {
if var as u8 == val {
return var;
}
}
panic!("Unknown Character ID: {val}");
}
}
impl std::fmt::Display for Character {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{self:?}")
}
}
impl Stamp {
}