bonk.io automatisieren, ohne einen Browser zu öffnen.
bonktools ist eine TypeScript-Bibliothek, die direkt das Protokoll des Spiels spricht. Erstelle Räume, steuere Teams, erkenne AFK-Spieler und halte einen Raum rund um die Uhr am Laufen.
npm install bonktoolsimport { createRoom } from 'bonktools';
const room = await createRoom({
auth: { type: 'registered', username, password },
desiredState: {
roomName: 'Mein Raum', password: '',
maxPlayers: 6, mode: 'b', rounds: 3,
},
});
room.lockTeams(); // nur der Host verschiebt Spieler
room.enableAntiAfk(); // 12 s reglos = 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/123456abcdeFunktionen
- Direkte Protokollverbindung. Socket.IO v2 und die TLS-Kette von bonk.io sind bereits gelöst. Kein Puppeteer, kein virtueller Bildschirm, keine anfällige UI-Automatisierung. Protokoll →
- 24/7-Räume, die sich erholen. BonkSession erstellt abgestürzte Räume neu, mit exponentiellem Backoff, Erstellungs-Throttle und einem Reconcile alle 60 s. 24/7-Sitzungen →
- Typisierte Events. Über 30 Events mit typisierten Payloads und der Raumzustand immer verfügbar in room.state. Events →
- Team-Kontrolle. lockTeams() verhindert, dass Spieler eigenständig das Team wechseln: Nur der Host verschiebt Spieler. Wer später beitritt, sieht den Raum bereits gesperrt. Teams und Sperre →
- Anti-AFK. Erkennt 12 s ohne Bewegung und ohne Chat und liest die Bewegung aus den WebRTC-Input-Frames. Anti-AFK →
- Zuschauer sehen das Spiel. Wer während einer laufenden Partie beitritt, bekommt sofort den Spielzustand, ohne die Partie für alle neu zu starten. Partien →
So funktioniert es
Du wählst die Abstraktionsebene: ein roher Socket, ein Raum mit Zustand und Events oder ein Raum-Pool, der sich selbst am Leben hält. Jeder Raum ist eine schlanke Verbindung; das Spiel muss nicht gerendert werden, um einen Raum zu hosten.
Dein Code
│
BonkSession Raum-Pool · gemeinsamer Login · Throttle · Reconcile alle 60 s
BonkRoom Zustand · typisierte Events · Teams · Sperre · Anti-AFK · Reconnect
BonkTransport Socket.IO v2 (EIO=3) · TLS · Timesync
│
bonk.io + PeerJS/WebRTC für die Input-Frames der Spieler- Ausfälle unter Kontrolle. Vorübergehende Abbrüche werden neu aufgebaut. Bans, volle Räume und erschöpfte Wiederholungen sind endgültig und werden gemeldet.
- Dokumentiertes Protokoll. Das Reverse Engineering ist ausführlich festgehalten, mit Paketformaten und Fallstricken. Protokoll ansehen →
Beispiele
Räume erstellen und beitreten
import { createRoom, joinRoom } from 'bonktools';
// Einen Raum erstellen (der Bot wird Host)
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);
// Einem bestehenden Raum beitreten
const guest = await joinRoom('https://bonk.io/123456abcde', {
auth: { type: 'guest', guestName: 'BonkBot' },
role: 'spectator',
});Events und Zustand
room.on('player-join', (p) => room.chat(`Willkommen, ${p.userName}!`));
room.on('team-change', (p) => console.log(`Spieler ${p.id} → Team ${p.team}`));
room.on('game-start', () => console.log('Partie gestartet'));
room.on('game-end', () => console.log('Partie beendet'));
room.on('room-dead', (reason) => console.error('Raum ist abgestürzt:', reason.kind));
room.on('room-rebuilt', (link) => console.log('Raum neu erstellt:', link));
// Zustand immer griffbereit
room.state.players.forEach((p) => console.log(p.userName, p.team));Teams und Anti-AFK
room.lockTeams(); // niemand wechselt eigenständig das Team
room.enableAntiAfk({ thresholdMs: 12_000 }); // 12 s ohne Bewegung und ohne Chat
room.on('player-afk', (id) => {
room.chat(`${room.state.players.get(id)?.userName} ist AFK!`);
room.kickPlayer(id);
});
room.on('player-back', () => room.chat('ist zurück!'));
room.setTeam(id, 3); // der Host kann weiterhin Spieler verschieben (3 = Blau)
room.isAfk(id); // einmalige Abfrage24/7-Sitzung
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('Raum aktiv:', room.shareLink);
});
session.on('room-dead-terminal', ({ localId, reason }) => console.error(localId, reason));
// deklarativ: erstellt den Raum selbst neu, falls er abstürzt
await session.startFromConfig({
rooms: [{ id: 'main', name: 'ATLAS', maxPlayers: 6, mode: 'b', rounds: 3 }],
throttle: { maxConcurrentRooms: 1, roomCreationDelayMs: 3000, roomCreationJitterMs: 2000 },
});Beispiel: ein 24/7-Fußballraum
Das Repository enthält einen kompletten Referenz-Bot, der nur mit der Bibliothek gebaut wurde. Er bildet die Teams, wählt Kapitäne, rotiert den Champion und behandelt AFK-Spieler. Nimm ihn als Grundlage für deinen eigenen.
- Immer gleich große Teams. Basierend auf
maxTeamSize: nie 2v1, 3v1 oder 3v4. - Kapitäne wählen. Wenn die Zuschauer die Teams auffüllen können, tippt der Kapitän die Nummer des gewünschten Spielers; der letzte Spieler tritt von allein bei.
- Der Sieger bleibt Blau. Der Verlierer geht ans Ende der Warteschlange und der Erste der Schlange wird Kapitän von Rot.
- AFK ohne Aufwand.
!afkschaltet um, AFK-Spieler werden nie gewählt, und wer spielt, kann sich nicht AFK melden. - Gesperrte Teams. Nur der Bot verschiebt Spieler.
So funktioniert die Auswahl
Blau
- Ana Kapitän
Rot
leer
Zuschauer (Warteschlange)
leer
Der erste Spieler geht zu Blau und wird Kapitän. Die Solo-Partie startet sofort.
Befehle
| Befehl | Wer ihn nutzt | Was er tut |
|---|---|---|
!afk | jeder Spieler | Schaltet AFK um: wechselt zu den Zuschauern und kann nicht gewählt werden. Während einer Partie kann, wer spielt, nicht AFK gehen. |
2 (nur die Zahl) | Kapitän, der an der Reihe ist | Wählt Spieler Nummer 2 aus der Liste, ganz ohne Befehl (30 s; ohne Antwort wird der Erste gewählt). |
!win blue · !win red | Spieler auf dem Feld | Meldet den Sieger und löst die Team-Rotation aus. |
!start · !stop | Spieler auf dem Feld | Startet oder stoppt die Partie (!stop hält den Neustart bis zum nächsten !start zurück). |
Qualität
Spielräume zeigen Fehler, die Unit-Tests übersehen, deshalb durchläuft jede Funktion drei Validierungsebenen:
- 123 Tests in der Bibliothek. Raum, Teams, Sperre, Anti-AFK, Codec und Reconnect.
- 32 Tests im 24/7-Raum, mit Fuzzing. Über 600 zufällige Abfolgen von Beitritten, Austritten, AFK und Auswahlen, mit Prüfung der Team-Verhältnisse in jeder Partie.
- Echte Spieler. Echte Browser spielen; wir messen sogar, ob sich die Scheibe auf dem Bildschirm wirklich bewegt.
Versionen
0.1.0Grundlage: Transport, Raum mit Zustand und Events, 24/7-Sitzung.0.1.1Balance pro Spieler (BALANCE_SET) im Zustand abgebildet.0.1.2Ein Zuschauer, der während einer laufenden Partie beitritt, sieht jetzt das Spiel.0.1.3Anti-AFK und der WebRTC-Handshake, mit dem Eventpeer-input.0.1.4lockTeams()undunlockTeams()sowie die Korrekturen fürgs.tlund die Teamfarben.
In 3 Schritten loslegen
Benötigt Node.js 20.18 oder neuer und ein bonk.io-Konto.
- Installieren.bash
npm install bonktools - Den Bot schreiben.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: 'Hallo, bonk!', password: '', maxPlayers: 6, mode: 'b', rounds: 3 }, }); console.log(room.shareLink); - Ausführen.bash
BONK_USER=dein_benutzer BONK_PASS=dein_passwort npx tsx bot.ts # → https://bonk.io/123456abcde