迁移到 rapidjson,增加 ssl 验证功能,其他改进

This commit is contained in:
Kohaku 2025-02-15 18:20:29 +08:00
parent fd46fbb123
commit 33c8a574df
17 changed files with 33 additions and 36 deletions

View File

@ -5,7 +5,7 @@
import hashlib import hashlib
import time import time
import requests import requests
import json from rapidjson import json
import re import re
# 常量 # 常量

View File

@ -1,4 +1,4 @@
# 舞萌DX 2024 # 舞萌DX
# 标题服务器通讯实现 # 标题服务器通讯实现
import zlib import zlib
@ -11,8 +11,10 @@ from ctypes import c_int32
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad from Crypto.Util.Padding import unpad
from Config import * from Config import *
import certifi
# 舞萌DX 2024 # 舞萌DX 2024
# omg it's leaking
AesKey = "n7bx6:@Fg_:2;5E89Phy7AyIcpxEQ:R@" AesKey = "n7bx6:@Fg_:2;5E89Phy7AyIcpxEQ:R@"
AesIV = ";;KjR1C3hgB1ovXa" AesIV = ";;KjR1C3hgB1ovXa"
ObfuscateParam = "BEs2D5vW" ObfuscateParam = "BEs2D5vW"
@ -57,6 +59,8 @@ class AES_PKCS7(object):
return text + padding_text return text + padding_text
def getSDGBApiHash(api): def getSDGBApiHash(api):
# 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):
@ -91,7 +95,7 @@ def apiSDGB(data:str, targetApi:str, userAgentExtraData:str, noLog:bool=False, t
"Expect": "100-continue" "Expect": "100-continue"
}, },
content=reqData_deflated, content=reqData_deflated,
verify=False, verify=certifi.where(),
timeout=timeout timeout=timeout
) )
if not noLog: if not noLog:
@ -129,16 +133,16 @@ def apiSDGB(data:str, targetApi:str, userAgentExtraData:str, noLog:bool=False, t
raise SDGBRequestError("请求格式错误") raise SDGBRequestError("请求格式错误")
except SDGBResponseError as e: except SDGBResponseError as e:
# 响应解析错误,重试但是只一次 # 响应解析错误,重试但是只一次
logger.warning(f"Will now retry. {e}") logger.warning(f"将重试一次 Resp Err: {e}")
retries += 2 retries += 2
time.sleep(2) time.sleep(2)
except Exception as e: except Exception as e:
# 其他错误,重试 # 其他错误,重试
logger.warning(f"Will now retry. {e}") logger.warning(f"将开始重试请求. {e}")
retries += 1 retries += 1
time.sleep(2) time.sleep(2)
raise SDGBApiError("Multiple retries failed to make a successful request") raise SDGBApiError("重试多次仍然无法成功请求服务器")
def calcSpecialNumber(): def calcSpecialNumber():
"""使用 c_int32 实现的 SpecialNumber 算法""" """使用 c_int32 实现的 SpecialNumber 算法"""

View File

@ -1,7 +1,7 @@
# ログインボーナス!やったね! # ログインボーナス!やったね!
# セガ秘 内部使用のみ(トレードマーク) # セガ秘 内部使用のみ(トレードマーク)
import json from rapidjson import json
from loguru import logger from loguru import logger
from Config import * from Config import *

1
AuthLite_GetUpdate.py Normal file
View File

@ -0,0 +1 @@
# It will be finished very soon, I promise

View File

@ -7,14 +7,6 @@ from HelperMusicDB import getMusicTitle
import requests import requests
# 日志设置
if False:
import sys
log_level = "DEBUG"
log_format = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS zz}</green> | <level>{level: <8}</level> | <yellow>Line {line: >4} ({file}):</yellow> <b>{message}</b>"
logger.add(sys.stderr, level=log_level, format=log_format, colorize=True, backtrace=True, diagnose=True)
logger.add("file.log", level=log_level, format=log_format, colorize=False, backtrace=True, diagnose=True)
# 水鱼查分器的 API 地址 # 水鱼查分器的 API 地址
BASE_URL = 'https://www.diving-fish.com/api/maimaidxprober' BASE_URL = 'https://www.diving-fish.com/api/maimaidxprober'
@ -79,18 +71,14 @@ def maimaiUserMusicDetailToDivingFishFormat(userMusicDetailList) -> list:
divingFishList.append({ divingFishList.append({
'achievements': (currentMusicDetail['achievement'] / 10000), # 水鱼的成绩是 float 而非舞萌的 int 'achievements': (currentMusicDetail['achievement'] / 10000), # 水鱼的成绩是 float 而非舞萌的 int
'title': currentMusicTitle, 'title': currentMusicTitle,
'type': notesType, # 我不理解这为什么不能在后端判断 'type': notesType,
'level_index': currentMusicDetail['level'], 'level_index': currentMusicDetail['level'],
'fc': COMBO_ID_TO_NAME[currentMusicDetail['comboStatus']], 'fc': COMBO_ID_TO_NAME[currentMusicDetail['comboStatus']],
'fs': SYNC_ID_TO_NAME[currentMusicDetail['syncStatus']], 'fs': SYNC_ID_TO_NAME[currentMusicDetail['syncStatus']],
'dxScore': currentMusicDetail['deluxscoreMax'], 'dxScore': currentMusicDetail['deluxscoreMax'],
}) })
except: except:
logger.error(f"Fish Format Translate Error: {currentMusicDetail}") logger.error(f"无法将 UserMusic 翻译成水鱼格式: {currentMusicDetail}")
# debug output fish list to file
#with open("fishList.txt", "w", encoding="utf-8") as f:
# f.write(str(divingFishList))
return divingFishList return divingFishList
@ -106,7 +94,7 @@ def isVaildFishToken(importToken:str):
def implUserMusicToDivingFish(userId:int, fishImportToken:str): def implUserMusicToDivingFish(userId:int, fishImportToken:str):
'''上传所有成绩到水鱼的参考实现返回成绩的数量或者False''' '''上传所有成绩到水鱼的参考实现返回成绩的数量或者False'''
logger.info("开始上传舞萌成绩到水鱼查分器!") logger.info("开始尝试上传舞萌成绩到水鱼查分器!")
userFullMusicDetailList = getUserFullMusicDetail(userId) userFullMusicDetailList = getUserFullMusicDetail(userId)
logger.info("成功得到成绩!转换成水鱼格式..") logger.info("成功得到成绩!转换成水鱼格式..")
divingFishData = maimaiUserMusicDetailToDivingFishFormat(userFullMusicDetailList) divingFishData = maimaiUserMusicDetailToDivingFishFormat(userFullMusicDetailList)

View File

@ -1,5 +1,5 @@
# 倍票相关 API 的实现 # 倍票相关 API 的实现
import json from rapidjson import json
import pytz import pytz
from datetime import datetime, timedelta from datetime import datetime, timedelta

View File

@ -5,7 +5,7 @@ from Config import *
from API_TitleServer import * from API_TitleServer import *
from GetPreview import apiGetUserPreview from GetPreview import apiGetUserPreview
from HelperLogInOut import apiLogout from HelperLogInOut import apiLogout
import json from rapidjson import json
from loguru import logger from loguru import logger
import time import time
from datetime import datetime from datetime import datetime
@ -25,10 +25,10 @@ def getHumanReadableTime(unixTime):
def getMaimaiUNIXTime(mmddhhmmss, year=2025): def getMaimaiUNIXTime(mmddhhmmss, year=2025):
""" """
解析用户输入的 MMDDHHMMSS 格式的时间返回 Unix 时间戳 解析用户输入的 MMDDHHMMSS 格式的时间返回 Unix 时间戳
时间会被推后一个小时因为舞萌貌似是 UTC+9 时间会被推后一个小时因为舞萌貌似是 UTC+9
""" """
#date_time_str = f"{year}{mmddhhmmss}" #date_time_str = f"{year}{mmddhhmmss}"
# 舞萌需要把小时按往后推一个小时来计算,加上一个小时 # 加上一个小时
date_time_str = f"{year}{mmddhhmmss[:4]}{int(mmddhhmmss[4:6])+1:02}{mmddhhmmss[6:]}" date_time_str = f"{year}{mmddhhmmss[:4]}{int(mmddhhmmss[4:6])+1:02}{mmddhhmmss[6:]}"
date_time_obj = datetime.strptime(date_time_str, '%Y%m%d%H%M%S') date_time_obj = datetime.strptime(date_time_str, '%Y%m%d%H%M%S')
# 将 datetime 对象转换为 Unix 时间戳 # 将 datetime 对象转换为 Unix 时间戳

View File

@ -1,6 +1,6 @@
# 获取用户简略预览数据的 API 实现,此 API 无需任何登录即可调取 # 获取用户简略预览数据的 API 实现,此 API 无需任何登录即可调取
import json from rapidjson import json
from API_TitleServer import apiSDGB from API_TitleServer import apiSDGB
from Config import * from Config import *
import time import time
@ -19,8 +19,12 @@ if __name__ == "__main__":
userId = testUid2 userId = testUid2
print(apiGetUserPreview(userId)) print(apiGetUserPreview(userId))
###
### 以下仅留作归档
###
def crawlAllUserPreview(): def crawlAllUserPreview():
"""omg it's a evil crawler"""
# 这里设置开始和结束的 UserId # 这里设置开始和结束的 UserId
BeginUserId = 11000000 BeginUserId = 11000000
EndUserId = 12599999 EndUserId = 12599999

View File

@ -1,4 +1,4 @@
import json from rapidjson import json
from loguru import logger from loguru import logger
from Config import * from Config import *

View File

@ -2,7 +2,7 @@
from API_TitleServer import * from API_TitleServer import *
from HelperLogInOut import apiLogin, apiLogout, generateTimestamp from HelperLogInOut import apiLogin, apiLogout, generateTimestamp
from Config import * from Config import *
import json from rapidjson import json
from HelperMusicDB import getMusicTitle from HelperMusicDB import getMusicTitle
from loguru import logger from loguru import logger
import sys import sys

View File

@ -1,6 +1,6 @@
# 获取用户数据的 API 实现 # 获取用户数据的 API 实现
from loguru import logger from loguru import logger
import json from rapidjson import json
from API_TitleServer import apiSDGB from API_TitleServer import apiSDGB
def apiGetUserData(userId:int) -> str: def apiGetUserData(userId:int) -> str:

View File

@ -1,7 +1,7 @@
# 登录·登出实现 # 登录·登出实现
# 一般作为模块使用,但也可以作为 CLI 程序运行以强制登出账号。 # 一般作为模块使用,但也可以作为 CLI 程序运行以强制登出账号。
import json from rapidjson import json
import time import time
from loguru import logger from loguru import logger

View File

@ -1,6 +1,6 @@
# 杂项助手函数 # 杂项助手函数
# 主要用于当作模块使用的时候的一些生活质量提升 # 主要用于当作模块使用的时候的一些生活质量提升
import json from rapidjson import json
from loguru import logger from loguru import logger
from HelperGetUserThing import implGetUser_ from HelperGetUserThing import implGetUser_
import unicodedata import unicodedata

View File

@ -1,6 +1,6 @@
# 上传一个占位用的游玩记录的 API 实现 # 上传一个占位用的游玩记录的 API 实现
import json from rapidjson import json
import pytz import pytz
import time import time
import random import random

View File

@ -29,7 +29,7 @@ from fastapi.responses import (
PlainTextResponse, PlainTextResponse,
JSONResponse JSONResponse
) )
import json from rapidjson import json
import uvicorn import uvicorn
from loguru import logger from loguru import logger

View File

@ -1,7 +1,7 @@
# 感谢伟大的 Diving-Fish 让我被迫直面恐惧 # 感谢伟大的 Diving-Fish 让我被迫直面恐惧
import xml.dom.minidom as minidom import xml.dom.minidom as minidom
from pathlib import Path from pathlib import Path
import json from rapidjson import json
from loguru import logger from loguru import logger
def makeMusicDBJson(): def makeMusicDBJson():

View File

@ -1,5 +1,5 @@
import sys import sys
import json from rapidjson import json
from PyQt6.QtWidgets import ( from PyQt6.QtWidgets import (
QApplication, QMainWindow, QWidget, QVBoxLayout, QLineEdit, QTextEdit, QPushButton, QLabel, QHBoxLayout QApplication, QMainWindow, QWidget, QVBoxLayout, QLineEdit, QTextEdit, QPushButton, QLabel, QHBoxLayout