Dienstag, 25 November 2025

Diese Woche am beliebtesten

Vertiefendes Material

IRC Bouncer Script

Dieses Dreamcodes Script stellt ein modernes IRC Bouncer Interface bereit und ermöglicht die zentrale Verwaltung von IRC Verbindungen, Channels und Benutzern. Es unterstützt mehrere Admins, TLS/SSL Verbindungen, automatische Reconnects bei Verbindungsabbrüchen sowie Timeouts für sichere Kommunikation. Zusätzlich protokolliert das Script alle gesendeten und empfangenen Nachrichten, sodass es als Monitoring Tool für Channels und Benutzeraktionen genutzt werden kann.

Funktionen im Überblick:

  • Mehrere Admins verwalten gleichzeitig
  • Channel join/leave, automatische Verbindung beim Senden von Nachrichten
  • Benutzer und Admin-Kommandos: hinzufügen, löschen, Passwort ändern, Adminrechte vergeben oder entziehen
  • Serververwaltung: Server hinzufügen/löschen, Leave-Messages setzen
  • TLS/SSL-Unterstützung für sichere Verbindungen
  • Automatische Reconnect-Mechanismen bei Unterbrechungen
  • Logging aller Nachrichten zur Überwachung und Fehleranalyse
  • PHP 8-kompatibel, sichere Input-Verarbeitung, moderne Struktur für einfache Erweiterung
<?php

class PsyBNC
{
    private $fp;
    private string $serverIp;
    private int $serverPort;
    private array $admins; // Format: ['nick' => 'password']
    private bool $useTls;
    private int $timeout;
    private int $reconnectAttempts;

    private array $channels = [];
    private array $log = [];

    public function __construct(
        string $serverIp,
        int $serverPort,
        array $admins,
        bool $useTls = false,
        int $timeout = 10,
        int $reconnectAttempts = 3
    ) {
        $this->serverIp = $serverIp;
        $this->serverPort = $serverPort;
        $this->admins = $admins;
        $this->useTls = $useTls;
        $this->timeout = $timeout;
        $this->reconnectAttempts = $reconnectAttempts;

        $this->connect();
    }

    private function connect(): void
    {
        $protocol = $this->useTls ? 'ssl://' : '';
        $attempt = 0;

        while ($attempt < $this->reconnectAttempts) {
            $this->fp = @fsockopen($protocol . $this->serverIp, $this->serverPort, $errno, $errstr, $this->timeout);
            if ($this->fp) {
                stream_set_timeout($this->fp, $this->timeout);
                $this->loginAdmins();
                return;
            }
            $attempt++;
            sleep(2); // Kurze Pause vor Retry
        }

        throw new \RuntimeException("Failed to connect after {$this->reconnectAttempts} attempts: $errstr ($errno)");
    }

    private function loginAdmins(): void
    {
        foreach ($this->admins as $nick => $pass) {
            $this->sendRaw("USER $nick $nick $nick@ :$nick");
            $this->sendRaw("NICK $nick");
            $this->sendRaw("PASS $pass");
        }
    }

    private function sendRaw(string $command): void
    {
        if (!$this->fp) {
            $this->reconnect();
        }
        fwrite($this->fp, $command . "\r\n");
        $this->log[] = "[" . date('Y-m-d H:i:s') . "] SENT: $command";
    }

    private function reconnect(): void
    {
        $this->close();
        $this->connect();
    }

    public function close(): void
    {
        if ($this->fp) {
            $this->sendRaw("QUIT");
            fclose($this->fp);
            $this->fp = null;
        }
    }

    // -------------------------
    // Channel Management
    // -------------------------
    public function joinChannel(string $channel): void
    {
        if (!in_array($channel, $this->channels, true)) {
            $this->sendRaw("JOIN $channel");
            $this->channels[] = $channel;
        }
    }

    public function leaveChannel(string $channel): void
    {
        if (in_array($channel, $this->channels, true)) {
            $this->sendRaw("PART $channel");
            $this->channels = array_filter($this->channels, fn($c) => $c !== $channel);
        }
    }

    public function sendMessage(string $channel, string $message): void
    {
        $this->joinChannel($channel);
        $this->sendRaw("PRIVMSG $channel :$message");
    }

    // -------------------------
    // User Management
    // -------------------------
    public function addUser(string $username): void { $this->sendRaw("ADDUSER $username :$username"); }
    public function delUser(string $username): void { $this->sendRaw("DELUSER $username"); }
    public function changeAdminPassword(string $nick, string $password): void { $this->sendRaw("PASSWORD $nick:$password"); }
    public function makeAdmin(string $username): void { $this->sendRaw("MADMIN $username :$username"); }
    public function revokeAdmin(string $username): void { $this->sendRaw("UNADMIN $username"); }

    // -------------------------
    // Server Management
    // -------------------------
    public function addServer(string $server): void { $this->sendRaw("ADDSERVER $server"); }
    public function delServer(string $server): void { $this->sendRaw("DELSERVER $server"); }
    public function setLeaveMessage(string $message): void { $this->sendRaw("LEAVEMSG $message"); }

    // -------------------------
    // Logging & Monitoring
    // -------------------------
    public function readData(int $length = 512): array
    {
        $lines = [];
        if (!$this->fp) {
            $this->reconnect();
        }

        while ($line = fgets($this->fp, $length)) {
            $lines[] = trim($line);
            $this->log[] = "[" . date('Y-m-d H:i:s') . "] RECV: " . htmlspecialchars($line, ENT_QUOTES, 'UTF-8');
        }

        return $lines;
    }

    public function getLog(): array
    {
        return $this->log;
    }
}

Beispiel zur Verwendung wäre:

$irc = new PsyBNC(
    'irc.example.com',
    6697,
    ['AdminNick1' => 'pass1', 'AdminNick2' => 'pass2'],
    true,  // TLS
    15,    // Timeout
    5      // Reconnect Attempts
);

// Channel beitreten und Nachricht senden
$irc->sendMessage('#dreamcodes', 'Hallo vom DC Bot!');

// Daten auslesen (Logs, PMs, Events)
$data = $irc->readData();
print_r($data);

// Log abrufen
$log = $irc->getLog();
print_r($log);

// Verbindung sauber schließen
$irc->close();
Vorheriges Tutorial
Nächstes Tutorial

Vielleicht einen Blick wert