diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b786932..5aa590a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,10 +8,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up Python 3.10 + - name: Set up Python 3.11 uses: actions/setup-python@v4 with: - python-version: "3.10" + python-version: "3.11" - name: Install requirements run: | diff --git a/system/lib/features/files.py b/system/lib/features/files.py index 661dd81..ee80b18 100644 --- a/system/lib/features/files.py +++ b/system/lib/features/files.py @@ -8,16 +8,16 @@ def write_sc( - output_filename: str | os.PathLike, + output_filename: os.PathLike | str, buffer: bytes, signature: Signatures, version: int | None = None, ): with open(output_filename, "wb") as file_out: - file_out.write(compress(buffer, signature, version)) + file_out.write(compress(buffer, signature, version)) # type: ignore -def open_sc(input_filename: str) -> tuple[bytes, Signatures]: +def open_sc(input_filename: os.PathLike | str) -> tuple[bytes, Signatures]: with open(input_filename, "rb") as f: file_data = f.read() diff --git a/system/lib/features/initialization.py b/system/lib/features/initialization.py index 76066b4..825b806 100644 --- a/system/lib/features/initialization.py +++ b/system/lib/features/initialization.py @@ -3,7 +3,7 @@ from loguru import logger from system import clear, run -from system.lib import config +from system.lib.config import config from system.lib.features.directories import create_directories from system.lib.features.update.check import get_pip_info, get_tags from system.localization import locale diff --git a/system/lib/features/sc/decode.py b/system/lib/features/sc/decode.py index 7e5bcd5..e831f74 100644 --- a/system/lib/features/sc/decode.py +++ b/system/lib/features/sc/decode.py @@ -39,7 +39,7 @@ def decode_textures_only(): ) _save_meta_file( - swf, objects_output_folder, base_name.rstrip("_"), signature + swf, objects_output_folder, base_name.rsplit("_", 1)[0], signature ) _save_textures(swf, objects_output_folder, base_name) except Exception as exception: @@ -96,6 +96,7 @@ def decode_and_render_objects(): def get_file_basename(swf: SupercellSWF): + assert swf.filename is not None return os.path.basename(swf.filename).rsplit(".", 1)[0] @@ -109,9 +110,9 @@ def _create_objects_output_folder(output_folder: Path, base_name: str) -> Path: def _save_textures(swf: SupercellSWF, textures_output: Path, base_name: str) -> None: os.makedirs(textures_output, exist_ok=True) - for img_index in range(len(swf.textures)): - filename = base_name + "_" * img_index - swf.textures[img_index].image.save(textures_output / f"{filename}.png") + for texture_index, texture in enumerate(swf.textures): + assert texture.image is not None + texture.image.save(textures_output / f"{base_name}_{texture_index}.png") def _save_meta_file( diff --git a/system/lib/features/update/check.py b/system/lib/features/update/check.py index 2261c67..a9ceb6c 100644 --- a/system/lib/features/update/check.py +++ b/system/lib/features/update/check.py @@ -4,7 +4,7 @@ from loguru import logger from system import run -from system.lib import config +from system.lib.config import config from system.lib.features.update.download import download_update from system.localization import locale diff --git a/system/lib/features/update/download.py b/system/lib/features/update/download.py index ec5f9b2..2c19504 100644 --- a/system/lib/features/update/download.py +++ b/system/lib/features/update/download.py @@ -4,7 +4,7 @@ from loguru import logger from system import run -from system.lib import config +from system.lib.config import config from system.localization import locale diff --git a/system/lib/images.py b/system/lib/images.py index 697fcab..abeb7ce 100644 --- a/system/lib/images.py +++ b/system/lib/images.py @@ -86,7 +86,7 @@ def add_pixel(pixel: tuple) -> None: if pixel_x >= width: break - add_pixel(loaded_clone[pixel_x, pixel_y]) + add_pixel(loaded_clone[pixel_x, pixel_y]) # type: ignore pixel_index += 1 Console.progress_bar(locale.split_pic, y_chunk, y_chunks_count + 1) @@ -149,7 +149,7 @@ def save_texture(writer: Writer, image: Image.Image, pixel_type: int) -> None: point = -1 for y in range(height): for x in range(width): - writer.write(write_pixel(pixels[y * width + x])) + writer.write(write_pixel(pixels[y * width + x])) # type: ignore curr = Console.percent(y, height) if curr > point: diff --git a/system/lib/math/polygon.py b/system/lib/math/polygon.py index 1880c10..596c71e 100644 --- a/system/lib/math/polygon.py +++ b/system/lib/math/polygon.py @@ -14,7 +14,7 @@ class PointOrder(IntEnum): COUNTER_CLOCKWISE = 1 -def get_polygon_sum_of_edges(polygon: Polygon) -> int: +def get_polygon_sum_of_edges(polygon: Polygon) -> float: """ Mostly like signed area, but two times bigger and more accurate with signs. diff --git a/system/lib/objects/movie_clip/movie_clip.py b/system/lib/objects/movie_clip/movie_clip.py index f1c495d..661e467 100644 --- a/system/lib/objects/movie_clip/movie_clip.py +++ b/system/lib/objects/movie_clip/movie_clip.py @@ -27,6 +27,8 @@ def __init__(self): self.matrix_bank_index: int = 0 def load(self, swf: SupercellSWF, tag: int): + assert swf.reader is not None + self.id = swf.reader.read_ushort() self.fps = swf.reader.read_char() diff --git a/system/lib/objects/renderable/renderable_movie_clip.py b/system/lib/objects/renderable/renderable_movie_clip.py index c8cdaeb..4c4e28b 100644 --- a/system/lib/objects/renderable/renderable_movie_clip.py +++ b/system/lib/objects/renderable/renderable_movie_clip.py @@ -84,6 +84,8 @@ def calculate_bounds(self, matrix: Matrix2x3) -> Rect: return rect def set_frame(self, frame_index: int): + assert self._matrix_bank is not None + self._frame_children = [] frame = self._frames[frame_index] diff --git a/system/lib/objects/shape/region.py b/system/lib/objects/shape/region.py index 6a3e8ad..6f4c3c1 100644 --- a/system/lib/objects/shape/region.py +++ b/system/lib/objects/shape/region.py @@ -27,6 +27,8 @@ def __init__(self): self._cache_image: Image.Image | None = None def load(self, swf: SupercellSWF, tag: int): + assert swf.reader is not None + self.texture_index = swf.reader.read_uchar() self._texture = swf.textures[self.texture_index] @@ -83,6 +85,8 @@ def get_image(self) -> Image.Image: if self._cache_image is not None: return self._cache_image + assert self._texture is not None and self._texture.image is not None + rect = get_rect(self._uv_points) width = max(int(rect.width), 1) diff --git a/system/lib/objects/shape/shape.py b/system/lib/objects/shape/shape.py index 2d5dc4d..5dfed07 100644 --- a/system/lib/objects/shape/shape.py +++ b/system/lib/objects/shape/shape.py @@ -17,6 +17,8 @@ def __init__(self): self.regions: list[Region] = [] def load(self, swf: SupercellSWF, tag: int): + assert swf.reader is not None + self.id = swf.reader.read_ushort() swf.reader.read_ushort() # regions_count diff --git a/system/lib/objects/texture.py b/system/lib/objects/texture.py index c2cc499..fb700e7 100644 --- a/system/lib/objects/texture.py +++ b/system/lib/objects/texture.py @@ -24,15 +24,18 @@ def __init__(self): self.height = 0 self.pixel_type = -1 - self.khronos_texture_filename: str | None = None self.image: Image.Image | None = None def load(self, swf: SupercellSWF, tag: int, has_texture: bool): + assert swf.reader is not None + + khronos_texture_length = 0 + khronos_texture_filename = None if tag == 45: khronos_texture_length = swf.reader.read_int() elif tag == 47: - self.khronos_texture_filename = swf.reader.read_string() + khronos_texture_filename = swf.reader.read_string() self.pixel_type = swf.reader.read_char() self.width, self.height = (swf.reader.read_ushort(), swf.reader.read_ushort()) @@ -45,9 +48,8 @@ def load(self, swf: SupercellSWF, tag: int, has_texture: bool): # noinspection PyUnboundLocalVariable khronos_texture_data = swf.reader.read(khronos_texture_length) elif tag == 47: - with open( - swf.filepath.parent / self.khronos_texture_filename, "rb" - ) as file: + assert khronos_texture_filename is not None + with open(swf.filepath.parent / khronos_texture_filename, "rb") as file: decompressor = zstandard.ZstdDecompressor() khronos_texture_data = decompressor.decompress(file.read()) diff --git a/system/lib/swf.py b/system/lib/swf.py index c203c28..675c7ec 100644 --- a/system/lib/swf.py +++ b/system/lib/swf.py @@ -35,7 +35,7 @@ def __init__(self): self.xcod_writer = Writer("big") self._filepath: Path | None = None - self._uncommon_texture_path: str | os.PathLike | None = None + self._uncommon_texture_path: os.PathLike | str | None = None self._lowres_suffix: str = DEFAULT_LOWRES_SUFFIX self._highres_suffix: str = DEFAULT_HIGHRES_SUFFIX @@ -63,6 +63,7 @@ def load(self, filepath: str | os.PathLike) -> tuple[bool, Signatures]: if not texture_loaded: if self._use_uncommon_texture: + assert self._uncommon_texture_path is not None texture_loaded, signature = self._load_internal( self._uncommon_texture_path, True ) @@ -73,7 +74,7 @@ def load(self, filepath: str | os.PathLike) -> tuple[bool, Signatures]: return texture_loaded, signature def _load_internal( - self, filepath: str | os.PathLike, is_texture_file: bool + self, filepath: os.PathLike | str, is_texture_file: bool ) -> tuple[bool, Signatures]: self.filename = os.path.basename(filepath) @@ -136,6 +137,8 @@ def _load_internal( return loaded, signature def _load_tags(self, is_texture_file: bool) -> bool: + assert self.reader is not None + has_texture = True texture_id = 0 @@ -183,6 +186,7 @@ def _load_tags(self, is_texture_file: bool) -> bool: self.movie_clips[movie_clips_loaded].load(self, tag) movie_clips_loaded += 1 elif tag == 8 or tag == 36: # Matrix + assert self._matrix_bank is not None self._matrix_bank.get_matrix(matrices_loaded).load(self.reader, tag) matrices_loaded += 1 elif tag == 26: @@ -244,4 +248,5 @@ def get_matrix_bank(self, index: int) -> MatrixBank: @property def filepath(self) -> Path: + assert self._filepath is not None return self._filepath