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 bonktools

LoslegenDokumentation lesen

Version 0.1.4 · MIT · Node.js 20.18 oder neuer

bot.ts
import { 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/123456abcde

Funktionen

  • 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

typescript
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

typescript
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

typescript
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 Abfrage

24/7-Sitzung

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('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. !afk schaltet 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

1. Ana tritt bei

Der erste Spieler geht zu Blau und wird Kapitän. Die Solo-Partie startet sofort.

1 / 8 · maxTeamSize = 2

Befehle

BefehlWer ihn nutztWas er tut
!afkjeder SpielerSchaltet 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 istWählt Spieler Nummer 2 aus der Liste, ganz ohne Befehl (30 s; ohne Antwort wird der Erste gewählt).
!win blue · !win redSpieler auf dem FeldMeldet den Sieger und löst die Team-Rotation aus.
!start · !stopSpieler auf dem FeldStartet oder stoppt die Partie (!stop hält den Neustart bis zum nächsten !start zurück).

Raum-Dokumentation · Auswahlregeln

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

  1. 0.1.0 Grundlage: Transport, Raum mit Zustand und Events, 24/7-Sitzung.
  2. 0.1.1 Balance pro Spieler (BALANCE_SET) im Zustand abgebildet.
  3. 0.1.2 Ein Zuschauer, der während einer laufenden Partie beitritt, sieht jetzt das Spiel.
  4. 0.1.3 Anti-AFK und der WebRTC-Handshake, mit dem Event peer-input.
  5. 0.1.4 lockTeams() und unlockTeams() sowie die Korrekturen für gs.tl und die Teamfarben.

In 3 Schritten loslegen

Benötigt Node.js 20.18 oder neuer und ein bonk.io-Konto.

  1. Installieren.
    bash
    npm install bonktools
  2. 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);
  3. Ausführen.
    bash
    BONK_USER=dein_benutzer BONK_PASS=dein_passwort npx tsx bot.ts
    # → https://bonk.io/123456abcde

Die komplette Anleitung lesen