add desc
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
target/
|
target/
|
||||||
.idea/
|
.idea/
|
||||||
|
/cross-build.bat
|
||||||
+118
-13
@@ -1,5 +1,6 @@
|
|||||||
use crate::CONFIG;
|
use crate::CONFIG;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -19,6 +20,7 @@ impl Config {
|
|||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct OptConfig {
|
pub struct OptConfig {
|
||||||
pub proxy: Option<String>,
|
pub proxy: Option<String>,
|
||||||
|
pub pjsk_proxy: Option<String>,
|
||||||
pub ghp: Option<String>,
|
pub ghp: Option<String>,
|
||||||
pub log_level: Option<String>,
|
pub log_level: Option<String>,
|
||||||
}
|
}
|
||||||
@@ -27,6 +29,7 @@ impl OptConfig {
|
|||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
proxy: None,
|
proxy: None,
|
||||||
|
pjsk_proxy: None,
|
||||||
ghp: None,
|
ghp: None,
|
||||||
log_level: None,
|
log_level: None,
|
||||||
}
|
}
|
||||||
@@ -44,7 +47,6 @@ impl State {
|
|||||||
serde_json::from_str(x).unwrap()
|
serde_json::from_str(x).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
git_hash: None,
|
git_hash: None,
|
||||||
@@ -82,17 +84,6 @@ pub struct EventStory {
|
|||||||
pub assetbundle_name: String,
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct EventCard {
|
pub struct EventCard {
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
@@ -102,6 +93,114 @@ pub struct EventCard {
|
|||||||
pub event_id: u64,
|
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<Ordering> {
|
||||||
|
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<String> {
|
||||||
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct CurrentVersion {
|
pub struct CurrentVersion {
|
||||||
pub app_hash: String,
|
pub app_hash: String,
|
||||||
@@ -111,8 +210,14 @@ pub struct CurrentVersion {
|
|||||||
pub asset_hash: String,
|
pub asset_hash: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct FetchResultCard {
|
||||||
|
pub text: String,
|
||||||
|
pub path: Vec<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct FetchResult {
|
pub struct FetchResult {
|
||||||
pub event_id: u64,
|
pub event_id: u64,
|
||||||
pub card_paths: Vec<PathBuf>,
|
pub cards: Vec<FetchResultCard>,
|
||||||
}
|
}
|
||||||
@@ -14,11 +14,11 @@ impl Downloader {
|
|||||||
pub async fn new() -> anyhow::Result<Downloader> {
|
pub async fn new() -> anyhow::Result<Downloader> {
|
||||||
let master_data = get_master_data().await?;
|
let master_data = get_master_data().await?;
|
||||||
let mut execution = ExecutionConfig::default();
|
let mut execution = ExecutionConfig::default();
|
||||||
// if let Ok(opt_conf) = &OPT_CONFIG.read()
|
if let Ok(opt_conf) = &OPT_CONFIG.read()
|
||||||
// && let Some(proxy) = &opt_conf.proxy
|
&& let Some(proxy) = &opt_conf.pjsk_proxy
|
||||||
// {
|
{
|
||||||
// execution.proxy = Some(proxy.to_string());
|
execution.proxy = Some(proxy.to_string());
|
||||||
// }
|
}
|
||||||
let app_config = AppConfig {
|
let app_config = AppConfig {
|
||||||
execution,
|
execution,
|
||||||
tools: ToolsConfig{
|
tools: ToolsConfig{
|
||||||
|
|||||||
+3
-3
@@ -61,7 +61,7 @@ pub fn raw_url(path: &str) -> String {
|
|||||||
|
|
||||||
pub async fn sync_data() -> anyhow::Result<()> {
|
pub async fn sync_data() -> anyhow::Result<()> {
|
||||||
let client = http_client()?;
|
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("eventCards.json")).send().await?.text(),
|
||||||
client
|
client
|
||||||
.get(raw_url("eventStories.json"))
|
.get(raw_url("eventStories.json"))
|
||||||
@@ -69,7 +69,7 @@ pub async fn sync_data() -> anyhow::Result<()> {
|
|||||||
.await?
|
.await?
|
||||||
.text(),
|
.text(),
|
||||||
client
|
client
|
||||||
.get(raw_url("cardEpisodes.json"))
|
.get(raw_url("cards.json"))
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await?
|
||||||
.text()
|
.text()
|
||||||
@@ -78,7 +78,7 @@ pub async fn sync_data() -> anyhow::Result<()> {
|
|||||||
let mut store = STORE.write().map_err(|e| anyhow!("{}", e))?;
|
let mut store = STORE.write().map_err(|e| anyhow!("{}", e))?;
|
||||||
store.set_event_cards(serde_json::from_str(&events_cards)?);
|
store.set_event_cards(serde_json::from_str(&events_cards)?);
|
||||||
store.set_event_stories(serde_json::from_str(&event_stories)?);
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ macro_rules! def_opt_str_setter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def_opt_str_setter!(proxy);
|
def_opt_str_setter!(proxy);
|
||||||
|
def_opt_str_setter!(pjsk_proxy);
|
||||||
def_opt_str_setter!(ghp);
|
def_opt_str_setter!(ghp);
|
||||||
def_opt_str_setter!(log_level);
|
def_opt_str_setter!(log_level);
|
||||||
|
|
||||||
|
|||||||
+27
-9
@@ -1,4 +1,4 @@
|
|||||||
use crate::data::{FetchResult, State};
|
use crate::data::{FetchResult, FetchResultCard, State};
|
||||||
use crate::download::Downloader;
|
use crate::download::Downloader;
|
||||||
use crate::github::{fetch_last_hash, sync_data};
|
use crate::github::{fetch_last_hash, sync_data};
|
||||||
use crate::{CONFIG, PROVIDE, STATE, STORE, ending_point};
|
use crate::{CONFIG, PROVIDE, STATE, STORE, ending_point};
|
||||||
@@ -70,7 +70,7 @@ pub async fn main() -> anyhow::Result<()> {
|
|||||||
ending_point!(ok);
|
ending_point!(ok);
|
||||||
debug!(
|
debug!(
|
||||||
"Pulling card {} from bundle {}",
|
"Pulling card {} from bundle {}",
|
||||||
card.card_id, card.assetbundle_name
|
card.id, card.assetbundle_name
|
||||||
);
|
);
|
||||||
let dir = downloader
|
let dir = downloader
|
||||||
.pull(&format!("character/member/{}", card.assetbundle_name))
|
.pull(&format!("character/member/{}", card.assetbundle_name))
|
||||||
@@ -97,25 +97,43 @@ pub async fn main() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs::remove_dir_all(dir.0)?;
|
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();
|
let mut images = Vec::new();
|
||||||
while let Some(res) = futures.next().await {
|
while let Some(res) = futures.next().await {
|
||||||
images.push(res?);
|
images.push(res?);
|
||||||
}
|
}
|
||||||
images.sort_by(|a, b| b.0.cmp(&a.0)); // 大在前
|
images.sort_by(|a, b| a.0.id.cmp(&b.0.id)); // 小在前
|
||||||
let images: Vec<_> = images.into_iter().flat_map(|(_, sub)| sub).collect();
|
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!(
|
info!(
|
||||||
"In event {} collected {} images",
|
"In event {} collected {} cards",
|
||||||
event.event_id,
|
event.event_id,
|
||||||
images.len()
|
images.len()
|
||||||
);
|
);
|
||||||
*PROVIDE.write().map_err(|e| anyhow!("{}", e))? = Some(FetchResult {
|
let result = FetchResult {
|
||||||
event_id: event.event_id,
|
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))?;
|
let mut state = STATE.write().map_err(|e| anyhow!("{}", e))?;
|
||||||
state.git_hash = Some(current_hash);
|
state.git_hash = Some(current_hash);
|
||||||
state.event_id = Some(event.event_id);
|
state.event_id = Some(event.event_id);
|
||||||
|
|||||||
+14
-14
@@ -1,5 +1,5 @@
|
|||||||
use crate::CONFIG;
|
use crate::CONFIG;
|
||||||
use crate::data::{CardEpisode, EventCard, EventStory};
|
use crate::data::{Card, EventCard, EventStory};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -8,16 +8,16 @@ use std::path::PathBuf;
|
|||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Store {
|
pub struct Store {
|
||||||
pub event_stories: Vec<EventStory>,
|
pub event_stories: Vec<EventStory>,
|
||||||
pub card_episodes: Vec<CardEpisode>,
|
|
||||||
pub event_cards: Vec<EventCard>,
|
pub event_cards: Vec<EventCard>,
|
||||||
|
pub cards: Vec<Card>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
event_cards: Vec::new(),
|
event_cards: Vec::new(),
|
||||||
card_episodes: Vec::new(),
|
|
||||||
event_stories: Vec::new(),
|
event_stories: Vec::new(),
|
||||||
|
cards: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,8 +31,8 @@ impl Store {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
event_stories: Self::load_file(&cache_dir.join("event_stories.json")),
|
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")),
|
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);
|
Self::save_file(&path, &self.event_stories);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_card_episodes(&mut self, data: Vec<CardEpisode>) {
|
|
||||||
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<EventCard>) {
|
pub fn set_event_cards(&mut self, data: Vec<EventCard>) {
|
||||||
self.event_cards = data;
|
self.event_cards = data;
|
||||||
let path = CONFIG.get().unwrap().cache_dir().join("event_cards.json");
|
let path = CONFIG.get().unwrap().cache_dir().join("event_cards.json");
|
||||||
Self::save_file(&path, &self.event_cards);
|
Self::save_file(&path, &self.event_cards);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_cards(&mut self, data: Vec<Card>) {
|
||||||
|
self.cards = data;
|
||||||
|
let path = CONFIG.get().unwrap().cache_dir().join("cards.json");
|
||||||
|
Self::save_file(&path, &self.cards);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn save_all(&self) {
|
pub fn save_all(&self) {
|
||||||
let cache_dir = CONFIG.get().unwrap().cache_dir();
|
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("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("event_cards.json"), &self.event_cards);
|
||||||
|
Self::save_file(&cache_dir.join("cards.json"), &self.cards);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_last_event(&self) -> Option<EventStory> {
|
pub fn find_last_event(&self) -> Option<EventStory> {
|
||||||
@@ -81,15 +81,15 @@ impl Store {
|
|||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_cards_by_event(&self, event_id: u64) -> Vec<CardEpisode> {
|
pub fn find_cards_by_event(&self, event_id: u64) -> Vec<Card> {
|
||||||
self.event_cards
|
self.event_cards
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|e| e.event_id == event_id)
|
.filter(|e| e.event_id == event_id)
|
||||||
.filter_map(|c| {
|
.filter_map(|c| {
|
||||||
self.card_episodes
|
self.cards
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.find(|e| e.card_id == c.card_id)
|
.find(|e| e.id == c.card_id)
|
||||||
})
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
|
|||||||
Reference in New Issue
Block a user