forked from Fragrance/eaquira
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
559cc98083 | ||
|
|
12cdd344e1 | ||
|
|
6c0d9336d2 | ||
|
|
12fc3f881d | ||
|
|
154ff02d73 | ||
|
|
f167858e0b |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
|||||||
**/__pycache__
|
**/__pycache__
|
||||||
**/settings.py
|
**/settings.py
|
||||||
|
**/.DS_Store
|
||||||
evil.py
|
evil.py
|
||||||
12
README.md
12
README.md
@@ -1,21 +1,25 @@
|
|||||||
# Eaquira
|
# Eaquira
|
||||||
|
|
||||||
A python 3 project to send game playlog to「舞萌DX」.
|
A python 3 project which is used to post title server of 「舞萌 DX」&「maimai DX International」
|
||||||
###### dev of SDGA was suspended
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Info
|
## Info
|
||||||
|
|
||||||
__Eaquira__ is a fork of `sdgb-some-api` main branch. Thanks to leakers.
|
__Eaquira__ is a fork of `sdgb-some-api` main branch. Thanks to leakers.
|
||||||
|
|
||||||
The whole project was powered by Python 3, same as the origin. EVIL Python XD
|
|
||||||
|
|
||||||
## SDGA Usage
|
## SDGA Usage
|
||||||
|
|
||||||
|
特别说明:国际服(下称 SDGA)部分代码仅提供参考,并不具备实用价值。
|
||||||
|
- 世嘉对 SDGA 的维护尚可,对于发送请求的 IP 有较为严格的要求。对于滥发请求的 IP 等会快速封禁。
|
||||||
|
- 由于 AiMeDB 已禁用对 FeliCa 卡类型老旧接口的支持(主要是 FeliCa Lookup 的部分,将 IDm 查表转换为 accessCode 相关),大部分使用蓝白卡(判断方式:卡号 5 开头)的玩家无法通过命令行模拟的方式实现上号,必须要通过购买第三方读卡器才能实现刷卡上号。
|
||||||
|
|
||||||
still in progress...
|
still in progress...
|
||||||
|
|
||||||
## SDGB Usage
|
## SDGB Usage
|
||||||
|
|
||||||
|
SDGB 目前仍然停留在老旧的 1.40 版本支持(即 DX 2024),仓库中现有代码并不支持最新版本。目前有计划在 Esquira 2.0 重构发送请求的架构(大饼)。
|
||||||
|
|
||||||
- _authlite.py_ Get latest opt file of SDGB.
|
- _authlite.py_ Get latest opt file of SDGB.
|
||||||
- _login.py_ ```UserLoginApi```
|
- _login.py_ ```UserLoginApi```
|
||||||
- _logout.py_ ```UserLogoutApi```
|
- _logout.py_ ```UserLogoutApi```
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import httpx
|
|||||||
|
|
||||||
def DownloadOrder():
|
def DownloadOrder():
|
||||||
ua = 'Windows/3.0'
|
ua = 'Windows/3.0'
|
||||||
content = b'game_id=SDGA&ver=1.50&serial=A63E01E0048&encode=UTF-8'
|
content = b'game_id=SDGA&ver=1.55&serial=A63E01E0048&encode=UTF-8'
|
||||||
body = base64.b64encode(zlib.compress(content))
|
body = base64.b64encode(zlib.compress(content))
|
||||||
r = httpx.post(
|
r = httpx.post(
|
||||||
'http://naominet.jp/sys/servlet/DownloadOrder',
|
'http://naominet.jp/sys/servlet/DownloadOrder',
|
||||||
@@ -14,7 +14,8 @@ def DownloadOrder():
|
|||||||
'Pragma': 'DFI',
|
'Pragma': 'DFI',
|
||||||
'User-Agent': ua,
|
'User-Agent': ua,
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
}
|
},
|
||||||
|
proxy = 'http://127.0.0.1:6152'
|
||||||
)
|
)
|
||||||
resp_data = r.content
|
resp_data = r.content
|
||||||
response = zlib.decompress(base64.b64decode(resp_data)).decode()
|
response = zlib.decompress(base64.b64decode(resp_data)).decode()
|
||||||
@@ -27,7 +28,7 @@ def uri():
|
|||||||
r = httpx.get(
|
r = httpx.get(
|
||||||
endpoint,
|
endpoint,
|
||||||
headers = {
|
headers = {
|
||||||
'User-Agent': 'A63E01E0000',
|
'User-Agent': 'A63E01E0048',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
resp_data = r.content
|
resp_data = r.content
|
||||||
|
|||||||
67
sdga/sdgb.py
67
sdga/sdgb.py
@@ -12,9 +12,14 @@ from datetime import datetime
|
|||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
from Crypto.Util.Padding import pad, unpad
|
from Crypto.Util.Padding import pad, unpad
|
||||||
|
|
||||||
AesKey = "A;mv5YUpHBK3YxTy5KB^[;5]C2AL50Bq"
|
# Key 1.50
|
||||||
AesIV = "9FM:sd9xA91X14v]"
|
# AesKey = "A;mv5YUpHBK3YxTy5KB^[;5]C2AL50Bq"
|
||||||
ObfuscateParam = "M9aBNKuY"
|
# AesIV = "9FM:sd9xA91X14v]"
|
||||||
|
# ObfuscateParam = "M9aBNKuY"
|
||||||
|
|
||||||
|
AesKey = "Z6@9UJ@U79^4TH7H^7Pd25Z@;YiIZS9Z"
|
||||||
|
AesIV = "f@FTcYHXVGYLM5UK"
|
||||||
|
ObfuscateParam = "X7eBJcEU"
|
||||||
|
|
||||||
class aes_pkcs7(object):
|
class aes_pkcs7(object):
|
||||||
def __init__(self, key: str, iv: str):
|
def __init__(self, key: str, iv: str):
|
||||||
@@ -62,13 +67,14 @@ def sdgb_api(data, useApi, userId):
|
|||||||
headers = {
|
headers = {
|
||||||
"User-Agent": "%s#%d"%(get_hash_api(useApi), userId),
|
"User-Agent": "%s#%d"%(get_hash_api(useApi), userId),
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Mai-Encoding": "1.51",
|
"Mai-Encoding": "1.55",
|
||||||
"Accept-Encoding": "",
|
"Accept-Encoding": "",
|
||||||
"Charset": "UTF-8",
|
"Charset": "UTF-8",
|
||||||
"Content-Encoding": "deflate",
|
"Content-Encoding": "deflate"
|
||||||
"Expect": "100-continue"
|
|
||||||
},
|
},
|
||||||
data = data_enc
|
content = data_enc,
|
||||||
|
timeout = 10000,
|
||||||
|
proxy = "http://127.0.0.1:6152"
|
||||||
)
|
)
|
||||||
resp_enc = r.content
|
resp_enc = r.content
|
||||||
try:
|
try:
|
||||||
@@ -158,3 +164,50 @@ def aimedb_api(accessCode):
|
|||||||
|
|
||||||
decimal_value = int(rearranged_hex, 16)
|
decimal_value = int(rearranged_hex, 16)
|
||||||
return decimal_value
|
return decimal_value
|
||||||
|
|
||||||
|
def mifare(accessCode, serial):
|
||||||
|
key = b'Copyright(C)SEGA'
|
||||||
|
# https://sega.bsnk.me/allnet/aimedb/common/
|
||||||
|
magic = "3ea1"
|
||||||
|
version = "2140"
|
||||||
|
command_id = "0f00" # ID = 15
|
||||||
|
length = "3000" # 48
|
||||||
|
gameId = "534447410000" # SDGA
|
||||||
|
storeId = "bc310000"
|
||||||
|
keychip_ID = "413633453031453032363400" # A63E01E0264
|
||||||
|
header = magic + version + command_id + length + "0000" + gameId + storeId + keychip_ID
|
||||||
|
|
||||||
|
access_code = str(accessCode)
|
||||||
|
serial = str(serial)
|
||||||
|
company_code = "00"
|
||||||
|
firmware_version = "02"
|
||||||
|
|
||||||
|
|
||||||
|
plaintext_hex_stream = header + access_code + company_code + firmware_version + serial
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ def hello():
|
|||||||
iv = bytes.fromhex('00000000000000000000000000000000')
|
iv = bytes.fromhex('00000000000000000000000000000000')
|
||||||
ua = 'SDGB;Windows/Lite'
|
ua = 'SDGB;Windows/Lite'
|
||||||
#ua = 'SDHJ;Windows/Lite'
|
#ua = 'SDHJ;Windows/Lite'
|
||||||
content = bytes([0] * 16) + b'title_id=SDGB&title_ver=1.41&client_id=A63E01C2805&token=205648745'
|
content = bytes([0] * 16) + b'title_id=SDGB&title_ver=1.50&client_id=A63E01C2805&token=205648745'
|
||||||
#content = bytes([0] * 16) + b'title_id=SDHJ&title_ver=1.11&client_id=A63E01E1326&token=205648745'
|
#content = bytes([0] * 16) + b'title_id=SDHJ&title_ver=1.11&client_id=A63E01E1326&token=205648745'
|
||||||
header = bytes.fromhex('00000000000000000000000000000000')
|
header = bytes.fromhex('00000000000000000000000000000000')
|
||||||
bytes_data = pad(header + content, 16)
|
bytes_data = pad(header + content, 16)
|
||||||
|
|||||||
@@ -347,28 +347,6 @@ def music():
|
|||||||
"deluxscoreMax": deluxscoreMax,
|
"deluxscoreMax": deluxscoreMax,
|
||||||
"scoreRank": scoreRank,
|
"scoreRank": scoreRank,
|
||||||
"extNum1": extNum1
|
"extNum1": extNum1
|
||||||
},
|
|
||||||
{
|
|
||||||
"musicId": music_details['userMusicList'][0]['userMusicDetailList'][0]['musicId'],
|
|
||||||
"level": music_details['userMusicList'][0]['userMusicDetailList'][0]['level'],
|
|
||||||
"playCount": music_details['userMusicList'][0]['userMusicDetailList'][0]['playCount'],
|
|
||||||
"achievement": music_details['userMusicList'][0]['userMusicDetailList'][0]['achievement'],
|
|
||||||
"comboStatus": music_details['userMusicList'][0]['userMusicDetailList'][0]['comboStatus'],
|
|
||||||
"syncStatus": music_details['userMusicList'][0]['userMusicDetailList'][0]['syncStatus'],
|
|
||||||
"deluxscoreMax": music_details['userMusicList'][0]['userMusicDetailList'][0]['deluxscoreMax'],
|
|
||||||
"scoreRank": music_details['userMusicList'][0]['userMusicDetailList'][0]['scoreRank'],
|
|
||||||
"extNum1": music_details['userMusicList'][0]['userMusicDetailList'][0]['extNum1']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"musicId": music_details['userMusicList'][1]['userMusicDetailList'][0]['musicId'],
|
|
||||||
"level": music_details['userMusicList'][1]['userMusicDetailList'][0]['level'],
|
|
||||||
"playCount": music_details['userMusicList'][1]['userMusicDetailList'][0]['playCount'],
|
|
||||||
"achievement": music_details['userMusicList'][1]['userMusicDetailList'][0]['achievement'],
|
|
||||||
"comboStatus": music_details['userMusicList'][1]['userMusicDetailList'][0]['comboStatus'],
|
|
||||||
"syncStatus": music_details['userMusicList'][1]['userMusicDetailList'][0]['syncStatus'],
|
|
||||||
"deluxscoreMax": music_details['userMusicList'][1]['userMusicDetailList'][0]['deluxscoreMax'],
|
|
||||||
"scoreRank": music_details['userMusicList'][1]['userMusicDetailList'][0]['scoreRank'],
|
|
||||||
"extNum1": music_details['userMusicList'][1]['userMusicDetailList'][0]['extNum1']
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"userCourseList": [],
|
"userCourseList": [],
|
||||||
@@ -384,7 +362,7 @@ def music():
|
|||||||
"playMode": 0,
|
"playMode": 0,
|
||||||
"useTicketId": -1,
|
"useTicketId": -1,
|
||||||
"playCredit": 1,
|
"playCredit": 1,
|
||||||
"playTrack": 3,
|
"playTrack": 1,
|
||||||
"clientId": clientId,
|
"clientId": clientId,
|
||||||
"isPlayTutorial": False,
|
"isPlayTutorial": False,
|
||||||
"isEventMode": False,
|
"isEventMode": False,
|
||||||
|
|||||||
Reference in New Issue
Block a user