Compare commits

8 Commits
19 changed files with 980 additions and 597 deletions

No files matched your search

+2
View File
@@ -1,3 +1,5 @@
**/__pycache__ **/__pycache__
**/settings.py **/settings.py
**/.DS_Store **/.DS_Store
*.egg-info
+1
View File
@@ -0,0 +1 @@
3.14
+13 -7
View File
@@ -1,23 +1,29 @@
import asyncio import asyncio
from chime import * import httpx
from sdgb import MaimaiClient from sdgb import MaimaiClient
from settings import * from sdgb.chime import qr_api
from sdgb.settings import clientId, qrCode
maimai = MaimaiClient() maimai = MaimaiClient()
userId = qr_api(qrCode)['userID'] qrResp = qr_api(qrCode)
token = qr_api(qrCode)['token'] userId = qrResp["userID"]
token = qrResp["token"]
async def run_workflow(maimai):
async def run_workflow(maimai: MaimaiClient):
async with httpx.AsyncClient(verify=False) as client: async with httpx.AsyncClient(verify=False) as client:
data = { data = {
"userId": userId, "userId": userId,
"segaIdAuthKey":"", "segaIdAuthKey": "",
"token": token, "token": token,
"clientId": clientId "clientId": clientId,
} }
result = await maimai.call_api(client, "GetUserPreviewApi", data, userId) result = await maimai.call_api(client, "GetUserPreviewApi", data, userId)
print(result)
# 执行入口 # 执行入口
if __name__ == "__main__": if __name__ == "__main__":
+17 -17
View File
@@ -1,46 +1,45 @@
from urllib.parse import unquote
import httpx import httpx
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Util.Padding import pad from Crypto.Util.Padding import pad
from urllib.parse import unquote
def enc(key, iv, data): def enc(key, iv, data):
cipher = AES.new(key, AES.MODE_CBC, iv) cipher = AES.new(key, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(data) encrypted = cipher.encrypt(data)
return encrypted return encrypted
def dec(key, iv, data): def dec(key, iv, data):
de_cipher = AES.new(key, AES.MODE_CBC, iv) de_cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = de_cipher.decrypt(data) decrypted = de_cipher.decrypt(data)
return decrypted return decrypted
def hello(): def hello():
key = bytes([ 47, 63, 106, 111, 43, 34, 76, 38, 92, 67, 114, 57, 40, 61, 107, 71 ]) key = bytes([47, 63, 106, 111, 43, 34, 76, 38, 92, 67, 114, 57, 40, 61, 107, 71])
#key = bytes([ 45, 97, 53, 55, 85, 88, 52, 121, 57, 47, 104, 40, 73, 109, 65, 81 ]) # key = bytes([ 45, 97, 53, 55, 85, 88, 52, 121, 57, 47, 104, 40, 73, 109, 65, 81 ])
iv = bytes.fromhex('00000000000000000000000000000000') iv = bytes.fromhex("00000000000000000000000000000000")
ua = 'SDGB;Windows/Lite' ua = "SDGB;Windows/Lite"
#ua = 'SDHJ;Windows/Lite' # ua = 'SDHJ;Windows/Lite'
# 构建 payload # 构建 payload
content = bytes([0] * 16) + b'title_id=SDGB&title_ver=1.52&client_id=A63E01E6149' content = bytes([0] * 16) + b"title_id=SDGB&title_ver=1.52&client_id=A63E01E6149"
print(f"Content: {content}") print(f"Content: {content}")
header = bytes.fromhex('00000000000000000000000000000000') header = bytes.fromhex("00000000000000000000000000000000")
bytes_data = pad(header + content, 16) bytes_data = pad(header + content, 16)
encrypted = enc(key, iv, bytes_data) encrypted = enc(key, iv, bytes_data)
# --- HTTPX 修改部分 --- # --- HTTPX 修改部分 ---
headers = { headers = {"User-Agent": ua, "Pragma": "DFI"}
'User-Agent': ua,
'Pragma': 'DFI'
}
try: try:
# 发送 POST 请求 # 发送 POST 请求
# urllib3 的 body 参数在 httpx 中对应 content (用于二进制数据) # urllib3 的 body 参数在 httpx 中对应 content (用于二进制数据)
r = httpx.post( r = httpx.post(
'http://at.sys-allnet.cn/net/initialize', "https://at.sys-allnet.cn/net/initialize", content=encrypted, headers=headers
content=encrypted,
headers=headers
) )
# 检查响应状态码 (可选,但在 httpx 中推荐) # 检查响应状态码 (可选,但在 httpx 中推荐)
@@ -54,7 +53,7 @@ def hello():
if len(resp_data) >= 16: if len(resp_data) >= 16:
decrypted = dec(key, resp_data[:16], resp_data) decrypted = dec(key, resp_data[:16], resp_data)
decrypted_bytes = decrypted[16:] decrypted_bytes = decrypted[16:]
decrypted_str = unquote(decrypted_bytes.decode('UTF-8'), 'utf-8') decrypted_str = unquote(decrypted_bytes.decode("UTF-8"), "utf-8")
print(f"Decrypted: {decrypted_str}") print(f"Decrypted: {decrypted_str}")
else: else:
print("Response data too short.") print("Response data too short.")
@@ -62,5 +61,6 @@ def hello():
except httpx.RequestError as e: except httpx.RequestError as e:
print(f"An error occurred while requesting: {e}") print(f"An error occurred while requesting: {e}")
if __name__ == '__main__':
if __name__ == "__main__":
hello() hello()
+154
View File
@@ -0,0 +1,154 @@
import json
import asyncio
import logging
from typing import Callable
import httpx
from sdgb import MaimaiClient
from sdgb.settings import userId, musicData
from sdgb.payload import (
requestData_UserLogin,
requestData_UserLogout,
requestData_UserPreview,
requestData_UserData,
UserAll_payload,
)
maimai = MaimaiClient()
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
def music_user_all_patcher(
musicId: int,
unlock_music: bool = True,
unlock_master: bool = False,
unlock_remaster: bool = False,
) -> Callable[[dict], None]:
userItemList = []
if unlock_music:
userItemList.append(
0,
{
"itemKind": 5, # MUSIC
"itemId": musicId,
"stock": 1,
"isValid": True,
},
)
if unlock_master:
userItemList.append(
0,
{
"itemKind": 6,
"itemId": musicId, # MASTER
"stock": 1,
"isValid": True,
},
)
if unlock_remaster:
userItemList.append(
{
"itemKind": 7,
"itemId": musicId, # RE: MASTER
"stock": 1,
"isValid": True,
}
)
def merge(d: dict):
d.update(
{
"userMusicDetailList": [musicData],
"isNewMusicDetailList": "1",
"userItemList": userItemList,
"isNewItemList": len(userItemList) * "1",
}
)
return merge
async def run_workflow(
self: MaimaiClient,
user_all_patcher: Callable[[dict], None],
):
async with httpx.AsyncClient(verify=False) as client:
# Preview 探测
PreviewResponse = json.loads(
await self.call_api(
client, "GetUserPreviewApi", requestData_UserPreview, userId
)
)
if PreviewResponse["isLogin"]:
logger.error("已在他处登录。")
return
# UserLogin
LoginResponse = json.loads(
await self.call_api(client, "UserLoginApi", requestData_UserLogin, userId)
)
if LoginResponse["returnCode"] != 1:
logger.error("login failed.")
return
loginId = LoginResponse["loginId"]
loginDate = LoginResponse["lastLoginDate"]
# UserData 等
tasks = [
self.call_api(client, "GetUserDataApi", requestData_UserData, userId),
self.call_api(client, "GetUserExtendApi", requestData_UserData, userId),
self.call_api(client, "GetUserOptionApi", requestData_UserData, userId),
self.call_api(client, "GetUserRatingApi", requestData_UserData, userId),
self.call_api(client, "GetUserChargeApi", requestData_UserData, userId),
self.call_api(client, "GetUserActivityApi", requestData_UserData, userId),
self.call_api(
client, "GetUserMissionDataApi", requestData_UserData, userId
),
]
GeneralUserInfo = await asyncio.gather(*tasks)
await asyncio.sleep(60) # 模拟游戏时间
# UserAll
requestData_UserAll = UserAll_payload(
loginId, loginDate, musicData, GeneralUserInfo
)
user_all_patcher(requestData_UserAll)
await self.call_api(client, "UpsertUserAllApi", requestData_UserAll, userId)
# UserLogout
await self.call_api(client, "UserLogoutApi", requestData_UserLogout, userId)
if __name__ == "__main__":
patcher = music_user_all_patcher(
musicId=834,
unlock_music=False,
# unlock_master=True,
unlock_remaster=True,
)
asyncio.run(
run_workflow(
maimai,
user_all_patcher=patcher,
)
)
+33 -18
View File
@@ -1,43 +1,53 @@
import json import json
import asyncio import asyncio
import httpx
import time
import logging import logging
from sdgb import MaimaiClient
from settings import userId, musicData import httpx
from chime import *
from payload import * from sdgb import MaimaiClient
from sdgb.settings import userId, musicData
from sdgb.payload import (
requestData_UserLogin,
requestData_UserLogout,
requestData_UserPreview,
requestData_UserData,
UserAll_payload,
)
maimai = MaimaiClient() maimai = MaimaiClient()
logging.basicConfig( logging.basicConfig(
level=logging.INFO, level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
format='%(asctime)s - %(levelname)s - %(message)s'
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
async def run_workflow(self):
async def run_workflow(self: MaimaiClient):
async with httpx.AsyncClient(verify=False) as client: async with httpx.AsyncClient(verify=False) as client:
# Preview 探测 # Preview 探测
PreviewResponse = json.loads(await self.call_api(client, "GetUserPreviewApi", requestData_UserPreview, userId)) PreviewResponse = json.loads(
if PreviewResponse["isLogin"] == True: await self.call_api(
client, "GetUserPreviewApi", requestData_UserPreview, userId
)
)
if PreviewResponse["isLogin"]:
logger.error("已在他处登录。") logger.error("已在他处登录。")
return return
# UserLogin # UserLogin
LoginResponse = json.loads(await self.call_api(client, "UserLoginApi", requestData_UserLogin, userId)) LoginResponse = json.loads(
await self.call_api(client, "UserLoginApi", requestData_UserLogin, userId)
)
if LoginResponse["returnCode"] != 1: if LoginResponse["returnCode"] != 1:
logger.error("login failed.") logger.error("login failed.")
return return
loginId = LoginResponse['loginId'] loginId = LoginResponse["loginId"]
loginDate = LoginResponse['lastLoginDate'] loginDate = LoginResponse["lastLoginDate"]
# UserData 等 # UserData 等
@@ -48,15 +58,19 @@ async def run_workflow(self):
self.call_api(client, "GetUserRatingApi", requestData_UserData, userId), self.call_api(client, "GetUserRatingApi", requestData_UserData, userId),
self.call_api(client, "GetUserChargeApi", requestData_UserData, userId), self.call_api(client, "GetUserChargeApi", requestData_UserData, userId),
self.call_api(client, "GetUserActivityApi", requestData_UserData, userId), self.call_api(client, "GetUserActivityApi", requestData_UserData, userId),
self.call_api(client, "GetUserMissionDataApi", requestData_UserData, userId), self.call_api(
client, "GetUserMissionDataApi", requestData_UserData, userId
),
] ]
GeneralUserInfo = await asyncio.gather(*tasks) GeneralUserInfo = await asyncio.gather(*tasks)
await asyncio.sleep(60) # 模拟游戏时间 await asyncio.sleep(60) # 模拟游戏时间
# UserAll # UserAll
requestData_UserAll = UserAll_payload(loginId, loginDate, musicData, GeneralUserInfo) requestData_UserAll = UserAll_payload(
loginId, loginDate, musicData, GeneralUserInfo
)
await self.call_api(client, "UpsertUserAllApi", requestData_UserAll, userId) await self.call_api(client, "UpsertUserAllApi", requestData_UserAll, userId)
@@ -64,5 +78,6 @@ async def run_workflow(self):
await self.call_api(client, "UserLogoutApi", requestData_UserLogout, userId) await self.call_api(client, "UserLogoutApi", requestData_UserLogout, userId)
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(run_workflow(maimai)) asyncio.run(run_workflow(maimai))
@@ -1,12 +1,19 @@
import json
import asyncio import asyncio
import httpx import httpx
from sdgb import MaimaiClient from sdgb import MaimaiClient
from settings import * from sdgb.settings import (
userId,
regionId,
placeId,
clientId,
)
maimai = MaimaiClient() maimai = MaimaiClient()
async def run_workflow(maimai):
async def run_workflow(maimai: MaimaiClient):
async with httpx.AsyncClient(verify=False) as client: async with httpx.AsyncClient(verify=False) as client:
data = { data = {
"userId": userId, "userId": userId,
@@ -15,9 +22,11 @@ async def run_workflow(maimai):
"placeId": placeId, "placeId": placeId,
"clientId": clientId, "clientId": clientId,
"dateTime": 1767000000, "dateTime": 1767000000,
"type": 4 "type": 4,
} }
await maimai.call_api(client, "UserLogoutApi", data, userId) await maimai.call_api(client, "UserLogoutApi", data, userId)
# 执行入口 # 执行入口
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(run_workflow(maimai)) asyncio.run(run_workflow(maimai))
View File
File renamed without changes.
Internal Server Error - 𝙵𝚛𝚊𝚐𝚛𝚊𝚗𝚌𝚎
500 Internal Server Error

An error occurred:

An error occurred