rs_pixel/util/
minecraft.rs1use super::error::Error;
2use crate::RsPixel;
3use serde_json::Value;
4
5pub async fn username_to_uuid(rs_pixel: &RsPixel, username: &str) -> Result<Response, Error> {
6 if let Some(uuid_to_username_cache) = &rs_pixel.config.uuid_to_username_cache {
7 if let Some(cache_entry) = uuid_to_username_cache
8 .iter()
9 .find(|e| e.1.eq_ignore_ascii_case(username))
10 {
11 return Ok(Response {
12 username: cache_entry.1,
13 uuid: cache_entry.0.to_string(),
14 });
15 }
16 }
17
18 uuid_username(rs_pixel, username, false).await
19}
20
21pub async fn uuid_to_username(rs_pixel: &RsPixel, uuid: &str) -> Result<Response, Error> {
22 if let Some(uuid_to_username_cache) = &rs_pixel.config.uuid_to_username_cache {
23 if let Some(username) = uuid_to_username_cache.get(uuid) {
24 return Ok(Response {
25 username,
26 uuid: uuid.to_string(),
27 });
28 }
29 }
30
31 uuid_username(rs_pixel, uuid, true).await
32}
33
34async fn uuid_username(
35 rs_pixel: &RsPixel,
36 uuid_username: &str,
37 is_uuid: bool,
38) -> Result<Response, Error> {
39 match rs_pixel
40 .config
41 .client
42 .get(match rs_pixel.config.minecraft_api_type {
43 ApiType::Mojang => {
44 if is_uuid {
45 format!("https://api.mojang.com/user/profiles/{uuid_username}/names")
46 } else {
47 format!("https://api.mojang.com/users/profiles/minecraft/{uuid_username}")
48 }
49 }
50 ApiType::Ashcon => {
51 format!("https://api.ashcon.app/mojang/v2/user/{uuid_username}")
52 }
53 ApiType::PlayerDb => {
54 format!("https://playerdb.co/api/player/minecraft/{uuid_username}")
55 }
56 })
57 .send()
58 .await
59 {
60 Ok(mut res_unwrap) => {
61 let json = res_unwrap.body_json::<Value>().await.map_err(Error::from);
62
63 if res_unwrap.status() == 200 {
64 return match json {
65 Ok(json_unwrap) => Ok(match rs_pixel.config.minecraft_api_type {
66 ApiType::Mojang => Response {
67 username: (if is_uuid {
68 json_unwrap
69 .as_array()
70 .and_then(|v| v.last())
71 .and_then(|v| v.get("name"))
72 } else {
73 json_unwrap.get("name")
74 })
75 .and_then(serde_json::Value::as_str)
76 .unwrap_or("")
77 .to_string(),
78 uuid: (if is_uuid {
79 uuid_username
80 } else {
81 json_unwrap
82 .get("id")
83 .and_then(serde_json::Value::as_str)
84 .unwrap_or("")
85 })
86 .to_string(),
87 },
88 ApiType::Ashcon => Response {
89 username: json_unwrap
90 .get("username")
91 .and_then(serde_json::Value::as_str)
92 .unwrap_or("")
93 .to_string(),
94 uuid: json_unwrap
95 .get("uuid")
96 .and_then(serde_json::Value::as_str)
97 .unwrap_or("")
98 .to_string()
99 .replace('-', ""),
100 },
101 ApiType::PlayerDb => Response {
102 username: json_unwrap
103 .get("data")
104 .and_then(|v| v.get("player"))
105 .and_then(|v| v.get("username"))
106 .and_then(serde_json::Value::as_str)
107 .unwrap_or("")
108 .to_string(),
109 uuid: json_unwrap
110 .get("data")
111 .and_then(|v| v.get("player"))
112 .and_then(|v| v.get("id"))
113 .and_then(serde_json::Value::as_str)
114 .unwrap_or("")
115 .to_string()
116 .replace('-', ""),
117 },
118 }),
119 Err(err) => Err(err),
120 };
121 }
122
123 Err(Error::from((
124 res_unwrap.status(),
125 json.ok()
126 .as_ref()
127 .and_then(|json_unwrap| {
128 json_unwrap.get(match rs_pixel.config.minecraft_api_type {
129 ApiType::Mojang => "errorMessage",
130 ApiType::Ashcon => "reason",
131 ApiType::PlayerDb => "code",
132 })
133 })
134 .and_then(serde_json::Value::as_str)
135 .unwrap_or("Unknown fail cause")
136 .to_string(),
137 )))
138 }
139 Err(err) => Err(Error::from(err)),
140 }
141}
142
143#[derive(Debug)]
144pub struct Response {
145 pub username: String,
146 pub uuid: String,
147}
148
149#[derive(Default)]
150pub enum ApiType {
151 #[default]
152 Mojang,
153 Ashcon,
154 PlayerDb,
155}