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.
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
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ñal | Origen | Evento |
|---|---|---|
| Chat | Socket.IO | chat-message |
| Movimiento | WebRTC (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-inputsolo existe cuando la sala usa el transporte real (conpeerID), como encreateRoom()yjoinRoom(). En pruebas con un transporte falso, emitepeer-inputmanualmente. - 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
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.`));
}