feat: initial support for GetUserRating

This commit is contained in:
mokurin000
2025-08-01 01:15:13 +08:00
parent 0b8de2b4bc
commit 9b046036c9
12 changed files with 139 additions and 15 deletions

View File

@@ -19,6 +19,9 @@ tokio = { workspace = true, optional = true }
compio = { workspace = true, optional = true }
spdlog-rs = { workspace = true }
# (de)serialization
serde = { workspace = true }
# hashing
digest = "0.10.7"
hmac-sha256 = { version = "1.1.12", features = ["digest010", "traits010"] }
@@ -30,8 +33,6 @@ chrono = "0.4.41"
# network request
nyquest = { version = "0.2.0", features = ["async", "json"] }
# (de)serialization
serde = { version = "1.0.219", features = ["derive"] }
# compression / encryption
flate2 = "1.1.2"

View File

@@ -0,0 +1,15 @@
pub fn level_name(level: u32) -> &'static str {
match level {
0 => "BASIC",
1 => "ADVANCED",
2 => "EXPERT",
3 => "MASTER",
4 => "RE: MASTER",
5 => "UTAGE",
_ => "Unknown",
}
}
// TODO: MusicDB lazy load
// struct MusicDB;
// static MUSIC_DB: LazyLock<MusicDB> = LazyLock::new(|| unimplemented!());

View File

@@ -2,6 +2,8 @@ pub mod all_net;
pub mod auth_lite;
pub mod title;
pub mod helper;
mod error;
pub use error::ApiError;

View File

@@ -1,6 +1,10 @@
use std::fmt::Display;
use serde::Deserialize;
use serde::Serialize;
use crate::helper::level_name;
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetUserRatingApi {
@@ -17,21 +21,22 @@ pub struct GetUserRatingApiResp {
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UserRating {
/// total rating, now it's 0
pub rating: i64,
/// b35
pub rating_list: Vec<RatingList>,
pub rating_list: Vec<MusicRating>,
/// b15
pub new_rating_list: Vec<RatingList>,
pub new_rating_list: Vec<MusicRating>,
/// 候补 b35
pub next_rating_list: Vec<RatingList>,
pub next_rating_list: Vec<MusicRating>,
/// 候补 b15
pub next_new_rating_list: Vec<RatingList>,
pub next_new_rating_list: Vec<MusicRating>,
pub udemae: Udemae,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RatingList {
pub struct MusicRating {
/// Maimai music id
pub music_id: u32,
/// difficulty
@@ -83,3 +88,43 @@ pub struct Udemae {
#[serde(rename = "NpcLoseNum")]
pub npc_lose_num2: i64,
}
impl Display for GetUserRatingApiResp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("用户ID: {}\n", self.user_id))?;
f.write_str("\n---------- B35 ----------\n")?;
for b35 in &self.user_rating.rating_list {
f.write_fmt(format_args!("{b35}\n---\n"))?;
}
f.write_str("\n---------- B15 ----------\n")?;
for b15 in &self.user_rating.new_rating_list {
f.write_fmt(format_args!("{b15}\n---\n"))?;
}
Ok(())
}
}
impl Display for MusicRating {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("歌曲ID: \t{}\n", self.music_id))?;
f.write_fmt(format_args!(
"谱面版本: \t{}\n",
match (self.music_id / 10000) % 10 {
0 => "SD",
1 => "DX",
_ => "",
}
))?;
f.write_fmt(format_args!("游玩难度: \t{}\n", level_name(self.level)))?;
f.write_fmt(format_args!(
"达成率: \t{}.{}%",
self.achievement / 10000,
self.achievement % 10000
))?;
Ok(())
}
}

View File

@@ -11,7 +11,9 @@ pub struct UserLoginApi {
pub acsess_code: String,
pub place_id: String,
pub client_id: String,
/// set to `false` is fine
/// false 的情况,二维码扫描后半小时可登录。
///
/// true 的情况,可延长至二维码扫描后的两小时可登录。
pub is_continue: bool,
/// fixed to 0
pub generic_flag: u8,