Initial commit

This commit is contained in:
Joseph Montanaro 2021-04-17 16:44:55 -07:00
commit e357408930
6 changed files with 199 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
aphremove.egg-info/**
**__pycache__**

18
README.md Normal file
View File

@ -0,0 +1,18 @@
This script removes the Aphrodite textures from Supergiant Games' *Hades*.
## Installation
git clone https://git.jfmonty2.com/jfmonty2/aphremove.git
pip install -e aphremove
aphremove
If Hades is installed to a Steam library folder somewhere other than the standard `C:\Program Files (x86)\Steam`, then
aphremove path\to\steam\dir
## Notes
All heavy lifting is done by [quaerus/deppth](https://github.com/quaerus/deppth).
There is no way I would have been able to reverse-engineer the Hades package format on my own.

84
aphremove/__init__.py Normal file
View File

@ -0,0 +1,84 @@
import json
import os, os.path
import pathlib
import sys
import tempfile
from deppth import deppth # not sure why the nested path
from PIL import Image, ImageDraw
def get_list(filename):
d = pathlib.Path(__file__).parent
lines = (d / filename).read_text().splitlines()
return set(lines)
def remove_subtexture(package_dir, manifest, sub_atlas):
filename = manifest['name'].split(os.path.sep)[-1] + '.png'
file = package_dir / 'textures/atlases' / filename
img = Image.open(file)
draw = ImageDraw.Draw(img)
r = sub_atlas['rect']
top_left = (r['x'], r['y'])
bottom_right = (r['x'] + r['width'], r['y'] + r['height'])
draw.rectangle(xy=(top_left, bottom_right), fill=(0, 0, 0, 0))
img.save(file)
def process_pkg(src_path, include, exclude):
print('Processing package', src_path,)
with tempfile.TemporaryDirectory() as tmp:
tmp = pathlib.Path(tmp)
pkg_dir = str(tmp / 'package')
print('Extracting package - this may take some time.')
deppth.extract(src_path, pkg_dir)
manifests = []
for m in (tmp / 'package/manifest').iterdir():
with open(m) as f:
manifests.append(json.load(f))
print('Removing subtextures')
modified = []
for manifest in manifests:
for sub in manifest['subAtlases']:
if 'aphrodite' in sub['name'].lower():
if sub['name'] in include:
remove_subtexture(tmp / 'package', manifest, sub)
manifest_name = manifest['name'].split(os.path.sep)[-1]
modified.append(manifest_name)
elif sub['name'] not in exclude:
print(f'WARNING: Unknown texture "{sub["name"]}". You may wish to add this texture to include.txt or exclude.txt.')
print('Constructing patches')
patch_path = str(tmp / 'patch.pkg')
deppth.pack(pkg_dir, patch_path, *modified)
print('Repacking package')
deppth.patch(src_path, patch_path)
print('Finished processing package.')
def run():
if len(sys.argv) > 1:
steam_dir = sys.argv[1]
else:
steam_dir = 'C:/Program Files (x86)/Steam'
base_dir = pathlib.Path(steam_dir) / 'steamapps/common/Hades/Content/Win/Packages'
if not base_dir.exists():
print(f'Could not find Hades at {base_dir}. Is {steam_dir} the correct location for your Steam library?')
return 1
include = get_list('include.txt')
exclude = get_list('exclude.txt')
for pkg in 'BC3/GUI.pkg', 'GUI.pkg', '720p/GUI.pkg':
path = str(base_dir / pkg)
process_pkg(path, include, exclude)
print()
print('Finished.')
if __name__ == '__main__':
run()

78
aphremove/exclude.txt Normal file
View File

@ -0,0 +1,78 @@
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0001
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0002
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0003
GUI\Screens\BoonIcons\Aphrodite_05_Large
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0004
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0005
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0006
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0007
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0008
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0009
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0045
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0047
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0048
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0049
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0010
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0050
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0011
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0040
GUI\HUD\BoonIconAphrodite
GUI\Screens\BoonIcons\Aphrodite_13_Large
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0041
GUI\Screens\BoonIcons\Aphrodite_09_Large
GUI\Screens\BoonIcons\Aphrodite_11_Large
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0012
GUI\Icons\RoomReward\Aphrodite
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0042
GUI\Screens\BoonIcons\Aphrodite_secondary_attack
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0043
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0044
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0014
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0046
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0015
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0016
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0017
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0018
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0019
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0021
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0022
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0023
GUI\Screens\BoonIcons\Aphrodite_07_Large
GUI\Screens\BoonIcons\Aphrodite_12_Large
GUI\Screens\BoonIcons\Aphrodite_Athena_01
GUI\Screens\BoonIcons\Aphrodite_01_Large
GUI\Screens\AwardMenu\KeepsakeMaxGift\Aphrodite_02
GUI\Screens\AwardMenu\KeepsakeMaxGift\Aphrodite
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0013
GUI\Screens\BoonSelectSymbols\Aphrodite
GUI\Epilogue\Olympus_Aphrodite
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0024
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0025
GUI\Screens\BoonSelectSymbols\Aphrodite2
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0020
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0026
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0032
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0034
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0027
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0035
GUI\Screens\BoonIcons\Ares_Aphrodite_01
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0028
GUI\Screens\BoonIcons\Zeus_Aphrodite_01
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0029
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0030
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0031
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0033
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0037
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0036
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0038
GUI\Screens\BoonSelectSymbols\Spin\AphroditeIconSpin\AphroditeIconSpin0039
GUI\Screens\BoonIcons\Aphrodite_03_Large
GUI\Screens\BoonIcons\Aphrodite_04_Large
GUI\Screens\BoonIcons\Artemis_Aphrodite_01
GUI\Screens\BoonIcons\Aphrodite_06_Large
GUI\Screens\BoonIcons\Aphrodite_10_Large
GUI\Screens\BoonIcons\Aphrodite_Demeter_01
GUI\Screens\BoonIcons\Aphrodite_Poseidon_01
GUI\Screens\BoonIcons\Dionysus_Aphrodite_01
GUI\Screens\BoonIcons\Aphrodite_02_Large
GUI\Screens\BoonIcons\Aphrodite_08_Large

2
aphremove/include.txt Normal file
View File

@ -0,0 +1,2 @@
Portraits\Portraits_Aphrodite_01
Portraits\Codex\CodexPortrait_Aphrodite

15
setup.py Normal file
View File

@ -0,0 +1,15 @@
from setuptools import setup, find_packages
setup(
name='aphremove',
description='Remove Aphrodite textures from Hades game',
author='Joseph Montanaro',
install_requires=[
'deppth@https://github.com/quaerus/deppth/releases/download/v0.1.0.0/deppth-0.1.0.0-py3-none-any.whl',
'pillow'
],
packages=find_packages(),
entry_points = {
'console_scripts': ['aphremove = aphremove:run']
},
)