From dba98608ac48aaa850335349540d330facf5557f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Fri, 27 Jan 2023 11:21:11 +0900 Subject: [PATCH 01/11] add winpwnage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- requirements.txt | Bin 1106 -> 1318 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index 9d6d749576929c127dc75e446d8264e5800501fd..8a83302657865ed4728244e58d6295d610690aaf 100644 GIT binary patch delta 159 zcmcb_v5ad&5Q|_rLncEWLjglMkW6GqXGopw%;a1j4i*hSh%)Fh1OVkr7?K$>7*ZKh z81#T@Gl6^uAkPvgY7P`jWv~E4a|Q#Tm?e-*W-wwfWk>^x8iG}s0aY0SMJyRi7>t3? W6s*F6AqfagfjAM!=VjnxWB>s3sv9Q& delta 7 OcmZ3+b%|p`5DNeczXFi} From f8a2d7cb762b290d59c2ef8cdf7c6e49af89e081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sat, 28 Jan 2023 22:49:00 +0900 Subject: [PATCH 02/11] add #50 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- DMMGamePlayerFastLauncher.py | 103 ++++++++++++++++++++++++++++--- DMMGamePlayerProductIdChecker.py | 2 +- Task.py | 14 +++++ build.ps1 | 2 + requirements.txt | Bin 1318 -> 1136 bytes windows/assets/template.xml | 43 +++++++++++++ 6 files changed, 153 insertions(+), 11 deletions(-) create mode 100644 Task.py create mode 100644 windows/assets/template.xml diff --git a/DMMGamePlayerFastLauncher.py b/DMMGamePlayerFastLauncher.py index e2c193b..959d632 100644 --- a/DMMGamePlayerFastLauncher.py +++ b/DMMGamePlayerFastLauncher.py @@ -11,6 +11,7 @@ import os import time from urllib.parse import urlparse +import win32security class DgpSession: @@ -211,6 +212,12 @@ class ErrorManager: url="https://github.com/fa0311/DMMGamePlayerFastLauncher/issues", ) + elevate_admin_error: ErrorManagerType = ErrorManagerType( + message="Failed to elevate to administrator privileges.", + solution="Report an Issues.", + url="https://github.com/fa0311/DMMGamePlayerFastLauncher/issues", + ) + def error(self, error: ErrorManagerType, log: str | None = None): output = filter( lambda x: x != None, @@ -225,7 +232,39 @@ def info(self, text: str): print(text) +class ProcessManager: + non_request_admin: bool = False + error_manager: ErrorManager + + def __init__(self, error_manager: ErrorManager) -> None: + self.error_manager = error_manager + + def run( + self, args: dict[str], admin: bool = False + ) -> subprocess.Popen[bytes] | None: + print(" ".join(args)) + if admin: + if self.non_request_admin: + self.error_manager.error(error=ErrorManager.permission_error) + else: + ctypes.windll.shell32.ShellExecuteW( + None, "runas", args[0], " ".join(args[1:]), None, 1 + ) + else: + return subprocess.Popen( + args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + + +def get_sid() -> str: + desc = win32security.GetFileSecurity(".", win32security.OWNER_SECURITY_INFORMATION) + sid = desc.GetSecurityDescriptorOwner() + sidstr = win32security.ConvertSidToStringSid(sid) + return sidstr + + error_manager = ErrorManager() +process_manager = ProcessManager(error_manager) argpar = argparse.ArgumentParser( prog="DMMGamePlayerFastLauncher", @@ -239,12 +278,59 @@ def info(self, text: str): argpar.add_argument("--skip-exception", action="store_true") argpar.add_argument("--https-proxy-uri", default=None) argpar.add_argument("--non-request-admin", action="store_true") +argpar.add_argument("--bypass-uac", action="store_true") +argpar.add_argument("--schtasks-path", default="schtasks.exe") + try: arg = argpar.parse_args() error_manager.skip = arg.skip_exception + process_manager.non_request_admin = arg.non_request_admin except: error_manager.error(error=ErrorManager.argument_error) + +if arg.bypass_uac: + schtasks_file = "schtasks_v1_" + os.getlogin() + schtasks_name = f"\Microsoft\Windows\DMMGamePlayerFastLauncher\{schtasks_file}" + + run_args = [arg.schtasks_path, "/run", "/tn", schtasks_name] + + if process_manager.run(run_args).wait() == 1: + schtasks_xml_path = ( + r"{appdata}\DMMGamePlayerFastLauncher\assets\{name}.xml".format( + appdata=os.environ["APPDATA"], name=schtasks_file + ) + ) + schtasks_task_path = ( + r"{appdata}\DMMGamePlayerFastLauncher\Tools\Task.exe".format( + appdata=os.environ["APPDATA"] + ) + ) + with open("assets/template.xml", "r") as f: + template = f.read() + + with open(f"assets/{schtasks_file}.xml", "w") as f: + f.write( + template.replace(r"{{UID}}", schtasks_file) + .replace(r"{{SID}}", get_sid()) + .replace(r"{{COMMAND}}", schtasks_task_path) + ) + + create_args = [ + arg.schtasks_path, + "/create", + "/xml", + schtasks_xml_path, + "/tn", + schtasks_name, + ] + process_manager.run(create_args, admin=True) + time.sleep(3) + process_manager.run(run_args) + time.sleep(8) + error_manager.error(error=ErrorManager.elevate_admin_error) + + session = DgpSession(arg.https_proxy_uri) try: @@ -324,20 +410,17 @@ def info(self, text: str): dmm_args = dmm_args + arg.game_args.split(" ") print(game_path) start_time = time.time() - process = subprocess.Popen( - [game_path] + dmm_args, shell=True, stdout=subprocess.PIPE - ) + process = process_manager.run([game_path] + dmm_args) for line in process.stdout: text = line.decode("utf-8").strip() print(text) - if time.time() - start_time < 2 and not arg.skip_exception: + if time.time() - start_time < 2: if response["data"]["is_administrator"]: - if not ctypes.windll.shell32.IsUserAnAdmin() and not arg.non_request_admin: - ctypes.windll.shell32.ShellExecuteW( - None, "runas", game_path, response["data"]["execute_args"], None, 1 - ) - else: - error_manager.error(error=ErrorManager.permission_error) + process = process_manager.run([game_path] + dmm_args, admin=True) + else: + error_manager.error( + error=ErrorManager.startup_error, log=json.dumps(response) + ) elif response["result_code"] == 307: error_manager.error(error=ErrorManager.auth_device_error) diff --git a/DMMGamePlayerProductIdChecker.py b/DMMGamePlayerProductIdChecker.py index 4737260..f05bb15 100644 --- a/DMMGamePlayerProductIdChecker.py +++ b/DMMGamePlayerProductIdChecker.py @@ -17,5 +17,5 @@ pd.set_option("display.unicode.east_asian_width", True) print(df) -print("終了するには何かキーを押してください") +print("Please press any key to exit") input() diff --git a/Task.py b/Task.py new file mode 100644 index 0000000..3b075d1 --- /dev/null +++ b/Task.py @@ -0,0 +1,14 @@ +import psutil +import subprocess +import os +import signal + + +for p in psutil.process_iter(attrs=("name", "pid", "cmdline")): + if p.info["name"] != "DMMGamePlayerFastLauncher.exe": + continue + if "--bypass-uac" in p.info["cmdline"]: + p.info["cmdline"].remove("--bypass-uac") + os.kill(p.info["pid"], signal.SIGTERM) + subprocess.Popen(p.info["cmdline"], shell=True) + break diff --git a/build.ps1 b/build.ps1 index 4377b6c..150ee42 100644 --- a/build.ps1 +++ b/build.ps1 @@ -2,6 +2,8 @@ black *.py pip freeze > requirements.txt pyinstaller DMMGamePlayerFastLauncher.py --onefile --noconsole pyinstaller DMMGamePlayerProductIdChecker.py --onefile +pyinstaller Task.py --onefile --noconsole New-Item "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\windows\tools" -ItemType Directory -Force Copy-Item -Path "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\dist\DMMGamePlayerProductIdChecker.exe" -Destination "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\windows\tools" -Force +Copy-Item -Path "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\dist\Task.exe" -Destination "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\windows\tools" -Force Start-Process "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\setup.iss" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 8a83302657865ed4728244e58d6295d610690aaf..10b94f1edf2cae05091df768e31a72b33f63c6b7 100644 GIT binary patch delta 40 scmZ3+^?_r90h4$!Ln%WELncEGgDnu6GUzc_0

Dw@lKTU6}Zo0Lozq@c;k- delta 168 zcmYLwV9hmPsg1Hz1njnjNY7vbEMUuvZm7iNyCl6g^k=!`>5qa3$Z{MQ;>-{ eb;A}*E1E~^AS)Mf?Aa+c8YQ)2bzXZ$I^hRFcpV}D diff --git a/windows/assets/template.xml b/windows/assets/template.xml new file mode 100644 index 0000000..bcf37a9 --- /dev/null +++ b/windows/assets/template.xml @@ -0,0 +1,43 @@ + + + + 2023-01-01T00:00:00 + fa0311 + uac_bypass_v1 + \Microsoft\Windows\DMMGamePlayerFastLauncher\{{UID}} + + + + + {{SID}} + InteractiveToken + HighestAvailable + + + + Parallel + false + false + false + false + false + + true + false + + true + true + false + false + false + true + false + PT0S + 7 + + + + {{COMMAND}} + + + \ No newline at end of file From 786a257fc45019505f640b7a443e87b67c4f1316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sat, 28 Jan 2023 23:00:40 +0900 Subject: [PATCH 03/11] fix Current dir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- DMMGamePlayerFastLauncher.py | 4 +--- windows/assets/template.xml | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/DMMGamePlayerFastLauncher.py b/DMMGamePlayerFastLauncher.py index 959d632..1e3d636 100644 --- a/DMMGamePlayerFastLauncher.py +++ b/DMMGamePlayerFastLauncher.py @@ -314,6 +314,7 @@ def get_sid() -> str: template.replace(r"{{UID}}", schtasks_file) .replace(r"{{SID}}", get_sid()) .replace(r"{{COMMAND}}", schtasks_task_path) + .replace(r"{{WORKING_DIRECTORY}}", os.getcwd()) ) create_args = [ @@ -327,9 +328,6 @@ def get_sid() -> str: process_manager.run(create_args, admin=True) time.sleep(3) process_manager.run(run_args) - time.sleep(8) - error_manager.error(error=ErrorManager.elevate_admin_error) - session = DgpSession(arg.https_proxy_uri) diff --git a/windows/assets/template.xml b/windows/assets/template.xml index bcf37a9..c6d3236 100644 --- a/windows/assets/template.xml +++ b/windows/assets/template.xml @@ -38,6 +38,7 @@ {{COMMAND}} + {{WORKING_DIRECTORY}} \ No newline at end of file From dfefc3a8ec5e1614fda576a0973226c1eb174c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sun, 29 Jan 2023 05:12:27 +0900 Subject: [PATCH 04/11] update README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- DMMGamePlayerFastLauncher.py | 68 ++++++++++++++++++-------------- Task.py | 11 ++++-- docs/README-advance.md | 75 +++++++++++++++++++++++++++++++----- setup.iss | 13 ++++--- windows/tools/refresh.ps1 | 2 + 5 files changed, 120 insertions(+), 49 deletions(-) create mode 100644 windows/tools/refresh.ps1 diff --git a/DMMGamePlayerFastLauncher.py b/DMMGamePlayerFastLauncher.py index 1e3d636..354a4ae 100644 --- a/DMMGamePlayerFastLauncher.py +++ b/DMMGamePlayerFastLauncher.py @@ -12,6 +12,7 @@ import time from urllib.parse import urlparse import win32security +import sys class DgpSession: @@ -234,6 +235,7 @@ def info(self, text: str): class ProcessManager: non_request_admin: bool = False + non_bypass_uac: bool = False error_manager: ErrorManager def __init__(self, error_manager: ErrorManager) -> None: @@ -244,7 +246,9 @@ def run( ) -> subprocess.Popen[bytes] | None: print(" ".join(args)) if admin: - if self.non_request_admin: + if not self.non_bypass_uac: + run_bypass_uac() + elif self.non_request_admin: self.error_manager.error(error=ErrorManager.permission_error) else: ctypes.windll.shell32.ShellExecuteW( @@ -263,33 +267,7 @@ def get_sid() -> str: return sidstr -error_manager = ErrorManager() -process_manager = ProcessManager(error_manager) - -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=None) -argpar.add_argument("--game-args", default=None) -argpar.add_argument("--login-force", action="store_true") -argpar.add_argument("--skip-exception", action="store_true") -argpar.add_argument("--https-proxy-uri", default=None) -argpar.add_argument("--non-request-admin", action="store_true") -argpar.add_argument("--bypass-uac", action="store_true") -argpar.add_argument("--schtasks-path", default="schtasks.exe") - -try: - arg = argpar.parse_args() - error_manager.skip = arg.skip_exception - process_manager.non_request_admin = arg.non_request_admin -except: - error_manager.error(error=ErrorManager.argument_error) - - -if arg.bypass_uac: +def run_bypass_uac(): schtasks_file = "schtasks_v1_" + os.getlogin() schtasks_name = f"\Microsoft\Windows\DMMGamePlayerFastLauncher\{schtasks_file}" @@ -325,9 +303,41 @@ def get_sid() -> str: "/tn", schtasks_name, ] + if arg.non_request_admin: + error_manager.error(error=ErrorManager.permission_error) + return process_manager.run(create_args, admin=True) time.sleep(3) - process_manager.run(run_args) + process_manager.run(run_args).wait() + time.sleep(5) + sys.exit() + + +error_manager = ErrorManager() +process_manager = ProcessManager(error_manager) + +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=None) +argpar.add_argument("--game-args", default=None) +argpar.add_argument("--login-force", action="store_true") +argpar.add_argument("--skip-exception", action="store_true") +argpar.add_argument("--https-proxy-uri", default=None) +argpar.add_argument("--non-request-admin", action="store_true") +argpar.add_argument("--non-bypass-uac", action="store_true") +argpar.add_argument("--schtasks-path", default="schtasks.exe") + +try: + arg = argpar.parse_args() + error_manager.skip = arg.skip_exception + process_manager.non_request_admin = arg.non_request_admin + process_manager.non_bypass_uac = arg.non_bypass_uac +except: + error_manager.error(error=ErrorManager.argument_error) session = DgpSession(arg.https_proxy_uri) diff --git a/Task.py b/Task.py index 3b075d1..05a2caf 100644 --- a/Task.py +++ b/Task.py @@ -1,14 +1,17 @@ import psutil -import subprocess import os import signal +import ctypes for p in psutil.process_iter(attrs=("name", "pid", "cmdline")): if p.info["name"] != "DMMGamePlayerFastLauncher.exe": continue - if "--bypass-uac" in p.info["cmdline"]: - p.info["cmdline"].remove("--bypass-uac") + cmdline = p.info["cmdline"] + if "--bypass-uac" in cmdline: + cmdline.remove("--bypass-uac") os.kill(p.info["pid"], signal.SIGTERM) - subprocess.Popen(p.info["cmdline"], shell=True) + ctypes.windll.shell32.ShellExecuteW( + None, "runas", cmdline[0], " ".join(cmdline[1:]), None, 1 + ) break diff --git a/docs/README-advance.md b/docs/README-advance.md index 4084323..197b9f9 100644 --- a/docs/README-advance.md +++ b/docs/README-advance.md @@ -19,15 +19,37 @@ `DMMGamePlayerFastLauncher.exe ` -| オプション | エイリアス | デフォルト | タイプ | -| ------------------- | ---------- | ---------- | ------------------ | -| --help | -h | False | Bool | -| --game-path | | None | String | None | -| --game-args | | None | String | None | -| --login-force | | Flase | Bool | -| --skip-exception | | False | Bool | -| --https-proxy-uri | | None | String | None | -| --non-request-admin | | False | Bool | +| オプション | エイリアス | デフォルト | タイプ | note | +| ------------------- | ---------- | ------------ | ------------------ | ---------- | +| --help | -h | False | Bool | | +| --game-path | | None | String | None | | +| --game-args | | None | String | None | | +| --login-force | | Flase | Bool | deprecated | +| --skip-exception | | False | Bool | | +| --https-proxy-uri | | None | String | None | | +| --non-request-admin | | False | Bool | deprecated | +| --non-bypass-uac | | False | Bool | | +| --schtasks-path | | schtasks.exe | String | | + +```mermaid + graph TD; + ゲームのプロセスを開始 --権限不備で起動しない--> non-bypass-uac; + ゲームのプロセスを開始 --Start/Error--> 続行; + non-bypass-uac --false--> 最初のリクエスト; + 最初のリクエスト --no-->ゲームに権限与える + 最初のリクエスト --yes--> non-request-admin + non-bypass-uac --true--> non-request-admin; + non-request-admin --true--> skip-exception; + non-request-admin --false--> UAC; + UAC --allow--> ゲームに権限与える + UAC --disabled--> 続行 + skip-exception --true--> 続行 + skip-exception --false--> エラー +``` + +**最初のリクエスト** - 最初のリクエストは、管理者権限を要求します +これは、タスクスケジューラーに自動的に権限を昇格させるプログラムを登録するために必要です +**skip-exception** - `skip-exception`はエラーが発生しても続行するためのものですが無限ループになる可能性があるためここでは特別に強制終了されます ### game-path @@ -55,7 +77,7 @@ Unity 製ゲームの引数はここに詳しく載ってます ### skip-exception -エラーを出力しません +エラーを出力しなくなります これはあくまで応急処置で基本的には使わないで下さい 原因不明なエラーが発生した場合は [issues](https://github.com/fa0311/DMMGamePlayerFastLauncher/issues) に報告して下さい @@ -85,6 +107,39 @@ Socks5 例: `%AppData%\DMMGamePlayerFastLauncher\DMMGamePlayerFastLauncher.exe umamusume --non-request-admin` +### non-bypass-uac + +この引数を使用すると UAC の自動許可を行わなくなります + +指定していない場合はタスクスケジューラを使った権限の自動昇格を行います +タスクの詳細はこのコマンドで確認できます +複雑な処理を行うため少し起動速度が遅くなります +`schtasks.exe /query /tn \Microsoft\Windows\DMMGamePlayerFastLauncher\` + +また、このコマンドで削除できます +`Get-ScheduledTask | where TaskPath -eq "\Microsoft\Windows\DMMGamePlayerFastLauncher" | Unregister-ScheduledTask -Confirm:$false` + +### schtasks-path + +`schtasks.exe`の起動パスです +ほとんどの場合、この引数は不要です + +## ファイル階層 + +| ファイル名 | 削除 | 詳細 | +| --------------------------------------- | ---- | ------------------------------------------------------------------------------ | +| DMMGamePlayerFastLauncher.exe | x | 本体 | +| unins000.dat | o | アンインストールする際に必要 | +| unins000.exe | x | アンインストールする際に必要 | +| cookie.bytes | o | セッションのキャッシュファイル, DMM のセッションが取得できなかった際に使用する | +| tools/DMMGamePlayerProductIdChecker.exe | o | プロダクト ID のチェッカー,左ダブルクリックで実行 | +| tools/Task.exe | x | タスクスケジューラから呼び出される | +| tools/refresh.ps1 | o | タスクを削除する,右クリックメニューから PowerShell で実行 | +| sample/ウマ娘.lnk | o | ウマ娘の起動ショートカット,左ダブルクリックで実行 | +| sample/プリコネ R.lnk | o | プリコネ R の起動ショートカット,左ダブルクリックで実行 | +| assets/template.xml | x | タスクスケジューラのテンプレートファイル | +| assets/schtasks_v1\_{username}.xml | o | タスクスケジューラの残骸ファイル | + ## ヘルプ ### セットアップする際、「Windows によって PC が保護されました」と表示される diff --git a/setup.iss b/setup.iss index b8a1a1d..46f1c0b 100644 --- a/setup.iss +++ b/setup.iss @@ -21,7 +21,7 @@ AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} -DefaultDirName={autopf}\{#MyAppName} +DefaultDirName={userappdata}\{#MyAppName} DisableDirPage=yes ChangesAssociations=yes DefaultGroupName={#MyAppName} @@ -34,6 +34,7 @@ OutputBaseFilename=DMMGamePlayerFastLauncher-Setup Compression=lzma SolidCompression=yes WizardStyle=modern +UninstallFilesDir={userappdata}\{#MyAppName} [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" @@ -41,16 +42,16 @@ Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl" [Files] -Source: "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\dist\{#MyAppExeName}"; DestDir: "{userappdata}\{#MyAppName}"; Flags: ignoreversion -Source: "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\windows\*"; DestDir: "{userappdata}\{#MyAppName}"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\dist\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion +Source: "Z:\Project\Python\hack\DMMGamePlayerFastLauncher\windows\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Registry] Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{userappdata}\{#MyAppName}\{#MyAppExeName},0" -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{userappdata}\{#MyAppName}\{#MyAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0" +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".myp"; ValueData: "" [Icons] -Name: "{group}\{#MyAppName}"; Filename: "{userappdata}\{#MyAppName}\{#MyAppExeName}" +Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" \ No newline at end of file diff --git a/windows/tools/refresh.ps1 b/windows/tools/refresh.ps1 new file mode 100644 index 0000000..32d74dc --- /dev/null +++ b/windows/tools/refresh.ps1 @@ -0,0 +1,2 @@ +if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) { Start-Process powershell.exe "-File `"$PSCommandPath`" -NoNewWindow -Wait" -Verb RunAs; exit } +Get-ScheduledTask | where TaskPath -eq "\Microsoft\Windows\DMMGamePlayerFastLauncher\" | Unregister-ScheduledTask -Confirm:$false \ No newline at end of file From 02a4941bc465af90b9947f299e6d0088b2409834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sun, 29 Jan 2023 05:14:55 +0900 Subject: [PATCH 05/11] update README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- docs/README-advance.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/README-advance.md b/docs/README-advance.md index 197b9f9..656d395 100644 --- a/docs/README-advance.md +++ b/docs/README-advance.md @@ -48,8 +48,7 @@ ``` **最初のリクエスト** - 最初のリクエストは、管理者権限を要求します -これは、タスクスケジューラーに自動的に権限を昇格させるプログラムを登録するために必要です -**skip-exception** - `skip-exception`はエラーが発生しても続行するためのものですが無限ループになる可能性があるためここでは特別に強制終了されます +これは、タスクスケジューラーに自動的に権限を昇格させるプログラムを登録するために必要です ### game-path From a96d47459a337cfd88549264297f87b8a8df4c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sun, 29 Jan 2023 05:16:07 +0900 Subject: [PATCH 06/11] update version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- setup.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.iss b/setup.iss index 46f1c0b..349907d 100644 --- a/setup.iss +++ b/setup.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "DMMGamePlayerFastLauncher" -#define MyAppVersion "4.5.2" +#define MyAppVersion "4.6.0" #define MyAppPublisher "yuki" #define MyAppURL "https://github.com/fa0311/DMMGamePlayerFastLauncher" #define MyAppExeName "DMMGamePlayerFastLauncher.exe" From 48f3fdc45c6c073f65a69e71881bdc54d96bb691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sun, 29 Jan 2023 05:21:09 +0900 Subject: [PATCH 07/11] update README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- docs/README-advance.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/README-advance.md b/docs/README-advance.md index 656d395..8f25460 100644 --- a/docs/README-advance.md +++ b/docs/README-advance.md @@ -50,6 +50,9 @@ **最初のリクエスト** - 最初のリクエストは、管理者権限を要求します これは、タスクスケジューラーに自動的に権限を昇格させるプログラムを登録するために必要です +特にこだわりが無ければ product_id 以外の引数は不要です +ゲームや環境によっては`game-path` `https-proxy-uri` `schtasks-path` などが必要です + ### game-path 何も指定していない場合は自動で検出しますがゲームによってはうまくいかない場合があります From fab917eb55027614e3745c9ec16aff9f9197ca17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sun, 29 Jan 2023 05:25:20 +0900 Subject: [PATCH 08/11] update README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- docs/README-advance.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/README-advance.md b/docs/README-advance.md index 8f25460..3ddc695 100644 --- a/docs/README-advance.md +++ b/docs/README-advance.md @@ -55,14 +55,15 @@ ### game-path -何も指定していない場合は自動で検出しますがゲームによってはうまくいかない場合があります +ゲームのパスを指定します +何も指定していない場合は自動で検出しますがうまくいかない場合は指定してください 例: `%AppData%\DMMGamePlayerFastLauncher\DMMGamePlayerFastLauncher.exe umamusume --game-path %UserProfile%/umamusume/umamusume.exe` ### game-args -ゲームに引数を追加したい場合はこれを指定します +ゲームに引数を追加したい場合はこの引数を使用します 通常の DMM を介した起動方法で使用できない隠された引数を使用することができます `"` で囲む必要があることに注意してください @@ -79,7 +80,7 @@ Unity 製ゲームの引数はここに詳しく載ってます ### skip-exception -エラーを出力しなくなります +この引数を使用するとエラーを出力しなくなります これはあくまで応急処置で基本的には使わないで下さい 原因不明なエラーが発生した場合は [issues](https://github.com/fa0311/DMMGamePlayerFastLauncher/issues) に報告して下さい @@ -103,7 +104,7 @@ Socks5 ### non-request-admin -このツールは管理者権限を必要なときのみ要求することがありますがそれを要求しなくなります +この引数を使用すると管理者権限を要求しません ほとんどの場合、この引数は不要です 例: @@ -120,10 +121,11 @@ Socks5 また、このコマンドで削除できます `Get-ScheduledTask | where TaskPath -eq "\Microsoft\Windows\DMMGamePlayerFastLauncher" | Unregister-ScheduledTask -Confirm:$false` +または `.\tools\refresh.ps1` ### schtasks-path -`schtasks.exe`の起動パスです +`schtasks.exe`のパスを指定します ほとんどの場合、この引数は不要です ## ファイル階層 From 6d856025c600eed5f43116ac2b7b75de306a1166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sun, 29 Jan 2023 05:30:02 +0900 Subject: [PATCH 09/11] update README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- README.md | 3 +++ docs/README-advance.md | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e995d2f..3507a4c 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,12 @@ DMM Game Player のゲームを高速かつセキュアに起動できるラン ## 特徴 - **ワンクリックでゲームを起動** +- **高速** - **最低限の権限で起動** +- **UAC の自動昇格** - **DMM にハードウェア情報を送信しない** - **隠されているコマンドライン引数を使用可能** +- **面倒な設定の必要無し** ## インストール diff --git a/docs/README-advance.md b/docs/README-advance.md index 3ddc695..d4d8fc1 100644 --- a/docs/README-advance.md +++ b/docs/README-advance.md @@ -112,11 +112,11 @@ Socks5 ### non-bypass-uac -この引数を使用すると UAC の自動許可を行わなくなります +この引数を使用すると UAC の自動昇格を行わなくなります 指定していない場合はタスクスケジューラを使った権限の自動昇格を行います タスクの詳細はこのコマンドで確認できます -複雑な処理を行うため少し起動速度が遅くなります +複雑な処理を行うため数秒程度起動速度が遅くなる場合があります `schtasks.exe /query /tn \Microsoft\Windows\DMMGamePlayerFastLauncher\` また、このコマンドで削除できます From d15213f692e113ee1378c9127c9f851bf6a7c00f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Sun, 29 Jan 2023 17:24:28 +0900 Subject: [PATCH 10/11] fix bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- DMMGamePlayerFastLauncher.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/DMMGamePlayerFastLauncher.py b/DMMGamePlayerFastLauncher.py index 354a4ae..0a0f8b7 100644 --- a/DMMGamePlayerFastLauncher.py +++ b/DMMGamePlayerFastLauncher.py @@ -242,11 +242,11 @@ def __init__(self, error_manager: ErrorManager) -> None: self.error_manager = error_manager def run( - self, args: dict[str], admin: bool = False + self, args: dict[str], admin: bool = False, force: bool = False ) -> subprocess.Popen[bytes] | None: print(" ".join(args)) if admin: - if not self.non_bypass_uac: + if not self.non_bypass_uac and not force: run_bypass_uac() elif self.non_request_admin: self.error_manager.error(error=ErrorManager.permission_error) @@ -303,10 +303,7 @@ def run_bypass_uac(): "/tn", schtasks_name, ] - if arg.non_request_admin: - error_manager.error(error=ErrorManager.permission_error) - return - process_manager.run(create_args, admin=True) + process_manager.run(create_args, admin=True, force=True) time.sleep(3) process_manager.run(run_args).wait() time.sleep(5) From 1a7460dac74320ee0c5150f74decacde9240a16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=B5=E3=81=81?= Date: Mon, 30 Jan 2023 00:16:01 +0900 Subject: [PATCH 11/11] fix uac bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ふぁ --- DMMGamePlayerFastLauncher.py | 1 + Task.py | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/DMMGamePlayerFastLauncher.py b/DMMGamePlayerFastLauncher.py index 0a0f8b7..ec285c8 100644 --- a/DMMGamePlayerFastLauncher.py +++ b/DMMGamePlayerFastLauncher.py @@ -251,6 +251,7 @@ def run( elif self.non_request_admin: self.error_manager.error(error=ErrorManager.permission_error) else: + args = [f'"{arg}"' for arg in args] ctypes.windll.shell32.ShellExecuteW( None, "runas", args[0], " ".join(args[1:]), None, 1 ) diff --git a/Task.py b/Task.py index 05a2caf..3a63afc 100644 --- a/Task.py +++ b/Task.py @@ -7,11 +7,16 @@ for p in psutil.process_iter(attrs=("name", "pid", "cmdline")): if p.info["name"] != "DMMGamePlayerFastLauncher.exe": continue + cmdline = p.info["cmdline"] - if "--bypass-uac" in cmdline: - cmdline.remove("--bypass-uac") + if "--non-bypass-uac" not in cmdline: + cmdline.append("--non-bypass-uac") + cmdline = [f'"{cmd}"' for cmd in cmdline] os.kill(p.info["pid"], signal.SIGTERM) + print("killed " + " ".join(cmdline)) ctypes.windll.shell32.ShellExecuteW( None, "runas", cmdline[0], " ".join(cmdline[1:]), None, 1 ) break +else: + print("Error")