| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- 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 SpeedPatch(Patch):
- """Parche específico para velocidad de movimiento"""
-
- def __init__(self, speed_multiplier: str = '2x'):
- self.speed_multiplier = speed_multiplier
-
- def create_patch(self, original_data: bytes) -> bytes:
- """Crea el código de parche para velocidad modificada"""
- # Obtener configuración del patch desde config
- speed_config = PATCH_CONFIG['speed']
-
- # Obtener el patrón de velocidad deseado
- if self.speed_multiplier in speed_config['speed_multipliers']:
- return bytes(speed_config['speed_multipliers'][self.speed_multiplier])
- else:
- # Fallback a velocidad normal si no se encuentra el multiplicador
- return bytes(speed_config['speed_multipliers']['1x'])
-
- def get_patch_size(self) -> int:
- """Retorna el tamaño del parche de velocidad"""
- return 16
-
- def get_description(self) -> str:
- """Descripción del parche de velocidad"""
- return f"{PATCH_CONFIG['speed']['description']} (Multiplicador: {self.speed_multiplier})"
- 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,
- 'speed': SpeedPatch,
- 'health': HealthPatch
- }
-
- @classmethod
- def create_patch(cls, patch_type: str, **kwargs) -> Optional[Patch]:
- """Crea un parche del tipo especificado"""
- patch_class = cls._patch_types.get(patch_type.lower())
- if patch_class:
- if patch_type.lower() == 'speed':
- speed_multiplier = kwargs.get('speed_multiplier', '2x')
- return patch_class(speed_multiplier)
- else:
- return patch_class()
- return None
-
- @classmethod
- def get_available_patches(cls) -> list:
- """Retorna la lista de parches disponibles"""
- return list(cls._patch_types.keys())
-
- @classmethod
- def get_speed_multipliers(cls) -> list:
- """Retorna la lista de multiplicadores de velocidad disponibles"""
- return list(PATCH_CONFIG['speed']['speed_multipliers'].keys())
|