diff --git a/rcon_debug_log.php b/rcon_debug_log.php
new file mode 100644
index 0000000..595e872
--- /dev/null
+++ b/rcon_debug_log.php
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+ RCON Debug Log - 420th Delta
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log File:
+
+
+
+ Status:
+
+
+
+ Size:
+
+
+
+
+
+
+
+
+
+
+
Log Content
+ 0): ?>
+
+
+
+
No log entries yet
+
Visit the Active Players page to generate RCON traffic
+
+
+
+
+
+
+
+
diff --git a/rcon_manager.php b/rcon_manager.php
index 7cb5373..95319b4 100644
--- a/rcon_manager.php
+++ b/rcon_manager.php
@@ -13,6 +13,9 @@ class RconManager {
// Steam ID64 is always 17 digits
const STEAM_ID64_LENGTH = 17;
+ // RCON debug log file
+ const LOG_FILE = __DIR__ . '/rcon_debug.log';
+
private $db;
private $rcon;
private $enabled;
@@ -28,6 +31,25 @@ public function __construct() {
$this->loadSettings();
}
+ /**
+ * Log RCON debug information
+ * @param string $message Log message
+ * @param mixed $data Optional data to log
+ */
+ private function logDebug($message, $data = null) {
+ $timestamp = date('Y-m-d H:i:s');
+ $logEntry = "[{$timestamp}] {$message}";
+
+ if ($data !== null) {
+ $logEntry .= "\n" . print_r($data, true);
+ }
+
+ $logEntry .= "\n" . str_repeat('-', 80) . "\n";
+
+ // Append to log file
+ file_put_contents(self::LOG_FILE, $logEntry, FILE_APPEND);
+ }
+
/**
* Load RCON settings from database
*/
@@ -127,17 +149,31 @@ public function getSettings() {
*/
private function connect() {
if (!$this->libraryAvailable) {
+ $this->logDebug("RCON library not available");
throw new Exception("RCON library not installed. Run 'composer install' to enable RCON features.");
}
if (!$this->isEnabled()) {
+ $this->logDebug("RCON not enabled or not configured");
throw new Exception("RCON is not enabled or not configured");
}
if (!$this->rcon) {
try {
+ $this->logDebug("Attempting RCON connection", [
+ 'host' => $this->host,
+ 'port' => $this->port,
+ 'password_set' => !empty($this->password)
+ ]);
+
$this->rcon = new \Nizarii\ARC($this->host, $this->password, $this->port);
+
+ $this->logDebug("RCON connection established successfully");
} catch (Exception $e) {
+ $this->logDebug("RCON connection failed", [
+ 'error' => $e->getMessage(),
+ 'trace' => $e->getTraceAsString()
+ ]);
throw new Exception("Failed to connect to RCON server: " . $e->getMessage());
}
}
@@ -151,17 +187,27 @@ private function connect() {
*/
public function testConnection() {
try {
+ $this->logDebug("testConnection() called");
+
$this->connect();
// Try to get player list as connection test
$players = $this->rcon->getPlayersArray();
+ $this->logDebug("testConnection() successful", [
+ 'player_count' => count($players)
+ ]);
+
return [
'success' => true,
'message' => 'Connected successfully to RCON server',
'player_count' => count($players)
];
} catch (Exception $e) {
+ $this->logDebug("testConnection() failed", [
+ 'error' => $e->getMessage()
+ ]);
+
return [
'success' => false,
'message' => $e->getMessage()
@@ -171,13 +217,69 @@ public function testConnection() {
/**
* Get list of online players
- * @return array Array of players
+ * @return array Array of players with enhanced fields
*/
public function getPlayers() {
try {
+ $this->logDebug("getPlayers() called");
+
$this->connect();
- return $this->rcon->getPlayersArray();
+
+ $this->logDebug("Calling RCON getPlayersArray()");
+ $rawPlayers = $this->rcon->getPlayersArray();
+
+ $this->logDebug("Raw RCON response from getPlayersArray()", [
+ 'player_count' => count($rawPlayers),
+ 'raw_data' => $rawPlayers
+ ]);
+
+ // Transform RCON data to expected format
+ // RCON returns numerically indexed arrays:
+ // [0] => player number
+ // [1] => IP:Port
+ // [2] => ping
+ // [3] => guid (BE GUID)
+ // [4] => player name
+ $players = [];
+ foreach ($rawPlayers as $rawPlayer) {
+ // Skip if not a valid player array
+ if (!is_array($rawPlayer) || count($rawPlayer) < 5) {
+ $this->logDebug("Skipping invalid player data", ['data' => $rawPlayer]);
+ continue;
+ }
+
+ // Extract IP and port from IP:Port format
+ // Ensure we have a string before splitting
+ $ipPortString = is_string($rawPlayer[1]) ? $rawPlayer[1] : '';
+ $ipPort = explode(':', $ipPortString);
+ $ip = $ipPort[0] ?? '';
+ $port = $ipPort[1] ?? '';
+
+ // Create associative array with expected field names
+ $player = [
+ 'num' => $rawPlayer[0],
+ 'ip' => $ip,
+ 'ipport' => $port, // Note: This is just the port number, not IP:Port
+ 'ping' => $rawPlayer[2],
+ 'guid' => $rawPlayer[3],
+ 'name' => $rawPlayer[4],
+ 'time' => 'N/A' // RCON doesn't track session time
+ ];
+
+ $players[] = $player;
+ }
+
+ $this->logDebug("Processed player data", [
+ 'player_count' => count($players),
+ 'processed_data' => $players
+ ]);
+
+ return $players;
} catch (Exception $e) {
+ $this->logDebug("getPlayers() failed", [
+ 'error' => $e->getMessage(),
+ 'trace' => $e->getTraceAsString()
+ ]);
throw new Exception("Failed to get player list: " . $e->getMessage());
}
}
@@ -311,4 +413,44 @@ public function executeCommand($command) {
throw new Exception("Failed to execute command: " . $e->getMessage());
}
}
+
+ /**
+ * Get the path to the RCON debug log file
+ * @return string Log file path
+ */
+ public static function getLogFilePath() {
+ return self::LOG_FILE;
+ }
+
+ /**
+ * Clear the RCON debug log file
+ * @return bool Success status
+ */
+ public static function clearLog() {
+ if (file_exists(self::LOG_FILE)) {
+ return unlink(self::LOG_FILE);
+ }
+ return true;
+ }
+
+ /**
+ * Get the contents of the RCON debug log file
+ * @param int $lines Number of lines to retrieve from the end (0 for all)
+ * @return string Log contents
+ */
+ public static function getLog($lines = 0) {
+ if (!file_exists(self::LOG_FILE)) {
+ return "Log file does not exist yet.";
+ }
+
+ $content = file_get_contents(self::LOG_FILE);
+
+ if ($lines > 0) {
+ $logLines = explode("\n", $content);
+ $logLines = array_slice($logLines, -$lines);
+ return implode("\n", $logLines);
+ }
+
+ return $content;
+ }
}