1
0
Fork 0
JapariBypass/dmmBypass.py

160 lines
7.0 KiB
Python
Raw Permalink Normal View History

2025-01-24 19:11:57 +08:00
import os
import sys
import wmi
2025-01-24 20:54:25 +08:00
import json
2025-01-24 19:11:57 +08:00
import hashlib
import requests
2025-01-24 20:31:49 +08:00
import dmmUpdater
2025-01-24 19:11:57 +08:00
import subprocess
import urllib.parse
from uuid import getnode
from bs4 import BeautifulSoup
from pypasser import reCaptchaV3
2025-01-24 20:54:25 +08:00
def print_request(url, data : str, headers, cookies_dict):
print("Sending to", url)
vars = {"headers":headers, "cookies":cookies_dict, "data":data}
print(json.dumps(vars, ensure_ascii=False, indent=1))
pass
2025-01-24 19:11:57 +08:00
def get_hash(data):
sha_obj = hashlib.sha256()
sha_obj.update(str(data).encode())
hash_hex = sha_obj.hexdigest()
return hash_hex
def get_mac():
mac = getnode()
return ':'.join(("%012X" % mac)[i:i+2] for i in range(0, 12, 2)).lower()
def get_motherboard():
return wmi.WMI().Win32_BaseBoard()[0].SerialNumber
def retrieve_login_token(session : requests.Session):
try:
print("Retrieving login form")
url = "https://accounts.dmm.com/service/login/password"
2025-01-24 20:54:25 +08:00
print_request(url, "", dict(session.headers), session.cookies.get_dict())
2025-01-24 19:11:57 +08:00
result = session.get(url)
2025-01-24 20:54:25 +08:00
print(result.status_code, result.text)
2025-01-24 20:31:49 +08:00
result.raise_for_status()
2025-01-24 19:11:57 +08:00
page = BeautifulSoup(result.content, 'html.parser')
token = page.find('input', attrs={"name":"token"}).get("value")
return token
except Exception as e:
print("Failed to retrieve login form:", e)
def retrieve_captcha_token():
try:
captcha = reCaptchaV3("https://www.google.com/recaptcha/enterprise/anchor?ar=1&k=6LfZLQEVAAAAAC-8pKwFNuzVoJW4tfUCghBX_7ZE&co=aHR0cHM6Ly9hY2NvdW50cy5kbW0uY29tOjQ0Mw..&hl=ja&v=1Bq_oiMBd4XPUhKDwr0YL1Js&size=invisible")
return captcha
except Exception as e:
print("Failed to solve captcha:", e)
def retrieve_auth_keys(login, password, token, captcha, session : requests.Session):
try:
print("Logging in")
url = "https://accounts.dmm.com/service/login/password/authenticate"
data = f"token={token}&login_id={login}&password={password}&prompt=&device=games-player&recaptchaToken={captcha}"
headers = {"Content-Type": "application/x-www-form-urlencoded"}
2025-01-24 20:54:25 +08:00
print_request(url, data, headers, session.cookies.get_dict())
2025-01-24 19:11:57 +08:00
result = session.post(url, data, headers=headers)
2025-01-24 20:54:25 +08:00
print(result.status_code, result.text)
2025-01-24 20:31:49 +08:00
result.raise_for_status()
2025-01-24 19:11:57 +08:00
cookies = result.cookies.get_dict()
return cookies["login_secure_id"], cookies["login_session_id"]
except Exception as e:
print("Failed to log in:", e)
def retrieve_update_params(game_id, login_secure, login_session, use_proxy):
try:
print("Retrieving update file list")
data = {"product_id":game_id,"game_type":"GCL","game_os":"win"}
headers = {"User-Agent": "DMMGamePlayer5-Win/5.3.12 Electron/32.1.0", "Client-App": "DMMGamePlayer5", "Client-version": "5.3.12", "Content-Type": "application/json"}
cookies = {"login_secure_id":login_secure, "login_session_id":login_session}
url = "https://katworks.sytes.net/KF/Api/DMM/filelist" if use_proxy else "https://apidgp-gameplayer.games.dmm.com/v5/r2/filelist/cl"
2025-01-24 20:54:25 +08:00
print_request(url, data, headers, cookies)
2025-01-24 19:11:57 +08:00
result = requests.post(url, cookies=cookies, headers=headers, json=data)
2025-01-24 20:54:25 +08:00
print(result.status_code, result.text)
2025-01-24 20:31:49 +08:00
result.raise_for_status()
2025-01-24 19:11:57 +08:00
data = result.json()["data"]
game_version = data["latest_version"]
print("Latest version:", game_version)
file_list_url = data["file_list_url"]
file_list_params = data["sign"]
file_list_params = "?" + file_list_params.replace(";", "&").replace("CloudFront-", "")
return file_list_url, file_list_params
except Exception as e:
print("Failed to retrieve update file list:", e)
def retrieve_launch_params(game_id, mac_addr, hdd_serial, motherboard, login_secure, login_session, use_proxy):
try:
print("Retrieving launch arguments")
data = {"product_id":game_id,"game_type":"GCL","game_os":"win","launch_type":"LIB","mac_address":mac_addr,"hdd_serial":hdd_serial,"motherboard":motherboard,"user_os":"win"}
headers = {"User-Agent": "DMMGamePlayer5-Win/5.3.12 Electron/32.1.0", "Client-App": "DMMGamePlayer5", "Client-version": "5.3.12", "Content-Type": "application/json"}
cookies = {"login_secure_id":login_secure, "login_session_id":login_session}
url = "https://katworks.sytes.net/KF/Api/DMM/launch" if use_proxy else "https://apidgp-gameplayer.games.dmm.com/v5/r2/launch/cl"
2025-01-24 20:54:25 +08:00
print_request(url, data, headers, cookies)
2025-01-24 19:11:57 +08:00
result = requests.post(url, cookies=cookies, headers=headers, json=data)
2025-01-24 20:54:25 +08:00
print(result.status_code, result.text)
2025-01-24 20:31:49 +08:00
result.raise_for_status()
2025-01-24 19:11:57 +08:00
data = result.json()["data"]
return data["execute_args"]
except Exception as e:
print("Failed to retrieve launch arguments:", e)
def main(args):
if len(args) != 7:
print("Usage:",
"\tpython dmmBypass.py game_id game_path email password update_game use_proxy",
"\t- game_id: DMM code name of the game",
"\t- game_path: full path to the game .exe. Wrap in \" if there are spaces in the path",
"\t- email, password: dmm credentials",
"\t- update_game: \"true\" to check for game update before launching",
"\t- use_proxy: \"true\" to send required request through Katboi VPN. Otherwise use your own VPN",
"\texample: python dmmBypass.py kfp2g \"D:\Games\KFP2G\けもフレ3.exe\" kat@email.com abc123 true", sep="\n")
return
game_id = args[1]
exe_location = args[2]
login = urllib.parse.quote_plus(args[3])
password = urllib.parse.quote_plus(args[4])
update_game = args[5].lower() == "true"
use_proxy = args[6].lower() == "true"
mac_addr = get_mac()
hdd_serial = get_hash('')
motherboard = get_hash(get_motherboard())
with requests.Session() as session:
token = retrieve_login_token(session)
captcha = retrieve_captcha_token()
if token == None or captcha == None:
return
login_secure, login_session = retrieve_auth_keys(login, password, token, captcha, session)
if not use_proxy: input("Enable VPN now and press Enter")
if update_game:
file_list_url, file_access_params = retrieve_update_params(game_id, login_secure, login_session, use_proxy)
if file_list_url == None or file_access_params == None:
return
execute_args = retrieve_launch_params(game_id, mac_addr, hdd_serial, motherboard, login_secure, login_session, use_proxy)
2025-01-24 20:31:49 +08:00
if execute_args == None:
return
2025-01-24 19:11:57 +08:00
if not use_proxy: input("Disable VPN now and press Enter")
2025-01-24 20:31:49 +08:00
if update_game:
dmmUpdater.update_game(os.path.dirname(exe_location), file_list_url, file_access_params)
2025-01-24 19:11:57 +08:00
print("Starting game")
args = [exe_location] + execute_args.split()
print(args)
subprocess.Popen(args, start_new_session=True)
input("Done. Press enter to exit")
args = sys.argv
main(args)