Created
September 21, 2023 14:59
-
-
Save RedFlames/994443678d91a403d7aad24ab65b711e to your computer and use it in GitHub Desktop.
UE 5 mod package/copy/launch Python script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
import json | |
import time | |
import shutil | |
import subprocess | |
from pathlib import Path | |
import argparse | |
""" | |
I run this e.g. like this | |
$ cd "/c/Users/rf/Documents/mod_testing/" && python mod_testing.py -a | |
or | |
$ cd "/c/Users/rf/Documents/mod_testing/" && python mod_testing.py -c -l | |
""" | |
""" | |
----------------------- Argparser ----------------------- | |
""" | |
parser = argparse.ArgumentParser() | |
parser.add_argument("-v", "--verbose", help="increase output verbosity", | |
action="store_true") | |
parser.add_argument("-b", "--build", help="package", | |
action="store_true") | |
parser.add_argument("-c", "--copy", help="copy paks", | |
action="store_true") | |
parser.add_argument("-a", "--all", help="all", | |
action="store_true") | |
parser.add_argument("-l", "--launch", help="launch game", | |
action="store_true") | |
args = parser.parse_args() | |
""" | |
----------------------- Map chunk IDs to mod name ----------------------- | |
""" | |
chunks_to_mods = { | |
"2": "rebindMod_p", | |
"3": "upgradeUnlocker_p", | |
"4": "stateHistoryGUI_p", | |
"5": "customFX_p", | |
"13": "rfMod_p", | |
"1337": "levelMod_p" | |
} | |
""" | |
----------------------- get ENV vars ----------------------- | |
""" | |
pr_game_root = os.environ['PR_GAME_ROOT'] | |
pr_cook_dir = os.environ['PR_COOK_DIR'] | |
pr_ue_base = os.environ['PR_UE_BASE'] | |
pr_uproj = os.environ['PR_UPROJECT'] | |
""" | |
Examples: | |
PR_GAME_ROOT = "C:/Program Files (x86)/Steam/steamapps/common/Pseudoregalia" | |
PR_COOK_DIR = "C:/Users/rf/Documents/COOK" | |
PR_UE_BASE = "H:/UnrealEngine/UE_5.1" | |
PR_UPROJECT = "C:/Users/rf/Documents/Unreal Projects/pseudoregalia/pseudoregalia.uproject" | |
""" | |
print(f""" | |
Running with: | |
PR_GAME_ROOT = {pr_game_root} | |
PR_COOK_DIR = {pr_cook_dir} | |
PR_UE_BASE = {pr_ue_base} | |
PR_UPROJECT = {pr_uproj} | |
""") | |
""" | |
----------------------- validate paths/files ----------------------- | |
""" | |
if not os.path.isdir(pr_game_root): | |
print("Can't find path PR_GAME_ROOT") | |
sys.exit() | |
if not os.path.isdir(pr_cook_dir): | |
print("Can't find path PR_COOK_DIR") | |
sys.exit() | |
if not os.path.isdir(pr_ue_base): | |
print("Can't find path PR_UE_BASE") | |
sys.exit() | |
if not os.path.isfile(pr_uproj): | |
print("Can't find path PR_UPROJECT") | |
sys.exit() | |
game_exe = os.path.abspath(os.path.join(pr_game_root, "pseudoregalia/Binaries/Win64/pseudoregalia-Win64-Shipping.exe")) | |
target_pak_dir = os.path.abspath(os.path.join(pr_game_root, "pseudoregalia/Content/Paks/LogicMods")) | |
build_config = "Shipping" | |
print(f""" | |
game_exe = {game_exe} | |
target_pak_dir = {target_pak_dir} | |
build_config = {build_config} | |
""") | |
""" | |
----------------------- prepare UE build call ----------------------- | |
""" | |
ue_run_bat = os.path.abspath(os.path.join(pr_ue_base, "Engine/Build/BatchFiles/RunUAT.bat")) | |
unreal_exe = os.path.abspath(os.path.join(pr_ue_base, "Engine/Binaries/Win64/UnrealEditor-Cmd.exe")) | |
command = [ | |
ue_run_bat, | |
#f"-ScriptsForProject={pr_uproj}", | |
#Turnkey | |
#-command=VerifySdk | |
#"-platform=Win64", | |
#"-UpdateIfNeeded", | |
#"-project={pr_uproj}", | |
"BuildCookRun", | |
"-nop4", | |
"-utf8output", | |
"-nocompileeditor", | |
"-skipbuildeditor", | |
"-cook", | |
f"-project={pr_uproj}", | |
f"-unrealexe={unreal_exe}", | |
"-platform=Win64", | |
"-installed", | |
"-stage", | |
"-archive", | |
"-package", | |
"-build", | |
"-pak", | |
"-compressed", | |
"-prereqs", | |
f"-archivedirectory={pr_cook_dir}", | |
"-manifests", | |
f"-clientconfig={build_config}", | |
"-nodebuginfo", | |
] | |
""" | |
----------------------- Call build if applicable ----------------------- | |
""" | |
if args.build or args.all: | |
try: | |
print(f"Will now run '{command}'") | |
subprocess.run(command, check=True) | |
print(f"Cooked {pr_uproj} ({build_config}) to {pr_cook_dir}.") | |
except subprocess.CalledProcessError as e: | |
print(f"Cook Error: {e}") | |
else: | |
print(f"SKIPPED build step...") | |
""" | |
----------------------- Copy paks if applicable ----------------------- | |
""" | |
packed_chunks = os.path.abspath(os.path.join(pr_cook_dir, "Windows/pseudoregalia/Content/Paks")) | |
if args.copy or args.all: | |
for k, v in chunks_to_mods.items(): | |
chunk_name = f"pakchunk{k}-Windows.pak" | |
chunk_abs = os.path.abspath(os.path.join(packed_chunks, chunk_name)) | |
if not os.path.isfile(chunk_abs): | |
print(f"Cannot find chunk file {chunk_name} for mod {v}!") | |
continue | |
target_file = os.path.abspath(os.path.join(target_pak_dir, f"{v}.pak")) | |
print(f""" | |
Copying: | |
FROM {chunk_abs} | |
TO {target_file} | |
... | |
""") | |
shutil.copy2(chunk_abs, target_file) | |
else: | |
print(f"SKIPPED copy step...") | |
""" | |
----------------------- Launch game if applicable ----------------------- | |
""" | |
command = [ | |
"C:\Program Files (x86)\Steam\steam.exe", | |
"steam://rungameid/2365810" | |
] | |
if args.launch or args.all: | |
print(""" | |
--------- | |
Launching game... | |
--------- | |
""") | |
subprocess.run(command) | |
else: | |
print(f"SKIPPED launch step...") | |
sys.exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment