mirror of
https://github.com/Remik1r3n/maimaiDX-Api.git
synced 2025-05-20 10:37:28 +08:00
Merge branch 'master' of https://github.com/Remik1r3n/maimaiDX-Api
This commit is contained in:
commit
3638de178d
82
Best50_To_Diving_Fish.py
Normal file
82
Best50_To_Diving_Fish.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# 非常 All-in Boom 的 B50 更新实现。
|
||||||
|
|
||||||
|
from API_TitleServer import *
|
||||||
|
from HelperLogInOut import apiLogin, apiLogout, generateTimestamp
|
||||||
|
from Static_Settings import *
|
||||||
|
import json
|
||||||
|
from MusicDB import musicDB
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
def getMusicTitle(musicId: int) -> str:
|
||||||
|
'''从数据库获取音乐的标题'''
|
||||||
|
logger.debug(f"查询歌名: {musicId}")
|
||||||
|
musicInfo = musicDB.get(musicId)
|
||||||
|
if not musicInfo:
|
||||||
|
logger.warning(f"数据库里未找到此歌曲: {musicId}")
|
||||||
|
return "ERR_R_MUSIC_ID_NOT_IN_DATABASE"
|
||||||
|
musicName = musicInfo.get("name")
|
||||||
|
logger.debug(f"成功查询到歌名: {musicName}")
|
||||||
|
return musicName
|
||||||
|
|
||||||
|
def getUserMusicDetail(userId:int, nextIndex:int=0, maxCount:int=50) -> dict:
|
||||||
|
'''获取用户的成绩的API'''
|
||||||
|
data = json.dumps({
|
||||||
|
"userId": int(userId),
|
||||||
|
"nextIndex": nextIndex,
|
||||||
|
"maxCount": maxCount
|
||||||
|
})
|
||||||
|
return json.loads(apiSDGB(data, "GetUserMusicApi", userId))
|
||||||
|
|
||||||
|
def maimaiUserMusicDetailToDivingFish(userMusicDetailList: list) -> list:
|
||||||
|
'''舞萌的 UserMusicDetail 成绩格式转换成水鱼的格式'''
|
||||||
|
divingFishList = []
|
||||||
|
for currentMusicDetail in userMusicDetailList:
|
||||||
|
# 每一个乐曲都判断下是 DX 还是标准
|
||||||
|
if currentMusicDetail['musicId'] >= 10000:
|
||||||
|
notesType = 'DX'
|
||||||
|
else:
|
||||||
|
notesType = 'SD'
|
||||||
|
|
||||||
|
divingFishList.append({
|
||||||
|
'achievements': (currentMusicDetail['achievement'] / 10000), # 水鱼的成绩是 float 而非舞萌的 int
|
||||||
|
'title': (getMusicTitle(currentMusicDetail['musicId'])), # 水鱼用的是歌名而不是 ID(导致不得不用数据库处理转换
|
||||||
|
'type': notesType, # 我不理解这为什么不能在后端判断
|
||||||
|
'level_index': currentMusicDetail['level'],
|
||||||
|
'fc': currentMusicDetail['comboStatus'],
|
||||||
|
'fs': currentMusicDetail['syncStatus'],
|
||||||
|
'dxScore': currentMusicDetail['deluxscoreMax'],
|
||||||
|
})
|
||||||
|
return divingFishList
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
userId = testUid
|
||||||
|
currentLoginTimestamp = generateTimestamp()
|
||||||
|
loginResult = apiLogin(currentLoginTimestamp, userId)
|
||||||
|
|
||||||
|
if loginResult['returnCode'] != 1:
|
||||||
|
logger.info("登录失败")
|
||||||
|
exit()
|
||||||
|
try:
|
||||||
|
## Begin
|
||||||
|
userMusicDetailList_current = []
|
||||||
|
|
||||||
|
nextIndex:int|None = None # 初始化 nextIndex
|
||||||
|
while nextIndex != 0 or nextIndex is None: #只要还有nextIndex就一直获取获取
|
||||||
|
userMusicResponse = getUserMusicDetail(userId, nextIndex or 0)
|
||||||
|
nextIndex = userMusicResponse['nextIndex']
|
||||||
|
logger.info(f"NextIndex: {nextIndex}")
|
||||||
|
for currentMusic in userMusicResponse['userMusicList']:
|
||||||
|
for currentMusicDetail in currentMusic['userMusicDetailList']:
|
||||||
|
if not currentMusicDetail['playCount'] > 0:
|
||||||
|
continue
|
||||||
|
userMusicDetailList_current.append(currentMusicDetail)
|
||||||
|
print("---------------")
|
||||||
|
print(str(userMusicDetailList_current))
|
||||||
|
## End
|
||||||
|
#logger.info(apiLogout(currentLoginTimestamp, userId))
|
||||||
|
logger.warning("Now We Begin To Build DiveFish Data")
|
||||||
|
divingFishData = maimaiUserMusicDetailToDivingFish(userMusicDetailList_current)
|
||||||
|
logger.info(divingFishData)
|
||||||
|
finally:
|
||||||
|
#logger.error(f"Error: {e}")
|
||||||
|
logger.info(apiLogout(currentLoginTimestamp, userId))
|
51
GenerateMusicDB.py
Normal file
51
GenerateMusicDB.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# 感谢伟大的 Diving-Fish 让我被迫直面恐惧写这个逼玩意
|
||||||
|
|
||||||
|
import xml.dom.minidom as minidom
|
||||||
|
from pathlib import Path
|
||||||
|
import json
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
def makeMusicDBJson():
|
||||||
|
'''
|
||||||
|
从 HDD 的文件来生成 music_db.json
|
||||||
|
推荐的是如果要国服用 那就用国际服的文件来生成
|
||||||
|
免得国服每次更新还要重新生成太麻烦
|
||||||
|
'''
|
||||||
|
# 记得改
|
||||||
|
A000_DIR = Path('/run/media/remik1r3n/软件/maimaiDX_SDGB/Sinmai_Data/StreamingAssets/A000')
|
||||||
|
OPTION_DIR = Path('/run/media/remik1r3n/软件/maimaiDX_SDGB/Sinmai_Data/StreamingAssets')
|
||||||
|
|
||||||
|
music_db: dict[str, dict[str, str | int]] = {}
|
||||||
|
DEST_PATH = Path('./musicDB.json')
|
||||||
|
|
||||||
|
music_folders = [f for f in (A000_DIR / 'music').iterdir() if f.is_dir()]
|
||||||
|
for option_dir in OPTION_DIR.iterdir():
|
||||||
|
if (option_dir / 'music').exists():
|
||||||
|
music_folders.extend([f for f in (option_dir / 'music').iterdir() if f.is_dir()])
|
||||||
|
|
||||||
|
for folder in music_folders:
|
||||||
|
xml_path = (folder / 'Music.xml')
|
||||||
|
if xml_path.exists():
|
||||||
|
xml = minidom.parse(xml_path.as_posix())
|
||||||
|
data = xml.getElementsByTagName('MusicData')[0]
|
||||||
|
music_id = data.getElementsByTagName('name')[0].getElementsByTagName('id')[0].firstChild.data
|
||||||
|
music_name = data.getElementsByTagName('name')[0].getElementsByTagName('str')[0].firstChild.data
|
||||||
|
music_version = data.getElementsByTagName('AddVersion')[0].getElementsByTagName('id')[0].firstChild.data
|
||||||
|
music_db[music_id] = {
|
||||||
|
"name": music_name,
|
||||||
|
"version": int(music_version)
|
||||||
|
}
|
||||||
|
logger.debug(f'Found {len(music_db)} music data')
|
||||||
|
serialized = '{\n'
|
||||||
|
sorted_keys = sorted(music_db.keys(), key=lambda x: int(x))
|
||||||
|
for key in sorted_keys:
|
||||||
|
value = music_db[key]
|
||||||
|
serialized += f' "{key}": {json.dumps(value, ensure_ascii=False)},\n'
|
||||||
|
serialized = serialized[:-2] + '\n}'
|
||||||
|
|
||||||
|
with open(DEST_PATH, 'w') as f:
|
||||||
|
f.write(serialized)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
makeMusicDBJson()
|
||||||
|
print('Done.')
|
20
MusicDB.py
Normal file
20
MusicDB.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# 感谢伟大的 Diving-Fish 让我被迫直面恐惧写这个逼玩意
|
||||||
|
|
||||||
|
import xml.dom.minidom as minidom
|
||||||
|
from pathlib import Path
|
||||||
|
import rapidjson as json
|
||||||
|
from typing import Dict, Union
|
||||||
|
|
||||||
|
# 定义音乐数据库的类型注解
|
||||||
|
MusicDBType = Dict[int, Dict[str, Union[int, str]]]
|
||||||
|
|
||||||
|
# 将 '__all__' 用于模块导出声明
|
||||||
|
__all__ = ['musicDB']
|
||||||
|
|
||||||
|
# 读取并解析 JSON 文件
|
||||||
|
with open('musicDB.json', 'r', encoding='utf-8') as f:
|
||||||
|
# 使用 json.load 直接从文件对象读取 JSON 数据
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
# 将 JSON 数据转换为指定格式的字典
|
||||||
|
musicDB: MusicDBType = {int(k): v for k, v in data.items()}
|
1113
musicDB.json
Normal file
1113
musicDB.json
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user