mirror of
https://github.com/Remik1r3n/maimaiDX-Api.git
synced 2025-05-20 07:27:28 +08:00
迁移到 rapidjson,增加 ssl 验证功能,其他改进
This commit is contained in:
parent
fd46fbb123
commit
33c8a574df
@ -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
|
||||||
|
|
||||||
# 常量
|
# 常量
|
||||||
|
@ -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 算法"""
|
||||||
|
@ -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
1
AuthLite_GetUpdate.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
# It will be finished very soon, I promise
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 时间戳
|
||||||
|
@ -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
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import json
|
from rapidjson import json
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from Config import *
|
from Config import *
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# 登录·登出实现
|
# 登录·登出实现
|
||||||
# 一般作为模块使用,但也可以作为 CLI 程序运行以强制登出账号。
|
# 一般作为模块使用,但也可以作为 CLI 程序运行以强制登出账号。
|
||||||
|
|
||||||
import json
|
from rapidjson import json
|
||||||
import time
|
import time
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# 上传一个占位用的游玩记录的 API 实现
|
# 上传一个占位用的游玩记录的 API 实现
|
||||||
|
|
||||||
import json
|
from rapidjson import json
|
||||||
import pytz
|
import pytz
|
||||||
import time
|
import time
|
||||||
import random
|
import random
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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():
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user