# Auditoría de williamdai8/evony_automation_tools

Repo: https://github.com/williamdai8/evony_automation_tools (GPL-3.0, 422+119+470 lineas de Python)

Tres scripts revisados: `evony_boss_queue_detector.py`, `evony_crash_detector.py`, `evony_rb.py`. Estado: funcional para Evony TKR pero acoplado a una infra concreta (MySQL local, BlueStacks via ADB, multiples instancias).

## Hallazgos portables, ordenados por valor

### 1) Arquitectura ADB en lugar de pyautogui (CAMBIO GRANDE)

En vez de mover el cursor del host, manda comandos directamente a Android dentro de BlueStacks:

```python
connection_string = "127.0.0.1:5565"  # puerto ADB de BlueStacks

# Tap
os.system(f"adb -s {connection_string} shell input tap {x} {y}")

# Screenshot (lo coge desde dentro de Android)
os.system(f"adb -s {connection_string} shell screencap -p /sdcard/cap.png")
os.system(f"adb -s {connection_string} pull /sdcard/cap.png ./cap.png")

# Texto
os.system(f"adb -s {connection_string} shell input text {value}")

# Tecla (backspace, etc)
os.system(f"adb -s {connection_string} shell input keyevent KEYCODE_DEL")

# Swipe (paneo del mapa)
os.system(f"adb -s {connection_string} shell input swipe {x1} {y1} {x2} {y2} {duration_ms}")

# Reiniciar Evony si crashea
os.system(f"adb -s {connection_string} shell am start -n com.topgamesinc.evony/com.topgamesinc.androidplugin.UnityActivity")
```

**Por que es mejor:**
- El cursor del Mac queda libre — puedes seguir trabajando mientras escanea
- Coordenadas en espacio Android (ej. 1080x1920), independientes de la posicion de la ventana de BlueStacks
- Taps "tactiles" — desde el punto de vista de Evony, identicos a un dedo real

**Coste:** Hay que habilitar ADB en BlueStacks (Settings > Preferences > "Android Debug Bridge: ON"), instalar `adb` en Mac (`brew install android-platform-tools`), y recalibrar las coordenadas en espacio Android. Una vez hecho, todo va via comandos `adb`, no via pyautogui/mss.

### 2) State-check antes de cada accion (robustez)

williamdai8 verifica con template matching que el juego esta donde el espera ANTES de hacer cualquier accion. Plantillas usadas:

- `world_button.png` — confirma "estamos en el mapa del mundo"
- `main_page_check.png` — confirma "estamos en la ciudad/menu principal"
- `cross_button_purchase.png` — detecta popup de tienda abierto
- `double_down_button_purchase.png` — detecta popup de evento
- `bluestack_error_freeze_msg.png` — detecta dialog de error de BlueStacks
- `bluestack_logo.png` — detecta que Evony se cerro y se ve solo BlueStacks

Si detecta un popup, lo cierra. Si detecta que se cerro Evony, reinicia la app. Solo cuando el estado es "estoy en el mapa del mundo, sin popups" procede a la siguiente accion del scan.

Este patron deberiamos copiarlo: **funcion `ensure_on_world_map()` que se llama antes de cada `jump_to(x, y)`**. Si esta en otro sitio, intenta recuperarse; si no puede, salta el ciclo.

### 3) Anti-crash detection por tamano de archivo (ingenioso)

`evony_crash_detector.py` corre en paralelo. Compara el tamano del PNG de screenshot entre ciclos. Si 10 screenshots consecutivos pesan casi lo mismo (diff < 15KB), asume que la pantalla esta congelada:

```python
if abs(file_size_prev - file_size_new) < 15000:
    num_of_similar_filesizes += 1
else:
    num_of_similar_filesizes = 0

if num_of_similar_filesizes >= 10:
    # juego congelado -> reset
```

Muy simple, muy efectivo. No hace falta OCR ni nada elaborado.

### 4) Jiggle anti-falso-positivo

Al inicio de cada ciclo, hace un swipe vertical inocuo:

```python
os.system(f"adb -s {connection_string} shell input swipe 430 300 430 900")
```

Triple proposito: (a) confirma que el juego responde, (b) cambia el tamano del PNG para que el crash detector no marque falso positivo, (c) parece actividad humana desde el punto de vista del servidor.

### 5) Secuencia de recovery (`perform_game_reset_seq`)

Si algo va mal, cascada de fallbacks:
- Si BlueStacks muestra logo de Android: relanza Evony
- Si hay popup de tienda: cierra con tap en la X
- Si esta en menu de ciudad: pulsa el boton "World"
- Vuelve al estado limpio antes de seguir

Nosotros podemos hacer una version mas simple: si tres jumps seguidos no funcionan, parar el ciclo y avisar.

### 6) Monitorizar Alliance Chat (idea lateral)

`collect_new_monsters_from_AC` no escanea el mapa. Lee con OCR el panel de Alliance Chat, donde los miembros comparten coords de bosses. Ventajas:
- Cero paneo
- Cero deteccion por barrido sospechoso
- Datos en tiempo real, sin esperar a que la camara llegue

Limitacion: solo te enteras de bosses que tus aliados ya vieron y compartieron. Pero como complemento al scanner es brutal.

Implementacion: definir region de pantalla donde aparece el AC, OCR cada 10s, parsear lineas tipo `X:458 Y:567 (Boss)`, log.

### 7) Configuracion en CSV

`config/bosses.csv` con columnas: `boss_name, hit, boss_level, type, priorities, slot_1_primary, ...`. Separa codigo de datos. Para los 8 bosses tuyos podemos hacer algo igual: nombre, nivel preferido, prioridad, bioma asociado.

## Lo que NO portamos

- MySQL backend: para nosotros un CSV o JSON local es suficiente.
- Multi-instancia (puertos 5575, 5585...): no lo necesitas.
- Rally / attack automatico (`evony_rb.py`): SOLO scanning. El rally entra en territorio de baneo mucho mas claro.
- IPs y credenciales hardcoded: no aplica.

## Plan de implementacion sugerido

Orden por valor/esfuerzo:

1. **ADB switch** (alto valor, esfuerzo medio): reescribir `human_click`, `clear_and_type`, `capture` para usar ADB. Permite usar el Mac mientras corre.
2. **State checks** (alto valor, esfuerzo bajo): plantillas extra + funcion `ensure_on_world_map()`. Hace el script mucho mas resistente.
3. **Crash detection por filesize** (medio valor, esfuerzo bajo): 30 lineas.
4. **Bosses CSV** (bajo valor pero limpieza importante): pasar la lista de bosses + prioridades a CSV.
5. **AC monitor** (alto valor potencial, esfuerzo medio): scanner pasivo del Alliance Chat. Solo si estas en alianza activa donde comparten coords.

## Notas de seguridad

El repo no exfiltra nada. Las credenciales que usa son las de la DB MySQL local del autor (`MY_SQL_USERNAME`/`MY_SQL_PWD` desde env vars hacia `192.168.68.101`). No hay llamadas a servidores externos sospechosos. Todo el codigo es local-only.

GPL-3.0 significa que podemos usar/modificar el codigo libremente, citando autoria y manteniendo la licencia si lo redistribuyes.
