Compare commits

1 Commits

Author SHA1 Message Date
f8f55bbc89 Add detection to check whether the track is newly uploaded 2025-01-19 02:05:09 +08:00
17 changed files with 1591 additions and 1595 deletions

View File

@@ -1,15 +1,12 @@
import random
# This file contains the config of the whole project.
# DO NOT share your crtical info to others.
# Change the file name from .settings.py to settings.py.
# 上传的乐曲成绩
# 此成绩将覆盖原有成绩
music_data = ({
"musicId": 11451,
"level": 0,
"playCount": random.randint(10, 20),
"achievement": random.randint(995000, 1000000),
"comboStatus": random.randint(0, 2),
"syncStatus": 0,
"deluxscoreMax": random.randint(150, 200),
"scoreRank": 11,
"extNum1": 0
"musicId":834,"level":4,"playCount":10,"achievement":912231,"comboStatus":0,"syncStatus":0,"deluxscoreMax":2106,"scoreRank":5, "extNum1": 0
})
# 机厅信息

View File

@@ -6,7 +6,12 @@ import random
from sdgb import sdgb_api
from datetime import datetime, timedelta
from settings import music_data, regionId, regionName, clientId, placeId, placeName
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
@@ -214,24 +219,6 @@ def music(userId, bonus_list):
user_charge = json.loads(sdgb_api(data, "GetUserChargeApi", userId))
data = json.dumps({
"userId": int(userId),
"nextIndex": musicId,
"maxCount": 1
})
user_music = json.loads(sdgb_api(data, "GetUserMusicApi", userId))
isNew = "0"
try:
for item in user_music['userMusicList'][0]['userMusicDetailList']:
if item['musicId'] == musicId and item['level'] == level:
isNew = "1"
break
else:
continue
except:
pass
# UserAll
data = json.dumps({
@@ -380,7 +367,7 @@ def music(userId, bonus_list):
"isNewMapList": "",
"isNewLoginBonusList": "0" * len(bonus_list),
"isNewItemList": "",
"isNewMusicDetailList": isNew,
"isNewMusicDetailList": "1",
"isNewCourseList": "0",
"isNewFavoriteList": "",
"isNewFriendSeasonRankingList": ""

17
character.py Normal file
View File

@@ -0,0 +1,17 @@
import json
from sdgb import sdgb_api
def character(userId):
data = json.dumps({
"userId": int(userId),
"nextIndex":10000000000,
"maxCount":1000000000
})
character_result = json.loads(sdgb_api(data, "GetUserCharacterApi", userId))
return character_result
if __name__ == "__main__":
print(character(int(input())))

13
charge.py Normal file
View File

@@ -0,0 +1,13 @@
import json
from sdgb import sdgb_api
def charge(userId):
data = json.dumps({
"userId": userId,
})
charge_result = json.loads(sdgb_api(data, "GetUserChargeApi", userId))
return charge_result

View File

@@ -4,7 +4,9 @@ import pytz
from sdgb import sdgb_api
from datetime import datetime
from settings import regionId, clientId, placeId
from settings import regionId
from settings import clientId
from settings import placeId
def login(userId, timestamp):
data = json.dumps({

View File

@@ -4,7 +4,9 @@ import pytz
from sdgb import sdgb_api
from datetime import datetime
from settings import regionId, clientId, placeId
from settings import regionId
from settings import clientId
from settings import placeId
def logout(userId, timestamp):
data = json.dumps({

118
main.py
View File

@@ -5,17 +5,123 @@ from datetime import datetime
from flask import Flask,request,redirect,jsonify
from flask_cors import CORS
from sdgb import qr_api
from logout import logout
from login import login
from process import *
from ticket import get_ticket
from charge import charge
from map import map
from userdata import userdata
from character import character
from sdgb import sdgb_api, qr_api
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:
if single["mapId"] == mapId:
return single
else:
continue
def isNewMapList(mapId, user_map_data):
if ('{"mapId": ' + str(mapId)) in user_map_data:
return 0
else:
return 1
def item(item_data, user_character_list):
item_list = []
character_list = []
for single in item_data:
if single['kind'] == 9:
if ('{"characterId": ' + str(single['id'])) in user_character_list:
pass
else:
data = ({
"characterId":single['id'],
"level":1,
"awakening":0,
"useCount": 0
})
character_list.append(data)
else:
data = ({
"itemKind": single['kind'],
"itemId": single['id'],
"stock": 1,
"isValid": True
})
item_list.append(data)
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
@@ -38,7 +144,7 @@ def bad_request(e):
@app.route("/")
def index():
return jsonify({"status": "200 OK", "timestamp": int(time.time()), "info": "Project Fragrance","availableApi": ["qr", "ticket", "mapstock", "unlock", "map", "bonus"], "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8')}), 200
return jsonify({"status": "200 OK", "timestamp": int(time.time()), "info": "Project Fragrance","availableApi": ["qr", "ticket", "mapstock", "unlock", "map"], "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8')}), 200
@app.route("/qr")
def qr_to_userid():
@@ -94,8 +200,8 @@ def ticket():
ticket_data = get_ticket(userId)
if ticket_data['returnCode'] == 0:
logout(userId, timestamp)
returnCode = 403
status = "403 Forbidden"
returnCode = 405
status = "405 Method Not Allowed"
info = "WARNING: THIS INFO SHOULD NEVER APPEARS. IF YOU SEE THIS WARNING PLEASE CONTACT Telegram@sasakure. Unable to operate. Successfully Logged in. Probably User has had one ticket."
log = {"UserLoginApiStatus": 1, "UserLogoutApiStatus": 1}
elif ticket_data['returnCode'] == 1:
@@ -296,7 +402,7 @@ def bonus():
status = "200 OK"
info = "Succeed."
log = {"UserLoginApiStatus": 1, "UploadUserPlaylogApiStatus": 1, "UpsertUserAllApi": 1, "UserLogoutApiStatus": 1}
data = jsonify({"status": status, "timestamp": timestamp, "info": info, "apiName": "bonus", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8'), "userId": userId})
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__':

17
map.py Normal file
View File

@@ -0,0 +1,17 @@
import json
from sdgb import sdgb_api
def map(userId):
data = json.dumps({
"userId": int(userId),
"nextIndex": 0,
"maxCount": 600
})
map_result = json.loads(sdgb_api(data, "GetUserMapApi", userId))
return map_result
if __name__ == "__main__":
print(map(int(input())))

View File

@@ -6,7 +6,12 @@ import random
from sdgb import sdgb_api
from datetime import datetime, timedelta
from settings import music_data, regionId, regionName, clientId, placeId, placeName
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
@@ -214,23 +219,7 @@ def music(userId, mapId, distance, item_list, character_list, isNewMapList):
user_charge = json.loads(sdgb_api(data, "GetUserChargeApi", userId))
data = json.dumps({
"userId": int(userId),
"nextIndex": musicId,
"maxCount": 1
})
user_music = json.loads(sdgb_api(data, "GetUserMusicApi", userId))
isNew = "0"
try:
for item in user_music['userMusicList'][0]['userMusicDetailList']:
if item['musicId'] == musicId and item['level'] == level:
isNew = "1"
break
else:
continue
except:
pass
# UserAll
@@ -388,7 +377,7 @@ def music(userId, mapId, distance, item_list, character_list, isNewMapList):
"isNewMapList": isNewMapList,
"isNewLoginBonusList": "",
"isNewItemList": "1" * len(item_list),
"isNewMusicDetailList": isNew,
"isNewMusicDetailList": "1",
"isNewCourseList": "0",
"isNewFavoriteList": "",
"isNewFriendSeasonRankingList": ""

View File

@@ -6,7 +6,12 @@ import random
from sdgb import sdgb_api
from datetime import datetime, timedelta
from settings import music_data, regionId, regionName, clientId, placeId, placeName
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
@@ -212,17 +217,6 @@ def music(userId):
user_charge = json.loads(sdgb_api(data, "GetUserChargeApi", userId))
isNew = "0"
try:
for item in user_music['userMusicList'][0]['userMusicDetailList']:
if item['musicId'] == musicId and item['level'] == level:
isNew = "1"
break
else:
continue
except:
pass
# UserAll
data = json.dumps({
@@ -371,7 +365,7 @@ def music(userId):
"isNewMapList": "",
"isNewLoginBonusList": "",
"isNewItemList": "",
"isNewMusicDetailList": isNew,
"isNewMusicDetailList": "1",
"isNewCourseList": "0",
"isNewFavoriteList": "",
"isNewFriendSeasonRankingList": ""

View File

@@ -6,7 +6,11 @@ import random
from sdgb import sdgb_api
from datetime import datetime, timedelta
from settings import regionId, regionName, clientId, placeId, placeName
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
@@ -46,6 +50,21 @@ def music(userId, music_data):
login_id = login_result['loginId']
login_date = login_result['lastLoginDate']
#MusicData
data = json.dumps({
"userId": int(userId),
"nextIndex": 0,
"maxCount": 2147483647
})
allmusicdata = json.loads(sdgb_api(data, "GetUserMusicApi", userId))
isnew="1"
try:
for item in allmusicdata['userMusicList']:
if item["userMusicDetailList"][0].get("musicId") == musicId:
isnew="0"
break
except:
pass
# UserData
@@ -211,23 +230,6 @@ def music(userId, music_data):
user_charge = json.loads(sdgb_api(data, "GetUserChargeApi", userId))
data = json.dumps({
"userId": int(userId),
"nextIndex": musicId,
"maxCount": 1
})
user_music = json.loads(sdgb_api(data, "GetUserMusicApi", userId))
isNew = "1"
try:
for item in user_music['userMusicList'][0]['userMusicDetailList']:
if item['musicId'] == musicId and item['level'] == level:
isNew = "0"
break
else:
continue
except:
pass
# UserAll
@@ -377,7 +379,7 @@ def music(userId, music_data):
"isNewMapList": "",
"isNewLoginBonusList": "",
"isNewItemList": "",
"isNewMusicDetailList": isNew,
"isNewMusicDetailList": isnew,
"isNewCourseList": "0",
"isNewFavoriteList": "",
"isNewFriendSeasonRankingList": ""

View File

@@ -1,177 +0,0 @@
import json
import pytz
import time
from sdgb import sdgb_api
from datetime import datetime, timedelta
from settings import regionId, clientId, placeId
from logout import logout
from login import login
def find_map(mapId, user_map_data):
for single in user_map_data:
if single["mapId"] == mapId:
return single
else:
continue
def isNewMapList(mapId, user_map_data):
if ('{"mapId": ' + str(mapId)) in user_map_data:
return 0
else:
return 1
def item(item_data, user_character_list):
item_list = []
character_list = []
for single in item_data:
if single['kind'] == 9:
if ('{"characterId": ' + str(single['id'])) in user_character_list:
pass
else:
data = ({
"characterId":single['id'],
"level":1,
"awakening":0,
"useCount": 0
})
character_list.append(data)
else:
data = ({
"itemKind": single['kind'],
"itemId": single['id'],
"stock": 1,
"isValid": True
})
item_list.append(data)
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
def map(userId):
data = json.dumps({
"userId": int(userId),
"nextIndex": 0,
"maxCount": 600
})
map_result = json.loads(sdgb_api(data, "GetUserMapApi", userId))
return map_result
def character(userId):
data = json.dumps({
"userId": int(userId),
"nextIndex":10000000000,
"maxCount":1000000000
})
character_result = json.loads(sdgb_api(data, "GetUserCharacterApi", userId))
return character_result
def userdata(userId):
data = json.dumps({
"userId": int(userId)
})
userdata_result = json.loads(sdgb_api(data, "GetUserDataApi", userId))
return userdata_result
def charge(userId):
data = json.dumps({
"userId": userId,
})
charge_result = json.loads(sdgb_api(data, "GetUserChargeApi", userId))
return charge_result
def get_ticket(userId):
data = json.dumps({
"userId": userId,
"userCharge": {
"chargeId": 6,
"stock": 1,
"purchaseDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S.0"),
"validDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1) + timedelta(days=90)).replace(hour=4, minute=0, second=0).strftime("%Y-%m-%d %H:%M:%S")
},
"userChargelog": {
"chargeId": 6,
"price": 4,
"purchaseDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S.0"),
"placeId": placeId,
"regionId": regionId,
"clientId": clientId
}
})
ticket_result = json.loads(sdgb_api(data, "UpsertUserChargelogApi", userId))
return ticket_result

View File

@@ -1,4 +1,4 @@
httpx
requests
pycryptodome
pytz
flask

22
sdgb.py
View File

@@ -3,7 +3,7 @@ import zlib
import pytz
import base64
import hashlib
import httpx
import requests
from datetime import datetime
from Crypto.Cipher import AES
@@ -29,6 +29,7 @@ class aes_pkcs7(object):
def decrypt(self, content):
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
#content = base64.b64decode(content)
return cipher.decrypt(content)
text = cipher.decrypt(content).decode('utf-8')
return self.pkcs7unpadding(text)
@@ -55,10 +56,9 @@ def sdgb_api(data, useApi, userId):
data = data
data_enc = aes.encrypt(data)
data_def = zlib.compress(data_enc)
requests.packages.urllib3.disable_warnings()
endpoint = "https://maimai-gm.wahlap.com:42081/Maimai2Servlet/"
r = httpx.post(
endpoint + get_hash_api(useApi),
headers = {
r = requests.post(endpoint + get_hash_api(useApi), headers={
"User-Agent": "%s#%d"%(get_hash_api(useApi), userId),
"Content-Type": "application/json",
"Mai-Encoding": "1.40",
@@ -66,15 +66,16 @@ def sdgb_api(data, useApi, userId):
"Charset": "UTF-8",
"Content-Encoding": "deflate",
"Expect": "100-continue"
},
data = data_def
)
}, data = data_def,verify=False)
resp_def = r.content
try:
resp_enc = zlib.decompress(resp_def)
#print(resp_enc)
except:
resp_enc = resp_def
#print("skipped")
#print(resp_enc)
return unpad(aes.decrypt(resp_enc), 16).decode()
def qr_api(qr_code):
@@ -95,10 +96,7 @@ def qr_api(qr_code):
"Host": "ai.sys-all.cn",
"User-Agent": "WC_AIME_LIB"
}
res = httpx.post(
"http://ai.sys-allnet.cn/wc_aime/api/get_data",
data = json.dumps(param, separators=(',', ':')),
headers = headers
)
res = requests.post("http://ai.sys-allnet.cn/wc_aime/api/get_data", data=json.dumps(param, separators=(',', ':')), headers=headers)
# print(param) # debug打印param数据
assert res.status_code == 200, "网络错误"
return json.loads(res.content)

43
ticket.py Normal file
View File

@@ -0,0 +1,43 @@
import json
import pytz
import time
from sdgb import sdgb_api
from datetime import datetime, timedelta
from settings import regionId
from settings import clientId
from settings import placeId
from logout import logout
from login import login
def get_ticket(userId):
data = json.dumps({
"userId": userId,
"userCharge": {
"chargeId": 6,
"stock": 1,
"purchaseDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S.0"),
"validDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1) + timedelta(days=90)).replace(hour=4, minute=0, second=0).strftime("%Y-%m-%d %H:%M:%S")
},
"userChargelog": {
"chargeId": 6,
"price": 4,
"purchaseDate": (datetime.now(pytz.timezone('Asia/Shanghai')) - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S.0"),
"placeId": placeId,
"regionId": regionId,
"clientId": clientId
}
})
ticket_result = json.loads(sdgb_api(data, "UpsertUserChargelogApi", userId))
return ticket_result
if __name__ == "__main__":
timestamp = int(time.time())
print(timestamp)
print(login(timestamp))
print(get_ticket())
print(logout(timestamp))

View File

@@ -6,7 +6,12 @@ import random
from sdgb import sdgb_api
from datetime import datetime, timedelta
from settings import music_data, regionId, regionName, clientId, placeId, placeName
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
@@ -506,17 +511,6 @@ def music(userId):
user_charge = json.loads(sdgb_api(data, "GetUserChargeApi", userId))
isNew = "0"
try:
for item in user_music['userMusicList'][0]['userMusicDetailList']:
if item['musicId'] == musicId and item['level'] == level:
isNew = "1"
break
else:
continue
except:
pass
# UserAll
data = json.dumps({
@@ -665,7 +659,7 @@ def music(userId):
"isNewMapList": "",
"isNewLoginBonusList": "",
"isNewItemList": "1" * len(music_item()),
"isNewMusicDetailList": isNew,
"isNewMusicDetailList": "1",
"isNewCourseList": "0",
"isNewFavoriteList": "",
"isNewFriendSeasonRankingList": ""

12
userdata.py Normal file
View File

@@ -0,0 +1,12 @@
import json
from sdgb import sdgb_api
def userdata(userId):
data = json.dumps({
"userId": int(userId)
})
userdata_result = json.loads(sdgb_api(data, "GetUserDataApi", userId))
return userdata_result