Initial commit
This commit is contained in:
commit
e357408930
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
aphremove.egg-info/**
|
||||
**__pycache__**
|
18
README.md
Normal file
18
README.md
Normal 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
84
aphremove/__init__.py
Normal 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
78
aphremove/exclude.txt
Normal 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
2
aphremove/include.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Portraits\Portraits_Aphrodite_01
|
||||
Portraits\Codex\CodexPortrait_Aphrodite
|
15
setup.py
Normal file
15
setup.py
Normal 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']
|
||||
},
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user