Skip to content

Commit

Permalink
Removed history due to ilegal data
Browse files Browse the repository at this point in the history
  • Loading branch information
janhohenheim committed Sep 28, 2021
0 parents commit 312f1e1
Show file tree
Hide file tree
Showing 12 changed files with 1,300 additions and 0 deletions.
139 changes: 139 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

108 changes: 108 additions & 0 deletions install_majoras_mask_3d/citra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
from tempfile import TemporaryDirectory
import os
import tarfile
from shutil import copyfile, copytree
import subprocess
from time import sleep
from threading import Thread

from install_majoras_mask_3d.utility import download_file, get_only_subdirectory_path, kill_child_processes
from install_majoras_mask_3d.paths import (
get_citra_config_directory,
get_citra_directory,
get_citra_sysdata_directory,
)


def install_and_configure_citra(url):
_install_citra(url)
_install_citra_aes_keys()


def install_cia(cia_path):
citra_program = os.path.join(".", get_citra_directory(), "citra.exe")
print(f"'{citra_program}'")
subprocess.run([citra_program, "-i", cia_path])


def _install_citra(url):
"""
Downloads and installs Citra and returns the path to the Citra directory.
"""
citra_directory = get_citra_directory()
if os.path.isdir(citra_directory):
return

with TemporaryDirectory() as temp_directory:
file_path = os.path.join(temp_directory, f"citra.tar.gz")
download_file(url, file_path)
with tarfile.open(file_path, "r:gz") as tar:
tar.extractall(temp_directory)
temp_citra_directory = get_only_subdirectory_path(temp_directory)
copytree(temp_citra_directory, citra_directory, dirs_exist_ok=True)


def _install_citra_aes_keys():
"""
Returns the path to the Citra configuration directory.
"""
target_directory = get_citra_sysdata_directory()
script_directory = os.path.abspath(os.path.dirname(__file__))
source_directory = os.path.join(script_directory, "data")
filename = "aes_keys.txt"
source_file = os.path.join(target_directory, filename)
target_file = os.path.join(target_directory, filename)
copyfile(os.path.join(source_directory, filename), target_file)
if not os.path.isfile(target_file):
copyfile(source_file, target_file)

def set_graphics_options():
thread = Thread(target = _initialize_config)
thread.start()
sleep(2)
kill_child_processes()
thread.join()
options = {
"texture_filter_name": "xBRZ freescale",
"custom_textures": "true",
"resolution_factor": "0",
"layout_option": "2",
}
old_config = _read_config()
new_config = _set_options(old_config, options)
_write_config(new_config)

def _initialize_config():
citra_directory = get_citra_directory()
citra_executable = os.path.join(citra_directory, "citra-qt.exe")
subprocess.run([citra_executable])

def _read_config():
config_path = _get_config_file_path()
with open(config_path, "r") as config_file:
return config_file.readlines()

def _write_config(config):
config_path = _get_config_file_path()
with open(config_path, "w") as config_file:
config_file.writelines(config)

def _get_config_file_path():
config_directory = get_citra_config_directory()
return os.path.join(config_directory, "qt-config.ini")


def _set_options(config, options):
new_config = []
for line in config:
new_line = None
for key, value in options.items():
if line.startswith(f"{key}\\default"):
new_line = f"{key}\\default=false\r"
break
elif line.startswith(key):
new_line = f"{key}={value}\r"
break
new_config.append(new_line) if new_line else new_config.append(line)
return new_config

52 changes: 52 additions & 0 deletions install_majoras_mask_3d/data/aes_keys.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
generator=1FF9E9AAC5FE0408024591DC5D52768A
slot0x03KeyX=647C9FFB4E494E54454E444F0D0AEE88
slot0x18KeyX=82E9C9BEBFB8BDB875ECC0A07D474374
slot0x19KeyX=F5367FCE73142E66ED13917914B7F2EF
slot0x1AKeyX=EABA984C9CB766D4A3A7E974E2E713A3
slot0x1BKeyX=45AD04953992C7C893724A9A7BCE6182
slot0x1CKeyX=C3830F8156E3543B723F0BC046741E8F
slot0x1DKeyX=D6B38BC759417596D619D6029D13E0D8
slot0x1EKeyX=BB623A97DDD793D757C4104B8D9FB969
slot0x1FKeyX=4C28EC6EFFA3C23646078BBA350C7995
slot0x25KeyX=CEE7D8AB30C00DAE850EF5E382AC5AF3
slot0x2CKeyX=B98E95CECA3E4D171F76A94DE934C053
slot0x2DKeyX=B98E95CECA3E4D171F76A94DE934C053
slot0x2EKeyX=B98E95CECA3E4D171F76A94DE934C053
slot0x2FKeyX=B98E95CECA3E4D171F76A94DE934C053
slot0x30KeyX=C66E23128F289133F04CDB877A3749F2
slot0x31KeyX=C66E23128F289133F04CDB877A3749F2
slot0x32KeyX=C66E23128F289133F04CDB877A3749F2
slot0x33KeyX=C66E23128F289133F04CDB877A3749F2
slot0x34KeyX=6FBB01F872CAF9C01834EEC04065EE53
slot0x35KeyX=6FBB01F872CAF9C01834EEC04065EE53
slot0x36KeyX=6FBB01F872CAF9C01834EEC04065EE53
slot0x37KeyX=6FBB01F872CAF9C01834EEC04065EE53
slot0x38KeyX=B529221CDDB5DB5A1BF26EFF2041E875
slot0x3AKeyX=B529221CDDB5DB5A1BF26EFF2041E875
slot0x3BKeyX=B529221CDDB5DB5A1BF26EFF2041E875
slot0x03KeyY=76DCB90AD3C44DBD1DDD2D200500A0E1
slot0x06KeyY=24B05AAAAC0B099252030C02D1040317
slot0x07KeyY=E9ACC5ABD4AD3F0660C83C8934882F3F
slot0x2EKeyY=7462553F9E5A7904B8647CCA736DA1F5
slot0x2FKeyY=C369BAA21E188A88A9AA94E5506A9F16
slot0x31KeyY=7462553F9E5A7904B8647CCA736DA1F5
slot0x0DKeyN=E7C9FF9D4F5B6F4DC5E2F50E856F0AB2
slot0x15KeyN=2AF3BBD32CD59C06FD4ABE58651987AD
slot0x16KeyN=2AF3BBD32CD59C06FD4ABE58651987AD
slot0x19KeyN=5DDD4739037BC6A870E620B70F673504
slot0x1AKeyN=5DDD4739037BC6A870E620B70F673504
slot0x1BKeyN=5DDD4739037BC6A870E620B70F673504
slot0x1CKeyN=59F4399C2F95A4128A1FE49D4DB686DD
slot0x1DKeyN=59F4399C2F95A4128A1FE49D4DB686DD
slot0x1EKeyN=59F4399C2F95A4128A1FE49D4DB686DD
slot0x1FKeyN=59F4399C2F95A4128A1FE49D4DB686DD
slot0x24KeyN=BBE8B4E09D0937816B234D8EB3CD3CA2
slot0x2DKeyN=3ED6F5CF2CC37C54655000B7C8B52E0D
slot0x2EKeyN=3ED6F5CF2CC37C54655000B7C8B52E0D
slot0x2FKeyN=3ED6F5CF2CC37C54655000B7C8B52E0D
slot0x31KeyN=59FC817E6446EA6190347B20E9BDCE52
slot0x32KeyN=B87E64018B190FFE048A8124C6454196
slot0x36KeyN=28C0D59B736657BCDF50FF174979958A
slot0x37KeyN=28C0D59B736657BCDF50FF174979958A
slot0x38KeyN=6E78A3BE9BDDDA09BFD569483F24FCE0
slot0x3BKeyN=6E78A3BE9BDDDA09BFD569483F24FCE0
24 changes: 24 additions & 0 deletions install_majoras_mask_3d/hd_textures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from tempfile import TemporaryDirectory
import os
from zipfile import ZipFile
from install_majoras_mask_3d.utility import download_file, copy_and_overwrite_files
from install_majoras_mask_3d.paths import get_citra_textures_directory

def download_hd_textures(url):
with TemporaryDirectory() as temp_directory:
filename = "hd_textures.zip"
file_path = os.path.join(temp_directory, filename)
download_file(url, file_path)
hd_texture_directory = os.path.join(temp_directory, "hd_textures")
with ZipFile(file_path, 'r') as archive:
archive.extractall(hd_texture_directory)
textures = ["[Main]", "[Fonts] Original WW (resembles 3DS)", "[Link] Nerrel Style", "[Link's Tunic] Nerrel Style"]
_copy_textures(textures, hd_texture_directory)

def _copy_textures(textures, parent_directory):
for texture in textures:
source_directory = os.path.join(parent_directory, texture)
target_path = get_citra_textures_directory()
files = [f for f in os.listdir(source_directory) if os.path.isfile(os.path.join(source_directory, f))]
copy_and_overwrite_files(files, source_directory, target_path)

58 changes: 58 additions & 0 deletions install_majoras_mask_3d/paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import os
from pathlib import Path

GAME_ID = "0004000000125500"


def get_citra_directory():
"""
Returns the path to the Citra directory.
"""
installation_directory = os.getenv("LOCALAPPDATA")
return os.path.join(installation_directory, "Citra")


def get_citra_settings_directory():
"""
Returns the path to the Citra config directory.
"""
roaming = os.getenv("APPDATA")
return os.path.join(roaming, "Citra")


def get_citra_mods_directory():
"""
Returns the path to the Citra mods directory.
"""
return _get_citra_load_directory("mods")


def get_citra_config_directory():
"""
Returns the path to the Citra config directory.
"""
citra_settings = get_citra_settings_directory()
return os.path.join(citra_settings, "config")


def get_citra_textures_directory():
"""
Returns the path to the Citra textures directory.
"""
return _get_citra_load_directory("textures")


def get_citra_sysdata_directory():
directory = os.path.join(get_citra_settings_directory(), "sysdata")
return _ensure_exists(directory)


def _get_citra_load_directory(subdirectory):
citra_settings = get_citra_settings_directory()
load_path = os.path.join(citra_settings, "load", subdirectory, GAME_ID)
return _ensure_exists(load_path)


def _ensure_exists(path):
Path(path).mkdir(parents=True, exist_ok=True)
return path
Loading

0 comments on commit 312f1e1

Please sign in to comment.