📂 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: clientid.php

<?php
/**
 * ClientID mod integration.
 *
 * RCON responses arrive as a single line, e.g.:
 *   "ezyalex700_'s mod list:appleskin, architectury, balm, ..."
 *   "ezyalex700_'s pack list:Default, Fabric Mod \"AppleSkin\", ..."
 *
 * There is no newline between the header and the list. We split on the
 * first ':' that appears AFTER the word "list".
 */

require_once __DIR__ . '/rcon.php';

function clientid_rcon(string $serverDir, array $cfg, string $command): string {
    $rcon = rcon_from_properties($serverDir, $cfg['rcon']);
    if (empty($rcon['password'])) {
        throw new RuntimeException('RCON not configured in server.properties');
    }
    $r = new Rcon($rcon['host'], (int)$rcon['port'], $rcon['password'], (int)$rcon['timeout']);
    try {
        return $r->command($command);
    } finally {
        $r->close();
    }
}

/**
 * Extract the comma-separated list part of a ClientID response.
 *
 * Examples:
 *   "ezyalex700_'s mod list:appleskin, architectury"      → "appleskin, architectury"
 *   "ezyalex700_'s pack list:Default, Fabric Mod \"X\""   → "Default, Fabric Mod \"X\""
 *   "ezyalex700_'s mod list:"                              → ""
 *   "<player> not found"                                   → null
 */
function clientid_extract_list(string $raw, string $kind): ?string {
    $raw = trim($raw);
    if ($raw === '') return null;

    // Find "mod list" or "pack list" (case-insensitive), then the first ':'
    // after it. Everything after that colon is the list.
    $needle = $kind . ' list';
    $pos = stripos($raw, $needle);
    if ($pos === false) return null;

    $colon = strpos($raw, ':', $pos);
    if ($colon === false) return null;

    return trim(substr($raw, $colon + 1));
}

/**
 * Parse the "viewmods" response into a lowercase list of mod IDs.
 */
function clientid_parse_mods(string $raw): array {
    $listPart = clientid_extract_list($raw, 'mod');
    if ($listPart === null || $listPart === '') return [];

    $mods = [];
    foreach (explode(',', $listPart) as $piece) {
        $piece = trim($piece);
        if ($piece !== '') $mods[] = strtolower($piece);
    }
    return array_values(array_unique($mods));
}

/**
 * Parse the "viewpacks" response.
 *
 * Entries look like:
 *   Default
 *   Fabric Mod "AppleSkin"
 *   Fullbright-UB-26.3 fub-7.0.zip
 *
 * Some pack names contain commas? Unlikely, but the split on ', ' with
 * a lookahead protects against it: we split on commas that are followed
 * by "Fabric Mod " or by a capitalized word that isn't inside quotes.
 * Simplest safe approach: split on ', ' and re-join any piece that
 * starts with a lowercase continuation of a quoted string.
 */
function clientid_parse_packs(string $raw): array {
    $listPart = clientid_extract_list($raw, 'pack');
    if ($listPart === null || $listPart === '') return [];

    // Split on ", " — the ClientID format uses a comma-space separator
    // between entries. Quoted names don't contain ", " inside them
    // (Fabric Mod names are simple).
    $parts = preg_split('/,\s+/', $listPart);
    $packs = [];
    foreach ($parts as $piece) {
        $piece = trim($piece);
        if ($piece !== '') $packs[] = $piece;
    }
    return array_values(array_unique($packs));
}

/**
 * Filter a mod list against a baseline (case-insensitive).
 */
function clientid_filter_mods(array $playerMods, array $baseline): array {
    $baseSet = [];
    foreach ($baseline as $b) $baseSet[strtolower(trim($b))] = true;

    $extra = [];
    foreach ($playerMods as $m) {
        $m = strtolower(trim($m));
        if ($m === '') continue;
        if (!isset($baseSet[$m])) $extra[] = $m;
    }
    sort($extra);
    return $extra;
}

/**
 * Filter a pack list against a baseline (case-insensitive).
 */
function clientid_filter_packs(array $playerPacks, array $baseline): array {
    $baseSet = [];
    foreach ($baseline as $b) $baseSet[strtolower(trim($b))] = true;

    $extra = [];
    foreach ($playerPacks as $p) {
        $p = trim($p);
        if ($p === '') continue;
        if (!isset($baseSet[strtolower($p)])) $extra[] = $p;
    }
    sort($extra);
    return $extra;
}
← Back