Feature/enhancement: Support for D2R launch options and cosmetic mods (#677)
Breaking change to param: `d2r_path`
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
{
|
||||
|
||||
"name": "ifilter",
|
||||
|
||||
"savepath": "../"
|
||||
|
||||
}
|
||||
+2
-1
@@ -14,7 +14,7 @@ loot_screenshots=0
|
||||
discord_status_count=20
|
||||
discord_status_condensed=1
|
||||
saved_games_folder=
|
||||
d2r_path=C:\Program Files (x86)\Diablo II Resurrected\D2R.exe
|
||||
d2r_path=C:\Program Files (x86)\Diablo II Resurrected
|
||||
; if you set this field to 1, botty will save the top-most visible character template just after
|
||||
; the online/offline tab and upon restart will attempt to find the same template to select the char
|
||||
restart_d2r_when_stuck=0
|
||||
@@ -280,3 +280,4 @@ hwnd_window_process=D2R\.exe
|
||||
;If you want to control Hyper-V window from host use 0,51 here
|
||||
window_client_area_offset=0,0
|
||||
ocr_during_pickit=0
|
||||
launch_options=-mod ifilter -txt
|
||||
|
||||
+2
-1
@@ -222,7 +222,7 @@ class Config:
|
||||
"discord_status_condensed": bool(int(self._select_val("general", "discord_status_condensed"))),
|
||||
"info_screenshots": bool(int(self._select_val("general", "info_screenshots"))),
|
||||
"loot_screenshots": bool(int(self._select_val("general", "loot_screenshots"))),
|
||||
"d2r_path": self._select_val("general", "d2r_path"),
|
||||
"d2r_path": _default_iff(self._select_val("general", "d2r_path"), "", "C:\Program Files (x86)\Diablo II Resurrected"),
|
||||
"restart_d2r_when_stuck": bool(int(self._select_val("general", "restart_d2r_when_stuck"))),
|
||||
}
|
||||
|
||||
@@ -366,6 +366,7 @@ class Config:
|
||||
"hwnd_window_process": _default_iff(Config()._select_val("advanced_options", "hwnd_window_process"), ''),
|
||||
"window_client_area_offset": tuple(map(int, Config()._select_val("advanced_options", "window_client_area_offset").split(","))),
|
||||
"ocr_during_pickit": bool(int(self._select_val("advanced_options", "ocr_during_pickit"))),
|
||||
"launch_options": self._select_val("advanced_options", "launch_options"),
|
||||
"override_capabilities": _default_iff(Config()._select_optional("advanced_options", "override_capabilities"), ""),
|
||||
}
|
||||
|
||||
|
||||
+58
-16
@@ -4,7 +4,7 @@ import shutil
|
||||
|
||||
from config import Config
|
||||
from mss import mss
|
||||
from utils.misc import close_down_d2
|
||||
from utils.misc import close_down_bnet_launcher, close_down_d2
|
||||
|
||||
|
||||
def get_d2r_folder() -> str:
|
||||
@@ -25,27 +25,66 @@ def get_d2r_folder() -> str:
|
||||
assert(f"Could not find D2R Saved Games at {d2_saved_games}")
|
||||
return d2_saved_games
|
||||
|
||||
|
||||
def backup_settings():
|
||||
d2_saved_games = get_d2r_folder()
|
||||
if os.path.exists(d2_saved_games + "\\Settings_backup.json"):
|
||||
r = input("Backup file already exist, are you sure you want to overwrite it? [y] to confirm")
|
||||
if r == 'y':
|
||||
shutil.copyfile(d2_saved_games + "\\Settings.json", d2_saved_games + "\\Settings_backup.json")
|
||||
print("Settings backed up successfully.")
|
||||
else:
|
||||
shutil.copyfile(d2_saved_games + "\\Settings.json", d2_saved_games + "\\Settings_backup.json")
|
||||
print("Settings backed up successfully.")
|
||||
backup_file = f"{d2_saved_games}/Settings_backup.json"
|
||||
current_file = f"{d2_saved_games}/Settings.json"
|
||||
if os.path.exists(backup_file):
|
||||
r = input("D2R settings backup already exists, are you sure you want to overwrite it? [y] to confirm")
|
||||
if not r == 'y':
|
||||
return
|
||||
shutil.copyfile(current_file, backup_file)
|
||||
print("D2R settings backed up successfully.")
|
||||
|
||||
backup_file = f"{d2_saved_games}/launch_options_backup.txt"
|
||||
current_file = f"{os.getenv('APPDATA')}/Battle.net/Battle.net.config"
|
||||
if os.path.exists(backup_file):
|
||||
r = input("D2R launch options backup already exists, are you sure you want to overwrite it? [y] to confirm")
|
||||
if not r == 'y':
|
||||
return
|
||||
f = open(current_file)
|
||||
curr_settings = json.load(f)
|
||||
launch_options = curr_settings["Games"]["osi"]["AdditionalLaunchArguments"]
|
||||
with open(backup_file, 'w') as f:
|
||||
f.write(launch_options)
|
||||
print("D2R launch options backed up successfully.")
|
||||
|
||||
def restore_settings_from_backup():
|
||||
d2_saved_games = get_d2r_folder()
|
||||
if os.path.exists(d2_saved_games + "\\Settings_backup.json"):
|
||||
close_down_d2()
|
||||
shutil.copyfile(d2_saved_games + "\\Settings_backup.json", d2_saved_games + "\\Settings.json")
|
||||
print("Settings restored successfully.")
|
||||
else:
|
||||
print("No backup was found, couldn't restore settings.")
|
||||
backup_file = f"{d2_saved_games}/Settings_backup.json"
|
||||
current_file = f"{d2_saved_games}/Settings.json"
|
||||
if not os.path.exists(backup_file):
|
||||
print("No D2R settings backup file was found, couldn't restore.")
|
||||
return
|
||||
close_down_d2()
|
||||
shutil.copyfile(backup_file, current_file)
|
||||
print("D2R settings restored successfully.")
|
||||
|
||||
backup_file = f"{d2_saved_games}/launch_options_backup.txt"
|
||||
current_file = f"{os.getenv('APPDATA')}/Battle.net/Battle.net.config"
|
||||
if not os.path.exists(backup_file):
|
||||
print("No D2R launch options backup file was found, couldn't restore.")
|
||||
return
|
||||
with open(backup_file, 'r') as f:
|
||||
launch_options = f.read().strip()
|
||||
set_launch_settings(launch_options)
|
||||
print("D2R launch options restored successfully.")
|
||||
|
||||
def set_launch_settings(launch_options):
|
||||
close_down_bnet_launcher()
|
||||
f = open(f"{os.getenv('APPDATA')}/Battle.net/Battle.net.config")
|
||||
curr_settings = json.load(f)
|
||||
curr_settings["Games"]["osi"]["AdditionalLaunchArguments"] = launch_options
|
||||
with open(f"{os.getenv('APPDATA')}/Battle.net/Battle.net.config", 'w') as outfile:
|
||||
json.dump(curr_settings, outfile, indent=4)
|
||||
|
||||
def copy_mod_files():
|
||||
new_path = f"{Config().general['d2r_path']}/mods"
|
||||
try:
|
||||
shutil.rmtree(new_path)
|
||||
shutil.copytree("assets/mods", new_path)
|
||||
except OSError as error:
|
||||
print(error)
|
||||
|
||||
def adjust_settings():
|
||||
close_down_d2()
|
||||
@@ -57,6 +96,9 @@ def adjust_settings():
|
||||
os._exit(1)
|
||||
d2_saved_games = get_d2r_folder()
|
||||
# adjust settings
|
||||
if Config().advanced_options["launch_options"]:
|
||||
set_launch_settings(Config().advanced_options["launch_options"])
|
||||
copy_mod_files()
|
||||
f = open(d2_saved_games + "\\Settings.json")
|
||||
curr_settings = json.load(f)
|
||||
f = open("assets/d2r_settings.json")
|
||||
|
||||
@@ -25,6 +25,9 @@ import psutil
|
||||
def close_down_d2():
|
||||
subprocess.call(["taskkill","/F","/IM","D2R.exe"], stderr=subprocess.DEVNULL)
|
||||
|
||||
def close_down_bnet_launcher():
|
||||
subprocess.call(["taskkill","/F","/IM","Battle.net.exe"], stderr=subprocess.DEVNULL)
|
||||
|
||||
@dataclass
|
||||
class WindowSpec:
|
||||
title_regex: 'Union[str, None]' = None
|
||||
|
||||
@@ -22,15 +22,11 @@ def kill_game():
|
||||
os.system("taskkill /f /im D2R.exe")
|
||||
wait(1.0, 1.5)
|
||||
|
||||
def restart_game(d2_path = None):
|
||||
if not d2_path:
|
||||
path = "C:\Program Files (x86)\Diablo II Resurrected\D2R.exe"
|
||||
else:
|
||||
path = d2_path
|
||||
def restart_game(d2_path):
|
||||
kill_game()
|
||||
wait(1.0, 1.5)
|
||||
# This method should function similar to opening the exe via double-click
|
||||
os.startfile(path)
|
||||
os.startfile(f"{d2_path}/D2R.exe")
|
||||
wait(4.4, 5.5)
|
||||
for i in range(20):
|
||||
keyboard.send("space")
|
||||
|
||||
Reference in New Issue
Block a user