Skip to content

Commit

Permalink
installer add unattended mode for Crowd Control one click install
Browse files Browse the repository at this point in the history
  • Loading branch information
Die4Ever committed Jun 25, 2023
1 parent 62b70ed commit 1579130
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 32 deletions.
20 changes: 2 additions & 18 deletions installer/GUI/InstallerWindow.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import webbrowser
from GUI import *
from pathlib import Path
from Install import Install, IsWindows
from Install import Install, IsWindows, getDefaultPath
import traceback
import re

Expand Down Expand Up @@ -85,7 +85,7 @@ def InitFlavorSettings(self, f: str, row, pad) -> int:

settings = { 'install': v, 'exe': exe }

if f in ['Vanilla', '#Vanilla? Madder.']: # TODO: VMD is commented out, needs map files and UnrealScript work
if f in ['Vanilla', '####Vanilla? Madder.']: # TODO: VMD is commented out, needs map files and UnrealScript work
v = BooleanVar(master=self.frame, value=True)
settings['mirrors'] = v
c = Checkbutton(self.frame, text="Download mirrored maps for "+f, variable=v)
Expand Down Expand Up @@ -181,19 +181,3 @@ def DownloadProgress(self, blocks:int, blocksize:int, totalsize:int, status='Dow

def main():
InstallerWindow()


def getDefaultPath():
checks = [
Path("C:\\") / "Program Files (x86)" / "Steam" / "steamapps" / "common" / "Deus Ex" / "System",
Path("D:\\") / "Program Files (x86)" / "Steam" / "steamapps" / "common" / "Deus Ex" / "System",
Path.home() /'snap'/'steam'/'common'/'.local'/'share'/'Steam'/'steamapps'/'common'/'Deus Ex'/'System',
Path.home() /'.steam'/'steam'/'SteamApps'/'common'/'Deus Ex'/'System',
Path.home() /'.local'/'share'/'Steam'/'steamapps'/'common'/'Deus Ex'/'System',
]
p:Path
for p in checks:
f:Path = p / "DeusEx.exe"
if f.exists():
return p
return None
40 changes: 35 additions & 5 deletions installer/Install/Install.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,45 @@
from Install import _DetectFlavors
from Install import MapVariants

def UnattendedInstall(installpath:str, downloadmirrors):
if not installpath:
p:Path = getDefaultPath()
p = p / 'DeusEx.exe'
else:
p:Path = Path(installpath)
if p.is_dir() and p.name == 'System':
p = p / 'DeusEx.exe'

assert p.exists(), str(p)

callback = lambda a,b,c, status='Downloading' : print(status, a,b,c)
flavors = DetectFlavors(p)
settings = {}
for f in flavors:
settings[f] = {'downloadcallback': callback}

if downloadmirrors and 'Vanilla' in settings:
settings['Vanilla']['mirrors'] = True

ret = Install(p, settings, True)


def DetectFlavors(exe:Path) -> list:
assert exe.exists(), str(exe)
assert exe.name.lower() == 'deusex.exe'
system:Path = exe.parent
assert system.name.lower() == 'system'

return _DetectFlavors(system)


def Install(exe:Path, flavors:dict, speedupfix:bool) -> dict:
assert exe.exists(), str(exe)
assert exe.name.lower() == 'deusex.exe'
system:Path = exe.parent
assert system.name.lower() == 'system'

print('Installing flavors:', flavors, speedupfix)
print('Installing flavors:', flavors, speedupfix, exe)

for(f, settings) in flavors.items():
ret={}
Expand All @@ -34,12 +60,16 @@ def Install(exe:Path, flavors:dict, speedupfix:bool) -> dict:
if 'Revision'==f:
ret = InstallRevision(system, settings)
if 'HX'==f:
ret =InstallHX(system, settings)
ret = InstallHX(system, settings)
if ret and settings:
settings.update(ret)

if speedupfix:
EngineDllFix(system)

if GetVerbose():
print("Install returning", flavors)

return flavors


Expand All @@ -50,7 +80,7 @@ def InstallVanilla(system:Path, settings:dict, speedupfix:bool):
InstallLDDP(system, settings)

exe_source = GetSourcePath() / '3rdParty' / "KentieDeusExe.exe"
exetype = settings['exetype']
exetype = settings.get('exetype')
kentie = True
if exetype == 'Launch':
exe_source = GetSourcePath() / '3rdParty' / "Launch.exe"
Expand Down Expand Up @@ -108,8 +138,8 @@ def InstallVanilla(system:Path, settings:dict, speedupfix:bool):
WriteBytes(DXRandoini, b)

dxrroot = gameroot / 'DXRando'
(dxrroot / 'Maps').mkdir(exist_ok=True, parents=True)
(dxrroot / 'System').mkdir(exist_ok=True, parents=True)
Mkdir((dxrroot / 'Maps'), exist_ok=True, parents=True)
Mkdir((dxrroot / 'System'), exist_ok=True, parents=True)
CopyPackageFiles('vanilla', gameroot, ['DeusEx.u'])
CopyD3D10Renderer(system)

Expand Down
3 changes: 3 additions & 0 deletions installer/Install/MapVariants.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

def InstallMirrors(mapsdir: Path, callback: callable, flavor:str):
print('\nInstallMirrors(', mapsdir, flavor, ')')
callback(0, 1, 1, 'Checking Maps')
totalmd5 = Md5Maps(mapsdir)
callback(1, 1, 1, 'Checking Maps')

if totalmd5 == 'd41d8cd98f00b204e9800998ecf8427e': # no map files found
print('no mirrored maps found')
elif totalmd5 == '265d1d8bef836074c28303c9326f5d35': # mirrored maps v0.7
Expand Down
58 changes: 52 additions & 6 deletions installer/Install/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@
import certifi
import ssl

verbose = False
dryrun = False
def SetDryrun(val):
def SetVerbose(val:bool):
global verbose
verbose = val

def GetVerbose() -> bool:
global verbose
return verbose

def SetDryrun(val:bool):
global dryrun
dryrun = val

Expand Down Expand Up @@ -51,6 +60,23 @@ def GetSourcePath() -> Path:
return p
raise RuntimeError('failed to GetSourcePath()', p)


def getDefaultPath():
checks = [
Path("C:\\") / "Program Files (x86)" / "Steam" / "steamapps" / "common" / "Deus Ex" / "System",
Path("D:\\") / "Program Files (x86)" / "Steam" / "steamapps" / "common" / "Deus Ex" / "System",
Path.home() /'snap'/'steam'/'common'/'.local'/'share'/'Steam'/'steamapps'/'common'/'Deus Ex'/'System',
Path.home() /'.steam'/'steam'/'SteamApps'/'common'/'Deus Ex'/'System',
Path.home() /'.local'/'share'/'Steam'/'steamapps'/'common'/'Deus Ex'/'System',
]
p:Path
for p in checks:
f:Path = p / "DeusEx.exe"
if f.exists():
return p
return None


def GetPackagesPath(modname:str) -> Path:
# TODO: these source files will be split up into a separate folder for each modname when we start using consistent filenames
p = GetSourcePath()
Expand All @@ -71,14 +97,25 @@ def _DetectFlavors(system:Path):
vanilla_md5 = None
is_vanilla = False

deusexu_md5s = {
'd343da03a6d311ee412dfae4b52ff975': 'vanilla',
'5964bd1dcea8edb20cb1bc89881b0556': 'DXRando v2.5',
}

if (game / 'VMDSim').is_dir():
return ['Vanilla? Madder.']# VMD seems like it can only exist by itself
flavors = ['Vanilla? Madder.']# VMD seems like it can only exist by itself
if GetVerbose():
print("_DetectFlavors", flavors)
return flavors

if (system / 'DeusEx.u').exists():
flavors.append('Vanilla')
vanilla_md5 = MD5((system / 'DeusEx.u').read_bytes())
if vanilla_md5 == 'd343da03a6d311ee412dfae4b52ff975':
md5_name = deusexu_md5s.get(vanilla_md5)
if md5_name == 'vanilla':
is_vanilla = True
elif md5_name:
print("found DeusEx.u", md5_name, vanilla_md5)
else:
print('unknown MD5 for DeusEx.u', vanilla_md5)

Expand All @@ -95,6 +132,8 @@ def _DetectFlavors(system:Path):
if (game / 'Revision').is_dir():
flavors.append('Revision')

if GetVerbose():
print("_DetectFlavors", flavors)
return flavors


Expand Down Expand Up @@ -170,24 +209,31 @@ def Mkdir(dir:Path, parents=False, exist_ok=False):
if GetDryrun():
print("dryrun would've created folder", dir)
else:
if GetVerbose():
print("creating folder", dir)
dir.mkdir(parents=parents, exist_ok=exist_ok)

def WriteBytes(out:Path, data:bytes):
if GetDryrun():
print("dryrun would've written to", out)
print("dryrun would've written", len(data), "bytes to", out)
else:
if GetVerbose():
print("writing", len(data), "bytes to", out)
out.write_bytes(data)


def CopyTo(source:Path, dest:Path, silent:bool=False):
if not silent:
if GetVerbose() or not silent:
print('Copying', source, 'to', dest)
bytes = source.read_bytes()
WriteBytes(dest, bytes)


def MD5(bytes:bytes) -> str:
return hashlib.md5(bytes).hexdigest()
ret = hashlib.md5(bytes).hexdigest()
if GetVerbose():
print("MD5 of", len(bytes), " bytes is", ret)
return ret


def DownloadFile(url, dest, callback):
Expand Down
24 changes: 21 additions & 3 deletions installer/installer.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
import argparse
import sys
import traceback

import GUI.InstallerWindow
from Install import SetDryrun
from Install import SetDryrun, SetVerbose
from Install.Install import UnattendedInstall

parser = argparse.ArgumentParser(description='Deus Ex Randomizer')
parser.add_argument('--version', action="store_true", help='Output version')
parser.add_argument('--dryrun', action="store_true", help="Dry run, don't actually change anything")
#parser.add_argument('--verbose', action="store_true", help="Output way more to the console")
parser.add_argument('--unattended', action="store_true", help='Unattended installation')
parser.add_argument('--path', help='Path to DeusEx.exe for installation')
parser.add_argument('--downloadmirrors', action="store_true", help='Default to download mirrored maps for unattended installations')
parser.add_argument('--verbose', action="store_true", help="Output way more to the console")
args = parser.parse_args()

def GetVersion():
return 'v0.2'
return 'v0.3'

if args.version:
print('DXRando Installer version:', GetVersion(), file=sys.stderr)
print('Python version:', sys.version_info, file=sys.stderr)
sys.exit(0)

if args.verbose:
SetVerbose(True)

if args.dryrun:
SetDryrun(True)

if args.unattended:
try:
UnattendedInstall(args.path, args.downloadmirrors)
sys.exit(0)
except Exception as e:
print('\n\nError!')
print(e, '\n')
print(traceback.format_exc())
print('falling back to manual install')

GUI.InstallerWindow.main()

0 comments on commit 1579130

Please sign in to comment.