todo: prepare for 1.53 API support

This commit is contained in:
2026-01-08 00:18:01 +08:00
parent c02ac2daad
commit 322b85ed65
3 changed files with 43 additions and 4 deletions

View File

@@ -9,7 +9,7 @@ use flate2::write::{ZlibDecoder, ZlibEncoder};
use spdlog::debug; use spdlog::debug;
use crate::error::ApiError; use crate::error::ApiError;
use crate::title::{MaiVersion, MaiVersionExt, Sdgb1_50}; use crate::title::{MaiVersion, MaiVersionExt, Sdgb1_50, Sdgb1_53};
impl MaiVersionExt for Sdgb1_50 { impl MaiVersionExt for Sdgb1_50 {
fn decode(mut data: impl AsMut<[u8]>) -> Result<Vec<u8>, ApiError> { fn decode(mut data: impl AsMut<[u8]>) -> Result<Vec<u8>, ApiError> {
@@ -29,6 +29,24 @@ impl MaiVersionExt for Sdgb1_50 {
} }
} }
impl MaiVersionExt for Sdgb1_53 {
fn decode(mut data: impl AsMut<[u8]>) -> Result<Vec<u8>, ApiError> {
if data.as_mut().is_empty() {
return Err(ApiError::EmptyResponse);
}
debug!("data size: {}", data.as_mut().len());
let decrypted = decrypt(&mut data, Self::AES_KEY, Self::AES_IV)?;
Ok(decompress(decrypted))
}
fn encode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, ApiError> {
let compressed = compress(data)?;
let enc = encrypt(compressed, Self::AES_KEY, Self::AES_IV)?;
Ok(enc)
}
}
type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>; type Aes256CbcEnc = cbc::Encryptor<aes::Aes256>;
type Aes256CbcDec = cbc::Decryptor<aes::Aes256>; type Aes256CbcDec = cbc::Decryptor<aes::Aes256>;

View File

@@ -13,7 +13,7 @@ use super::ApiError;
use nyquest::{ use nyquest::{
AsyncClient, Body, AsyncClient, Body,
r#async::Request, r#async::Request,
header::{ACCEPT_ENCODING, CONTENT_ENCODING, EXPECT, USER_AGENT}, header::{ACCEPT_ENCODING, CONTENT_ENCODING, COOKIE, EXPECT, USER_AGENT},
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use spdlog::debug; use spdlog::debug;
@@ -48,7 +48,7 @@ pub trait MaiVersionExt: MaiVersion {
let payload = Self::encode(json)?; let payload = Self::encode(json)?;
let api_hash = Self::api_hash(api); let api_hash = Self::api_hash(api);
let req = Request::post(format!( let mut req = Request::post(format!(
"https://maimai-gm.wahlap.com:42081/Maimai2Servlet/{api_hash}" "https://maimai-gm.wahlap.com:42081/Maimai2Servlet/{api_hash}"
)) ))
.with_body(Body::json_bytes(payload)) .with_body(Body::json_bytes(payload))
@@ -59,6 +59,11 @@ pub trait MaiVersionExt: MaiVersion {
.with_header(CONTENT_ENCODING, "deflate") .with_header(CONTENT_ENCODING, "deflate")
.with_header(EXPECT, "100-continue"); .with_header(EXPECT, "100-continue");
// TODO: userid, token
if Self::VERSION >= "1.53" {
req = req.with_header(COOKIE, format!(""))
}
debug!("request: {req:?}"); debug!("request: {req:?}");
Ok(req) Ok(req)
@@ -122,6 +127,7 @@ pub trait MaiVersionExt: MaiVersion {
} }
pub struct Sdgb1_50; pub struct Sdgb1_50;
pub struct Sdgb1_53;
impl MaiVersion for Sdgb1_50 { impl MaiVersion for Sdgb1_50 {
const AES_KEY: &[u8; 32] = b"a>32bVP7v<63BVLkY[xM>daZ1s9MBP<R"; const AES_KEY: &[u8; 32] = b"a>32bVP7v<63BVLkY[xM>daZ1s9MBP<R";
@@ -130,3 +136,11 @@ impl MaiVersion for Sdgb1_50 {
const VERSION: &str = "1.50"; const VERSION: &str = "1.50";
} }
impl MaiVersion for Sdgb1_53 {
const AES_KEY: &[u8; 32] = b"o2U8F6<adcYl25f_qwx_n]5_qxRcbLN>";
const AES_IV: &[u8; 16] = b"AL<G:k:X6Vu7@_U]";
const OBFUSECATE_SUFFIX: &str = "MaimaiChnLatuAa81";
const VERSION: &str = "1.53";
}

View File

@@ -14,7 +14,7 @@ use sdgb_api::{
all_net::QRCode, all_net::QRCode,
auth_lite::{SDGB, SDHJ, delivery_raw}, auth_lite::{SDGB, SDHJ, delivery_raw},
title::{ title::{
MaiVersionExt, Sdgb1_50, MaiVersionExt, Sdgb1_50, Sdgb1_53,
helper::get_user_all_music, helper::get_user_all_music,
methods::APIMethod, methods::APIMethod,
model::{ model::{
@@ -184,6 +184,13 @@ async fn main() -> Result<(), Box<dyn snafu::Error>> {
"sdgb 1.50 resp: {decoded}, {}ms", "sdgb 1.50 resp: {decoded}, {}ms",
time.elapsed().unwrap_or_default().as_millis() time.elapsed().unwrap_or_default().as_millis()
); );
let decoded: PingResp =
Sdgb1_53::request(&client, APIMethod::Ping, "", Ping {}).await?;
info!(
"sdgb 1.53 resp: {decoded}, {}ms",
time.elapsed().unwrap_or_default().as_millis()
);
} }
Commands::QRLogin { ref qrcode_content } => { Commands::QRLogin { ref qrcode_content } => {
let qrcode = QRCode { qrcode_content }; let qrcode = QRCode { qrcode_content };