1
0
Fork 0
JapariBypass/dmmBypass.py

159 lines
6.9 KiB
Python
Raw Normal View History

2025-01-24 19:11:57 +08:00
import os
import sys
2025-01-25 07:55:47 +08:00
import json
2025-01-24 19:11:57 +08:00
import hashlib
2025-01-25 07:55:47 +08:00
import argparse
2025-01-24 19:11:57 +08:00
import requests
import subprocess
import urllib.parse
from uuid import getnode
2025-01-25 07:55:47 +08:00
parser = argparse.ArgumentParser(description='DMM bypass script')
parser.add_argument('-g', '--game', type=str, help="DMM code name of the game", default="kfp2g")
parser.add_argument('-u', '--update', help="Check for game update before launching", action='store_true')
args = parser.parse_args()
config_name = args.game + '.cfg'
if not os.path.exists(config_name):
2025-01-25 08:23:27 +08:00
subprocess.check_call([sys.executable, "-m", "pip", "install", "requests", "beautifulsoup4", "PyPasser"])
2025-01-25 07:55:47 +08:00
config = {
"game_id" : args.game,
"file_path" : input('Enter full file path to KF3 .exe: ').strip('\"'),
"dmm_login" : input('DMM Login (email): '),
"dmm_password" : input('DMM Password: '),
"use_proxy" : input('Your login tokens will be sent through my VPN machine.\nIs that okay? (yes/no): ').lower() == "yes"
}
with open(config_name, 'wt', encoding="utf-8") as f:
json.dump(config, f, indent=1, ensure_ascii=False)
else:
with open(config_name, "rt", encoding="utf-8") as f:
config = json.load(f)
print(f'Loaded settings from {config_name}')
config["update_game"] = args.update
import wmi
import dmmUpdater
2025-01-24 19:11:57 +08:00
from bs4 import BeautifulSoup
from pypasser import reCaptchaV3
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 retrieve_login_token(session : requests.Session):
try:
print("Retrieving login form")
url = "https://accounts.dmm.com/service/login/password"
result = session.get(url)
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"}
result = session.post(url, data, headers=headers)
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"
result = requests.post(url, cookies=cookies, headers=headers, json=data)
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"
result = requests.post(url, cookies=cookies, headers=headers, json=data)
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)
2025-01-25 07:55:47 +08:00
def main(config):
game_id = config["game_id"]
exe_location = config["file_path"]
login = urllib.parse.quote_plus(config["dmm_login"])
password = urllib.parse.quote_plus(config["dmm_password"])
update_game = config["update_game"] if "update_game" in config else False
use_proxy = config["use_proxy"] if "use_proxy" in config else False
2025-01-24 19:11:57 +08:00
mac_addr = get_mac()
hdd_serial = get_hash('')
2025-01-25 08:12:26 +08:00
#actual moterboard serial is unknown, but this works
motherboard = get_hash(getnode())
2025-01-24 19:11:57 +08:00
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)
2025-01-25 07:55:47 +08:00
input("Done. Press enter to exit (this will close the game)")
2025-01-24 19:11:57 +08:00
2025-01-25 07:55:47 +08:00
main(config)