diff --git a/.gitignore b/.gitignore index 96ef862..f9f414d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target/ .idea/ +/cross-build.bat \ No newline at end of file diff --git a/entry/src/data.rs b/entry/src/data.rs index 49fdfac..c65620c 100644 --- a/entry/src/data.rs +++ b/entry/src/data.rs @@ -1,5 +1,6 @@ use crate::CONFIG; use serde::{Deserialize, Serialize}; +use std::cmp::Ordering; use std::path::PathBuf; #[derive(Debug)] @@ -19,6 +20,7 @@ impl Config { #[derive(Debug, Default)] pub struct OptConfig { pub proxy: Option, + pub pjsk_proxy: Option, pub ghp: Option, pub log_level: Option, } @@ -27,6 +29,7 @@ impl OptConfig { pub const fn new() -> Self { Self { proxy: None, + pjsk_proxy: None, ghp: None, log_level: None, } @@ -44,7 +47,6 @@ impl State { serde_json::from_str(x).unwrap() } - pub const fn new() -> Self { Self { git_hash: None, @@ -82,17 +84,6 @@ pub struct EventStory { pub assetbundle_name: String, } -// 用这个找是因为这个文件小一点((( -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CardEpisode { - pub id: u64, - pub seq: u64, - #[serde(rename = "cardId")] - pub card_id: u64, - #[serde(rename = "assetbundleName")] - pub assetbundle_name: String, -} - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EventCard { pub id: u64, @@ -102,6 +93,114 @@ pub struct EventCard { pub event_id: u64, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Card { + pub id: u64, + #[serde(rename = "characterId")] + pub character_id: u64, + #[serde(rename = "cardRarityType")] + pub card_rarity_type: String, + pub attr: String, + #[serde(rename = "skillId")] + pub skill_id: u64, + pub prefix: String, + #[serde(rename = "assetbundleName")] + pub assetbundle_name: String, +} +impl PartialEq for Card { + fn eq(&self, other: &Self) -> bool { + self.id.eq(&other.id) + } +} + +impl Eq for Card {} + +impl PartialOrd for Card { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} +impl Ord for Card { + fn cmp(&self, other: &Self) -> Ordering { + self.id.cmp(&other.id) + } +} + +impl Card { + pub fn rarity_short_text(&self) -> String { + match self.card_rarity_type.as_str() { + "rarity_1" => "⭐".to_string(), + "rarity_2" => "⭐⭐".to_string(), + "rarity_3" => "⭐⭐⭐".to_string(), + "rarity_4" => "⭐⭐⭐⭐".to_string(), + "rarity_birthday" => "🎀".to_string(), + _ => self.card_rarity_type.clone(), + } + } + pub fn attr_short_text(&self) -> String { + match self.attr.as_str() { + "cute" => "粉花".to_string(), + "pure" => "绿草".to_string(), + "cool" => "蓝星".to_string(), + "mysterious" => "紫月".to_string(), + "happy" => "橙心".to_string(), + _ => self.attr.clone(), + } + } + pub fn skill_id_short(&self) -> Option { + match self.skill_id { + 1..=4 => Some("得分提高".to_string()), + 5..=8 => Some("判定提升".to_string()), + 9..=10 => Some("回复".to_string()), + 11 => Some("P分".to_string()), + 12 => Some("血分".to_string()), + 13 => Some("P分(特殊)".to_string()), + 14 => Some("回复P分(特殊)".to_string()), + 15 => Some("LN团分".to_string()), + 16 => Some("MMJ团分".to_string()), + 17 => Some("VBS团分".to_string()), + 18 => Some("WS团分".to_string()), + 19 => Some("25团分".to_string()), + 22 => Some("等级分(bfes)".to_string()), + 23 => Some("队内抽分(bfes)".to_string()), + 24 => Some("多团分".to_string()), + _ => None, + } + } + + pub fn character_name(&self) -> String { + match self.character_id { + 1 => "星乃一歌".to_string(), + 2 => "天馬咲希".to_string(), + 3 => "望月穂波".to_string(), + 4 => "日野森志歩".to_string(), + 5 => "花里みのり".to_string(), + 6 => "桐谷遥".to_string(), + 7 => "桃井愛莉".to_string(), + 8 => "日野森雫".to_string(), + 9 => "小豆沢こはね".to_string(), + 10 => "白石杏".to_string(), + 11 => "東雲彰人".to_string(), + 12 => "青柳冬弥".to_string(), + 13 => "天馬司".to_string(), + 14 => "鳳えむ".to_string(), + 15 => "草薙寧々".to_string(), + 16 => "神代類".to_string(), + 17 => "宵崎奏".to_string(), + 18 => "朝比奈まふゆ".to_string(), + 19 => "東雲絵名".to_string(), + 20 => "暁山瑞希".to_string(), + 21 => "初音ミク".to_string(), + 22 => "鏡音リン".to_string(), + 23 => "鏡音レン".to_string(), + 24 => "巡音ルカ".to_string(), + 25 => "MEIKO".to_string(), + 26 => "KAITO".to_string(), + _ => "".to_string(), + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CurrentVersion { pub app_hash: String, @@ -112,7 +211,13 @@ pub struct CurrentVersion { } #[derive(Debug, Clone, Serialize)] -pub struct FetchResult{ +pub struct FetchResultCard { + pub text: String, + pub path: Vec, +} + +#[derive(Debug, Clone, Serialize)] +pub struct FetchResult { pub event_id: u64, - pub card_paths: Vec, -} \ No newline at end of file + pub cards: Vec, +} diff --git a/entry/src/download.rs b/entry/src/download.rs index 978d420..a81133a 100644 --- a/entry/src/download.rs +++ b/entry/src/download.rs @@ -14,11 +14,11 @@ impl Downloader { pub async fn new() -> anyhow::Result { let master_data = get_master_data().await?; let mut execution = ExecutionConfig::default(); - // if let Ok(opt_conf) = &OPT_CONFIG.read() - // && let Some(proxy) = &opt_conf.proxy - // { - // execution.proxy = Some(proxy.to_string()); - // } + if let Ok(opt_conf) = &OPT_CONFIG.read() + && let Some(proxy) = &opt_conf.pjsk_proxy + { + execution.proxy = Some(proxy.to_string()); + } let app_config = AppConfig { execution, tools: ToolsConfig{ diff --git a/entry/src/github.rs b/entry/src/github.rs index ca278a0..47fab5d 100644 --- a/entry/src/github.rs +++ b/entry/src/github.rs @@ -61,7 +61,7 @@ pub fn raw_url(path: &str) -> String { pub async fn sync_data() -> anyhow::Result<()> { let client = http_client()?; - let (events_cards, event_stories, card_episodes) = tokio::try_join!( + let (events_cards, event_stories, cards) = tokio::try_join!( client.get(raw_url("eventCards.json")).send().await?.text(), client .get(raw_url("eventStories.json")) @@ -69,7 +69,7 @@ pub async fn sync_data() -> anyhow::Result<()> { .await? .text(), client - .get(raw_url("cardEpisodes.json")) + .get(raw_url("cards.json")) .send() .await? .text() @@ -78,7 +78,7 @@ pub async fn sync_data() -> anyhow::Result<()> { let mut store = STORE.write().map_err(|e| anyhow!("{}", e))?; store.set_event_cards(serde_json::from_str(&events_cards)?); store.set_event_stories(serde_json::from_str(&event_stories)?); - store.set_card_episodes(serde_json::from_str(&card_episodes)?); + store.set_cards(serde_json::from_str(&cards)?); Ok(()) } diff --git a/entry/src/lib.rs b/entry/src/lib.rs index 09019ec..eca90be 100644 --- a/entry/src/lib.rs +++ b/entry/src/lib.rs @@ -78,6 +78,7 @@ macro_rules! def_opt_str_setter { } def_opt_str_setter!(proxy); +def_opt_str_setter!(pjsk_proxy); def_opt_str_setter!(ghp); def_opt_str_setter!(log_level); diff --git a/entry/src/main_loop.rs b/entry/src/main_loop.rs index 60a671f..a3eec37 100644 --- a/entry/src/main_loop.rs +++ b/entry/src/main_loop.rs @@ -1,4 +1,4 @@ -use crate::data::{FetchResult, State}; +use crate::data::{FetchResult, FetchResultCard, State}; use crate::download::Downloader; use crate::github::{fetch_last_hash, sync_data}; use crate::{CONFIG, PROVIDE, STATE, STORE, ending_point}; @@ -70,7 +70,7 @@ pub async fn main() -> anyhow::Result<()> { ending_point!(ok); debug!( "Pulling card {} from bundle {}", - card.card_id, card.assetbundle_name + card.id, card.assetbundle_name ); let dir = downloader .pull(&format!("character/member/{}", card.assetbundle_name)) @@ -97,25 +97,43 @@ pub async fn main() -> anyhow::Result<()> { } } fs::remove_dir_all(dir.0)?; - Ok::<_, anyhow::Error>((card.card_id, local_images)) + Ok::<_, anyhow::Error>((card.clone(), local_images)) }); } let mut images = Vec::new(); while let Some(res) = futures.next().await { images.push(res?); } - images.sort_by(|a, b| b.0.cmp(&a.0)); // 大在前 - let images: Vec<_> = images.into_iter().flat_map(|(_, sub)| sub).collect(); + images.sort_by(|a, b| a.0.id.cmp(&b.0.id)); // 小在前 + let images: Vec<_> = images + .into_iter() + .map(|(card, path)| FetchResultCard { + text: format!( + "#{id} {attr}{rarity} {skill} [{prefix}]{name}", + id = card.id, + attr = card.attr_short_text(), + rarity = card.rarity_short_text(), + skill = card + .skill_id_short().map(|s| format!("({})", s)) + .unwrap_or_default(), + prefix = card.prefix, + name = card.character_name() + ), + path, + }) + .collect(); info!( - "In event {} collected {} images", + "In event {} collected {} cards", event.event_id, images.len() ); - *PROVIDE.write().map_err(|e| anyhow!("{}", e))? = Some(FetchResult { + let result = FetchResult { event_id: event.event_id, - card_paths: images, - }); + cards: images, + }; + debug!("Providing result: {:?}", result); + *PROVIDE.write().map_err(|e| anyhow!("{}", e))? = Some(result); let mut state = STATE.write().map_err(|e| anyhow!("{}", e))?; state.git_hash = Some(current_hash); state.event_id = Some(event.event_id); diff --git a/entry/src/store.rs b/entry/src/store.rs index 299df67..24de17e 100644 --- a/entry/src/store.rs +++ b/entry/src/store.rs @@ -1,5 +1,5 @@ use crate::CONFIG; -use crate::data::{CardEpisode, EventCard, EventStory}; +use crate::data::{Card, EventCard, EventStory}; use serde::Serialize; use serde::de::DeserializeOwned; use std::fs; @@ -8,16 +8,16 @@ use std::path::PathBuf; #[derive(Debug, Default)] pub struct Store { pub event_stories: Vec, - pub card_episodes: Vec, pub event_cards: Vec, + pub cards: Vec, } impl Store { pub const fn new() -> Self { Self { event_cards: Vec::new(), - card_episodes: Vec::new(), event_stories: Vec::new(), + cards: Vec::new(), } } @@ -31,8 +31,8 @@ impl Store { Self { event_stories: Self::load_file(&cache_dir.join("event_stories.json")), - card_episodes: Self::load_file(&cache_dir.join("card_episodes.json")), event_cards: Self::load_file(&cache_dir.join("event_cards.json")), + cards: Self::load_file(&cache_dir.join("cards.json")), } } @@ -55,23 +55,23 @@ impl Store { Self::save_file(&path, &self.event_stories); } - pub fn set_card_episodes(&mut self, data: Vec) { - self.card_episodes = data; - let path = CONFIG.get().unwrap().cache_dir().join("card_episodes.json"); - Self::save_file(&path, &self.card_episodes); - } - pub fn set_event_cards(&mut self, data: Vec) { self.event_cards = data; let path = CONFIG.get().unwrap().cache_dir().join("event_cards.json"); Self::save_file(&path, &self.event_cards); } + pub fn set_cards(&mut self, data: Vec) { + self.cards = data; + let path = CONFIG.get().unwrap().cache_dir().join("cards.json"); + Self::save_file(&path, &self.cards); + } + pub fn save_all(&self) { let cache_dir = CONFIG.get().unwrap().cache_dir(); Self::save_file(&cache_dir.join("event_stories.json"), &self.event_stories); - Self::save_file(&cache_dir.join("card_episodes.json"), &self.card_episodes); Self::save_file(&cache_dir.join("event_cards.json"), &self.event_cards); + Self::save_file(&cache_dir.join("cards.json"), &self.cards); } pub fn find_last_event(&self) -> Option { @@ -81,15 +81,15 @@ impl Store { .cloned() } - pub fn find_cards_by_event(&self, event_id: u64) -> Vec { + pub fn find_cards_by_event(&self, event_id: u64) -> Vec { self.event_cards .iter() .filter(|e| e.event_id == event_id) .filter_map(|c| { - self.card_episodes + self.cards .iter() .rev() - .find(|e| e.card_id == c.card_id) + .find(|e| e.id == c.card_id) }) .cloned() .collect()