From 7742a8b01136b37b02dd1fc4b72afb9f5ecd89a5 Mon Sep 17 00:00:00 2001 From: mokurin000 <1348292515a@gmail.com> Date: Thu, 31 Jul 2025 02:04:49 +0800 Subject: [PATCH] refactor: login-logout action --- sdgb-api/src/error.rs | 8 +++ sdgb-api/src/title/model/mod.rs | 2 +- .../src/title/model/user_login_api/mod.rs | 25 +++++++ sdgb-cli/src/main.rs | 65 ++----------------- sdgb-cli/src/utils/mod.rs | 46 +++++++++++++ 5 files changed, 86 insertions(+), 60 deletions(-) create mode 100644 sdgb-cli/src/utils/mod.rs diff --git a/sdgb-api/src/error.rs b/sdgb-api/src/error.rs index 4b37771..2f2b564 100644 --- a/sdgb-api/src/error.rs +++ b/sdgb-api/src/error.rs @@ -1,6 +1,8 @@ use aes::cipher::{block_padding::UnpadError, inout::PadError}; use snafu::Snafu; +use crate::title::model::LoginError; + #[derive(Debug, Snafu)] pub enum ApiError { JoinError, @@ -33,6 +35,12 @@ pub enum ApiError { Request { source: nyquest::Error, }, + + #[snafu(display("login error: {source}"))] + #[snafu(context(false))] + Login { + source: LoginError, + }, } impl From for ApiError { diff --git a/sdgb-api/src/title/model/mod.rs b/sdgb-api/src/title/model/mod.rs index 8656a36..cf1ebe0 100644 --- a/sdgb-api/src/title/model/mod.rs +++ b/sdgb-api/src/title/model/mod.rs @@ -8,7 +8,7 @@ mod user_logout_api; pub use user_logout_api::{UserLogoutApi, UserLogoutApiResp}; mod user_login_api; -pub use user_login_api::{UserLoginApi, UserLoginApiResp}; +pub use user_login_api::{LoginError, UserLoginApi, UserLoginApiResp}; mod get_user_data_api; pub use get_user_data_api::{GetUserDataApi, GetUserDataApiResp}; diff --git a/sdgb-api/src/title/model/user_login_api/mod.rs b/sdgb-api/src/title/model/user_login_api/mod.rs index e6b70be..e401a96 100644 --- a/sdgb-api/src/title/model/user_login_api/mod.rs +++ b/sdgb-api/src/title/model/user_login_api/mod.rs @@ -52,3 +52,28 @@ impl UserLoginApi { } } } + +impl UserLoginApiResp { + pub fn error(&self) -> Option { + match self.return_code { + 1 => None, + 100 => Some(LoginError::AlreadyLogged), + 102 => Some(LoginError::QRCodeExpired), + 103 => Some(LoginError::AccountUnregistered), + error @ _ => Some(LoginError::Unknown { error }), + } + } +} + +#[derive(Debug, snafu::Snafu)] +pub enum LoginError { + #[snafu(display("QRCode was expired"))] + QRCodeExpired, + #[snafu(display("You did not logout last session"))] + AlreadyLogged, + #[snafu(display("userId does not exist"))] + AccountUnregistered, + + #[snafu(display("Unknown error: {error}"))] + Unknown { error: i32 }, +} diff --git a/sdgb-cli/src/main.rs b/sdgb-cli/src/main.rs index 9c514c9..2a4fc6f 100644 --- a/sdgb-cli/src/main.rs +++ b/sdgb-cli/src/main.rs @@ -18,17 +18,18 @@ use sdgb_api::{ methods::APIMethod, model::{ GetUserDataApi, GetUserDataApiResp, GetUserPreviewApi, GetUserPreviewApiResp, Ping, - PingResp, UserLoginApi, UserLoginApiResp, UserLogoutApi, UserLogoutApiResp, + PingResp, UserLogoutApi, UserLogoutApiResp, }, }, }; use spdlog::{error, info, warn}; -use crate::commands::Cli; +use crate::{commands::Cli, utils::login_action}; #[cfg(feature = "cache")] mod cache; mod commands; +mod utils; static EARLY_QUIT: AtomicBool = AtomicBool::new(false); @@ -202,48 +203,7 @@ async fn main() -> Result<(), Box> { serde_json::to_writer_pretty(output, &players)?; } commands::Commands::Userdata { user_id } => { - let login = UserLoginApi::new(user_id); - let date_time = login.date_time; - let Ok(login_resp): Result = - Sdgb1_50::request(&client, APIMethod::UserLoginApi, user_id, login).await - else { - let logout_resp: UserLogoutApiResp = Sdgb1_50::request( - &client, - APIMethod::UserLogoutApi, - user_id, - UserLogoutApi { - user_id, - date_time, - ..Default::default() - }, - ) - .await?; - - info!("logout: {logout_resp:?}"); - return Ok(()); - }; - - match login_resp.return_code { - 1 => info!("login succeed"), - 100 => { - error!("user already logged"); - return Ok(()); - } - 102 => { - error!("QRCode expired"); - return Ok(()); - } - 103 => { - error!("Unregistered userId"); - return Ok(()); - } - e @ _ => { - error!("unknown login error: {e}"); - return Ok(()); - } - } - - match Sdgb1_50::request::<_, GetUserDataApiResp>( + let action = async |_| match Sdgb1_50::request::<_, GetUserDataApiResp>( &client, APIMethod::GetUserDataApi, user_id, @@ -257,21 +217,8 @@ async fn main() -> Result<(), Box> { Err(e) => { error!("failed to get userdata: {e}"); } - } - - let logout_resp: UserLogoutApiResp = Sdgb1_50::request( - &client, - APIMethod::UserLogoutApi, - user_id, - UserLogoutApi { - user_id, - date_time, - ..Default::default() - }, - ) - .await?; - - info!("logout: {logout_resp:?}"); + }; + login_action(&client, user_id, action).await?; } } diff --git a/sdgb-cli/src/utils/mod.rs b/sdgb-cli/src/utils/mod.rs new file mode 100644 index 0000000..eccac35 --- /dev/null +++ b/sdgb-cli/src/utils/mod.rs @@ -0,0 +1,46 @@ +use nyquest_preset::nyquest::AsyncClient; +use sdgb_api::{ + ApiError, + title::{ + MaiVersionExt as _, Sdgb1_50, + methods::APIMethod, + model::{UserLoginApi, UserLoginApiResp, UserLogoutApi, UserLogoutApiResp}, + }, +}; +use spdlog::info; + +pub async fn login_action( + client: &AsyncClient, + user_id: u32, + action: impl AsyncFn(UserLoginApiResp) -> R, +) -> Result { + let login = UserLoginApi::new(user_id); + let date_time = login.date_time; + + info!("login unix timestamp: {date_time}"); + + let login_resp: UserLoginApiResp = + Sdgb1_50::request(&client, APIMethod::UserLoginApi, user_id, login).await?; + + match login_resp.error() { + None => info!("login succeed"), + Some(e) => return Err(e)?, + } + + let return_data = action(login_resp).await; + + let logout_resp = Sdgb1_50::request::<_, UserLogoutApiResp>( + &client, + APIMethod::UserLogoutApi, + user_id, + UserLogoutApi { + user_id, + date_time, + ..Default::default() + }, + ) + .await; + + info!("logout: {logout_resp:?}"); + Ok(return_data) +}