todo: fix UserData decryption
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1441,6 +1441,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"snafu",
|
"snafu",
|
||||||
|
"spdlog-rs",
|
||||||
"strum 0.27.2",
|
"strum 0.27.2",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ resolver = "3"
|
|||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
sdgb-api = { path = "./sdgb-api", default-features = false }
|
sdgb-api = { path = "./sdgb-api", default-features = false }
|
||||||
|
|
||||||
|
spdlog-rs = { version = "0.4.3", default-features = false, features = [
|
||||||
|
"level-debug",
|
||||||
|
"release-level-info",
|
||||||
|
] }
|
||||||
|
|
||||||
snafu = { version = "0.8.6", features = ["backtrace", "rust_1_81"] }
|
snafu = { version = "0.8.6", features = ["backtrace", "rust_1_81"] }
|
||||||
serde_json = "1.0.141"
|
serde_json = "1.0.141"
|
||||||
strum = { version = "0.27.2", features = ["derive"] }
|
strum = { version = "0.27.2", features = ["derive"] }
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ serde_json = { workspace = true }
|
|||||||
strum = { workspace = true }
|
strum = { workspace = true }
|
||||||
tokio = { workspace = true, optional = true }
|
tokio = { workspace = true, optional = true }
|
||||||
compio = { workspace = true, optional = true }
|
compio = { workspace = true, optional = true }
|
||||||
|
spdlog-rs = { workspace = true }
|
||||||
|
|
||||||
# hashing
|
# hashing
|
||||||
digest = "0.10.7"
|
digest = "0.10.7"
|
||||||
@@ -34,7 +35,7 @@ serde = { version = "1.0.219", features = ["derive"] }
|
|||||||
|
|
||||||
# compression / encryption
|
# compression / encryption
|
||||||
flate2 = "1.1.2"
|
flate2 = "1.1.2"
|
||||||
cbc = "0.1.2"
|
cbc = { version = "0.1.2", features = ["alloc"] }
|
||||||
aes = "0.8.4"
|
aes = "0.8.4"
|
||||||
cipher = { version = "0.4.4", features = ["block-padding"] }
|
cipher = { version = "0.4.4", features = ["block-padding"] }
|
||||||
bincode = { version = "2.0.1", optional = true }
|
bincode = { version = "2.0.1", optional = true }
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
use std::io::{Read, Write as _};
|
use std::io::Write as _;
|
||||||
|
|
||||||
use aes::cipher::{
|
use aes::cipher::{
|
||||||
BlockDecryptMut, BlockEncryptMut, BlockSizeUser, KeyIvInit, block_padding::Pkcs7,
|
BlockDecryptMut, BlockEncryptMut, BlockSizeUser, KeyIvInit, block_padding::Pkcs7,
|
||||||
};
|
};
|
||||||
|
|
||||||
use digest::generic_array::GenericArray;
|
use digest::generic_array::GenericArray;
|
||||||
use flate2::write::ZlibEncoder;
|
use flate2::Compression;
|
||||||
use flate2::{Compression, read::ZlibDecoder};
|
use flate2::write::{ZlibDecoder, ZlibEncoder};
|
||||||
|
|
||||||
use crate::error::ApiError;
|
use crate::error::ApiError;
|
||||||
use crate::title::{MaiVersion, MaiVersionExt, Sdgb1_40, Sdgb1_50};
|
use crate::title::{MaiVersion, MaiVersionExt, Sdgb1_40, Sdgb1_50};
|
||||||
|
|
||||||
impl MaiVersionExt for Sdgb1_40 {
|
impl MaiVersionExt for Sdgb1_40 {
|
||||||
fn decode(mut data: impl AsMut<[u8]>) -> Result<Vec<u8>, ApiError> {
|
fn decode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError> {
|
||||||
let mut decompressed = decompress(data.as_mut());
|
let mut decompressed = decompress(data.as_ref());
|
||||||
if decompressed.is_empty() {
|
if decompressed.is_empty() {
|
||||||
return Err(ApiError::EmptyResponse);
|
return Err(ApiError::EmptyResponse);
|
||||||
}
|
}
|
||||||
@@ -41,14 +40,19 @@ impl MaiVersionExt for Sdgb1_40 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MaiVersionExt for Sdgb1_50 {
|
impl MaiVersionExt for Sdgb1_50 {
|
||||||
fn decode(mut data: impl AsMut<[u8]>) -> Result<Vec<u8>, ApiError> {
|
fn decode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError> {
|
||||||
if data.as_mut().is_empty() {
|
let mut data = data.as_ref().to_vec();
|
||||||
|
if data.is_empty() {
|
||||||
return Err(ApiError::EmptyResponse);
|
return Err(ApiError::EmptyResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
let decrypted = decrypt(&mut data, Self::AES_KEY, Self::AES_IV)?;
|
if data.len() % 16 != 0 {
|
||||||
let decompressed = decompress(decrypted);
|
let pad = 16 - (data.len() % 16);
|
||||||
Ok(decompressed)
|
data.resize(data.len() + pad, pad as _);
|
||||||
|
}
|
||||||
|
|
||||||
|
let decrypted = decrypt_vec(&data, Self::AES_KEY, Self::AES_IV)?;
|
||||||
|
Ok(decompress(decrypted))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError> {
|
fn encode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError> {
|
||||||
@@ -72,8 +76,9 @@ fn compress(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError> {
|
|||||||
|
|
||||||
fn decompress(data: impl AsRef<[u8]>) -> Vec<u8> {
|
fn decompress(data: impl AsRef<[u8]>) -> Vec<u8> {
|
||||||
let mut buf = Vec::with_capacity(data.as_ref().len() * 2);
|
let mut buf = Vec::with_capacity(data.as_ref().len() * 2);
|
||||||
let mut decode = ZlibDecoder::new(data.as_ref());
|
let mut decode = ZlibDecoder::new(&mut buf);
|
||||||
_ = decode.read_to_end(&mut buf);
|
_ = decode.write_all(data.as_ref());
|
||||||
|
_ = decode.finish();
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +109,13 @@ fn decrypt<'ct>(
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn decrypt_vec(data: impl AsRef<[u8]>, key: &[u8; 32], iv: &[u8; 16]) -> Result<Vec<u8>, ApiError> {
|
||||||
|
let key = GenericArray::from_slice(key);
|
||||||
|
let iv = GenericArray::from_slice(iv);
|
||||||
|
let decryptor = Aes256CbcDec::new(key, iv);
|
||||||
|
Ok(decryptor.decrypt_padded_vec_mut::<Pkcs7>(data.as_ref())?)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod _tests {
|
mod _tests {
|
||||||
|
|
||||||
@@ -148,4 +160,69 @@ mod _tests {
|
|||||||
assert_eq!(enc, data);
|
assert_eq!(enc, data);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: user data decryption
|
||||||
|
#[test]
|
||||||
|
fn test_user_data_dec() -> Result<(), ApiError> {
|
||||||
|
let data = [
|
||||||
|
60, 33, 100, 111, 99, 116, 121, 112, 101, 32, 104, 116, 109, 108, 62, 60, 104, 116,
|
||||||
|
109, 108, 32, 108, 97, 110, 103, 61, 34, 101, 110, 34, 62, 60, 104, 101, 97, 100, 62,
|
||||||
|
60, 116, 105, 116, 108, 101, 62, 72, 84, 84, 80, 32, 83, 116, 97, 116, 117, 115, 32,
|
||||||
|
53, 48, 48, 32, 226, 128, 147, 32, 73, 110, 116, 101, 114, 110, 97, 108, 32, 83, 101,
|
||||||
|
114, 118, 101, 114, 32, 69, 114, 114, 111, 114, 60, 47, 116, 105, 116, 108, 101, 62,
|
||||||
|
60, 115, 116, 121, 108, 101, 32, 116, 121, 112, 101, 61, 34, 116, 101, 120, 116, 47,
|
||||||
|
99, 115, 115, 34, 62, 104, 49, 32, 123, 102, 111, 110, 116, 45, 102, 97, 109, 105, 108,
|
||||||
|
121, 58, 84, 97, 104, 111, 109, 97, 44, 65, 114, 105, 97, 108, 44, 115, 97, 110, 115,
|
||||||
|
45, 115, 101, 114, 105, 102, 59, 99, 111, 108, 111, 114, 58, 119, 104, 105, 116, 101,
|
||||||
|
59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 45, 99, 111, 108, 111, 114, 58, 35,
|
||||||
|
53, 50, 53, 68, 55, 54, 59, 102, 111, 110, 116, 45, 115, 105, 122, 101, 58, 50, 50,
|
||||||
|
112, 120, 59, 125, 32, 104, 50, 32, 123, 102, 111, 110, 116, 45, 102, 97, 109, 105,
|
||||||
|
108, 121, 58, 84, 97, 104, 111, 109, 97, 44, 65, 114, 105, 97, 108, 44, 115, 97, 110,
|
||||||
|
115, 45, 115, 101, 114, 105, 102, 59, 99, 111, 108, 111, 114, 58, 119, 104, 105, 116,
|
||||||
|
101, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 45, 99, 111, 108, 111, 114, 58,
|
||||||
|
35, 53, 50, 53, 68, 55, 54, 59, 102, 111, 110, 116, 45, 115, 105, 122, 101, 58, 49, 54,
|
||||||
|
112, 120, 59, 125, 32, 104, 51, 32, 123, 102, 111, 110, 116, 45, 102, 97, 109, 105,
|
||||||
|
108, 121, 58, 84, 97, 104, 111, 109, 97, 44, 65, 114, 105, 97, 108, 44, 115, 97, 110,
|
||||||
|
115, 45, 115, 101, 114, 105, 102, 59, 99, 111, 108, 111, 114, 58, 119, 104, 105, 116,
|
||||||
|
101, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 45, 99, 111, 108, 111, 114, 58,
|
||||||
|
35, 53, 50, 53, 68, 55, 54, 59, 102, 111, 110, 116, 45, 115, 105, 122, 101, 58, 49, 52,
|
||||||
|
112, 120, 59, 125, 32, 98, 111, 100, 121, 32, 123, 102, 111, 110, 116, 45, 102, 97,
|
||||||
|
109, 105, 108, 121, 58, 84, 97, 104, 111, 109, 97, 44, 65, 114, 105, 97, 108, 44, 115,
|
||||||
|
97, 110, 115, 45, 115, 101, 114, 105, 102, 59, 99, 111, 108, 111, 114, 58, 98, 108, 97,
|
||||||
|
99, 107, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 45, 99, 111, 108, 111, 114,
|
||||||
|
58, 119, 104, 105, 116, 101, 59, 125, 32, 98, 32, 123, 102, 111, 110, 116, 45, 102, 97,
|
||||||
|
109, 105, 108, 121, 58, 84, 97, 104, 111, 109, 97, 44, 65, 114, 105, 97, 108, 44, 115,
|
||||||
|
97, 110, 115, 45, 115, 101, 114, 105, 102, 59, 99, 111, 108, 111, 114, 58, 119, 104,
|
||||||
|
105, 116, 101, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 45, 99, 111, 108,
|
||||||
|
111, 114, 58, 35, 53, 50, 53, 68, 55, 54, 59, 125, 32, 112, 32, 123, 102, 111, 110,
|
||||||
|
116, 45, 102, 97, 109, 105, 108, 121, 58, 84, 97, 104, 111, 109, 97, 44, 65, 114, 105,
|
||||||
|
97, 108, 44, 115, 97, 110, 115, 45, 115, 101, 114, 105, 102, 59, 98, 97, 99, 107, 103,
|
||||||
|
114, 111, 117, 110, 100, 58, 119, 104, 105, 116, 101, 59, 99, 111, 108, 111, 114, 58,
|
||||||
|
98, 108, 97, 99, 107, 59, 102, 111, 110, 116, 45, 115, 105, 122, 101, 58, 49, 50, 112,
|
||||||
|
120, 59, 125, 32, 97, 32, 123, 99, 111, 108, 111, 114, 58, 98, 108, 97, 99, 107, 59,
|
||||||
|
125, 32, 97, 46, 110, 97, 109, 101, 32, 123, 99, 111, 108, 111, 114, 58, 98, 108, 97,
|
||||||
|
99, 107, 59, 125, 32, 46, 108, 105, 110, 101, 32, 123, 104, 101, 105, 103, 104, 116,
|
||||||
|
58, 49, 112, 120, 59, 98, 97, 99, 107, 103, 114, 111, 117, 110, 100, 45, 99, 111, 108,
|
||||||
|
111, 114, 58, 35, 53, 50, 53, 68, 55, 54, 59, 98, 111, 114, 100, 101, 114, 58, 110,
|
||||||
|
111, 110, 101, 59, 125, 60, 47, 115, 116, 121, 108, 101, 62, 60, 47, 104, 101, 97, 100,
|
||||||
|
62, 60, 98, 111, 100, 121, 62, 60, 104, 49, 62, 72, 84, 84, 80, 32, 83, 116, 97, 116,
|
||||||
|
117, 115, 32, 53, 48, 48, 32, 226, 128, 147, 32, 73, 110, 116, 101, 114, 110, 97, 108,
|
||||||
|
32, 83, 101, 114, 118, 101, 114, 32, 69, 114, 114, 111, 114, 60, 47, 104, 49, 62, 60,
|
||||||
|
104, 114, 32, 99, 108, 97, 115, 115, 61, 34, 108, 105, 110, 101, 34, 32, 47, 62, 60,
|
||||||
|
112, 62, 60, 98, 62, 84, 121, 112, 101, 60, 47, 98, 62, 32, 83, 116, 97, 116, 117, 115,
|
||||||
|
32, 82, 101, 112, 111, 114, 116, 60, 47, 112, 62, 60, 112, 62, 60, 98, 62, 68, 101,
|
||||||
|
115, 99, 114, 105, 112, 116, 105, 111, 110, 60, 47, 98, 62, 32, 84, 104, 101, 32, 115,
|
||||||
|
101, 114, 118, 101, 114, 32, 101, 110, 99, 111, 117, 110, 116, 101, 114, 101, 100, 32,
|
||||||
|
97, 110, 32, 117, 110, 101, 120, 112, 101, 99, 116, 101, 100, 32, 99, 111, 110, 100,
|
||||||
|
105, 116, 105, 111, 110, 32, 116, 104, 97, 116, 32, 112, 114, 101, 118, 101, 110, 116,
|
||||||
|
101, 100, 32, 105, 116, 32, 102, 114, 111, 109, 32, 102, 117, 108, 102, 105, 108, 108,
|
||||||
|
105, 110, 103, 32, 116, 104, 101, 32, 114, 101, 113, 117, 101, 115, 116, 46, 60, 47,
|
||||||
|
112, 62, 60, 104, 114, 32, 99, 108, 97, 115, 115, 61, 34, 108, 105, 110, 101, 34, 32,
|
||||||
|
47, 62, 60, 104, 51, 62, 65, 112, 97, 99, 104, 101, 32, 84, 111, 109, 99, 97, 116, 47,
|
||||||
|
56, 46, 53, 46, 51, 57, 60, 47, 104, 51, 62, 60, 47, 98, 111, 100, 121, 62, 60, 47,
|
||||||
|
104, 116, 109, 108, 62,
|
||||||
|
];
|
||||||
|
let _ = Sdgb1_50::decode(data)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use nyquest::{
|
|||||||
header::{ACCEPT_ENCODING, CONTENT_ENCODING, EXPECT, USER_AGENT},
|
header::{ACCEPT_ENCODING, CONTENT_ENCODING, EXPECT, USER_AGENT},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use spdlog::debug;
|
||||||
|
|
||||||
pub trait MaiVersion {
|
pub trait MaiVersion {
|
||||||
const AES_KEY: &[u8; 32];
|
const AES_KEY: &[u8; 32];
|
||||||
@@ -24,7 +25,7 @@ pub trait MaiVersion {
|
|||||||
|
|
||||||
pub trait MaiVersionExt: MaiVersion {
|
pub trait MaiVersionExt: MaiVersion {
|
||||||
fn encode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError>;
|
fn encode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError>;
|
||||||
fn decode(data: impl AsMut<[u8]>) -> Result<Vec<u8>, ApiError>;
|
fn decode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError>;
|
||||||
|
|
||||||
fn api_hash(api: APIMethod) -> String {
|
fn api_hash(api: APIMethod) -> String {
|
||||||
let api_name: &str = api.into();
|
let api_name: &str = api.into();
|
||||||
@@ -78,6 +79,9 @@ pub trait MaiVersionExt: MaiVersion {
|
|||||||
.await
|
.await
|
||||||
.map_err(|_| ApiError::JoinError)??;
|
.map_err(|_| ApiError::JoinError)??;
|
||||||
let data = client.request(req).await?.bytes().await?;
|
let data = client.request(req).await?.bytes().await?;
|
||||||
|
|
||||||
|
debug!("received: {data:?}");
|
||||||
|
|
||||||
let decoded = spawn_blocking(move || Self::decode(data))
|
let decoded = spawn_blocking(move || Self::decode(data))
|
||||||
.await
|
.await
|
||||||
.map_err(|_| ApiError::JoinError)??;
|
.map_err(|_| ApiError::JoinError)??;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
pub struct GetUserDataApi {}
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct GetUserDataApi {
|
||||||
|
pub user_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
@@ -29,3 +31,24 @@ pub struct UserLoginApiResp {
|
|||||||
/// needed for some operation
|
/// needed for some operation
|
||||||
pub login_id: Option<u64>,
|
pub login_id: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UserLoginApi {
|
||||||
|
pub fn new(user_id: u32) -> Self {
|
||||||
|
let date_time = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.map(|t| t.as_secs())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
// 爱玩星球焦作解放店
|
||||||
|
UserLoginApi {
|
||||||
|
user_id,
|
||||||
|
date_time,
|
||||||
|
region_id: 13,
|
||||||
|
acsess_code: "".to_owned(),
|
||||||
|
place_id: 3223.to_string(),
|
||||||
|
is_continue: false,
|
||||||
|
generic_flag: 0,
|
||||||
|
client_id: "A63E01E6170".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ cache = ["dep:redb"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sdgb-api = { workspace = true, features = ["bincode"] }
|
sdgb-api = { workspace = true, features = ["bincode"] }
|
||||||
|
spdlog-rs = { workspace = true }
|
||||||
|
|
||||||
snafu = { workspace = true }
|
snafu = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
@@ -25,10 +26,6 @@ compio = { workspace = true, features = ["macros"], optional = true }
|
|||||||
nyquest-preset = { version = "0.2.0", features = ["async"] }
|
nyquest-preset = { version = "0.2.0", features = ["async"] }
|
||||||
|
|
||||||
palc = { version = "0.0.1", features = ["derive"] }
|
palc = { version = "0.0.1", features = ["derive"] }
|
||||||
spdlog-rs = { version = "0.4.3", default-features = false, features = [
|
|
||||||
"level-info",
|
|
||||||
"release-level-info",
|
|
||||||
] }
|
|
||||||
futures-util = "0.3.31"
|
futures-util = "0.3.31"
|
||||||
redb = { version = "2.6.1", optional = true }
|
redb = { version = "2.6.1", optional = true }
|
||||||
ctrlc = { version = "3.4.7", features = ["termination"] }
|
ctrlc = { version = "3.4.7", features = ["termination"] }
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ pub enum Commands {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
user_id: u32,
|
user_id: u32,
|
||||||
},
|
},
|
||||||
|
Userdata {
|
||||||
|
#[arg(short, long)]
|
||||||
|
user_id: u32,
|
||||||
|
},
|
||||||
|
|
||||||
ListAllUser,
|
ListAllUser,
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use std::{
|
|||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use nyquest_preset::nyquest::ClientBuilder;
|
use nyquest_preset::nyquest::ClientBuilder;
|
||||||
use palc::Parser;
|
use palc::Parser;
|
||||||
|
use spdlog::{Level, LevelFilter::MoreSevereEqual};
|
||||||
|
|
||||||
use sdgb_api::{
|
use sdgb_api::{
|
||||||
ApiError,
|
ApiError,
|
||||||
@@ -16,8 +17,8 @@ use sdgb_api::{
|
|||||||
MaiVersionExt, Sdgb1_40, Sdgb1_50,
|
MaiVersionExt, Sdgb1_40, Sdgb1_50,
|
||||||
methods::APIMethod,
|
methods::APIMethod,
|
||||||
model::{
|
model::{
|
||||||
GetUserPreviewApi, GetUserPreviewApiResp, Ping, PingResp, UserLogoutApi,
|
GetUserDataApi, GetUserDataApiResp, GetUserPreviewApi, GetUserPreviewApiResp, Ping,
|
||||||
UserLogoutApiResp,
|
PingResp, UserLoginApi, UserLoginApiResp, UserLogoutApi, UserLogoutApiResp,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -36,6 +37,12 @@ static EARLY_QUIT: AtomicBool = AtomicBool::new(false);
|
|||||||
async fn main() -> Result<(), Box<dyn snafu::Error>> {
|
async fn main() -> Result<(), Box<dyn snafu::Error>> {
|
||||||
nyquest_preset::register();
|
nyquest_preset::register();
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
spdlog::default_logger().set_level_filter(MoreSevereEqual(Level::Debug));
|
||||||
|
} else {
|
||||||
|
spdlog::default_logger().set_level_filter(MoreSevereEqual(Level::Info));
|
||||||
|
}
|
||||||
|
|
||||||
ctrlc::set_handler(|| {
|
ctrlc::set_handler(|| {
|
||||||
warn!("received early-quit request! will abort soon");
|
warn!("received early-quit request! will abort soon");
|
||||||
EARLY_QUIT.store(true, Ordering::Relaxed);
|
EARLY_QUIT.store(true, Ordering::Relaxed);
|
||||||
@@ -45,6 +52,7 @@ async fn main() -> Result<(), Box<dyn snafu::Error>> {
|
|||||||
|
|
||||||
let client = ClientBuilder::default().build_async().await?;
|
let client = ClientBuilder::default().build_async().await?;
|
||||||
|
|
||||||
|
// TODO: refactor via enum_dispatch
|
||||||
match cmd.command {
|
match cmd.command {
|
||||||
commands::Commands::Logout { user_id } => {
|
commands::Commands::Logout { user_id } => {
|
||||||
let logout: UserLogoutApiResp = Sdgb1_50::request(
|
let logout: UserLogoutApiResp = Sdgb1_50::request(
|
||||||
@@ -193,6 +201,76 @@ async fn main() -> Result<(), Box<dyn snafu::Error>> {
|
|||||||
.open("players.json")?;
|
.open("players.json")?;
|
||||||
serde_json::to_writer_pretty(output, &players)?;
|
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<UserLoginApiResp, _> =
|
||||||
|
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>(
|
||||||
|
&client,
|
||||||
|
APIMethod::GetUserDataApi,
|
||||||
|
user_id,
|
||||||
|
GetUserDataApi { user_id },
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => {}
|
||||||
|
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:?}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user