Files
maimaiDX-Api/ActionLoginBonus.py
2025-07-29 17:07:34 +08:00

157 lines
6.3 KiB
Python

# ログインボーナス!やったね!
# セガ秘 内部使用のみ(トレードマーク)
import rapidjson as json
from loguru import logger
import xml.etree.ElementTree as ET
from Config import (
loginBonusDBPath,
loginBonusDBPathFallback,
)
from MyConfig import testUid
from API_TitleServer import apiSDGB
from HelperLogInOut import apiLogin, apiLogout, generateTimestamp
from HelperFullPlay import implFullPlayAction, generateMusicData
class NoSelectedBonusError(Exception):
pass
def apiQueryLoginBonus(userId: int) -> str:
"""ログインボーナスを取得する API"""
data = json.dumps({"userId": int(userId), "nextIndex": 0, "maxCount": 2000})
return apiSDGB(data, "GetUserLoginBonusApi", userId)
def implLoginBonus(
userId: int, currentLoginTimestamp: int, currentLoginResult, bonusGenerateMode=1
):
"""
ログインボーナスデータをアップロードする
bonusGenerateMode は、ログインボーナスを生成する方法を指定します。
1: 選択したボーナスのみ MAX にする(選択したボーナスはないの場合は False を返す)
2: 全部 MAX にする
"""
musicData = generateMusicData()
# サーバーからログインボーナスデータを取得
data = json.dumps({"userId": int(userId), "nextIndex": 0, "maxCount": 2000})
UserLoginBonusResponse = json.loads(apiSDGB(data, "GetUserLoginBonusApi", userId))
# ログインボーナスリストを生成、それから処理してアップロード
UserLoginBonusList = UserLoginBonusResponse["userLoginBonusList"]
finalBonusList = generateLoginBonusList(UserLoginBonusList, bonusGenerateMode)
if not finalBonusList:
return False # ログインボーナスを選択していないから失敗
# UserAllのパッチ
userAllPatches = {
"upsertUserAll": {
"userMusicDetailList": [musicData],
"isNewMusicDetailList": "1", # 上書きしない
"userLoginBonusList": finalBonusList,
"isNewLoginBonusList": "0" * len(finalBonusList),
}
}
result = implFullPlayAction(
userId, currentLoginTimestamp, currentLoginResult, musicData, userAllPatches
)
return result
def generateLoginBonusList(UserLoginBonusList, generateMode=1):
"""
ログインボーナスリストを生成します。
generateMode は、ログインボーナスを生成する方法を指定します。
1: 選択したボーナスのみ MAX にする(選択したボーナスはないの場合は False を返す)
2: 全部 MAX にする
"""
# HDDから、ログインボーナスデータを読み込む
# アップデートがある場合、このファイルを更新する必要があります
# 必ず最新のデータを使用してください
try:
tree = ET.parse(loginBonusDBPath)
root = tree.getroot()
loginBonusIdList = [
int(item.find("id").text) for item in root.findall(".//StringID")
]
logger.debug(f"ログインボーナスIDリスト: {loginBonusIdList}")
except FileNotFoundError:
try:
tree = ET.parse(loginBonusDBPathFallback)
root = tree.getroot()
loginBonusIdList = [
int(item.find("id").text) for item in root.findall(".//StringID")
]
logger.debug(f"ログインボーナスIDリスト: {loginBonusIdList}")
except Exception:
raise FileNotFoundError("ログインボーナスデータベースを読み込めません")
# ログインボーナスの MAX POINT は5の場合があります
# その全部のボーナスIDをこのリストに追加してください
# 必ず最新のデータを使用してください
Bonus5Id = [12, 29, 30, 38, 43, 604, 611]
# UserBonusList から bonusId を取得
UserLoginBonusIdList = [item["bonusId"] for item in UserLoginBonusList]
# 存在しないボーナス
NonExistingBonuses = list(set(loginBonusIdList) - set(UserLoginBonusIdList))
logger.debug(f"存在しないボーナス: {NonExistingBonuses}")
bonusList = []
if generateMode == 1: # 選択したボーナスのみ MAX にする
for item in UserLoginBonusList:
if item["isCurrent"] and not item["isComplete"]:
point = 4 if item["bonusId"] in Bonus5Id else 9
data = {
"bonusId": item["bonusId"],
"point": point,
"isCurrent": True,
"isComplete": False,
}
bonusList.append(data)
if len(bonusList) == 0:
raise NoSelectedBonusError("選択したログインボーナスがありません")
elif generateMode == 2: # 全部 MAX にする
# 存在しているボーナスを追加
for item in UserLoginBonusList:
if not item["isComplete"]:
data = {
"bonusId": item["bonusId"],
"point": 4 if item["bonusId"] in Bonus5Id else 9,
"isCurrent": item["isCurrent"],
"isComplete": False,
}
bonusList.append(data)
elif item["bonusId"] == 999:
data = {
"bonusId": 999,
"point": (item["point"] // 10) * 10 + 9,
"isCurrent": item["isCurrent"],
"isComplete": False,
}
bonusList.append(data)
# 存在しないボーナスを追加
for bonusId in NonExistingBonuses:
data = {
"bonusId": bonusId,
"point": 4 if bonusId in Bonus5Id else 9,
"isCurrent": False,
"isComplete": False,
}
bonusList.append(data)
else:
raise SyntaxError("generateMode は 1 または 2 でなければなりません")
logger.debug(f"ログインボーナスリスト: {bonusList}")
return bonusList
if __name__ == "__main__":
# ログインボーナスデータをアップロードする
userId = testUid
currentLoginTimestamp = generateTimestamp()
currentLoginResult = apiLogin(currentLoginTimestamp, userId)
implLoginBonus(userId, currentLoginTimestamp, currentLoginResult, 2)
apiLogout(currentLoginTimestamp, userId)