whos online extended
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 "✔ 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;
?>
|
|