📂 File Browser

serversdashboard/lib
🌙 Dark Mode
🎯 Quick Launch:

📁 Directories

📄 Files

🐘 clientid.php
▶ Open 📄 View Source
🐘 net.php
▶ Open 📄 View Source
🐘 rcon.php
▶ Open 📄 View Source
🐘 servers.php
▶ Open 📄 View Source
🐘 snbt.php
▶ Open 📄 View Source
🐘 tmux.php
▶ Open 📄 View Source
🐘 users.php
▶ Open 📄 View Source

📄 Source: rcon.php

<?php
/**
 * Minimal Minecraft (Source) RCON client in pure PHP.
 * Implements just enough of the protocol to send commands and read replies.
 *
 * Protocol reference: https://wiki.vg/RCON
 */

class RconException extends Exception {}

class Rcon {
    private $sock;
    private int $reqId = 0;

    public function __construct(string $host, int $port, string $password, int $timeout = 3) {
        $errno = 0; $errstr = '';
        $this->sock = @fsockopen($host, $port, $errno, $errstr, $timeout);
        if (!$this->sock) {
            throw new RconException("Cannot connect to RCON at $host:$port ($errstr)");
        }
        stream_set_timeout($this->sock, $timeout);

        // Auth packet: type 3
        $this->sendPacket(3, $password);
        $resp = $this->readPacket();
        if ($resp === null) {
            throw new RconException("No RCON auth response");
        }
        // Response id -1 means auth failed
        if ($resp['id'] === -1) {
            throw new RconException("RCON auth failed");
        }
    }

    public function command(string $cmd): string {
        $this->sendPacket(2, $cmd);
        $resp = $this->readPacket();
        return $resp['body'] ?? '';
    }

    public function close(): void {
        if ($this->sock) {
            fclose($this->sock);
            $this->sock = null;
        }
    }

    private function sendPacket(int $type, string $body): void {
        $this->reqId++;
        $id = $this->reqId;
        $payload = pack('VV', $id, $type) . $body . "\x00\x00";
        $packet  = pack('V', strlen($payload)) . $payload;
        fwrite($this->sock, $packet);
    }

    private function readPacket(): ?array {
        $lenRaw = fread($this->sock, 4);
        if (strlen($lenRaw) < 4) {
            return null;
        }
        $len = unpack('V', $lenRaw)[1];
        if ($len < 10) {
            return null;
        }
        $data = '';
        while (strlen($data) < $len) {
            $chunk = fread($this->sock, $len - strlen($data));
            if ($chunk === false || $chunk === '') {
                break;
            }
            $data .= $chunk;
        }
        if (strlen($data) < 10) {
            return null;
        }
        $id   = unpack('V', substr($data, 0, 4))[1];
        $type = unpack('V', substr($data, 4, 4))[1];
        $body = substr($data, 8, -2); // strip trailing \x00\x00
        return ['id' => $id, 'type' => $type, 'body' => $body];
    }
}

/**
 * Read RCON settings from a server.properties file, if present.
 */
function rcon_from_properties(string $serverDir, array $defaults): array {
    $props = $serverDir . '/server.properties';
    $conf = $defaults;
    if (is_file($props)) {
        foreach (file($props, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
            if ($line === '' || $line[0] === '#') continue;
            $pos = strpos($line, '=');
            if ($pos === false) continue;
            $k = trim(substr($line, 0, $pos));
            $v = trim(substr($line, $pos + 1));
            if ($k === 'rcon.port')     $conf['port'] = (int)$v;
            if ($k === 'rcon.password') $conf['password'] = $v;
        }
    }
    return $conf;
}
← Back