1use serde::{ Deserialize, Serialize };
2
3use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
4
5#[derive(Debug, Serialize, Clone, Deserialize)]
6pub struct UserInfo {
7 pub uid: i64,
9 pub base: UserBaseInfo,
11 pub medal: UserMedalInfo,
13 pub wealth: Option<serde_json::Value>,
15 pub title: Option<serde_json::Value>,
17 pub guard: UserGuardInfo,
19 pub uhead_frame: Option<serde_json::Value>,
21 pub guard_leader: Option<serde_json::Value>,
23}
24
25#[derive(Debug, Serialize, Clone, Deserialize)]
26pub struct GuardTabInfo {
27 pub num: i32,
29 pub page: i32,
31 pub now: i32,
33 pub achievement_level: i32,
35 pub anchor_guard_achieve_level: i32,
37 pub achievement_icon_src: String,
39 pub buy_guard_icon_src: String,
41 pub rule_doc_src: String,
43 pub ex_background_src: String,
45 pub color_start: String,
47 pub color_end: String,
49 pub tab_color: Vec<String>,
51 pub title_color: Vec<String>,
53}
54
55#[derive(Debug, Serialize, Clone, Deserialize)]
56pub struct UserOriginInfo {
57 pub name: String,
59 pub face: String,
61}
62
63#[derive(Debug, Serialize, Clone, Deserialize)]
64pub struct UserOfficialInfo {
65 pub role: i32,
67 pub title: String,
69 pub desc: String,
71 pub r#type: i32,
73}
74
75#[derive(Debug, Serialize, Clone, Deserialize)]
76pub struct UserBaseInfo {
77 pub name: String,
79 pub face: String,
81 pub name_color: i32,
83 pub is_mystery: bool,
85 pub risk_ctrl_info: Option<serde_json::Value>,
87 pub origin_info: UserOriginInfo,
89 pub official_info: UserOfficialInfo,
91 pub name_color_str: String,
93}
94
95#[derive(Debug, Serialize, Clone, Deserialize)]
96pub struct UserMedalInfo {
97 pub name: String,
99 pub level: i32,
101 pub color_start: i32,
103 pub color_end: i32,
105 pub color_border: i32,
107 pub color: i32,
109 pub id: i32,
111 pub typ: i32,
113 pub is_light: i32,
115 pub ruid: i64,
117 pub guard_level: i32,
119 pub score: i32,
121 pub guard_icon: String,
123 pub honor_icon: String,
125 pub v2_medal_color_start: String,
127 pub v2_medal_color_end: String,
129 pub v2_medal_color_border: String,
131 pub v2_medal_color_text: String,
133 pub v2_medal_color_level: String,
135 pub user_receive_count: i32,
137}
138
139#[derive(Debug, Serialize, Clone, Deserialize)]
140pub struct UserGuardInfo {
141 pub level: i32,
143 pub expired_str: String,
145}
146
147#[derive(Debug, Serialize, Clone, Deserialize)]
148pub struct GuardMember {
149 pub ruid: i64,
151 pub rank: i32,
153 pub accompany: i32,
155 pub uinfo: UserInfo,
157 pub score: i32,
159}
160
161#[derive(Debug, Serialize, Clone, Deserialize)]
162pub struct GuardListData {
163 pub info: GuardTabInfo,
165 pub top3: Vec<GuardMember>,
167 pub list: Vec<GuardMember>,
169}
170
171pub type GuardListResponse = BpiResponse<GuardListData>;
172
173impl BpiClient {
176 pub async fn live_guard_list(
197 &self,
198 room_id: i64,
199 ruid: i64,
200 page: Option<i32>,
201 page_size: Option<i32>,
202 typ: Option<i32>
203 ) -> Result<GuardListResponse, BpiError> {
204 let params: Vec<(&str, String)> = vec![
205 ("roomid", room_id.to_string()),
206 ("ruid", ruid.to_string()),
207 ("page", page.unwrap_or(1).to_string()),
208 ("page_size", page_size.unwrap_or(20).to_string()),
209 ("typ", typ.unwrap_or(5).to_string())
210 ];
211
212 let resp: GuardListResponse = self
213 .get("https://api.live.bilibili.com/xlive/app-room/v2/guardTab/topListNew")
214 .query(¶ms)
215 .send_bpi("查询大航海成员").await?;
216
217 Ok(resp)
218 }
219}
220
221#[cfg(test)]
222mod tests {
223 use super::*;
224
225 #[tokio::test]
226 async fn test_get_guard_list() -> Result<(), Box<BpiError>> {
227 let bpi = BpiClient::new();
228 let resp = bpi.live_guard_list(23174842, 504140200, None, None, None).await?;
229
230 let data = resp.data.unwrap();
231 assert!(data.list.len() > 0);
232 Ok(())
233 }
234}