📂 File Browser

//serversdashboard/serversdashboard/api
🌙 Dark Mode
🎯 Quick Launch:

📁 Directories

📄 Files

🐘 clientid.php
▶ Open 📄 View Source
🐘 command.php
▶ Open 📄 View Source
🐘 console.php
▶ Open 📄 View Source
🐘 disable.php
▶ Open 📄 View Source
🐘 enable.php
▶ Open 📄 View Source
🐘 inventory.php
▶ Open 📄 View Source
🐘 login.php
▶ Open 📄 View Source
🐘 logout.php
▶ Open 📄 View Source
🐘 players.php
▶ Open 📄 View Source
🐘 restart.php
▶ Open 📄 View Source
🐘 start.php
▶ Open 📄 View Source
🐘 status.php
▶ Open 📄 View Source
🐘 stop.php
▶ Open 📄 View Source
🐘 users.php
▶ Open 📄 View Source
🐘 whoami.php
▶ Open 📄 View Source

📄 Source: inventory.php

<?php
require_once __DIR__ . '/../auth.php';
require_once __DIR__ . '/../lib/servers.php';
require_once __DIR__ . '/../lib/clientid.php';
require_once __DIR__ . '/../lib/snbt.php';
require_auth_json();

$CFG = $GLOBALS['__CFG'];
$server = $_GET['server'] ?? '';
$player = $_GET['player'] ?? '';

if ($server === '' || strpos($server, '/') !== false || strpos($server, '..') !== false) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'Invalid server name']);
    exit;
}
if ($player === '' || strlen($player) > 32) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'Invalid player name']);
    exit;
}

$path = server_path($CFG['server_root'], $server);

try {
    // Main inventory
    $invRaw = clientid_rcon($path, $CFG, "data get entity $player Inventory");

    // Optional: ender chest contents
    $enderRaw = '';
    try {
        $enderRaw = clientid_rcon($path, $CFG, "data get entity $player EnderItems");
    } catch (Throwable $e) {
        // EnderItems may not exist yet — ignore
    }

    $inventory = snbt_response_to_array($invRaw);
    $enderchest = snbt_response_to_array($enderRaw);

    $main  = is_array($inventory) ? snbt_summarize_inventory($inventory) : ['items' => []];
    $ender = is_array($enderchest) ? snbt_summarize_inventory($enderchest) : ['items' => []];

    // Also grab a couple of useful stats
    $health = null; $xpLevel = null; $food = null;
    foreach (['Health' => 'health', 'XpLevel' => 'xp_level', 'foodLevel' => 'food'] as $nbt => $key) {
        try {
            $r = clientid_rcon($path, $CFG, "data get entity $player $nbt");
            if (preg_match('/has the following entity data:\s*(.+)$/m', $r, $m)) {
                $val = trim($m[1]);
                $val = rtrim($val, 'bslfBSLF');
                if (is_numeric($val)) {
                    $$key = $val + 0;
                }
            }
        } catch (Throwable $e) {}
    }

    header('Content-Type: application/json');
    echo json_encode([
        'ok'         => true,
        'player'     => $player,
        'inventory'  => $main['items'],
        'enderchest' => $ender['items'],
        'health'     => $health,
        'xp_level'   => $xpLevel,
        'food'       => $food,
    ]);
} catch (Throwable $e) {
    header('Content-Type: application/json');
    echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
}

/**
 * RCON "data get entity" responses look like:
 *   <player> has the following entity data: [ {...}, {...} ]
 * We strip the prefix, then parse the SNBT.
 */
function snbt_response_to_array(string $raw): ?array {
    if ($raw === '') return null;
    $pos = strpos($raw, 'entity data:');
    if ($pos === false) return null;
    $snbt = trim(substr($raw, $pos + strlen('entity data:')));
    if ($snbt === '' || $snbt === '[]') return [];
    try {
        $v = SnbtParser::parse($snbt);
        return is_array($v) ? $v : null;
    } catch (Throwable $e) {
        return null;
    }
}
← Back