from abc import ABC, abstractmethod from typing import Optional import sys import os # Agregar el directorio padre al path para importar config sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from config import PATCH_CONFIG class Patch(ABC): """Clase base para todos los tipos de parches""" @abstractmethod def create_patch(self, original_data: bytes) -> bytes: """Crea el código del parche""" pass @abstractmethod def get_patch_size(self) -> int: """Retorna el tamaño del parche""" pass @abstractmethod def get_description(self) -> str: """Retorna la descripción del parche""" pass class StaminaPatch(Patch): """Parche específico para stamina infinita""" def create_patch(self, original_data: bytes) -> bytes: """Crea el código de parche para stamina infinita""" # Obtener configuración del patch desde config stamina_config = PATCH_CONFIG['stamina'] # Preservar el byte del salto original jump_offset = original_data[1] if len(original_data) > 1 else 0x16 # Usar instrucciones desde configuración instructions = stamina_config['instructions'].copy() instructions[1] = jump_offset # Actualizar el offset del salto return bytes(instructions) def get_patch_size(self) -> int: """Retorna el tamaño del parche de stamina""" return 18 def get_description(self) -> str: """Descripción del parche de stamina""" return PATCH_CONFIG['stamina']['description'] class HealthPatch(Patch): """Parche para vida infinita (ejemplo de extensibilidad)""" def create_patch(self, original_data: bytes) -> bytes: """Placeholder para parche de vida""" # Implementación futura return b'\x90' * 8 # NOPs por ahora def get_patch_size(self) -> int: return 8 def get_description(self) -> str: return "Parche de vida infinita (no implementado)" class PatchFactory: """Factory para crear diferentes tipos de parches""" _patch_types = { 'stamina': StaminaPatch, 'health': HealthPatch } @classmethod def create_patch(cls, patch_type: str) -> Optional[Patch]: """Crea un parche del tipo especificado""" patch_class = cls._patch_types.get(patch_type.lower()) if patch_class: return patch_class() return None @classmethod def get_available_patches(cls) -> list: """Retorna la lista de parches disponibles""" return list(cls._patch_types.keys())