add sdga part

This commit is contained in:
91c0e59d-6161-45ab-8aa4-2371574db28f 2025-01-19 14:13:14 +08:00
parent 47b63c6aa0
commit 5d1fcaeca2
7 changed files with 261 additions and 1 deletions

1
.gitignore vendored
View File

@ -1,5 +1,4 @@
**/__pycache__
**/settings.py
sdga/
evil.py

31
sdga/.settings.py Normal file
View File

@ -0,0 +1,31 @@
# 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.
# UserId 自行获取
userId = 10000000
accessCode = 50000000000000000000
# 上传的乐曲成绩
# 此成绩将覆盖原有成绩
music_data = ({
"musicId": 11588,
"level": 3,
"playCount": 11,
"achievement": 1005627,
"comboStatus": 0,
"syncStatus": 0,
"deluxscoreMax": 2362,
"scoreRank": 13,
"extNum1": 0
})
# 机厅信息
regionId = 114
regionName = "Yau Tsim Mong"
placeId = 6412
placeName = "GOLDEN ERA GAME CENTRE"
clientId = "A63E01E0048"

30
sdga/login.py Normal file
View File

@ -0,0 +1,30 @@
import json
import pytz
from sdgb import sdgb_api
from sdgb import aimedb_api
from datetime import datetime
from settings import userId, accessCode
from settings import regionId
from settings import clientId
from settings import placeId
def login(timestamp):
data = json.dumps({
"userId": userId,
"acsessCode": accessCode,
"regionId": regionId,
"placeId": placeId,
"clientId": clientId,
"dateTime": timestamp,
"isContinue": False,
"genericFlag": 0,
})
login_result = json.loads(sdgb_api(data, "UserLoginApi", userId))
return login_result
if __name__ == "__main__":
print(aimedb_api(accessCode))
print(login(int(input())))

28
sdga/logout.py Normal file
View File

@ -0,0 +1,28 @@
import json
import pytz
from sdgb import sdgb_api
from datetime import datetime
from settings import userId, accessCode
from settings import regionId
from settings import clientId
from settings import placeId
def logout(timestamp):
data = json.dumps({
"userId": int(userId),
"accessCode": int(accessCode),
"regionId": regionId,
"placeId": placeId,
"clientId": clientId,
"dateTime": timestamp,
"type": 1
})
logout_result = json.loads(sdgb_api(data, "UserLogoutApi", userId))
return logout_result
if __name__ == "__main__":
print(logout(int(input())))

18
sdga/preview.py Normal file
View File

@ -0,0 +1,18 @@
import json
from sdgb import sdgb_api
from sdgb import aimedb_api
from settings import userId, accessCode
def preview(userId):
data = json.dumps({
"userId": int(userId)
})
preview_result = sdgb_api(data, "GetUserPreviewApi", userId)
return preview_result
if __name__ == "__main__":
print(aimedb_api(accessCode))
print(preview(userId))

110
sdga/sdgb.py Normal file
View File

@ -0,0 +1,110 @@
import json
import zlib
import pytz
import base64
import hashlib
import requests
from binascii import unhexlify, hexlify
import socket
import re
from datetime import datetime
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
AesKey = "A;mv5YUpHBK3YxTy5KB^[;5]C2AL50Bq"
AesIV = "9FM:sd9xA91X14v]"
ObfuscateParam = "M9aBNKuY"
KeychipID = "A63E-01E00488964"
class aes_pkcs7(object):
def __init__(self, key: str, iv: str):
self.key = key.encode('utf-8')
self.iv = iv.encode('utf-8')
self.mode = AES.MODE_CBC
def encrypt(self, content: bytes) -> bytes:
cipher = AES.new(self.key, self.mode, self.iv)
content_padded = pad(content, AES.block_size)
encrypted_bytes = cipher.encrypt(content_padded)
return encrypted_bytes
def decrypt(self, content):
cipher = AES.new(self.key, self.mode, self.iv)
decrypted_padded = cipher.decrypt(content)
decrypted = unpad(decrypted_padded, AES.block_size)
return decrypted
def pkcs7unpadding(self, text):
length = len(text)
unpadding = ord(text[length - 1])
return text[0:length - unpadding]
def pkcs7padding(self, text):
bs = 16
length = len(text)
bytes_length = len(text.encode('utf-8'))
padding_size = length if (bytes_length == length) else bytes_length
padding = bs - padding_size % bs
padding_text = chr(padding) * padding
return text + padding_text
def get_hash_api(api):
return hashlib.md5((api+"MaimaiExp"+ObfuscateParam).encode()).hexdigest()
def sdgb_api(data, useApi, userId):
aes = aes_pkcs7(AesKey,AesIV)
data = bytes(data, encoding="utf-8")
data_def = zlib.compress(data)
data_enc = aes.encrypt(data_def)
endpoint = "https://mai2exp.sic-rd1.jp:42081/Maimai2Servlet/"
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.51",
"Accept-Encoding": "",
"Charset": "UTF-8",
"Content-Encoding": "deflate",
"Expect": "100-continue"
}, data = data_enc,verify=False)
resp_enc = r.content
try:
resp_def = aes.decrypt(resp_enc)
except:
resp_def = resp_enc
return zlib.decompress(resp_def).decode('utf-8')
def aimedb_api(accessCode):
key = b'Copyright(C)SEGA'
base_hex_stream = "3ea121400f00300000005344474100000c190000413633453031453030343800"
access_code = str(accessCode)
end_stream = "000201020304"
plaintext_hex_stream = base_hex_stream + access_code + end_stream
plaintext = unhexlify(plaintext_hex_stream)
cipher = AES.new(key, AES.MODE_ECB)
encrypted_message = cipher.encrypt(plaintext)
encrypted_hex_stream = hexlify(encrypted_message).decode('utf-8')
server_address = ('aime.naominet.jp', 22345)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect(server_address)
sock.sendall(encrypted_message)
response = sock.recv(1024)
decrypted_response = cipher.decrypt(response)
decrypted_hex_stream = hexlify(decrypted_response).decode('utf-8')
match = re.search(r'[0-9a-f]{64}([0-9a-f]{6})', decrypted_hex_stream)
if match:
six_digit_code = match.group(1)
rearranged_hex = six_digit_code[4:6] + six_digit_code[2:4] + six_digit_code[0:2]
decimal_value = int(rearranged_hex, 16)
return decimal_value

44
sdga/ticket.py Normal file
View File

@ -0,0 +1,44 @@
import json
import pytz
import time
from sdgb import sdgb_api
from datetime import datetime, timedelta
from settings import userId
from settings import regionId
from settings import clientId
from settings import placeId
from logout import logout
from login import login
def get_ticket():
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))