forked from Fragrance/eaquira
add sdga part
This commit is contained in:
parent
47b63c6aa0
commit
5d1fcaeca2
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
**/__pycache__
|
**/__pycache__
|
||||||
**/settings.py
|
**/settings.py
|
||||||
|
|
||||||
sdga/
|
|
||||||
evil.py
|
evil.py
|
31
sdga/.settings.py
Normal file
31
sdga/.settings.py
Normal 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
30
sdga/login.py
Normal 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
28
sdga/logout.py
Normal 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
18
sdga/preview.py
Normal 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
110
sdga/sdgb.py
Normal 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
44
sdga/ticket.py
Normal 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))
|
Loading…
x
Reference in New Issue
Block a user