miHoYo_API/
client.rs

1use std::collections::HashMap;
2use itertools::Itertools;
3use crate::components::base::InnerClient;
4use crate::components::chronicle::starrail::StarRailClient;
5use crate::components::models::Base;
6use crate::components::models::hoyolab::record::{Account, AccountList};
7use crate::typing::{Dict, Game, Languages};
8
9
10
11pub struct Client {
12    pub(crate) client: InnerClient,
13    pub starrail: StarRailClient,
14}
15
16impl Default for Client {
17    fn default() -> Self {
18        Client {
19            client: InnerClient::default(),
20            #[cfg(feature = "starrail")]
21            starrail: StarRailClient::default(),
22        }
23    }
24}
25
26impl AsMut<Client> for Client {
27    fn as_mut(&mut self) -> &mut Client {
28        self
29    }
30}
31
32impl Client {
33    pub fn new() -> Client {
34        Client {
35            client: InnerClient::default(),
36            #[cfg(feature = "starrail")]
37            starrail: StarRailClient::default(),
38        }
39    }
40
41
42    /// HELP: Someone tell me how to use as method chain without as_mut func
43    pub fn set_cookies(mut self,  cookies: CookieType) -> anyhow::Result<Self> {
44        use crate::components::managers::manager::{__parse_cookies, auto_cookie};
45
46        let cookies = match cookies {
47            CookieType::Str(cookies) => __parse_cookies(String::from(cookies)),
48            CookieType::Dict(cookies) => {
49                let mut dict = Dict::new();
50                for (key, value) in cookies.into_iter() {
51                    dict.insert(key.to_string(), value.to_string());
52                }
53                dict
54            }
55        };
56
57        self.client.cookie_manager = auto_cookie(cookies.clone());
58
59        #[cfg(feature = "genshin")] {
60
61        }
62
63        #[cfg(feature = "starrail")] {
64            self.starrail.0.cookie_manager = auto_cookie(cookies.clone());
65        }
66
67        #[cfg(feature = "honkai")] {
68
69        }
70
71        Ok(self)
72    }
73
74    pub fn set_from_env(mut self, path: Option<&str>) -> anyhow::Result<Self> {
75        use std::env::var;
76
77        match path {
78            None => dotenv::dotenv()?,
79            Some(path) => dotenv::from_filename(path)?
80        };
81
82        let ltuid = var("ltuid").unwrap_or_else(|_| var("ltuid_v2").unwrap());
83        let ltoken = var("ltoken").unwrap_or_else(|_| var("ltoken_v2").unwrap());
84        let name = if ltoken.contains("v2") {
85            (String::from("ltuid_v2"), String::from("ltoken_v2"))
86        } else {
87            (String::from("ltuid"), String::from("ltoken"))
88        };
89
90        let dict = HashMap::from([
91            (name.0, ltuid),
92            (name.1, ltoken),
93        ]);
94
95        self.set_cookies(CookieType::Dict(dict))
96    }
97
98    // Vec<Account>
99    pub async fn get_game_accounts(&self, lang: Option<Languages>) -> anyhow::Result<Vec<Account>> {
100        let result = self.client.request_hoyolab("binding/api/getUserGameRolesByCookie",
101             lang,
102         None,
103         None,
104         None,
105         None
106        ).await?;
107
108        match result.json::<Base<AccountList>>().await {
109            Ok(val) => Ok(val.data.list),
110            Err(why) => {
111                panic!("{}", why)
112            }
113        }
114    }
115
116    pub async fn get_game_account(&self, game: Option<Game>, lang: Option<Languages>) -> anyhow::Result<Vec<Account>> {
117        let game = game.unwrap_or_else(|| self.client.game.clone());
118        let accounts = self.get_game_accounts(lang).await?
119            .into_iter()
120            .filter(|account| {
121                account.which_game().eq(&game)
122            })
123            .collect_vec();
124        Ok(accounts)
125    }
126}
127
128pub enum CookieType {
129    Str(&'static str),
130    Dict(HashMap<String, String>),
131}