diff --git a/bonus9.py b/bonus9.py new file mode 100644 index 0000000..1f055cc --- /dev/null +++ b/bonus9.py @@ -0,0 +1,395 @@ +import json +import pytz +import time +import random + +from sdgb import sdgb_api +from datetime import datetime, timedelta + +from settings import music_data +from settings import regionId +from settings import regionName +from settings import clientId +from settings import placeId +from settings import placeName + +from login import login +from logout import logout + +def CalcRandom(): + max = 1037933 + num2 = random.randint(1, max) * 2069 + + num2 += 1024 # specialnum + num3 = 0 + for i in range(0, 32): + num3 <<= 1 + num3 += num2 % 2 + num2 >>= 1 + + return num3 + +timestamp = int(time.time()) + + + +def music(userId, bonus_list): + + music = music_data + + musicId = music['musicId'] + level = music['level'] + playCount = music['playCount'] + achievement = music['achievement'] + comboStatus = music['comboStatus'] + syncStatus = music['syncStatus'] + deluxscoreMax = music['deluxscoreMax'] + scoreRank = music['scoreRank'] + extNum1 = music['extNum1'] + + # UserLogin + + login_result = login(userId,timestamp) + + login_id = login_result['loginId'] + login_date = login_result['lastLoginDate'] + + + # UserData + + data = json.dumps({ + "userId": int(userId) + }) + + userdata = json.loads(sdgb_api(data, "GetUserDataApi", userId)) + + # UserLog + + data = json.dumps({ + "userId": int(userId), + "userPlaylog": { + "userId": 0, + "orderId": 0, + "playlogId": login_id, + "version": 1041000, + "placeId": placeId, + "placeName": placeName, + "loginDate": int(time.time()), + "playDate": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%Y-%m-%d'), + "userPlayDate": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S') + '.0', + "type": 0, + "musicId": int(musicId), + "level": int(level), + "trackNo": 1, + "vsMode": 0, + "vsUserName": "", + "vsStatus": 0, + "vsUserRating": 0, + "vsUserAchievement": 0, + "vsUserGradeRank": 0, + "vsRank": 0, + "playerNum": 1, + "playedUserId1": 0, + "playedUserName1": "", + "playedMusicLevel1": 0, + "playedUserId2": 0, + "playedUserName2": "", + "playedMusicLevel2": 0, + "playedUserId3": 0, + "playedUserName3": "", + "playedMusicLevel3": 0, + "characterId1": userdata['userData']['charaSlot'][0], + "characterLevel1": random.randint(1000,6500), + "characterAwakening1": 5, + "characterId2": userdata['userData']['charaSlot'][1], + "characterLevel2": random.randint(1000,6500), + "characterAwakening2": 5, + "characterId3": userdata['userData']['charaSlot'][2], + "characterLevel3": random.randint(1000,6500), + "characterAwakening3": 5, + "characterId4": userdata['userData']['charaSlot'][3], + "characterLevel4": random.randint(1000,6500), + "characterAwakening4": 5, + "characterId5": userdata['userData']['charaSlot'][4], + "characterLevel5": random.randint(1000,6500), + "characterAwakening5": 5, + "achievement": int(achievement), + "deluxscore": int(deluxscoreMax), + "scoreRank": int(scoreRank), + "maxCombo": random.randint(400,500), + "totalCombo": random.randint(700,900), + "maxSync": 0, + "totalSync": 0, + "tapCriticalPerfect": random.randint(200,400), + "tapPerfect": random.randint(100,250), + "tapGreat": random.randint(0,10), + "tapGood": random.randint(0,10), + "tapMiss": random.randint(0,10), + "holdCriticalPerfect": random.randint(20,40), + "holdPerfect": random.randint(0,15), + "holdGreat": 0, + "holdGood": 0, + "holdMiss": 0, + "slideCriticalPerfect": random.randint(34,60), + "slidePerfect": 0, + "slideGreat": 0, + "slideGood": 0, + "slideMiss": 0, + "touchCriticalPerfect": random.randint(20,70), + "touchPerfect": 0, + "touchGreat": 0, + "touchGood": 0, + "touchMiss": 0, + "breakCriticalPerfect": random.randint(8,30), + "breakPerfect": random.randint(7,10), + "breakGreat": 0, + "breakGood": 0, + "breakMiss": 0, + "isTap": True, + "isHold": True, + "isSlide": True, + "isTouch": True, + "isBreak": True, + "isCriticalDisp": True, + "isFastLateDisp": True, + "fastCount": random.randint(20,30), + "lateCount": random.randint(50,70), + "isAchieveNewRecord": True, + "isDeluxscoreNewRecord": True, + "comboStatus": 0, + "syncStatus": 0, + "isClear": True, + 'beforeRating': userdata['userData']['playerRating'], + 'afterRating': userdata['userData']['playerRating'], + "beforeGrade": 0, + "afterGrade": 0, + "afterGradeRank": 2, + 'beforeDeluxRating': userdata['userData']['playerRating'], + 'afterDeluxRating': userdata['userData']['playerRating'], + "isPlayTutorial": False, + "isEventMode": False, + "isFreedomMode": False, + "playMode": 0, + "isNewFree": False, + "trialPlayAchievement": -1, + "extNum1": 0, + "extNum2": 0, + "extNum4": 3020, + "extBool1": False + } + }) + + userlog_result = json.loads(sdgb_api(data, "UploadUserPlaylogApi", userId)) + + # 获取 User Extend + data = json.dumps({ + "userId": int(userId) + }) + + user_extend = json.loads(sdgb_api(data, "GetUserExtendApi", userId)) + + # 获取 User Option + data = json.dumps({ + "userId": int(userId) + }) + + user_option = json.loads(sdgb_api(data, "GetUserOptionApi", userId)) + + + # 获取 User Rating + data = json.dumps({ + "userId": int(userId) + }) + + user_rating = json.loads(sdgb_api(data, "GetUserRatingApi", userId)) + + + # 获取 User Activity + data = json.dumps({ + "userId": int(userId) + }) + + user_activity = json.loads(sdgb_api(data, "GetUserActivityApi", userId)) + + + # 获取账号功能票 + data = json.dumps({ + "userId": int(userId) + }) + + user_charge = json.loads(sdgb_api(data, "GetUserChargeApi", userId)) + + # UserAll + + data = json.dumps({ + "userId": int(userId), + "playlogId": login_id, + "isEventMode": False, + "isFreePlay": False, + "upsertUserAll": { + "userData": [ + { + "accessCode": "", + "userName": userdata['userData']['userName'], + "isNetMember": 1, + "iconId": userdata['userData']['iconId'], + "plateId": userdata['userData']['plateId'], + "titleId": userdata['userData']['titleId'], + "partnerId": userdata['userData']['partnerId'], + "frameId": userdata['userData']['frameId'], + "selectMapId": userdata['userData']['selectMapId'], + "totalAwake": userdata['userData']['totalAwake'], + "gradeRating": userdata['userData']['gradeRating'], + "musicRating": userdata['userData']['musicRating'], + "playerRating": userdata['userData']['playerRating'], + "highestRating": userdata['userData']['highestRating'], + "gradeRank": userdata['userData']['gradeRank'], + "classRank": userdata['userData']['classRank'], + "courseRank": userdata['userData']['courseRank'], + "charaSlot": userdata['userData']['charaSlot'], + "charaLockSlot": userdata['userData']['charaLockSlot'], + "contentBit": userdata['userData']['contentBit'], + "playCount": userdata['userData']['playCount'], + "currentPlayCount": userdata['userData']['currentPlayCount'], + "renameCredit": 0, + "mapStock": 99000, + "eventWatchedDate": userdata['userData']['eventWatchedDate'], + "lastGameId": "SDGB", + "lastRomVersion": userdata['userData']['lastRomVersion'], + "lastDataVersion": userdata['userData']['lastDataVersion'], + "lastLoginDate": login_date, + "lastPlayDate": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S') + '.0', + "lastPlayCredit": 1, + "lastPlayMode": 0, + "lastPlaceId": placeId, + "lastPlaceName": placeName, + "lastAllNetId": 0, + "lastRegionId": regionId, + "lastRegionName": regionName, + "lastClientId": clientId, + "lastCountryCode": "CHN", + "lastSelectEMoney": 0, + "lastSelectTicket": 0, + "lastSelectCourse": userdata['userData']['lastSelectCourse'], + "lastCountCourse": 0, + "firstGameId": "SDGB", + "firstRomVersion": userdata['userData']['firstRomVersion'], + "firstDataVersion": userdata['userData']['firstDataVersion'], + "firstPlayDate": userdata['userData']['firstPlayDate'], + "compatibleCmVersion": userdata['userData']['compatibleCmVersion'], + "dailyBonusDate": userdata['userData']['dailyBonusDate'], + "dailyCourseBonusDate": userdata['userData']['dailyCourseBonusDate'], + "lastPairLoginDate": userdata['userData']['lastPairLoginDate'], + "lastTrialPlayDate": userdata['userData']['lastTrialPlayDate'], + "playVsCount": 0, + "playSyncCount": 0, + "winCount": 0, + "helpCount": 0, + "comboCount": 0, + "totalDeluxscore": userdata['userData']['totalDeluxscore'], + "totalBasicDeluxscore": userdata['userData']['totalBasicDeluxscore'], + "totalAdvancedDeluxscore": userdata['userData']['totalAdvancedDeluxscore'], + "totalExpertDeluxscore": userdata['userData']['totalExpertDeluxscore'], + "totalMasterDeluxscore": userdata['userData']['totalMasterDeluxscore'], + "totalReMasterDeluxscore": userdata['userData']['totalReMasterDeluxscore'], + "totalSync": userdata['userData']['totalSync'], + "totalBasicSync": userdata['userData']['totalBasicSync'], + "totalAdvancedSync": userdata['userData']['totalAdvancedSync'], + "totalExpertSync": userdata['userData']['totalExpertSync'], + "totalMasterSync": userdata['userData']['totalMasterSync'], + "totalReMasterSync": userdata['userData']['totalReMasterSync'], + "totalAchievement": userdata['userData']['totalAchievement'], + "totalBasicAchievement": userdata['userData']['totalBasicAchievement'], + "totalAdvancedAchievement": userdata['userData']['totalAdvancedAchievement'], + "totalExpertAchievement": userdata['userData']['totalExpertAchievement'], + "totalMasterAchievement": userdata['userData']['totalMasterAchievement'], + "totalReMasterAchievement": userdata['userData']['totalReMasterAchievement'], + "playerOldRating": userdata['userData']['playerOldRating'], + "playerNewRating": userdata['userData']['playerNewRating'], + "banState": 0, + "dateTime": timestamp + } + ], + "userExtend": [user_extend['userExtend']], + "userOption": [user_option['userOption']], + "userCharacterList": [], + "userGhost": [], + "userMapList": [], + "userLoginBonusList": bonus_list, + "userRatingList": [user_rating['userRating']], + "userItemList": [], + "userMusicDetailList": [ + { + "musicId": musicId, + "level": level, + "playCount": playCount, + "achievement": achievement, + "comboStatus": comboStatus, + "syncStatus": syncStatus, + "deluxscoreMax": deluxscoreMax, + "scoreRank": scoreRank, + "extNum1": extNum1 + } + ], + "userCourseList": [], + "userFriendSeasonRankingList": [], + "userChargeList": user_charge['userChargeList'], + "userFavoriteList": [], + "userActivityList": [user_activity['userActivity']], + "userGamePlaylogList": [ + { + "playlogId": login_id, + "version": "1.41.00", + "playDate": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S') + '.0', + "playMode": 0, + "useTicketId": -1, + "playCredit": 1, + "playTrack": 1, + "clientId": clientId, + "isPlayTutorial": False, + "isEventMode": False, + "isNewFree": False, + "playCount": 0, + "playSpecial": CalcRandom(), + "playOtherUserId": 0 + } + ], + "user2pPlaylog": { + "userId1": 0, + "userId2": 0, + "userName1": "", + "userName2": "", + "regionId": 0, + "placeId": 0, + "user2pPlaylogDetailList": [] + }, + "isNewCharacterList": "", + "isNewMapList": "", + "isNewLoginBonusList": "0" * len(bonus_list), + "isNewItemList": "", + "isNewMusicDetailList": "1", + "isNewCourseList": "0", + "isNewFavoriteList": "", + "isNewFriendSeasonRankingList": "" + } + }) + + userall_result = json.loads(sdgb_api(data, "UpsertUserAllApi", userId)) + + data = json.dumps({ + "UserLogin": login_result, + "UserPlaylog": userlog_result, + "UpsertUserall": userall_result + }) + + return data + +def music_with_retry(userId, bonus_list): + for i in range(5): # 重试次数 + try: + music(userId, bonus_list) + return logout(userId, timestamp) + except ValueError as e: + logout(userId, timestamp) + time.sleep(3) + return json.dumps({"status": "500 Internal Server Error"}), 500 diff --git a/login_bonus.json b/login_bonus.json new file mode 100644 index 0000000..6b11975 --- /dev/null +++ b/login_bonus.json @@ -0,0 +1,242 @@ +[ + { + "id": 38, + "name": "パートナー:ずんだもん" + }, + { + "id": 39, + "name": "パートナー:乙姫(ばでぃーず)" + }, + { + "id": 40, + "name": "パートナー:らいむっくま&れもんっくま(ばでぃーず)" + }, + { + "id": 34, + "name": "パートナー:黒姫" + }, + { + "id": 24, + "name": "パートナー:ラズ(ふぇすてぃばる)" + }, + { + "id": 25, + "name": "パートナー:シフォン(ふぇすてぃばる)" + }, + { + "id": 26, + "name": "パートナー:ソルト(ふぇすてぃばる)" + }, + { + "id": 19, + "name": "パートナー:ちびみるく" + }, + { + "id": 20, + "name": "パートナー:百合咲ミカ" + }, + { + "id": 8, + "name": "パートナー:しゃま(ゆにばーす)" + }, + { + "id": 9, + "name": "パートナー:みるく(ゆにばーす)" + }, + { + "id": 7, + "name": "パートナー:乙姫(すぷらっしゅ)" + }, + { + "id": 1, + "name": "パートナー:乙姫" + }, + { + "id": 2, + "name": "パートナー:ラズ" + }, + { + "id": 3, + "name": "パートナー:シフォン" + }, + { + "id": 4, + "name": "パートナー:ソルト" + }, + { + "id": 5, + "name": "パートナー:しゃま" + }, + { + "id": 6, + "name": "パートナー:みるく" + }, + { + "id": 605, + "name": "でらっくす譜面:oboro" + }, + { + "id": 606, + "name": "でらっくす譜面:ナミダと流星" + }, + { + "id": 607, + "name": "スタンダード譜面:渦状銀河のシンフォニエッタ" + }, + { + "id": 508, + "name": "でらっくす譜面:LatentKingdom" + }, + { + "id": 41, + "name": "でらっくす譜面:初音ミクの消失" + }, + { + "id": 42, + "name": "でらっくす譜面:色は匂へど散りぬるを" + }, + { + "id": 601, + "name": "でらっくす譜面:BULKUP(GAMEEXCLUSIVEEDIT)" + }, + { + "id": 602, + "name": "でらっくす譜面:MonochromeRainbow" + }, + { + "id": 603, + "name": "でらっくす譜面:Selector" + }, + { + "id": 35, + "name": "でらっくす譜面:深海少女" + }, + { + "id": 36, + "name": "でらっくす譜面:ナイト・オブ・ナイツ" + }, + { + "id": 27, + "name": "でらっくす譜面:M.S.S.Planet" + }, + { + "id": 28, + "name": "でらっくす譜面:響縁" + }, + { + "id": 501, + "name": "スタンダード譜面:Halcyon" + }, + { + "id": 502, + "name": "スタンダード譜面:サンバランド" + }, + { + "id": 503, + "name": "でらっくす譜面:StarlightDisco" + }, + { + "id": 504, + "name": "でらっくす譜面:火炎地獄" + }, + { + "id": 505, + "name": "スタンダード譜面:VIIIbitExplorer" + }, + { + "id": 506, + "name": "でらっくす譜面:Maxi" + }, + { + "id": 507, + "name": "でらっくす譜面:ケロ⑨destiny" + }, + { + "id": 21, + "name": "でらっくす譜面:セツナトリップ" + }, + { + "id": 22, + "name": "でらっくす譜面:Grip&Breakdown!!" + }, + { + "id": 17, + "name": "でらっくす譜面:ゴーストルール" + }, + { + "id": 18, + "name": "でらっくす譜面:tabootearsyouup" + }, + { + "id": 43, + "name": "アイコン:BUDDiES" + }, + { + "id": 604, + "name": "アイコン:FESTiVALラズ&シフォン&ソルト" + }, + { + "id": 29, + "name": "アイコン:FESTiVAL" + }, + { + "id": 30, + "name": "アイコン:Lia=Fail" + }, + { + "id": 12, + "name": "アイコン:UNiVERSE" + }, + { + "id": 14, + "name": "ネームプレート:はっぴー(ゆにばーす)" + }, + { + "id": 44, + "name": "フレーム:mystiqueasiris" + }, + { + "id": 45, + "name": "フレーム:VeRForTeαRtE:VEiN" + }, + { + "id": 37, + "name": "フレーム:Tricolor⁂circuS" + }, + { + "id": 31, + "name": "フレーム:HeavenlyBlast" + }, + { + "id": 32, + "name": "フレーム:sølips" + }, + { + "id": 33, + "name": "フレーム:RainbowRushStory" + }, + { + "id": 23, + "name": "フレーム:ふたりでばかんすにゃ♪" + }, + { + "id": 15, + "name": "フレーム:ここからはじまるプロローグ。" + }, + { + "id": 16, + "name": "フレーム:モ゜ルモ゜ル" + }, + { + "id": 10, + "name": "フレーム:黒姫" + }, + { + "id": 11, + "name": "フレーム:百合咲ミカ" + }, + { + "id": 999, + "name": "ちほー進行1.5倍チケット" + } +] \ No newline at end of file diff --git a/main.py b/main.py index 3bb9e05..33cd7da 100644 --- a/main.py +++ b/main.py @@ -12,11 +12,14 @@ from ticket import get_ticket from charge import charge from map import map from userdata import userdata -from mapstock import music_with_retry as mapstock from character import character + +from sdgb import sdgb_api +from mapstock import music_with_retry as mapstock from music import music_with_retry as music from unlock_all import music_with_retry as unlock from map_clear import music_with_retry as map_clear +from bonus9 import music_with_retry as login_bonus def find_map(mapId, user_map_data): for single in user_map_data: @@ -57,6 +60,68 @@ def item(item_data, user_character_list): return item_list, character_list, item_data[-1]['distance'] +def bonus_list_gen(userId): + with open('login_bonus.json') as file: + cache = json.load(file) + bonus_data = [] + for item in cache: + bonus_data.append(item['id']) + cache = [] + data = json.dumps({ + "userId": int(userId), + "nextIndex":0, + "maxCount":2000 + }) + user_bonus = json.loads(sdgb_api(data, "GetUserLoginBonusApi", userId))['userLoginBonusList'] + for item in user_bonus: + cache.append(item['bonusId']) + bonus_list_unexist = list(set(bonus_data) - set(cache)) + bonus_list = [] + for item in user_bonus: + if item['isComplete'] == False: + if item['bonusId'] in [12, 29, 30, 38, 43, 604]: + data = ({ + "bonusId": item['bonusId'], + "point": 4, + "isCurrent": item['isCurrent'], + "isComplete": False + }) + else: + data = ({ + "bonusId": item['bonusId'], + "point": 9, + "isCurrent": item['isCurrent'], + "isComplete": False + }) + bonus_list.append(data) + elif item['bonusId'] == 999: + data = ({ + "bonusId": 999, + "point": item['point'] // 10 * 10 + 9, + "isCurrent": item['isCurrent'], + "isComplete": False + }) + bonus_list.append(data) + else: + pass + for item in bonus_list_unexist: + if item in [12, 29, 30, 38, 43, 604]: + data = ({ + "bonusId": item, + "point": 4, + "isCurrent": False, + "isComplete": False + }) + else: + data = ({ + "bonusId": item, + "point": 9, + "isCurrent": False, + "isComplete": False + }) + bonus_list.append(data) + return bonus_list + app = Flask(__name__) app.json.sort_keys = False app.json.ensure_ascii = False @@ -311,5 +376,34 @@ def maps(): data = jsonify({"status": status, "timestamp": timestamp, "info": info, "apiName": "map", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8'), "userId": userId}) return data, returnCode +@app.route("/bonus") +def bonus(): + userId = request.args.get('userid') + if userId is None or userId.isdigit() is False or len(str(userId)) != 8: + return jsonify({"apiName": "bonus", "apiInfo": "Get 9 Stamps in Login Bonus Items.", "apiUsage": "/bonus?userid="}) + else: + userId = int(userId) + timestamp = int(time.time()) + login_data = login(userId, timestamp) + if login_data['returnCode'] == 102: + returnCode = 403 + status = "403 Forbidden" + info = "Unable to operate. Please refresh QrCode." + log = {} + elif login_data['returnCode'] == 100: + returnCode = 403 + status = "403 Forbidden" + info = "Unable to operate. Probably User has logged in." + log = {} + elif login_data['returnCode'] == 1: + logout(userId, timestamp) + login_bonus(userId, bonus_list_gen(userId)) + returnCode = 200 + status = "200 OK" + info = "Succeed." + log = {"UserLoginApiStatus": 1, "UploadUserPlaylogApiStatus": 1, "UpsertUserAllApi": 1, "UserLogoutApiStatus": 1} + data = jsonify({"status": status, "timestamp": timestamp, "info": info, "apiName": "unlock", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8'), "userId": userId}) + return data, returnCode + if __name__ == '__main__': app.run(port = 8080)