This commit is contained in:
Remik1r3n 2025-06-11 09:52:45 +08:00
parent 472844474f
commit 31361541fd

View File

@ -11,6 +11,7 @@ from ctypes import c_int32
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad from Crypto.Util.Padding import pad, unpad
from Config import * from Config import *
from typing import Optional
import certifi import certifi
# 舞萌DX 2024 # 舞萌DX 2024
@ -70,62 +71,53 @@ def getSDGBApiHash(api):
# 有空做一下 Hash 的彩虹表? # 有空做一下 Hash 的彩虹表?
return hashlib.md5((api+"MaimaiChn"+ObfuscateParam).encode()).hexdigest() return hashlib.md5((api+"MaimaiChn"+ObfuscateParam).encode()).hexdigest()
def apiSDGB(data:str, targetApi:str, userAgentExtraData:str, noLog:bool=False, timeout:int=5): def apiSDGB(
data: str,
targetApi: str,
userAgentExtraData: str,
noLog: bool = False,
timeout: int = 5,
useProxy: bool = False,
proxyUrl: Optional[str] = None
) -> str:
""" """
舞萌DX 2024 API 通讯用函数 舞萌DX API 通讯用函数增强版
:param data: 请求数据 :param data: 请求数据
:param targetApi: 使用的 API :param targetApi: 使用的 API
:param userAgentExtraData: UA 附加信息机台相关则为狗号如A63E01E9564用户相关则为 UID :param userAgentExtraData: UA 附加信息机台相关则为狗号如A63E01E9564用户相关则为 UID
:param noLog: 是否不记录日志 :param noLog: 是否不记录日志
:param timeout: 请求超时时间
:param useProxy: 是否使用代理
:param proxyUrl: 代理地址如果使用代理
:return: 解码后的响应数据
""" """
maxRetries = 3 maxRetries = 3
agentExtra = str(userAgentExtraData) agentExtra = str(userAgentExtraData)
aes = aes_pkcs7(AesKey,AesIV) aes = aes_pkcs7(AesKey, AesIV) # Assuming aes_pkcs7, AesKey, AesIV are defined elsewhere
endpoint = "https://maimai-gm.wahlap.com:42081/Maimai2Servlet/"
data = bytes(data, encoding="utf-8") # Prepare request data
data_def = zlib.compress(data)
data_enc = aes.encrypt(data_def)
endpoint = "https://maimai-gm.wahlap.com:42081/Maimai2Servlet/"
r = httpx.post(
endpoint + getSDGBApiHash(targetApi),
headers = {
"User-Agent": f"{getSDGBApiHash(targetApi)}#{agentExtra}",
"Content-Type": "application/json",
"Mai-Encoding": "1.50",
"Accept-Encoding": "",
"Charset": "UTF-8",
"Content-Encoding": "deflate",
"Expect": "100-continue"
},
data = data_enc
)
resp_enc = r.content
try:
resp_def = aes.decrypt(resp_enc)
except:
resp_def = resp_enc
return zlib.decompress(resp_def).decode('utf-8')
# Begin Build
requestDataFinal = aes.encrypt(zlib.compress(data.encode('utf-8'))) requestDataFinal = aes.encrypt(zlib.compress(data.encode('utf-8')))
# End Build
endpoint = "https://maimai-gm.wahlap.com:42081/Maimai2Servlet/"
if not noLog: if not noLog:
logger.debug(f"开始请求 {targetApi},以 {data}") logger.debug(f"开始请求 {targetApi},以 {data}")
retries = 0 retries = 0
while retries < maxRetries: while retries < maxRetries:
try: try:
if useProxy: # Configure HTTP client
# 使用代理 if useProxy and proxyUrl:
logger.debug("使用代理") if not noLog:
logger.debug("使用代理")
httpClient = httpx.Client(proxy=proxyUrl, verify=False) httpClient = httpx.Client(proxy=proxyUrl, verify=False)
else: else:
# 不使用代理 if not noLog:
logger.debug("不使用代理") logger.debug("不使用代理")
httpClient = httpx.Client(verify=False) httpClient = httpx.Client(verify=False)
responseDataRaw = httpClient.post(
url=endpoint + getSDGBApiHash(targetApi), # Send request
response = httpClient.post(
url=endpoint + getSDGBApiHash(targetApi), # Assuming getSDGBApiHash is defined
headers={ headers={
"User-Agent": f"{getSDGBApiHash(targetApi)}#{agentExtra}", "User-Agent": f"{getSDGBApiHash(targetApi)}#{agentExtra}",
"Content-Type": "application/json", "Content-Type": "application/json",
@ -136,57 +128,69 @@ def apiSDGB(data:str, targetApi:str, userAgentExtraData:str, noLog:bool=False, t
"Expect": "100-continue" "Expect": "100-continue"
}, },
content=requestDataFinal, content=requestDataFinal,
# 经测试,加 Verify 之后速度慢好多,因此建议选择性开
#verify=certifi.where(),
#verify=False,
timeout=timeout timeout=timeout
) )
if not noLog: if not noLog:
logger.info(f"{targetApi} 请求结果: {responseDataRaw.status_code}") logger.info(f"{targetApi} 请求结果: {response.status_code}")
if responseDataRaw.status_code == 200: if response.status_code != 200:
logger.debug("200 OK!") errorMessage = f"请求失败: {response.status_code}"
else:
errorMessage = f"请求失败: {responseDataRaw.status_code}"
logger.error(errorMessage) logger.error(errorMessage)
raise SDGBRequestError(errorMessage) raise SDGBRequestError(errorMessage)
responseContentRaw = responseDataRaw.content # Process response
responseContentRaw = response.content
try: try:
responseContentDecrypted = aes.decrypt(responseContentRaw) responseContentDecrypted = aes.decrypt(responseContentRaw)
logger.debug(f"成功解密响应!") if not noLog:
except: logger.debug("成功解密响应!")
logger.warning(f"解密失败,得到的原始响应: {responseContentRaw}") except Exception as e:
logger.warning(f"解密失败,原始响应: {responseContentRaw}, 错误: {e}")
raise SDGBResponseError("解密失败") raise SDGBResponseError("解密失败")
try: try:
zlib.decompress(responseContentDecrypted).decode('utf-8') # 检查 ResponseContentDecrypted 是否为 zlib 压缩格式
logger.debug("成功解压响应!") if not responseContentDecrypted.startswith(b'\x78\x9c'):
except: logger.warning("Not Zlib. Not decompressed.")
logger.warning(f"无法解压,解密的原始响应: {responseContentDecrypted}") raise Exception(f"响应内容不是 zlib 压缩格式, 内容: {responseContentDecrypted}")
responseContentFinal = zlib.decompress(responseContentDecrypted).decode('utf-8')
if not noLog:
logger.debug("成功解压响应!")
logger.debug(f"响应: {responseContentFinal}")
return responseContentFinal
except zlib.error as e:
logger.warning(f"解压失败,原始响应: {responseContentDecrypted}, 错误: {e}")
raise SDGBResponseError("解压失败") raise SDGBResponseError("解压失败")
# If decompression fails after attempts, trigger a retry of the entire request
if not noLog: retries += 1
logger.debug(f"响应: {responseContentDecrypted}") if retries < maxRetries:
return responseContentDecrypted.decode('utf-8') logger.warning(f"解压失败,将重试请求 (第 {retries + 1}/{maxRetries} 次)")
time.sleep(2)
# 异常处理 continue
raise SDGBResponseError("多次尝试后仍无法解压响应")
except SDGBRequestError as e: except SDGBRequestError as e:
# 请求格式错误,不需要重试 # Request format error, no retry
raise SDGBRequestError("请求格式错误") logger.error(f"请求格式错误: {e}")
raise
except SDGBResponseError as e: except SDGBResponseError as e:
# 响应解析错误,这种有一定可能是我们的问题,所以只重试一次 # Response parsing error, retry once more
logger.warning(f"将重试一次 Resp Err: {e}") logger.warning(f"响应错误,将重试: {e}")
retries += 2
time.sleep(2)
except Exception as e:
# 其他错误,重试多次
logger.warning(f"将开始重试请求. {e}")
retries += 1 retries += 1
time.sleep(2) time.sleep(2)
except Exception as e:
# Other errors, retry
logger.warning(f"请求失败,将重试: {e}")
retries += 1
time.sleep(2)
finally:
if 'httpClient' in locals():
httpClient.close()
raise SDGBApiError("重试多次仍然无法成功请求服务器") raise SDGBApiError("重试多次仍然无法成功请求服务器")