diff --git a/Mumble/stats.php b/Mumble/stats.php new file mode 100644 index 0000000..f2e653a --- /dev/null +++ b/Mumble/stats.php @@ -0,0 +1,809 @@ +stringToProxy($iceConnectionString); + + if (class_exists("\\MumbleServer\\MetaPrxHelper")) { + $meta = \MumbleServer\MetaPrxHelper::checkedCast($proxy); + } + + $context = ["secret" => $iceSecret]; + $servers = $meta->getAllServers($context); + + // Get server by ID or use first server in the list + $server = null; + try { + $server = $meta->getServer($serverId, $context); + } catch (Exception $e) { + if (count($servers) > 0) { + $server = $servers[0]; + $serverId = $server->id($context); + } + } + + if ($server) { + // Get server information + try { + $serverName = $server->getConf("registerName", $context); + if (empty($serverName)) { + $serverName = + $serverExpectedName ?: "Mumble Server #" . $serverId; + } + } catch (Exception $e) { + $serverName = $serverExpectedName ?: "Mumble Server #" . $serverId; + } + + // Get server hostname + try { + $serverHostname = $server->getConf("registerHostname", $context); + } catch (Exception $e) { + $serverHostname = "voice.claytonia.net"; + } + // Try to get port if available (default to 64738) + try { + $confPort = $server->getConf("registerPort", $context); + if (!empty($confPort) && is_numeric($confPort)) { + $serverPort = (int) $confPort; + } + } catch (Exception $e) { + $serverPort = 64738; + } + + // Get version - note: getVersion doesn't work in this implementation + $serverVersion = "Mumble Server"; + + // Get uptime + try { + $uptimeSeconds = $server->getUptime($context); + $days = floor($uptimeSeconds / 86400); + $hours = floor(($uptimeSeconds % 86400) / 3600); + $minutes = floor(($uptimeSeconds % 3600) / 60); + $uptime = ""; + if ($days > 0) { + $uptime .= "$days days, "; + } + if ($hours > 0 || $days > 0) { + $uptime .= "$hours hours, "; + } + $uptime .= "$minutes minutes"; + } catch (Exception $e) { + $uptime = "Unknown"; + } + + // Get configuration values and users + try { + $maxUsers = $server->getConf("users", $context); + } catch (Exception $e) { + $maxUsers = "?"; + } + + try { + $rawUsers = $server->getUsers($context); + $currentUsers = count($rawUsers); + } catch (Exception $e) { + $rawUsers = []; + $currentUsers = 0; + } + + // Get channels + try { + $rawChannels = $server->getChannels($context); + foreach ($rawChannels as $id => $channel) { + // Get users in this channel + $channelUsers = []; + foreach ($rawUsers as $uid => $user) { + $userChannel = null; + if (is_object($user) && isset($user->channel)) { + $userChannel = $user->channel; + } elseif (is_array($user) && isset($user["channel"])) { + $userChannel = $user["channel"]; + } + if ($userChannel == $id) { + $channelUsers[] = $uid; + } + } + $channelName = ""; + if (is_object($channel) && isset($channel->name)) { + $channelName = $channel->name; + } elseif (is_array($channel) && isset($channel["name"])) { + $channelName = $channel["name"]; + } + $channels[] = [ + "name" => $channelName, + "users" => count($channelUsers), + ]; + } + } catch (Exception $e) { + $rawChannels = []; + $channels = []; + } + + // Process users and update stats + if (isset($userStatsFile) && file_exists($userStatsFile)) { + $userStats = + json_decode(file_get_contents($userStatsFile), true) ?: []; + } else { + $userStats = []; + } + $now = time(); + $today = date("Y-m-d"); + + foreach ($rawUsers as $id => $user) { + $channelName = "Unknown"; + $userName = ""; + $userChannelId = null; + $userSession = null; + $userIdHash = null; + + if (is_object($user)) { + $userName = isset($user->name) ? $user->name : "Unknown User"; + $userChannelId = isset($user->channel) ? $user->channel : null; + $userSession = isset($user->session) ? $user->session : $id; + $userIdHash = isset($user->hash) ? $user->hash : md5($userName); + } else { + $userName = isset($user["name"]) + ? $user["name"] + : "Unknown User"; + $userChannelId = isset($user["channel"]) + ? $user["channel"] + : null; + $userSession = isset($user["session"]) ? $user["session"] : $id; + $userIdHash = isset($user["hash"]) + ? $user["hash"] + : md5($userName); + } + + if ( + $userChannelId !== null && + isset($rawChannels[$userChannelId]) + ) { + $channel = $rawChannels[$userChannelId]; + if (is_object($channel) && isset($channel->name)) { + $channelName = $channel->name; + } elseif (is_array($channel) && isset($channel["name"])) { + $channelName = $channel["name"]; + } + } + + $users[] = [ + "name" => $userName, + "channel" => $channelName, + ]; + } + + // Update and save user stats + if (isset($userStatsFile)) { + foreach ($users as $user) { + $userName = $user["name"]; + $userHash = md5($userName); + $userChannel = $user["channel"] ?? "Unknown"; + + if (!isset($userStats[$userHash])) { + $userStats[$userHash] = [ + "name" => $userName, + "first_seen" => $now, + "last_seen" => $now, + "connect_count" => 1, + "days" => [ + $today => 1, + ], + // "channels" => [ $userChannel => 1 ], + "total_time" => 0, + // "sessions" => [[ "start" => $now, "end" => null, "channel" => $userChannel ]], + ]; + continue; + } + + $userStats[$userHash]["last_seen"] = $now; + $userStats[$userHash]["days"][$today] = 1; + // Removed all channels/session management from stats page + $hasActiveSession = false; + // Removed all session/channel logic from stats page + } + // file_put_contents removed: stats page should never write to mumble_users.json + } + } +} catch (Exception $e) { + // No error output +} +?> + + + + + <?= htmlspecialchars( + $serverName ?: "Mumble Server" + ) ?> - Mumble Stats + + + + + + + +
+

Stats

+
+
+
+
Server Info
+


+ + Visit Website + +

+
+
+
+
+
Uptime
+

+
+
+
+
+
Users
+

+
+
+
+
+
Channels
+

+
+
+
+
+
+
+
Connection Details
+
+

+ Server: + +

+

+ Port: + +

+ +
+

+ + Connect to Claytonia Mumble + +

+
+
+
+
+
+
+

Channels

+
    + +
  • No channels available
  • + + +
  • + + users +
  • + + +
+
+
+
+
+

Online Users

+
    + +
  • No users online
  • + + +
  • + + +
  • + + +
+
+
+
+ +
+
+
+
User Statistics
+
+ + + + + + + + + + + + + $stat + ) { + + $dayCount = isset($stat["days"]) + ? count($stat["days"]) + : 0; + + // Display total_time from JSON directly + $totalSeconds = isset( + $stat["total_time"] + ) + ? $stat["total_time"] + : 0; + $totalHours = round( + $totalSeconds / 3600, + 1 + ); + $totalTime = $totalHours . " hours"; + + $isOnline = false; + if ( + isset($stat["sessions"]) && + !empty($stat["sessions"]) + ) { + $lastSession = end( + $stat["sessions"] + ); + if ( + $lastSession && + isset($lastSession["end"]) && + $lastSession["end"] === null + ) { + $isOnline = true; + } + } + $rowStyle = $isOnline + ? "background-color: rgba(140, 82, 255, 0.15);" + : ""; + $nameStyle = $isOnline + ? "color: #ffffff; font-weight: 700;" + : "color: #ffffff; font-weight: 600;"; + ?> + + + + + + + + + + + + + + + + + + +
UserFirst SeenLast SeenConnectionsDays ActiveTotal Time
+ + + Online + + + + +
No user statistics available yet
Statistics file not found
+
+
+
+
+
+ + +