merge: analyze vehicle destruction score correlation
This commit is contained in:
339
docs/vehicle-destruction-score-correlation-analysis.md
Normal file
339
docs/vehicle-destruction-score-correlation-analysis.md
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
# Análisis: inferencia de destrucción de vehículos en partida actual por correlación de puntuación de combate
|
||||||
|
|
||||||
|
## 1) Resumen ejecutivo
|
||||||
|
|
||||||
|
No hay evidencia en la arquitectura actual de un `combat_score` (ni `offense_score`, `defense_score`, `support_score` ni `total_score`) consultable **en vivo por jugador** para partidas en tiempo real.
|
||||||
|
|
||||||
|
Se puede inferir destrucción de vehículo solo con baja confianza a partir del AdminLog (`kill` + arma anti-tanque) y sin score delta en vivo.
|
||||||
|
|
||||||
|
### Recomendación principal
|
||||||
|
|
||||||
|
Clasificación de viabilidad: **no viable sin nueva fuente** (para confirmación de destrucción de vehículo en partida actual).
|
||||||
|
- Viable parcialmente: generar **candidatos débiles** con evidencia de arma anti-tanque y metadatos de kill.
|
||||||
|
- No viable: confirmación robusta (`confirmed_adminlog_vehicle_event` o `score_delta_match`) bajo fuentes actuales.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2) Fuentes revisadas
|
||||||
|
|
||||||
|
- `backend/app/rcon_client.py`
|
||||||
|
- `backend/app/providers/rcon_provider.py`
|
||||||
|
- `backend/app/payloads.py`
|
||||||
|
- `backend/app/rcon_admin_log_parser.py`
|
||||||
|
- `backend/app/rcon_admin_log_storage.py`
|
||||||
|
- `backend/app/rcon_historical_worker.py`
|
||||||
|
- `backend/app/config.py`
|
||||||
|
- `backend/app/scoreboard_origins.py`
|
||||||
|
- `backend/app/rcon_scoreboard_correlation.py`
|
||||||
|
- `backend/app/providers/public_scoreboard_provider.py`
|
||||||
|
- `backend/app/rcon_historical_storage.py`
|
||||||
|
- `backend/app/postgres_rcon_storage.py`
|
||||||
|
- `backend/tests/test_current_match_payload.py`
|
||||||
|
- `backend/tests/test_rcon_admin_log_parser.py`
|
||||||
|
- `frontend/assets/js/partida-actual.js` (solo consumo actual, sin cambios)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3) Qué datos tenemos hoy
|
||||||
|
|
||||||
|
### RCON en vivo
|
||||||
|
- `query_live_server_sample` consulta `GetServerInformation` y expone estado general del servidor (mapa, modo, tiempos, jugadores conectados/máximos, scores por equipo, etc.).
|
||||||
|
- No hay consulta de roster detallada ni endpoint en este flujo que devuelva métricas por jugador.
|
||||||
|
|
||||||
|
### AdminLog
|
||||||
|
- El parser ya reconoce `kill`, `message`, `connected`, `disconnected`, `team_switch`, `match_*`, `chat`, `kick`, `ban`.
|
||||||
|
- `kill` incluye `killer_*`, `victim_*`, `weapon` y timestamp aproximado.
|
||||||
|
- No existe evento explícito de tipo “vehicle_destroyed” ni campo dedicado de score en el evento.
|
||||||
|
|
||||||
|
### Almacenamiento histórico/persistencia
|
||||||
|
- Eventos y mensajes se guardan en `rcon_admin_log_events`.
|
||||||
|
- Hay metadata de jugador en eventos (incluyendo identificadores de jugador cuando parseable), y payloads sin schema de puntuación por componente.
|
||||||
|
- No hay snapshot de `combat_score` por jugador en `live` ni en tablas de snapshot del flujo actual.
|
||||||
|
|
||||||
|
### Scoreboard público
|
||||||
|
- `public_scoreboard_provider.py` consume endpoints tipo `get_public_info`, `get_scoreboard_maps`, `get_map_scoreboard`.
|
||||||
|
- No hay integración que entregue componente de score por jugador en vivo dentro del código actual.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4) Qué datos faltan para inferencia robusta de destrucción de vehículo
|
||||||
|
|
||||||
|
- Score por jugador en vivo al instante (combat/offense/defense/support/total).
|
||||||
|
- Snapshot continuo por jugador (`target_key`, `player_id`) con timestamps alineables al servidor.
|
||||||
|
- Evento de destrucción de vehículo explícito en AdminLog.
|
||||||
|
- Normalización confiable de daño/munición en AdminLog que distinga:
|
||||||
|
- arma anti-tanque vs no anti-tanque,
|
||||||
|
- kill a infantería vs kill por daño de vehicular.
|
||||||
|
- Fuente de verdad para tabla de puntos de recompensa por vehículo/arma (si no hay oficial).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5) Respuesta a preguntas clave
|
||||||
|
|
||||||
|
1. ¿Alguna fuente actual devuelve score por jugador en vivo?
|
||||||
|
- `combat_score`, `offense_score`, `defense_score`, `support_score`, `total_score`: **no hay fuentes vivas por jugador identificadas en el flujo actual**.
|
||||||
|
- `kills/deaths` por jugador en vivo: **no desde RCON live payload actual**, solo derivables de AdminLog offline/cron histórico.
|
||||||
|
|
||||||
|
2. ¿`query_live_server_sample` o client actual devuelven roster nominal o solo conteos?
|
||||||
|
- Solo conteos/síntesis del servidor; **no roster nominal**.
|
||||||
|
|
||||||
|
3. ¿Scoreboard público expone API/página con stats por jugador en vivo?
|
||||||
|
- No se encontró en el código actual una fuente dedicada a estadísticas en vivo por jugador.
|
||||||
|
|
||||||
|
4. ¿AdminLog incluye `player_id` en kills/messages/connected/team_switch?
|
||||||
|
- Sí en eventos parseables (kill, connected, disconnected, team_switch), aunque `player_id` puede faltar o ser inconsistente por mensajes no normalizados.
|
||||||
|
|
||||||
|
5. ¿Se puede correlacionar de forma fiable un kill con snapshots de score?
|
||||||
|
- Hoy por hoy: **no**, porque no hay snapshots de score por jugador en vivo.
|
||||||
|
|
||||||
|
6. ¿Granularidad temporal necesaria?
|
||||||
|
- Para correlación por delta, se necesitan al menos snapshots cada `5s` (o menos idealmente) y tolerancia temporal acotada.
|
||||||
|
|
||||||
|
7. ¿Tablas temporales necesarias?
|
||||||
|
- Sí, si se adopta inferencia:
|
||||||
|
- `rcon_current_player_score_snapshots`
|
||||||
|
- `rcon_vehicle_destruction_candidates`
|
||||||
|
|
||||||
|
8. ¿Campos mínimos a guardar?
|
||||||
|
- Ver modelado propuesto en sección 8.
|
||||||
|
|
||||||
|
9. ¿Armas candidatas anti-tanque?
|
||||||
|
- `BAZOOKA`, `PIAT`, `PANZERSCHRECK`, `AT MINE`, `ANTI-TANK MINE`, `SATCHEL`, `AT GUN`, `CANNON` y variantes normalizadas.
|
||||||
|
|
||||||
|
10. ¿Cómo evitar falsos positivos?
|
||||||
|
- Usar reglas de confianza multi-factor y penalizar eventos con múltiples kills rápidas, sin score_delta, o cambios de identidad.
|
||||||
|
|
||||||
|
11. ¿Confianza de inferencia?
|
||||||
|
- Depende de la evidencia:
|
||||||
|
- `confirmed_adminlog_vehicle_event` (si aparece en futuro)
|
||||||
|
- `score_delta_match`
|
||||||
|
- `anti_tank_weapon_score_delta`
|
||||||
|
- `anti_tank_weapon_only`
|
||||||
|
|
||||||
|
12. ¿Distinguir bazooka matando infantería vs destruyendo vehículo?
|
||||||
|
- No de forma confiable con datos actuales.
|
||||||
|
|
||||||
|
13. ¿Distinguir mina antitanque vs antipersonal en AdminLog actual?
|
||||||
|
- No con seguridad actual; se puede mejorar por normalización de texto de arma, pero queda incierto.
|
||||||
|
|
||||||
|
14. ¿Hay datos suficientes para delta de puntuación antes/después?
|
||||||
|
- No. Falta captura continua de score por jugador en vivo.
|
||||||
|
|
||||||
|
15. ¿Cambios necesarios si la fuente existe?
|
||||||
|
- Backend: nuevo collector de snapshots por jugador + normalizador de armas/eventos.
|
||||||
|
- Worker: ventana de correlación, persistencia candidatos y limpieza.
|
||||||
|
- Sin cambios frontend si el objetivo inicial es solo análisis de viabilidad.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6) Diseño propuesto si `combat_score` **sí existiera** (ideal)
|
||||||
|
|
||||||
|
### Esquema temporal 1: snapshots de score
|
||||||
|
- Al recibir cada sample live:
|
||||||
|
- Capturar `combat_score`, `offense_score`, `defense_score`, `support_score`, `total_score` por jugador.
|
||||||
|
- Persistir con `captured_at` y `server_time`.
|
||||||
|
- Mantener ventana corta (1–3h) para memoria en caliente.
|
||||||
|
|
||||||
|
### Correlación
|
||||||
|
- Input: `kill` con arma anti-tanque.
|
||||||
|
- Buscar snapshot anterior en ventana `[-10s, 0s]` y posterior `[0s, +10s]`.
|
||||||
|
- Calcular delta y clasificar solo si salto cumple condiciones y hay contexto consistente.
|
||||||
|
|
||||||
|
### Decisión operativa sugerida
|
||||||
|
- Si la delta coincide con patrón fuerte y sin ruido: marca candidata de alta confianza.
|
||||||
|
- Si solo arma anti-tanque sin delta: candidata baja confianza.
|
||||||
|
- Si hay conflictos (multieventos) bajar confiabilidad o descartar.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7) Diseño alternativo si `combat_score` **no existe** (estado actual)
|
||||||
|
|
||||||
|
- Mantener estado actual sin feature productiva.
|
||||||
|
- Documentar y visualizar internamente solo candidatos débiles:
|
||||||
|
- Evento kill con arma anti-tanque.
|
||||||
|
- Co-ocurrencia de cambio de equipo/mapa/rounds en un rango temporal.
|
||||||
|
- No mostrar como “destrucción de vehículo” sin evidencia adicional.
|
||||||
|
- Guardar trazabilidad mínima para revisión manual futura.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8) Modelo de datos temporal propuesto
|
||||||
|
|
||||||
|
### Tabla: `rcon_current_player_score_snapshots`
|
||||||
|
- `id`
|
||||||
|
- `target_key`
|
||||||
|
- `player_id`
|
||||||
|
- `player_name`
|
||||||
|
- `team`
|
||||||
|
- `combat_score`
|
||||||
|
- `offense_score`
|
||||||
|
- `defense_score`
|
||||||
|
- `support_score`
|
||||||
|
- `total_score`
|
||||||
|
- `captured_at`
|
||||||
|
- `server_time`
|
||||||
|
- `source`
|
||||||
|
- `created_at`
|
||||||
|
|
||||||
|
### Tabla: `rcon_vehicle_destruction_candidates`
|
||||||
|
- `id`
|
||||||
|
- `target_key`
|
||||||
|
- `source_event_id`
|
||||||
|
- `event_timestamp`
|
||||||
|
- `server_time`
|
||||||
|
- `player_id`
|
||||||
|
- `player_name`
|
||||||
|
- `weapon`
|
||||||
|
- `score_before`
|
||||||
|
- `score_after`
|
||||||
|
- `combat_score_delta`
|
||||||
|
- `total_score_delta`
|
||||||
|
- `matched_score_bucket`
|
||||||
|
- `confidence`
|
||||||
|
- `evidence_json`
|
||||||
|
- `created_at`
|
||||||
|
|
||||||
|
### Retención recomendada
|
||||||
|
- Snapshots live: `1–3 horas`.
|
||||||
|
- Agregados agregados: no guardar indefinidamente; compactar por ventanas/ciclos.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9) Algoritmo de correlación before/after
|
||||||
|
|
||||||
|
1) Detectar evento `kill`.
|
||||||
|
2) Normalizar y clasificar arma (`AT`, ignorable, desconocida).
|
||||||
|
3) Obtener `player_id` del killer.
|
||||||
|
4) Buscar snapshot previo `[event_ts - 10s, event_ts]` (preferible el más cercano a `event_ts`).
|
||||||
|
5) Buscar snapshot posterior `[event_ts, event_ts + 10s]`.
|
||||||
|
6) Si existen ambos:
|
||||||
|
- `delta = score_after - score_before` por componente y total.
|
||||||
|
7) Clasificar:
|
||||||
|
- `confirmed_adminlog_vehicle_event`: si en el futuro aparece evento explícito.
|
||||||
|
- `score_delta_match`: si delta positivo con patrón fuerte y único.
|
||||||
|
- `anti_tank_weapon_score_delta`: AT + delta positivo compatible.
|
||||||
|
- `anti_tank_weapon_only`: solo evento AT sin delta.
|
||||||
|
8) Ajustar confianza por ruido:
|
||||||
|
- múltiples eventos en ventana,
|
||||||
|
- falta de `player_id`,
|
||||||
|
- desalineación temporal alta,
|
||||||
|
- cambios de nombre/teams.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10) Ventanas temporales recomendadas
|
||||||
|
|
||||||
|
- Ventana principal: `[-10s, +10s]` respecto al kill.
|
||||||
|
- Ventana de captura de snapshots: `5s` entre muestras.
|
||||||
|
- Ventana de desempate:
|
||||||
|
- Si hay múltiples eventos del mismo jugador en ±10s, reducir confianza.
|
||||||
|
- Si hay 2+ snapshots en ventana, tomar snapshot más cercano al evento y registrar distancia temporal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11) Armas anti-tanque candidatas
|
||||||
|
|
||||||
|
- `BAZOOKA`, `PIAT`, `PANZERSCHRECK`, `AT MINE`, `ANTI-TANK MINE`, `SATCHEL`, `AT GUN`, `CANNON`.
|
||||||
|
- `SATCHEL` puede aparecer como variantes de texto; normalizar case/espacios/dashes.
|
||||||
|
- Mantener lista configurable (diccionario de normalización) y tabla de excepciones.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12) Niveles de confianza y señales
|
||||||
|
|
||||||
|
- `high`: score delta consistente + evento AT + pocos eventos paralelos + match limpio de ventana temporal.
|
||||||
|
- `medium`: weapon AT + score delta parcial o sin un campo consistente.
|
||||||
|
- `low`: solo AT weapon sin delta.
|
||||||
|
- `invalid`: sin `player_id` ni evidencia de correlación temporal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13) Riesgos y falsos positivos
|
||||||
|
|
||||||
|
- Misclasificación de kills de infantería con armas AT.
|
||||||
|
- Eventos AT en spam (misfires, intentos, daños no letales).
|
||||||
|
- Mismatches de identidad (`player_id` ausente o cambiante).
|
||||||
|
- Latencia entre `event_timestamp` y `server_time`.
|
||||||
|
- Diferencias entre entorno de servidor y extracción live.
|
||||||
|
- Suposición de valor fijo de puntuación por destrucción.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14) Consultas SQL de validación en producción/JTA
|
||||||
|
|
||||||
|
### a) Revisión de términos vehiculares en AdminLog
|
||||||
|
```sql
|
||||||
|
select event_type, count(*)
|
||||||
|
from rcon_admin_log_events
|
||||||
|
where raw_message ilike '%vehicle%'
|
||||||
|
or raw_message ilike '%destroy%'
|
||||||
|
or raw_message ilike '%destroyed%'
|
||||||
|
or raw_message ilike '%tank%'
|
||||||
|
or raw_message ilike '%truck%'
|
||||||
|
or raw_message ilike '%halftrack%'
|
||||||
|
group by event_type
|
||||||
|
order by count(*) desc;
|
||||||
|
```
|
||||||
|
|
||||||
|
### b) Ejemplos de eventos relacionados con vehículo
|
||||||
|
```sql
|
||||||
|
select id, target_key, event_type, event_timestamp, raw_message
|
||||||
|
from rcon_admin_log_events
|
||||||
|
where raw_message ilike '%vehicle%'
|
||||||
|
or raw_message ilike '%destroy%'
|
||||||
|
or raw_message ilike '%destroyed%'
|
||||||
|
or raw_message ilike '%tank%'
|
||||||
|
or raw_message ilike '%truck%'
|
||||||
|
or raw_message ilike '%halftrack%'
|
||||||
|
order by id desc
|
||||||
|
limit 50;
|
||||||
|
```
|
||||||
|
|
||||||
|
### c) Armas reales en kills (extract de payload JSON)
|
||||||
|
PostgreSQL con `jsonb`:
|
||||||
|
```sql
|
||||||
|
select parsed_payload_json->>'weapon' as weapon, count(*)
|
||||||
|
from rcon_admin_log_events
|
||||||
|
where event_type = 'kill'
|
||||||
|
group by parsed_payload_json->>'weapon'
|
||||||
|
order by count(*) desc;
|
||||||
|
```
|
||||||
|
|
||||||
|
Fallback no-`jsonb` (si `json`/texto):
|
||||||
|
```sql
|
||||||
|
select parsed_payload_json::text::json ->> 'weapon' as weapon, count(*)
|
||||||
|
from rcon_admin_log_events
|
||||||
|
where event_type = 'kill'
|
||||||
|
group by parsed_payload_json::text::json ->> 'weapon'
|
||||||
|
order by count(*) desc;
|
||||||
|
```
|
||||||
|
|
||||||
|
### c1) Top players con kills por weapon (validación adicional)
|
||||||
|
```sql
|
||||||
|
select parsed_payload_json->>'killer_name' as player, parsed_payload_json->>'weapon' as weapon, count(*) as kills
|
||||||
|
from rcon_admin_log_events
|
||||||
|
where event_type = 'kill'
|
||||||
|
group by 1,2
|
||||||
|
order by kills desc
|
||||||
|
limit 100;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 15) Recomendación final
|
||||||
|
|
||||||
|
Con el estado actual del repositorio, la inferencia de destrucción de vehículo **no es confirmable en vivo**.
|
||||||
|
|
||||||
|
Conclusión:
|
||||||
|
- `combat_score` en vivo por jugador: **no disponible** hoy.
|
||||||
|
- Por tanto, el score-delta **no puede implementarse hoy como verificación fuerte**.
|
||||||
|
- Se recomienda:
|
||||||
|
1. Mantener esta tarea como análisis/documento.
|
||||||
|
2. Validar si CRCON u otro canal puede proveer snapshots por jugador (`GetPlayers`/`GetPlayer`/endpoint oficial con score componentes).
|
||||||
|
3. En caso afirmativo, implementar primero snapshots y luego pipeline de correlación con ventanas y niveles de confianza.
|
||||||
|
4. Si no aparece fuente, continuar con señal heurística de baja confianza (AT kill only) sin presentación como destrucción confirmada.
|
||||||
|
|
||||||
|
### Nivel de viabilidad
|
||||||
|
- **No viable sin nueva fuente de score live** para detección fiable.
|
||||||
|
- **Viable parcialmente** para candidatos por heurística de arma + tiempo.
|
||||||
|
|
||||||
Reference in New Issue
Block a user