mirror of
https://github.com/Faraphel/Atlas-Install.git
synced 2025-07-02 02:38:30 +02:00
added get_hash_map and comp_dict_changes to get information about all the files of an extracted game
This commit is contained in:
parent
b9d6913e22
commit
9f8aa05c04
7 changed files with 72 additions and 33 deletions
|
@ -1,9 +1,3 @@
|
|||
import os
|
||||
import sys
|
||||
from threading import Thread
|
||||
from typing import Callable
|
||||
|
||||
|
||||
# metadata
|
||||
__version__ = (0, 12, 0)
|
||||
__author__ = 'Faraphel'
|
||||
|
@ -21,33 +15,10 @@ Mo: int = 1_000 * Ko
|
|||
Go: int = 1_000 * Mo
|
||||
|
||||
minimum_space_available: int = 15*Go
|
||||
file_block_size: int = 128*Ko
|
||||
|
||||
|
||||
# global type hint
|
||||
TemplateSafeEval: str
|
||||
TemplateMultipleSafeEval: str
|
||||
Env: dict[str, any]
|
||||
|
||||
|
||||
# useful functions
|
||||
def threaded(func: Callable) -> Callable:
|
||||
"""
|
||||
Decorate a function to run in a separate thread
|
||||
:param func: a function
|
||||
:return: the decorated function
|
||||
"""
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
# run the function in a Daemon, so it will stop when the main thread stops
|
||||
thread = Thread(target=func, args=args, kwargs=kwargs, daemon=True)
|
||||
thread.start()
|
||||
return thread
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def restart_program():
|
||||
"""
|
||||
Restart the program
|
||||
"""
|
||||
os.execl(sys.executable, sys.executable, *sys.argv)
|
||||
|
|
|
@ -17,6 +17,7 @@ from source.progress import Progress
|
|||
from source.translation import translate as _, translate_external
|
||||
from source import plugins
|
||||
from source import *
|
||||
from source.utils import threaded
|
||||
import os
|
||||
|
||||
from source.mkw.collection.Extension import Extension
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import hashlib
|
||||
import shutil
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from typing import Generator, IO, TYPE_CHECKING
|
||||
|
||||
from source import file_block_size
|
||||
from source.mkw.ModConfig import ModConfig
|
||||
from source.mkw.Patch.Patch import Patch
|
||||
from source.mkw.collection.Extension import Extension
|
||||
|
@ -202,3 +204,20 @@ class ExtractedGame:
|
|||
shutil.rmtree(self.path)
|
||||
|
||||
return converted_game
|
||||
|
||||
def get_hash_map(self) -> dict[str, str]:
|
||||
"""
|
||||
Return a dictionary associating all the game subfiles to a hash
|
||||
:return: a dictionary associating all the game subfiles to a hash
|
||||
"""
|
||||
md5_map: dict[str, str] = {}
|
||||
|
||||
for fp in filter(lambda fp: fp.is_file(), self.path.rglob("*")):
|
||||
hasher = hashlib.md5()
|
||||
|
||||
with open(fp, "rb") as file:
|
||||
while block := file.read(file_block_size):
|
||||
hasher.update(block)
|
||||
md5_map[str(fp.relative_to(self.path))] = hasher.hexdigest()
|
||||
|
||||
return md5_map
|
||||
|
|
|
@ -7,6 +7,7 @@ from source.mkw.collection.Extension import Extension
|
|||
from source.mkw.collection.Region import Region
|
||||
from source.option import Options
|
||||
from source.progress import Progress
|
||||
from source.utils import comp_dict_changes
|
||||
from source.wt.wit import WITPath
|
||||
from source.translation import translate as _
|
||||
|
||||
|
@ -123,6 +124,9 @@ class Game:
|
|||
yield Progress(title=_("EXTRACTION"), set_part=1)
|
||||
yield from self.extract(extracted_game.path)
|
||||
|
||||
# Riivolution hash map for the final comparaison
|
||||
riivolution_original_hash_map = extracted_game.get_hash_map()
|
||||
|
||||
# install mystuff
|
||||
yield Progress(title=_("MYSTUFF"), set_part=2)
|
||||
mystuff_packs = options.mystuff_packs.get()
|
||||
|
@ -158,7 +162,15 @@ class Game:
|
|||
yield from extracted_game.install_all_patch(mod_config)
|
||||
yield from extracted_game.recreate_all_szs()
|
||||
|
||||
# Riivolution comparaison
|
||||
riivolution_patched_hash_map = extracted_game.get_hash_map()
|
||||
riivolution_diff: dict[str, Path] = comp_dict_changes(
|
||||
riivolution_original_hash_map,
|
||||
riivolution_patched_hash_map
|
||||
)
|
||||
|
||||
# convert the extracted game into a file
|
||||
yield Progress(title=_("CONVERTING_TO_GAME_FILE"), set_part=7)
|
||||
converted_game: WITPath = yield from extracted_game.convert_to(output_type)
|
||||
if converted_game is not None: yield from Game(converted_game.path).edit(mod_config)
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import shutil
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Generator, Callable, Iterator, Iterable, TYPE_CHECKING
|
||||
from typing import Generator, Callable, Iterator, TYPE_CHECKING
|
||||
import json
|
||||
from PIL import Image
|
||||
|
||||
from source import threaded
|
||||
from source.utils import threaded
|
||||
from source.mkw import Tag
|
||||
from source.mkw.ModSettings.ModSettingsGroup import ModSettingsGroup
|
||||
from source.mkw.Track.Cup import Cup
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from source import restart_program
|
||||
from source.utils import restart_program
|
||||
|
||||
|
||||
class OptionLoadingError(Exception):
|
||||
|
|
36
source/utils.py
Normal file
36
source/utils.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
import os
|
||||
import sys
|
||||
from threading import Thread
|
||||
from typing import Callable
|
||||
|
||||
|
||||
# useful functions
|
||||
def threaded(func: Callable) -> Callable:
|
||||
"""
|
||||
Decorate a function to run in a separate thread
|
||||
:param func: a function
|
||||
:return: the decorated function
|
||||
"""
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
# run the function in a Daemon, so it will stop when the main thread stops
|
||||
thread = Thread(target=func, args=args, kwargs=kwargs, daemon=True)
|
||||
thread.start()
|
||||
return thread
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def restart_program():
|
||||
"""
|
||||
Restart the program
|
||||
"""
|
||||
os.execl(sys.executable, sys.executable, *sys.argv)
|
||||
|
||||
|
||||
def comp_dict_changes(d_old: dict, d_new: dict) -> dict:
|
||||
"""
|
||||
Return a comparaison dict showing every value that changed between d_old and d_new. Deleted value are ignored.
|
||||
Example : {"a": 1, "b": 3, "d": 13}, {"b": 2, "c": 10, "d": 13} -> {"b": 2, "c": 10}
|
||||
"""
|
||||
return {name: value for name, value in d_new.items() if d_old.get(name) != value}
|
Loading…
Reference in a new issue