From a9ce21c9095d6a45948333befee675327d833861 Mon Sep 17 00:00:00 2001 From: mokurin000 <1348292515a@gmail.com> Date: Tue, 29 Jul 2025 17:42:15 +0800 Subject: [PATCH] refactor: split modules --- Cargo.lock | 61 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- src/all_net/mod.rs | 55 +++++++++++++++++++++++++++++++++++++++ src/all_net/model.rs | 52 +++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 ++- src/main.rs | 52 ------------------------------------- src/model.rs | 24 ----------------- src/title/mod.rs | 1 + 8 files changed, 172 insertions(+), 78 deletions(-) create mode 100644 src/all_net/mod.rs create mode 100644 src/all_net/model.rs delete mode 100644 src/model.rs create mode 100644 src/title/mod.rs diff --git a/Cargo.lock b/Cargo.lock index ee82ad7..f7b2e29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aligned-array" version = "1.0.1" @@ -50,6 +65,21 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + [[package]] name = "bitflags" version = "2.9.1" @@ -453,6 +483,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "hashbrown" version = "0.15.4" @@ -566,6 +602,15 @@ version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -705,6 +750,15 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -786,6 +840,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + [[package]] name = "rustix" version = "1.0.8" @@ -891,6 +951,7 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320b01e011bf8d5d7a4a4a4be966d9160968935849c83b918827f6a435e7f627" dependencies = [ + "backtrace", "snafu-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 70338a4..5c34c80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ nyquest-preset = { version = "0.2.0", features = ["async"] } serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.141" -snafu = "0.8.6" +snafu = { version = "0.8.6", features = ["backtrace", "rust_1_81"] } compio = { version = "0.15.0", default-features = false, features = [ "runtime", "macros", diff --git a/src/all_net/mod.rs b/src/all_net/mod.rs new file mode 100644 index 0000000..e24da84 --- /dev/null +++ b/src/all_net/mod.rs @@ -0,0 +1,55 @@ +use std::backtrace::Backtrace; + +use nyquest::{AsyncClient, Body, Request}; + +mod model; +use model::{GetResponse, GetUserId}; + +pub struct QRCode<'a> { + qrcode_content: &'a str, +} + +#[derive(Debug, snafu::Snafu)] +pub enum QRLoginError { + QRCodeExpired10, + QRCodeExpired30, + BadSingature, + Unknown { + error_kind: i64, + }, + + #[snafu(context(false))] + NyquestError { + source: nyquest::Error, + backtrace: Backtrace, + }, + + #[snafu(context(false))] + JSONError { + source: serde_json::error::Error, + backtrace: Backtrace, + }, +} + +impl QRCode<'_> { + pub async fn login(self, client: &AsyncClient) -> Result { + let qr_code = &self.qrcode_content.as_bytes()[self.qrcode_content.len() - 64..]; + let qr_code = String::from_utf8_lossy(qr_code); + + let req = Request::post("http://ai.sys-allnet.cn/wc_aime/api/get_data") + .with_body(Body::json(&GetUserId::new(qr_code))?); + + let resp = client.request(req).await?; + let resp: GetResponse = resp.json().await?; + + let user_id = resp.user_id; + + match resp.error_id { + 0 => return Ok(user_id), + 2 => Err(QRLoginError::QRCodeExpired10), + 1 => Err(QRLoginError::QRCodeExpired30), + 50 => Err(QRLoginError::BadSingature), + error_kind @ _ => Err(QRLoginError::Unknown { error_kind }), + } + } +} diff --git a/src/all_net/model.rs b/src/all_net/model.rs new file mode 100644 index 0000000..2668e7b --- /dev/null +++ b/src/all_net/model.rs @@ -0,0 +1,52 @@ +use chrono::{FixedOffset, Utc}; +use digest::Digest as _; +use hmac_sha256::WrappedHash; +use serde::{Deserialize, Serialize}; + +#[derive(Default, Debug, Clone, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct GetUserId { + #[serde(rename = "chipID")] + pub chip_id: String, + #[serde(rename = "openGameID")] + pub open_game_id: &'static str, + pub key: String, + pub qr_code: String, + pub timestamp: String, +} + +#[derive(Default, Debug, Clone, PartialEq, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GetResponse { + pub key: String, + pub timestamp: String, + #[serde(rename = "errorID")] + pub error_id: i64, + #[serde(rename = "userID")] + pub user_id: i64, +} + +impl GetUserId { + pub fn new(qr_code: impl Into) -> Self { + let chip_id = "A63E-01E54389854".to_string(); + + let timestamp = Utc::now() + .with_timezone(&FixedOffset::east_opt(8 * 60 * 60).unwrap()) + .format("%y%m%d%H%M%S") + .to_string(); + + let mut hash = WrappedHash::new(); + hash.update(&chip_id); + hash.update(×tamp); + hash.update("XcW5FW4cPArBXEk4vzKz3CIrMuA5EVVW"); + let key = format!("{:X}", hash.finalize()); + + GetUserId { + qr_code: qr_code.into(), + chip_id, + open_game_id: "MAID", + key, + timestamp, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 65880be..fda4883 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,2 @@ -pub mod model; +pub mod title; +pub mod all_net; diff --git a/src/main.rs b/src/main.rs index 0716898..d33f2bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,58 +1,6 @@ -use std::env; - -use chrono::{FixedOffset, Utc}; -use digest::Digest; -use hmac_sha256::WrappedHash; -use nyquest::{Body, ClientBuilder, Request}; -use sdgb_utils_rs::model::{GetResponse, GetUserId}; - #[compio::main] async fn main() -> Result<(), Box> { nyquest_preset::register(); - let qr_code = env::args().nth(1).expect("missing argument: QRCode"); - let qr_code = String::from_utf8_lossy(&qr_code.as_bytes()[qr_code.len() - 64..]).into_owned(); - - let chip_id = "A63E-01E54389854".to_string(); - - let timestamp = Utc::now() - .with_timezone(&FixedOffset::east_opt(8 * 60 * 60).unwrap()) - .format("%y%m%d%H%M%S") - .to_string(); - - let mut hash = WrappedHash::new(); - hash.update(&chip_id); - hash.update(×tamp); - hash.update("XcW5FW4cPArBXEk4vzKz3CIrMuA5EVVW"); - let key = format!("{:X}", hash.finalize()); - - let get_user_id = GetUserId { - chip_id, - open_game_id: "MAID", - qr_code, - key, - timestamp, - }; - - let client = ClientBuilder::default() - .user_agent("WC_AIME_LIB") - .build_async() - .await?; - let req = Request::post("http://ai.sys-allnet.cn/wc_aime/api/get_data") - .with_body(Body::json(&get_user_id)?); - - let resp = client.request(req).await?; - let resp: GetResponse = resp.json().await?; - - let user_id = resp.user_id; - - match resp.error_id { - 0 => println!("{user_id}"), - 1 => eprintln!("[30min] QRCode Expired"), - 2 => eprintln!("[10min] QRCode Expired"), - 50 => eprintln!("Bad keychip"), - _ => eprintln!("{resp:#?}"), - } - Ok(()) } diff --git a/src/model.rs b/src/model.rs deleted file mode 100644 index b25c5b5..0000000 --- a/src/model.rs +++ /dev/null @@ -1,24 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Default, Debug, Clone, PartialEq, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct GetUserId { - #[serde(rename = "chipID")] - pub chip_id: String, - #[serde(rename = "openGameID")] - pub open_game_id: &'static str, - pub key: String, - pub qr_code: String, - pub timestamp: String, -} - -#[derive(Default, Debug, Clone, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GetResponse { - pub key: String, - pub timestamp: String, - #[serde(rename = "errorID")] - pub error_id: i64, - #[serde(rename = "userID")] - pub user_id: i64, -} diff --git a/src/title/mod.rs b/src/title/mod.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/title/mod.rs @@ -0,0 +1 @@ +