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 bonktoolsCommencerLire la documentation
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/123456abcdeFonctionnalité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
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
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
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 ponctuelleSession 24h/24
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.
!afkbascule, 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
Le premier joueur va en bleu et devient capitaine. La partie en solo démarre tout de suite.
Commandes
| Commande | Qui peut l’utiliser | Ce qu’elle fait |
|---|---|---|
!afk | tout joueur | Bascule 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 tour | Choisit le joueur numéro 2 de la liste, sans commande (30 s ; sans réponse, le premier est choisi). |
!win blue · !win red | joueur sur le terrain | Indique le vainqueur et déclenche la rotation des équipes. |
!start · !stop | joueur sur le terrain | Démarre ou arrête la partie (!stop retient le redémarrage jusqu’au prochain !start). |
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
0.1.0Fondations : transport, salon avec état et événements, session 24h/24.0.1.1Équilibre par joueur (BALANCE_SET) reflété dans l’état.0.1.2Un spectateur qui arrive pendant une partie voit désormais le jeu.0.1.3Anti-AFK et handshake WebRTC, avec l’événementpeer-input.0.1.4lockTeams()etunlockTeams(), ainsi que les corrections degs.tlet des couleurs d’équipe.
Démarrez en 3 étapes
Nécessite Node.js 20.18 ou plus récent et un compte bonk.io.
- Installez.bash
npm install bonktools - É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); - Lancez-le.bash
BONK_USER=votre_utilisateur BONK_PASS=votre_mot_de_passe npx tsx bot.ts # → https://bonk.io/123456abcde