Skip to content

Commit

Permalink
Merge pull request #22 from fa0311/develop-v4
Browse files Browse the repository at this point in the history
update Develop v4
  • Loading branch information
fa0311 authored Mar 26, 2022
2 parents 85c7789 + 0cc7c9f commit 36bd5c3
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 142 deletions.
191 changes: 74 additions & 117 deletions DMMGamePlayerFastLauncher.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,13 @@
import subprocess
import requests
import argparse
import re
import json
import glob
import win32crypt
import random
import hashlib

requests.packages.urllib3.disable_warnings()

argpar = argparse.ArgumentParser(
prog="DMMGamePlayerFastLauncher",
usage="https://github.com/fa0311/DMMGamePlayerFastLauncher",
description="DMM Game Player Fast Launcher",
)

argpar.add_argument("product_id", default=None)
argpar.add_argument("--game-path", default=False)
argpar.add_argument(
"-dgp-path",
"--dmmgameplayer-path",
default="C:/Program Files/DMMGamePlayer/DMMGamePlayer.exe",
)
argpar.add_argument("--non-kill", action="store_true")
argpar.add_argument("--debug", action="store_true")
argpar.add_argument("--login-force", action="store_true")
argpar.add_argument("--anonymous", action="store_true")
arg = argpar.parse_args()
import sqlite3
import os


def gen_rand_hex():
Expand All @@ -44,109 +24,95 @@ def gen_rand_address():
return address[:-1]


class dgp5_process:
def __init__(self):
self.process = subprocess.Popen(
args="",
executable=arg.dmmgameplayer_path,
shell=True,
stdout=subprocess.PIPE,
)
self.debug = False

def get_install_data(self):
for line in self.process.stdout:
text = self._decode(line)
if "Parsing json string is " in text:
install_data = json.loads(
text.lstrip("Parsing json string is ").rstrip(".")
)
return install_data
self._end_stdout()

def get_client_data(self):
for line in self.process.stdout:
text = self._decode(line)
if (
"https://apidgp-gameplayer.games.dmm.com/v5/gameplayer/agreement/check"
in text
):
return self._req_body_to_dict(text)
self._end_stdout()

def get_cookie(self):
for line in self.process.stdout:
text = self._decode(line)
if 'Header key: "cookie"' in text:
cookie = re.findall(r'"(.*?)"', text)[1]
return cookie
self._end_stdout()

def wait(self):
for line in self.process.stdout:
self._decode(line)

def kill(self):
self.process.terminate()

def _req_body_to_dict(self, line):
return json.loads(line.split(" :: Request body is ")[1][:-1])

def _decode(self, line):
text = line.decode("utf-8").strip()
if self.debug:
print(text)
return text

def _end_stdout(self):
raise Exception("DMMGamePlayerの実行中にエラーが発生しました\n既に実行されているか実行中に終了した可能性があります")


headers = {
def get_dgp5_session(dgp5_path):
db = sqlite3.connect(dgp5_path + "Network/Cookies").cursor()
session = requests.session()
for cookie_row in db.execute("select * from cookies"):
cookie_data = {
"name": cookie_row[3],
"value": cookie_row[4],
"domain": cookie_row[1],
"path": cookie_row[6],
"secure": cookie_row[8],
}
session.cookies.set_cookie(requests.cookies.create_cookie(**cookie_data))
return session


def get_dpg5_config(dgp5_path):
with open(dgp5_path + "dmmgame.cnf", "r") as f:
config = f.read()
return json.loads(config)


requests.packages.urllib3.disable_warnings()

argpar = argparse.ArgumentParser(
prog="DMMGamePlayerFastLauncher",
usage="https://github.com/fa0311/DMMGamePlayerFastLauncher",
description="DMM Game Player Fast Launcher",
)
argpar.add_argument("product_id", default=None)
argpar.add_argument("--game-path", default=False)
argpar.add_argument("--login-force", action="store_true")
arg = argpar.parse_args()

HEADERS = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36",
}
DGP5_HEADERS = {
"Host": "apidgp-gameplayer.games.dmm.com",
"Connection": "keep-alive",
"User-Agent": "DMMGamePlayer5-Win/17.1.2 Electron/17.1.2",
"Client-App": "DMMGamePlayer5",
"Client-version": "17.1.2",
}

params = {
DGP5_LAUNCH_PARAMS = {
"product_id": arg.product_id,
"game_type": "GCL",
"game_os": "win",
"launch_type": "LIB",
"mac_address": gen_rand_address(),
"hdd_serial": gen_rand_hex(),
"motherboard": gen_rand_hex(),
"user_os": "win",
}

if arg.anonymous:
client_data = {
"mac_address": gen_rand_address(),
"hdd_serial": gen_rand_hex(),
"motherboard": gen_rand_hex(),
"user_os": "win",
}
DGP5_PATH = os.environ["APPDATA"] + "/dmmgameplayer5/"


open("cookie.bytes", "a+")
with open("cookie.bytes", "rb") as f:
blob = f.read()

process = dgp5_process()
process.debug = arg.debug
install_data = process.get_install_data()

if not arg.anonymous:
client_data = process.get_client_data()[0]

if blob == b"" or arg.login_force:
cookie = process.get_cookie()
new_blob = win32crypt.CryptProtectData(cookie.encode(), "DMMGamePlayerFastLauncher")
session = get_dgp5_session(DGP5_PATH)
response = session.get(
"https://www.dmm.com/my/-/login/auth/=/direct_login=1/path=DRVESVwZTkVPEh9cXltIVA4IGV5ETRQWVlID",
headers=HEADERS,
)
if session.cookies.get("login_session_id") == None:
raise Exception(
"ログインに失敗しました\nDMMGamePlayerでログインしていない時またはDMMGamePlayerが起動している時にこのエラーが発生する可能性があります"
)
contents = json.dumps(
{
"login_session_id": session.cookies.get("login_session_id"),
"login_secure_id": session.cookies.get("login_secure_id"),
}
)
new_blob = win32crypt.CryptProtectData(
contents.encode(), "DMMGamePlayerFastLauncher"
)
with open("cookie.bytes", "wb") as f:
f.write(new_blob)
else:
_, cookie = win32crypt.CryptUnprotectData(blob)
_, contents = win32crypt.CryptUnprotectData(blob)
cookie = json.loads(contents)

dpg5_config = get_dpg5_config(DGP5_PATH)
if not arg.game_path:
for contents in install_data["contents"]:
for contents in dpg5_config["contents"]:
if contents["productId"] == arg.product_id:
game_path_list = glob.glob(
"{path}\*.exe._".format(path=contents["detail"]["path"])
Expand All @@ -163,37 +129,28 @@ def _end_stdout(self):
game_path = path
break
else:
process.kill()
raise Exception("ゲームのパスの検出に失敗しました")
break
else:
process.kill()
raise Exception(
"product_id が無効です\n"
+ " ".join([contents["productId"] for contents in install_data["contents"]])
+ " ".join([contents["productId"] for contents in dpg5_config["contents"]])
+ "から選択して下さい"
)

headers["cookie"] = cookie
params.update(client_data)

response = requests.post(
"https://apidgp-gameplayer.games.dmm.com/v5/launch/cl",
headers=headers,
json=params,
cookies=cookie,
headers=DGP5_HEADERS,
json=DGP5_LAUNCH_PARAMS,
verify=False,
).json()

if response["result_code"] == 100:
dmm_args = response["data"]["execute_args"].split(" ")
print(dmm_args)
subprocess.Popen([game_path, dmm_args[0], dmm_args[1]])
else:
with open("cookie.bytes", "wb") as f:
f.write(b"")
process.kill()
raise Exception("起動にエラーが発生したため修復プログラムを実行しました\n" + json.dumps(response))

if arg.non_kill:
process.wait()
else:
process.kill()
33 changes: 9 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# 重要なお知らせ
## 2022年3月25日に配信されたDMMGamePlayer5.0.119以降のバージョンで動作しません
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
# DMMGamePlayerFastLauncher
DMM Game Player のゲームを高速かつセキュアに起動できるランチャー

Expand Down Expand Up @@ -30,12 +27,8 @@ DMM Game Player のゲームを高速かつセキュアに起動できるラン
| オプション | エイリアス | デフォルト | 備考 | タイプ |
|----------------------|------------|--------------------------------------------------|-----------------------------------------|--------|
| --help | -h | False | | bool |
| --game-path | | False | Falseにすると自動 | |
| --dmmgameplayer-path | -dgp-path | C:/Program Files/DMMGamePlayer/DMMGamePlayer.exe | | |
| --non-kill | | False | DMMGamePlayerが起動したままになる | bool |
| --debug | | False | デバッグモード | bool |
| --game-path | | False | ゲームのパス Falseにすると自動 | |
| --login-force | | False | ログインを強制する | bool |
| --anonymous | | False | ハードウェアの情報をDMMに送信しなくなる | bool |

## ヘルプ

Expand All @@ -50,11 +43,8 @@ DMM Game Player のゲームを高速かつセキュアに起動できるラン
> ショートカットを右クリック→プロパティ→アイコンの変更→参照
> **このツールを使用するとDMMGamePlayerを起動する際に毎回ログインを求められるようになった**<br>
> DMMGamePlayerのバグです<br>
> `--non-kill` を指定すると毎回ログインを求められなくなりますがこのツールからゲームを起動する際にDMMGamePlayerを立ち上げたままになります<br>
> 要するに旧DMMGamePlayerのショートカットと似た感じになります<br>
例<br>
`%AppData%\DMMGamePlayerFastLauncher\DMMGamePlayerFastLauncher.exe umamusume --non-kill`<br>
> DMMGamePlayerのバグ(仕様?)です<br>
> どうすることも出来ないので頻繁にDMMGamePlayerを起動する方にこのツールはオススメしません<br>
> **「ゲームのパスの検出に失敗しました」というエラーが出る**<br>
> **アンインストーラーなどの別のソフトが起動する**<br>
Expand All @@ -69,27 +59,22 @@ DMM Game Player のゲームを高速かつセキュアに起動できるラン
例<br>
`%AppData%\DMMGamePlayerFastLauncher\DMMGamePlayerFastLauncher.exe umamusume --game-path %UserProfile%/umamusume/umamusume.exe`<br>

> **BlueStacksを利用しているゲームだとエラーが出る**<br>
> 現在、BlueStacksを利用しているゲームは対応していません
> **「ログインに失敗しました」というエラーが出る**<br>
> DMMGamePlayerを起動してログインして下さい<br>
> DMMGamePlayerを起動しているなら終了させて下さい<br>
> **「要求された操作には管理者特権が必要です」というエラーが出る**<br>
> DMMGamePlayerが管理者権限でインストールされています<br>
> DMMGamePlayerから管理者権限を外して下さい<br>
> **「指定されたファイルが見つかりません」というエラーが出る**<br>
> DMMGamePlayerがインストールされていないかDMMGamePlayerのインストール先フォルダがデフォルトではない可能性があります<br>
> インストール先フォルダがデフォルトではない場合は`--dmmgameplayer-path <DMMGamePlayerのパス>`で指定して下さい<br>
例<br>
`%AppData%\DMMGamePlayerFastLauncher\DMMGamePlayerFastLauncher.exe umamusume --dmmgameplayer-path "C:/Program Files/DMMGamePlayer/DMMGamePlayer.exe"`<br>
> ※パスに空白が含まれる場合は例のように `"` で囲んで下さい
> **「DMMGamePlayerの実行中にエラーが発生しました」というエラーが出る**<br>
> 既にDMMGamePlayerが実行中かDMMGamePlayerの実行中にDMMGamePlayerが何らかの理由で終了した可能性があります<br>
> タスクバーにDMMGamePlayerが無くても裏で待機している可能性が高いです タスクキルするか再起動してみて下さい<br>
> `--game-path` で指定したゲームのパスが間違っています<br>
> **「起動にエラーが発生したため修復プログラムを実行しました」というエラーが出る**<br>
> まれに表示される場合は正常な動作です 1年に1回程度ログイン情報が無効になる仕様なのでこの処置です<br>
> まれに表示される場合は正常な動作です<br>
> **「起動にエラーが発生したため修復プログラムを実行しました」と連続して何度も表示される**<br>
> `%AppData%\DMMGamePlayerFastLauncher``cookie.bytes` を削除してみて下さい<br>
Expand Down
Binary file modified requirements.txt
Binary file not shown.
2 changes: 1 addition & 1 deletion setup.iss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "DMMGamePlayerFastLauncher"
#define MyAppVersion "3.1"
#define MyAppVersion "4.0"
#define MyAppPublisher "yuki"
#define MyAppURL "https://github.com/fa0311/DMMGamePlayerFastLauncher"
#define MyAppExeName "DMMGamePlayerFastLauncher.exe"
Expand Down

0 comments on commit 36bd5c3

Please sign in to comment.