forked from katboi01/JapariBypass
160 lines
7.0 KiB
Python
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) |