Compare commits

...

2 Commits

Author SHA1 Message Date
katboi01 95e4057a49 updated file downloading code, error handling 2025-01-25 04:28:38 +01:00
katboi01 c454d7b8be updated download progress bar 2025-01-25 02:46:23 +01:00
3 changed files with 71 additions and 21 deletions

20
README.md Normal file
View File

@ -0,0 +1,20 @@
# Japari Bypass
Efficient KF3/DMM game launcher.
## Requirements
Python 3
KF3 installed from DMM. DMM itself does not need to be running.
## Instructions
Download the files from this repo. Unzip them to a safe place.
Run `run_KF3.bat`, it will ask you for some information.
It will ask for the location of the KF3 executable. Generally this will be `C:\users\[your name]\KFP2G\けもフレ3.exe`.
Input your DMM email and then password when prompted, and `yes` if you want to use the public VPN to connect to DMM's server. If you choose not to use the public VPN, then you will need to enable your own Japanese VPN while logging in to the game.
If you make a mistake or you want to change login details, edit the `kfp2g.cfg` config file, or delete it to run the configuration again.
## Known issues
Retrieving launch arguments - error 308: Every once in a while, DMM games may have updated terms of service that need to be accepted. This can only be done via the official DMM app.

View File

@ -78,6 +78,7 @@ def retrieve_auth_keys(login, password, token, captcha, session : requests.Sessi
return cookies["login_secure_id"], cookies["login_session_id"]
except Exception as e:
print("Failed to log in:", e)
return None, None
def retrieve_update_params(game_id, login_secure, login_session, use_proxy):
try:
@ -88,7 +89,10 @@ def retrieve_update_params(game_id, login_secure, login_session, use_proxy):
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)
result.raise_for_status()
data = result.json()["data"]
result_json = result.json()
if result_json["result_code"] != 100:
raise Exception(f'{result_json["result_code"]}: {result_json["error"]}')
data = result_json["data"]
game_version = data["latest_version"]
print("Latest version:", game_version)
file_list_url = data["file_list_url"]
@ -97,6 +101,7 @@ def retrieve_update_params(game_id, login_secure, login_session, use_proxy):
return file_list_url, file_list_params
except Exception as e:
print("Failed to retrieve update file list:", e)
return None, None
def retrieve_launch_params(game_id, mac_addr, hdd_serial, motherboard, login_secure, login_session, use_proxy):
try:
@ -107,7 +112,10 @@ def retrieve_launch_params(game_id, mac_addr, hdd_serial, motherboard, login_sec
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)
result.raise_for_status()
data = result.json()["data"]
result_json = result.json()
if result_json["result_code"] != 100:
raise Exception(f'{result_json["result_code"]}: {result_json["error"]}')
data = result_json["data"]
return data["execute_args"]
except Exception as e:
print("Failed to retrieve launch arguments:", e)
@ -132,6 +140,8 @@ def main(config):
return
login_secure, login_session = retrieve_auth_keys(login, password, token, captcha, session)
if login_secure == None or login_session == None:
return
if not use_proxy: input("Enable VPN now and press Enter")

View File

@ -1,24 +1,10 @@
import os
import sys
import hashlib
import requests
import urllib.parse
from urllib.request import urlretrieve
import sys
def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.3+
"""https://stackoverflow.com/questions/3160699/python-progress-bar"""
count = len(it)
if count == 0: return
def show(j):
x = int(size*j/count)
print("{}[{}{}] {}/{}".format(prefix, "#"*x, "."*(size-x), j, count),
end='\r', file=out, flush=True)
show(0)
for i, item in enumerate(it):
yield item
show(i+1)
print("\n", flush=True, file=out)
def get_file_list(url):
url = "https://apidgp-gameplayer.games.dmm.com" + url
print("Retrieving file list from " + url)
@ -71,10 +57,44 @@ def update_game(game_path, files_url, files_param):
print("Files to download:", len(files_to_download))
for file in progressbar(files_to_download, "Downloading: ", 40):
count = len(files_to_download)
if count > 0:
index = 0
max_len = 0
def show(j, downloaded, total_size):
nonlocal max_len
x = int(40*j/count)
string = "Downloading: [{}{}] {}/{} ({}/{})".format("#"*x, "."*(40-x), j, count, min(downloaded,total_size), total_size)
max_len = max(len(string), max_len)
print(string.ljust(max_len, ' '), end='\r', file=sys.stdout, flush=True)
retries = 3
show(0, 0, 0)
while index < len(files_to_download):
try:
file = files_to_download[index]
url, path = file["url"], file["path"]
response = requests.get(url, timeout=10, stream=True)
total_size = int(response.headers.get("content-length", 0))
block_size = 1024 * 1024
downloaded = 0
os.makedirs(os.path.dirname(path), exist_ok=True)
urlretrieve(url, path)
with open(path, 'wb') as out_file:
for data in response.iter_content(block_size):
out_file.write(data)
downloaded += len(data)
show(index + 1, downloaded, total_size)
index += 1
retries = 3
except Exception as e:
print(e, "retrying")
retries -= 1
if retries == 0:
print(f'Retry for file {file["url"]} failed 3 times')
return False
print("\n", flush=True, file=sys.stdout)
# #files_to_delete is unused until fully tested
# for file in files_to_delete: