JapariBypass/dmmBypass.py

160 lines
7.0 KiB
Python

import os
import sys
import wmi
import json
import hashlib
import requests
import dmmUpdater
import subprocess
import urllib.parse
from uuid import getnode
from bs4 import BeautifulSoup
from pypasser import reCaptchaV3
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
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"
print_request(url, "", dict(session.headers), session.cookies.get_dict())
result = session.get(url)
print(result.status_code, result.text)
result.raise_for_status()
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"}
print_request(url, data, headers, session.cookies.get_dict())
result = session.post(url, data, headers=headers)
print(result.status_code, result.text)
result.raise_for_status()
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"
print_request(url, data, headers, cookies)
result = requests.post(url, cookies=cookies, headers=headers, json=data)
print(result.status_code, result.text)
result.raise_for_status()
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"
print_request(url, data, headers, cookies)
result = requests.post(url, cookies=cookies, headers=headers, json=data)
print(result.status_code, result.text)
result.raise_for_status()
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)
if execute_args == None:
return
if not use_proxy: input("Disable VPN now and press Enter")
if update_game:
dmmUpdater.update_game(os.path.dirname(exe_location), file_list_url, file_access_params)
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)