Biblioteca

Anti-AFK

Detecta jugadores inactivos por movimiento y por chat, con 12 s de tolerancia.

El anti-AFK marca como AFK a un jugador que estuvo 12 segundos sin moverse y sin hablar. Cualquiera de las dos señales reinicia el reloj.

ts
room.enableAntiAfk();                                  // por defecto: 12 s

room.on('player-afk',  (id) => room.kickPlayer(id));   // una vez, cuando pasa a AFK
room.on('player-back', (id) => room.chat(`el jugador ${id} ha vuelto`));

room.isAfk(playerId);                                  // consulta puntual
room.disableAntiAfk();

Opciones

ts
room.enableAntiAfk({
  thresholdMs: 12_000,     // tiempo quieto hasta pasar a AFK
  checkIntervalMs: 1_000,  // frecuencia de la comprobación
});

El tiempo por defecto también está disponible como la constante AFK_THRESHOLD_MS.

A quién se vigila

Solo a los jugadores en un equipo durante una partida. Los espectadores y el propio bot se ignoran. El reloj arranca cuando empieza la partida (o cuando el jugador entra en un equipo durante la partida) y se descarta cuando la partida termina.

De dónde vienen las señales

SeñalOrigenEvento
ChatSocket.IOchat-message
MovimientoWebRTC (frames de input entre peers)peer-input

El movimiento no pasa por Socket.IO: los jugadores se intercambian frames de input por WebRTC. La biblioteca completa el handshake WebRTC como si fuera un jugador y recibe esos frames. Recibe un frame por tecla pulsada o soltada, y ninguno mientras el jugador está quieto, lo que hace fiable la detección.

peer-input entrega { playerId, peerID, data }, con el frame ya asociado al jugador correcto. Puedes usarlo directamente para estadísticas de actividad.

Limitaciones importantes

  • Necesita el modo real. El evento peer-input solo existe cuando la sala usa el transporte real (con peerID), como en createRoom() y joinRoom(). En pruebas con un transporte falso, emite peer-input manualmente.
  • Fiabilidad de la señal. Si, por algún motivo, no llega ningún frame de movimiento durante toda una partida, la señal no es fiable. La sala 24/7 ignora el AFK automático en ese caso, para no castigar nunca a todos por un fallo de red. Haz lo mismo si aplicas penalizaciones.

Ejemplo completo

ts
import type { BonkRoom } from 'bonktools';

export function setupAntiAfk(room: BonkRoom): void {
  room.enableAntiAfk();

  const name = (id: number) => room.state.players.get(id)?.userName ?? `#${id}`;

  room.on('player-afk', (id) => {
    room.chat(`${name(id)} está AFK!`);
    room.kickPlayer(id); // quita esta línea si solo quieres avisar
  });

  room.on('player-back', (id) => room.chat(`${name(id)} ha vuelto.`));
}