Automatisez bonk.io sans ouvrir de navigateur.

bonktools est une bibliothèque TypeScript qui parle directement le protocole du jeu. Créez des salons, contrôlez les équipes, détectez les joueurs AFK et gardez un salon actif 24 heures sur 24.

npm install bonktools

CommencerLire la documentation

Version 0.1.4 · MIT · Node.js 20.18 ou plus récent

bot.ts
import { createRoom } from 'bonktools';

const room = await createRoom({
  auth: { type: 'registered', username, password },
  desiredState: {
    roomName: 'Mon Salon', password: '',
    maxPlayers: 6, mode: 'b', rounds: 3,
  },
});

room.lockTeams();       // seul l'hôte déplace les joueurs
room.enableAntiAfk();   // 12 s immobile = AFK

room.on('player-afk', (id) => room.kickPlayer(id));
room.on('chat-message', ({ message }) => {
  if (message === '!ping') room.chat('Pong!');
});

console.log(room.shareLink); // https://bonk.io/123456abcde

Fonctionnalités

  • Connexion directe au protocole. Socket.IO v2 et la chaîne TLS de bonk.io sont déjà gérés. Pas de Puppeteer, pas d’écran virtuel, pas d’automatisation fragile de l’interface. Protocole
  • Des salons 24h/24 qui se rétablissent. BonkSession recrée les salons qui tombent, avec un backoff exponentiel, un throttle de création et un reconcile toutes les 60 s. Sessions 24h/24
  • Événements typés. Plus de 30 événements avec des payloads typés, et l’état du salon toujours disponible dans room.state. Événements
  • Contrôle des équipes. lockTeams() empêche les joueurs de changer d’équipe seuls : seul l’hôte déplace les joueurs. Celui qui arrive ensuite voit déjà le salon verrouillé. Équipes et verrouillage
  • Anti-AFK. Détecte 12 s sans bouger ni écrire, en lisant le mouvement dans les frames d’input WebRTC. Anti-AFK
  • Les spectateurs voient la partie. Celui qui arrive pendant une partie reçoit tout de suite son état, sans la redémarrer pour tout le monde. Parties

Comment ça marche

Vous choisissez le niveau d’abstraction : un socket brut, un salon avec état et événements, ou un pool de salons qui se maintient tout seul. Chaque salon est une connexion légère ; inutile d’afficher le jeu pour héberger un salon.

Votre code
    │
BonkSession     pool de salons · login partagé · throttle · reconcile de 60 s
BonkRoom        état · événements typés · équipes · verrou · anti-AFK · reconnexion
BonkTransport   Socket.IO v2 (EIO=3) · TLS · timesync
    │
bonk.io         + PeerJS/WebRTC pour les frames d’input des joueurs
  • Pannes maîtrisées. Les coupures transitoires sont rétablies. Les bans, salons pleins et tentatives épuisées sont terminaux et vous en sont notifiés.
  • Protocole documenté. La rétro-ingénierie est consignée en détail, avec les formats de paquets et les pièges. Voir le protocole

Exemples

Créer et rejoindre des salons

typescript
import { createRoom, joinRoom } from 'bonktools';

// Créer un salon (le bot devient l'hôte)
const room = await createRoom({
  auth: { type: 'registered', username, password },
  desiredState: { roomName: 'HERMES', password: '', maxPlayers: 6, mode: 'b', rounds: 3 },
  hidden: false,
});
console.log('Link:', room.shareLink);

// Rejoindre un salon existant
const guest = await joinRoom('https://bonk.io/123456abcde', {
  auth: { type: 'guest', guestName: 'BonkBot' },
  role: 'spectator',
});

Événements et état

typescript
room.on('player-join', (p) => room.chat(`Bienvenue, ${p.userName}!`));
room.on('team-change', (p) => console.log(`joueur ${p.id} → équipe ${p.team}`));

room.on('game-start', () => console.log('partie démarrée'));
room.on('game-end',   () => console.log('partie terminée'));

room.on('room-dead',    (reason) => console.error('le salon est tombé :', reason.kind));
room.on('room-rebuilt', (link)   => console.log('salon recréé :', link));

// l'état toujours à portée de main
room.state.players.forEach((p) => console.log(p.userName, p.team));

Équipes et anti-AFK

typescript
room.lockTeams();                              // personne ne change d'équipe seul
room.enableAntiAfk({ thresholdMs: 12_000 });   // 12 s sans bouger ni écrire

room.on('player-afk', (id) => {
  room.chat(`${room.state.players.get(id)?.userName} est AFK !`);
  room.kickPlayer(id);
});
room.on('player-back', () => room.chat('est de retour !'));

room.setTeam(id, 3);    // l'hôte peut toujours déplacer les joueurs (3 = bleu)
room.isAfk(id);         // vérification ponctuelle

Session 24h/24

typescript
import { BonkSession } from 'bonktools';

const session = new BonkSession({
  auth: { type: 'registered', username, password },
  throttle: { capacity: 1, refillPerSec: 0.3 },
});
await session.getToken();

session.on('room-added', (localId) => {
  const { room } = session.rooms.get(localId)!;
  console.log('salon actif :', room.shareLink);
});
session.on('room-dead-terminal', ({ localId, reason }) => console.error(localId, reason));

// déclaratif : recrée le salon tout seul s'il tombe
await session.startFromConfig({
  rooms: [{ id: 'main', name: 'ATLAS', maxPlayers: 6, mode: 'b', rounds: 3 }],
  throttle: { maxConcurrentRooms: 1, roomCreationDelayMs: 3000, roomCreationJitterMs: 2000 },
});

Exemple : un salon de football 24h/24

Le dépôt inclut un bot de référence complet construit uniquement avec la bibliothèque. Il forme les équipes, choisit les capitaines, fait tourner le champion et gère les joueurs AFK. Servez-vous-en comme base pour le vôtre.

  • Équipes toujours égales. Basé sur maxTeamSize : jamais de 2v1, 3v1 ou 3v4.
  • Les capitaines choisissent. Quand les spectateurs peuvent compléter les équipes, le capitaine tape le numéro du joueur voulu ; le dernier joueur entre tout seul.
  • Le vainqueur reste en bleu. Le perdant passe en fin de file et le premier de la file devient capitaine des rouges.
  • AFK sans prise de tête. !afk bascule, les joueurs AFK ne sont jamais choisis, et celui qui joue ne peut pas se déclarer AFK.
  • Équipes verrouillées. Seul le bot déplace les joueurs.

Comment fonctionne le choix

Bleu

  • Ana capitaine

Rouge

vide

Spectateurs (file)

vide

1. Ana arrive

Le premier joueur va en bleu et devient capitaine. La partie en solo démarre tout de suite.

1 / 8 · maxTeamSize = 2

Commandes

CommandeQui peut l’utiliserCe qu’elle fait
!afktout joueurBascule l’AFK : passe en spectateur et ne peut pas être choisi. Pendant une partie, celui qui joue ne peut pas passer AFK.
2 (juste le numéro)capitaine dont c’est le tourChoisit le joueur numéro 2 de la liste, sans commande (30 s ; sans réponse, le premier est choisi).
!win blue · !win redjoueur sur le terrainIndique le vainqueur et déclenche la rotation des équipes.
!start · !stopjoueur sur le terrainDémarre ou arrête la partie (!stop retient le redémarrage jusqu’au prochain !start).

Documentation du salon · Règles du choix

Qualité

Les salons de jeu révèlent des bugs que les tests unitaires ratent, donc chaque fonctionnalité passe par trois niveaux de validation :

  • 123 tests dans la bibliothèque. Salon, équipes, verrou, anti-AFK, codec et reconnexion.
  • 32 tests dans le salon 24h/24, avec fuzzing. Plus de 600 séquences aléatoires d’arrivées, départs, AFK et choix, avec vérification des proportions d’équipes à chaque partie.
  • De vrais joueurs. De vrais navigateurs qui jouent ; on mesure même si le disque bouge réellement à l’écran.

Versions

  1. 0.1.0 Fondations : transport, salon avec état et événements, session 24h/24.
  2. 0.1.1 Équilibre par joueur (BALANCE_SET) reflété dans l’état.
  3. 0.1.2 Un spectateur qui arrive pendant une partie voit désormais le jeu.
  4. 0.1.3 Anti-AFK et handshake WebRTC, avec l’événement peer-input.
  5. 0.1.4 lockTeams() et unlockTeams(), ainsi que les corrections de gs.tl et des couleurs d’équipe.

Démarrez en 3 étapes

Nécessite Node.js 20.18 ou plus récent et un compte bonk.io.

  1. Installez.
    bash
    npm install bonktools
  2. Écrivez le bot.
    bot.ts
    import { createRoom } from 'bonktools';
    
    const room = await createRoom({
      auth: { type: 'registered', username: process.env.BONK_USER!, password: process.env.BONK_PASS! },
      desiredState: { roomName: 'Bonjour, bonk !', password: '', maxPlayers: 6, mode: 'b', rounds: 3 },
    });
    console.log(room.shareLink);
  3. Lancez-le.
    bash
    BONK_USER=votre_utilisateur BONK_PASS=votre_mot_de_passe npx tsx bot.ts
    # → https://bonk.io/123456abcde

Lire le guide complet