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, } } }