XMB Forum Software

whos online extended

lottos - 6-24-2025 at 02:00 AM

Want to know if your forum is being visited by known good bots?
Want to see additional data such as ASN to block bad actors? (optional - free ipinfo API access required)
View all visitors, just guests, just known good bots, sort by user name or latest visit time.



Code:
<?php define('X_SCRIPT', 'whosonlinexmb.php'); require_once 'header.php'; header('Content-Type: text/html; charset=UTF-8'); if (!X_STAFF) { echo "<div class='alert'>Access Denied - Staff Only</div>"; exit; } // config options // ipinfo lite offers additional unlimited data lookups, sign up for free at // https://ipinfo.io/signup $ipinfo_token = ''; // Add your IPInfo Lite token here, or leave blank to disable $cache_ttl = 300; // Cache time in seconds // $cache_dir = __DIR__ . '/cache'; $cache_dir = __DIR__ . '/../../cache'; // Change this to your cache path @mkdir($cache_dir, 0755, true); // Input $view = $_GET['view'] ?? 'all'; $sort = $_GET['sort'] ?? 'time'; $clear = isset($_GET['clearcache']); $cache_file = "$cache_dir/whosonlinexmb_{$view}_{$sort}.html"; // Cache if (!$clear && file_exists($cache_file) && time() - filemtime($cache_file) < $cache_ttl) { readfile($cache_file); exit; } // DB Query $where = ''; switch ($view) { case 'users': $where = "WHERE username != 'xguest123'"; break; case 'guests': $where = "WHERE username = 'xguest123'"; break; case 'bots': $where = "WHERE username = 'xguest123'"; break; } $order_by = $sort === 'username' ? 'username ASC' : '`time` DESC'; $sql = "SELECT username, ip, `time`, location, invisible FROM " . X_PREFIX . "whosonline $where ORDER BY $order_by"; $query = $db->query($sql); // Known Bot detection function verify_bot($ip) { static $bots = [ 'Googlebot' => '/\.google(bot)?\.com$/', 'Bingbot' => '/\.search\.msn\.com$/', 'Applebot' => '/\.applebot\.apple\.com$/', 'DuckDuckBot' => '/\.duckduckgo\.com$/', 'YandexBot' => '/\.yandex\.ru$/', 'Baiduspider' => '/\.baidu\.com$/', ]; $hostname = gethostbyaddr($ip); $forward = gethostbyname($hostname); foreach ($bots as $name => $pattern) { if (preg_match($pattern, $hostname) && $forward === $ip) { return "&#10004; Verified $name (High Trust)"; } } return null; } function ipinfo_lite($ip, $token) { if (!$token) return null; $cache_file = __DIR__ . "/cache/ipinfo_" . md5($ip) . ".json"; if (file_exists($cache_file) && time() - filemtime($cache_file) < 86400) { return json_decode(file_get_contents($cache_file), true); } $url = "https://api.ipinfo.io/lite/{$ip}?token=$token"; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, CURLOPT_USERAGENT => 'WhosOnlineXMBScript/1.0', ]); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($http_code !== 200 || !$response) { return null; } file_put_contents($cache_file, $response); return json_decode($response, true); } // Output ob_start(); ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Who's Online</title> <style> body { font-family: sans-serif; background: #f4f4f4; padding: 20px; } h1 { font-size: 24px; } .filters a { margin-right: 10px; } table { width: 100%; border-collapse: collapse; background: #fff; margin-top: 10px; } th, td { padding: 8px; border: 1px solid #ccc; text-align: left; font-size: 14px; } th { background: #eee; } .bot { color: #d2691e; } .verified { color: green; } .ipinfo { color: #555; font-size: 12px; } .clearcache { float: right; } </style> </head> <body> <h1>Who's Online</h1> <div class="filters"> <a href="?view=all">All</a> | <a href="?view=users">Users</a> | <a href="?view=guests">Guests</a> | <a href="?view=bots">Bots</a> | <a class="clearcache" href="?view=<?=htmlspecialchars($view)?>&sort=<?=htmlspecialchars($sort)?>&clearcache=1">Clear Cache</a> </div> <div class="filters"> Sort by: <a href="?view=<?=htmlspecialchars($view)?>&sort=time">Time</a> | <a href="?view=<?=htmlspecialchars($view)?>&sort=username">Username</a> </div> <?php if ($ipinfo_token): ?> <p><em>IP data powered by ipinfo.io</em></p> <?php endif; ?> <table> <tr> <th>Username</th> <th>IP</th> <th>Time</th> <th>Location</th> <th>Status</th> </tr> <?php while ($row = $db->fetch_array($query)) { $ip = $row['ip']; $time = gmdate('Y-m-d H:i:s', $row['time'] + ($timeoffset * 3600)); //$location = htmlspecialchars(shortenString(url_to_text($row['location'])['text'], 80)); $location = htmlspecialchars(substr($row['location'], 0, 80)); $is_guest = $row['username'] === 'xguest123'; $username = $is_guest ? 'Guest' : htmlspecialchars($row['username']); $status = ''; $bot_check = verify_bot($ip); if ($bot_check) { $status = '<span class="bot verified">' . $bot_check . '</span>'; } if (!$bot_check && $is_guest && $view === 'bots') { continue; // Filtering bots only, skip normal guest } if ($ipinfo_token) { $info = ipinfo_lite($ip, $ipinfo_token); if ($info) { $asn = $info['asn'] ?? ''; $asname = $info['as_name'] ?? ''; $asdom = $info['as_domain'] ?? ''; $country = $info['country'] ?? ''; $ip_link = "https://ipinfo.io/$ip"; $asn_link = $asn ? "https://ipinfo.io/$asn" : ''; $asn_html = $asn_link ? "<a href='$asn_link' target='_blank' rel='noopener noreferrer'>$asn</a>" : htmlspecialchars($asn); $status .= "<br><span class='ipinfo'>" . "IP: <a href='$ip_link' target='_blank' rel='noopener noreferrer'>$ip</a> " . "| ASN: $asn_html ($asname, $asdom) - $country" . "</span>"; } } echo "<tr> <td>$username</td> <td>$ip</td> <td>$time</td> <td>$location</td> <td>$status</td> </tr>"; } ?> </table> </body> </html> <?php $html = ob_get_clean(); file_put_contents($cache_file, $html); echo $html; ?>