patch_factory.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from abc import ABC, abstractmethod
  2. from typing import Optional
  3. import sys
  4. import os
  5. # Agregar el directorio padre al path para importar config
  6. sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  7. from config import PATCH_CONFIG
  8. class Patch(ABC):
  9. """Clase base para todos los tipos de parches"""
  10. @abstractmethod
  11. def create_patch(self, original_data: bytes) -> bytes:
  12. """Crea el código del parche"""
  13. pass
  14. @abstractmethod
  15. def get_patch_size(self) -> int:
  16. """Retorna el tamaño del parche"""
  17. pass
  18. @abstractmethod
  19. def get_description(self) -> str:
  20. """Retorna la descripción del parche"""
  21. pass
  22. class StaminaPatch(Patch):
  23. """Parche específico para stamina infinita"""
  24. def create_patch(self, original_data: bytes) -> bytes:
  25. """Crea el código de parche para stamina infinita"""
  26. # Obtener configuración del patch desde config
  27. stamina_config = PATCH_CONFIG['stamina']
  28. # Preservar el byte del salto original
  29. jump_offset = original_data[1] if len(original_data) > 1 else 0x16
  30. # Usar instrucciones desde configuración
  31. instructions = stamina_config['instructions'].copy()
  32. instructions[1] = jump_offset # Actualizar el offset del salto
  33. return bytes(instructions)
  34. def get_patch_size(self) -> int:
  35. """Retorna el tamaño del parche de stamina"""
  36. return 18
  37. def get_description(self) -> str:
  38. """Descripción del parche de stamina"""
  39. return PATCH_CONFIG['stamina']['description']
  40. class HealthPatch(Patch):
  41. """Parche para vida infinita (ejemplo de extensibilidad)"""
  42. def create_patch(self, original_data: bytes) -> bytes:
  43. """Placeholder para parche de vida"""
  44. # Implementación futura
  45. return b'\x90' * 8 # NOPs por ahora
  46. def get_patch_size(self) -> int:
  47. return 8
  48. def get_description(self) -> str:
  49. return "Parche de vida infinita (no implementado)"
  50. class PatchFactory:
  51. """Factory para crear diferentes tipos de parches"""
  52. _patch_types = {
  53. 'stamina': StaminaPatch,
  54. 'health': HealthPatch
  55. }
  56. @classmethod
  57. def create_patch(cls, patch_type: str) -> Optional[Patch]:
  58. """Crea un parche del tipo especificado"""
  59. patch_class = cls._patch_types.get(patch_type.lower())
  60. if patch_class:
  61. return patch_class()
  62. return None
  63. @classmethod
  64. def get_available_patches(cls) -> list:
  65. """Retorna la lista de parches disponibles"""
  66. return list(cls._patch_types.keys())