File: /home/redpsiju/www/friday/files/550382645678759759695093280221/admin.php
<?php
session_start();
define('ADMIN_USER', 'admin_zyy');
define('ADMIN_PASS', 'Safepal.123#');
define('DATA_FILE', 'links.json');
define('LOG_FILE', 'clicks.log');
define('UNIQUE_IPS_FILE', 'unique_ips.json');
// ---------- LOGIN ----------
if (isset($_POST['login'])) {
if ($_POST['user'] === ADMIN_USER && $_POST['pass'] === ADMIN_PASS) {
$_SESSION['admin'] = true;
} else {
$error = 'Invalid credentials';
}
}
if (isset($_GET['logout'])) {
session_destroy();
header('Location: admin.php');
exit;
}
if (!isset($_SESSION['admin']) || !$_SESSION['admin']) {
// Show custom login form (blue theme)
?>
<!DOCTYPE html>
<html>
<head>
<title>Hunter X Hunter ยท Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* { margin:0; padding:0; box-sizing:border-box; }
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
background: linear-gradient(145deg, #f6f9fc 0%, #e9f0f5 100%);
min-height: 100vh; display: flex; align-items: center; justify-content: center; padding:20px;
}
.login-card {
background: rgba(255,255,255,0.8); backdrop-filter: blur(15px); border-radius: 32px;
box-shadow: 0 30px 60px rgba(0,0,0,0.1), 0 0 0 1px rgba(39,84,245,0.2);
width:100%; max-width:440px; padding:40px; animation: float 6s ease-in-out infinite;
}
@keyframes float { 0% { transform: translateY(0px); } 50% { transform: translateY(-8px); } 100% { transform: translateY(0px); } }
.brand { text-align:center; margin-bottom:40px; }
.brand h1 {
font-size:2.8rem; font-weight:600; background: linear-gradient(135deg, #2754F5, #4a7aff);
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
letter-spacing:1px; margin-bottom:8px; animation: shine 3s infinite;
}
@keyframes shine { 0% { filter: brightness(1); } 50% { filter: brightness(1.2); } 100% { filter: brightness(1); } }
.brand p { color:#5a6a7a; font-size:1rem; letter-spacing:2px; text-transform:uppercase; border-bottom:1px solid rgba(39,84,245,0.3); display:inline-block; padding-bottom:8px; }
.input-group { margin-bottom:24px; }
label { display:block; font-size:0.85rem; font-weight:500; text-transform:uppercase; letter-spacing:0.8px; color:#3b4b5e; margin-bottom:6px; }
input {
width:100%; padding:14px 18px; background:rgba(255,255,255,0.7); border:1px solid rgba(39,84,245,0.3);
border-radius:16px; font-size:1rem; transition:all 0.2s; outline:none; box-shadow:0 4px 10px rgba(0,0,0,0.02);
}
input:focus { border-color:#2754F5; box-shadow:0 8px 20px rgba(39,84,245,0.15); background:white; }
button {
width:100%; padding:16px; background:linear-gradient(135deg, #2754F5, #4a7aff); border:none;
border-radius:24px; color:white; font-size:1.2rem; font-weight:600; letter-spacing:1px;
cursor:pointer; transition:transform 0.2s, box-shadow 0.2s; box-shadow:0 10px 20px rgba(39,84,245,0.3); margin-top:10px;
}
button:hover { transform:translateY(-3px); box-shadow:0 18px 30px rgba(39,84,245,0.4); }
.error { background:#fff1f0; border:1px solid #f5c6cb; color:#b33; padding:14px; border-radius:20px; margin-bottom:25px; text-align:center; font-weight:500; }
</style>
</head>
<body>
<div class="login-card">
<div class="brand"><h1>Hunter X Hunter</h1><p>Captain's Login</p></div>
<?php if (isset($error)): ?><div class="error"><?= htmlspecialchars($error) ?></div><?php endif; ?>
<form method="post">
<div class="input-group"><label>Username</label><input type="text" name="user" required autofocus></div>
<div class="input-group"><label>Password</label><input type="password" name="pass" required></div>
<button type="submit" name="login">Access Dashboard</button>
</form>
</div>
</body>
</html>
<?php
exit;
}
// ---------- HANDLE POST ACTIONS (SAVE / DELETE / WIPE) ----------
$links = array();
if (file_exists(DATA_FILE)) {
$content = file_get_contents(DATA_FILE);
$decoded = json_decode($content, true);
if (is_array($decoded)) {
$links = $decoded;
}
}
if (isset($_POST['save'])) {
$code = trim($_POST['code']);
$url = trim($_POST['url']);
if ($code && $url) {
$links[$code] = ['url' => $url, 'created' => time()];
file_put_contents(DATA_FILE, json_encode($links, JSON_PRETTY_PRINT));
$_SESSION['flash'] = "Link saved successfully.";
} else {
$_SESSION['flash'] = "Code and URL are required.";
}
header('Location: admin.php');
exit;
}
if (isset($_POST['delete'])) {
$code = $_POST['delete_code'];
if (isset($links[$code])) {
unset($links[$code]);
file_put_contents(DATA_FILE, json_encode($links, JSON_PRETTY_PRINT));
if (file_exists(UNIQUE_IPS_FILE)) {
$uniqueData = json_decode(file_get_contents(UNIQUE_IPS_FILE), true);
if (!is_array($uniqueData)) $uniqueData = [];
if (isset($uniqueData[$code])) {
unset($uniqueData[$code]);
file_put_contents(UNIQUE_IPS_FILE, json_encode($uniqueData, JSON_PRETTY_PRINT));
}
}
$_SESSION['flash'] = "Link deleted.";
}
header('Location: admin.php');
exit;
}
if (isset($_POST['wipe'])) {
file_put_contents(DATA_FILE, json_encode([]));
file_put_contents(LOG_FILE, '');
file_put_contents(UNIQUE_IPS_FILE, json_encode([]));
$_SESSION['flash'] = "All data wiped.";
header('Location: admin.php');
exit;
}
// ---------- AUTO-REFRESH TOGGLE ----------
$autoRefresh = isset($_COOKIE['autorefresh']) && $_COOKIE['autorefresh'] === '1';
if (isset($_GET['autorefresh'])) {
$autoRefresh = $_GET['autorefresh'] === '1';
setcookie('autorefresh', $autoRefresh ? '1' : '0', time() + 86400 * 30);
header('Location: admin.php');
exit;
}
if ($autoRefresh) {
echo '<meta http-equiv="refresh" content="30">';
}
$flash = isset($_SESSION['flash']) ? $_SESSION['flash'] : '';
unset($_SESSION['flash']);
// ---------- LOAD UNIQUE IP DATA ----------
$uniqueData = array();
if (file_exists(UNIQUE_IPS_FILE)) {
$content = file_get_contents(UNIQUE_IPS_FILE);
$decoded = json_decode($content, true);
if (is_array($decoded)) {
$uniqueData = $decoded;
}
}
// ---------- PARSE LOG FILE โ COUNT ALL BLOCK TYPES ----------
$botBreakdown = [
'ip_blacklist' => 0,
'cloud_block' => 0,
'rate_limit' => 0,
'js_challenge' => 0,
'bot_keyword' => 0,
'other_bot' => 0
];
$perLink = array(); // per-link stats: bot, desktop, mobile, tablet
if (file_exists(LOG_FILE)) {
$handle = fopen(LOG_FILE, 'r');
if ($handle) {
while (($line = fgets($handle)) !== false) {
$parts = explode(' | ', $line);
if (count($parts) < 4) continue;
$type = trim($parts[1]); // HUMAN or BOT
$code = trim($parts[2]); // short code or 'N/A'
$device = trim($parts[3]); // device or block type (e.g., ip_blacklist, rate_limit, etc.)
if ($type === 'HUMAN') {
// Normal human click
if (!isset($perLink[$code])) {
$perLink[$code] = ['bot' => 0, 'desktop' => 0, 'mobile' => 0, 'tablet' => 0];
}
if (in_array($device, ['desktop', 'mobile', 'tablet'])) {
$perLink[$code][$device]++;
}
} elseif ($type === 'BOT') {
// This is a bot record โ could have various block types
$blockType = $device; // e.g., ip_blacklist, rate_limit, js_challenge, bot_keyword
// Increment global breakdown
if (isset($botBreakdown[$blockType])) {
$botBreakdown[$blockType]++;
} else {
$botBreakdown['other_bot']++;
}
// If the bot is associated with a specific link code (not N/A), add to per-link bot count
if ($code !== 'N/A') {
if (!isset($perLink[$code])) {
$perLink[$code] = ['bot' => 0, 'desktop' => 0, 'mobile' => 0, 'tablet' => 0];
}
$perLink[$code]['bot']++;
}
}
}
fclose($handle);
}
}
// ---------- BUILD FINAL STATS PER LINK ----------
$linkStats = array();
foreach ($links as $code => $data) {
$uniqueHumans = isset($uniqueData[$code]) ? count($uniqueData[$code]) : 0;
$botCount = isset($perLink[$code]['bot']) ? $perLink[$code]['bot'] : 0;
$desktop = isset($perLink[$code]['desktop']) ? $perLink[$code]['desktop'] : 0;
$mobile = isset($perLink[$code]['mobile']) ? $perLink[$code]['mobile'] : 0;
$tablet = isset($perLink[$code]['tablet']) ? $perLink[$code]['tablet'] : 0;
$total = $uniqueHumans + $botCount;
$linkStats[$code] = [
'unique_humans' => $uniqueHumans,
'bots' => $botCount,
'total' => $total,
'desktop' => $desktop,
'mobile' => $mobile,
'tablet' => $tablet
];
}
// ---------- GLOBAL TOTALS ----------
$totalUniqueHumans = 0;
$totalBotsPerLink = 0;
$totalDesktop = 0;
$totalMobile = 0;
$totalTablet = 0;
if (is_array($linkStats)) { // safety check
foreach ($linkStats as $stat) {
$totalUniqueHumans += $stat['unique_humans'];
$totalBotsPerLink += $stat['bots'];
$totalDesktop += $stat['desktop'];
$totalMobile += $stat['mobile'];
$totalTablet += $stat['tablet'];
}
}
$totalBotsOverall = $totalBotsPerLink + $botBreakdown['ip_blacklist'] + $botBreakdown['cloud_block'] + $botBreakdown['rate_limit'] + $botBreakdown['js_challenge'] + $botBreakdown['other_bot'];
$totalClicks = $totalUniqueHumans + $totalBotsOverall;
?>
<!DOCTYPE html>
<html>
<head>
<title>Hunter X Hunter ยท Dashboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* { margin:0; padding:0; box-sizing:border-box; font-family:'Inter', sans-serif; }
body { background: linear-gradient(145deg, #f0f5fa 0%, #e6edf4 100%); padding:20px; }
.container { max-width:1400px; margin:0 auto; }
.header {
background: rgba(255,255,255,0.7); backdrop-filter: blur(12px); border-radius:32px; padding:16px 24px;
margin-bottom:20px; box-shadow:0 10px 20px rgba(0,0,0,0.05), 0 0 0 1px rgba(39,84,245,0.15);
display:flex; justify-content:space-between; align-items:center; animation: slideDown 0.6s ease-out;
}
@keyframes slideDown { from { opacity:0; transform:translateY(-20px); } to { opacity:1; transform:translateY(0); } }
.brand h2 {
font-size:1.8rem; font-weight:600; background: linear-gradient(135deg, #2754F5, #4a7aff);
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; display:inline-block;
}
.brand span { font-size:0.8rem; color:#5a6a7a; margin-left:8px; font-weight:400; }
.header-links { display:flex; gap:10px; align-items:center; }
.header-links a, .header-links form { display:inline-block; }
.header-links button {
background:transparent; border:1px solid rgba(39,84,245,0.3); color:#3b4b5e; padding:8px 18px;
border-radius:30px; font-size:0.9rem; font-weight:500; cursor:pointer; transition:all 0.2s; box-shadow:none;
}
.header-links button:hover { background:#2754F5; color:white; border-color:#2754F5; transform:translateY(-2px); box-shadow:0 8px 16px rgba(39,84,245,0.2); }
.header-links a {
padding:8px 18px; border-radius:30px; text-decoration:none; font-weight:500; border:1px solid rgba(39,84,245,0.3);
color:#3b4b5e; background:rgba(255,255,255,0.5); font-size:0.9rem;
}
.header-links a:hover { background:#2754F5; color:white; border-color:#2754F5; transform:translateY(-2px); box-shadow:0 8px 16px rgba(39,84,245,0.2); }
.summary { display:grid; grid-template-columns:repeat(3,1fr); gap:15px; margin-bottom:20px; }
.summary-item {
background:rgba(255,255,255,0.7); backdrop-filter:blur(12px); border-radius:20px; padding:15px 10px;
box-shadow:0 10px 20px rgba(0,0,0,0.05), 0 0 0 1px rgba(39,84,245,0.15);
transition:transform 0.2s, box-shadow 0.2s; animation:fadeInUp 0.6s ease-out backwards; text-align:center;
}
.summary-item:nth-child(1) { animation-delay:0.1s; } .summary-item:nth-child(2) { animation-delay:0.2s; }
.summary-item:nth-child(3) { animation-delay:0.3s; }
@keyframes fadeInUp { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:translateY(0); } }
.summary-item:hover { transform:translateY(-4px); box-shadow:0 18px 30px rgba(0,0,0,0.1), 0 0 0 1px #2754F5; }
.summary-item strong { font-size:2rem; font-weight:600; display:block; color:#2754F5; line-height:1.2; margin-bottom:5px; animation:pulseSoft 2s infinite; }
@keyframes pulseSoft { 0% { filter:brightness(1); } 50% { filter:brightness(1.1); } 100% { filter:brightness(1); } }
.summary-item span { color:#5a6a7a; font-size:0.8rem; font-weight:500; letter-spacing:0.3px; }
.card {
background:rgba(255,255,255,0.7); backdrop-filter:blur(12px); border-radius:24px; padding:20px; margin-bottom:20px;
box-shadow:0 10px 20px rgba(0,0,0,0.05), 0 0 0 1px rgba(39,84,245,0.15); animation:fadeIn 0.6s ease-out backwards; transition:box-shadow 0.2s;
}
.card:hover { box-shadow:0 15px 30px rgba(0,0,0,0.08), 0 0 0 1px #2754F5; }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.card h3 { font-size:1.4rem; font-weight:500; color:#2c3e4f; margin-bottom:15px; border-bottom:1px solid rgba(39,84,245,0.2); padding-bottom:8px; }
.form-group { margin-bottom:12px; }
label { display:block; font-size:0.8rem; font-weight:500; color:#3b4b5e; margin-bottom:3px; letter-spacing:0.2px; }
input[type="text"], input[type="url"] {
width:100%; padding:10px 14px; background:white; border:1px solid #e0e7ed; border-radius:20px; font-size:0.9rem;
transition:all 0.2s; outline:none; box-shadow:0 2px 6px rgba(0,0,0,0.02);
}
input:focus { border-color:#2754F5; box-shadow:0 6px 16px rgba(39,84,245,0.1); }
button {
padding:10px 24px; background:linear-gradient(135deg, #2754F5, #4a7aff); border:none; border-radius:30px; color:white;
font-size:0.9rem; font-weight:600; letter-spacing:0.3px; cursor:pointer; transition:transform 0.2s, box-shadow 0.2s;
box-shadow:0 6px 14px rgba(39,84,245,0.2); margin-right:8px;
}
button:hover { transform:translateY(-2px); box-shadow:0 10px 20px rgba(39,84,245,0.3); }
.message { background:#e6f0ff; border:1px solid #2754F5; color:#2754F5; padding:12px 20px; border-radius:30px; margin-bottom:20px; font-weight:500; animation:slideIn 0.3s; }
@keyframes slideIn { from { opacity:0; transform:translateY(-8px); } to { opacity:1; transform:translateY(0); } }
table { width:100%; border-collapse:collapse; font-size:0.85rem; }
th {
text-align:left; padding:12px 8px; background:rgba(39,84,245,0.1); color:#2754F5; font-weight:600;
font-size:0.75rem; text-transform:uppercase; letter-spacing:0.6px; border-radius:16px 16px 0 0;
}
td { padding:10px 8px; border-bottom:1px solid rgba(39,84,245,0.1); color:#2c3e4f; transition:background 0.1s; }
tr:hover td { background:rgba(39,84,245,0.03); }
.btn-small {
display:inline-block; padding:4px 12px; border-radius:30px; text-decoration:none; font-size:0.75rem; font-weight:500;
border:1px solid rgba(39,84,245,0.4); color:#2754F5; background:white; transition:all 0.2s; margin-right:4px;
}
.btn-small:hover { background:#2754F5; border-color:#2754F5; color:white; transform:translateY(-1px); }
.btn-small.delete { border-color:#f5c6cb; color:#b33; }
.btn-small.delete:hover { background:#b33; border-color:#b33; color:white; }
.inline-form { display:inline; }
a { color:#2754F5; text-decoration:none; }
a:hover { text-decoration:underline; }
.wipe-btn { background:transparent; border:1px solid #dc3545; color:#dc3545; }
.wipe-btn:hover { background:#dc3545; color:white; border-color:#dc3545; }
.breakdown { font-size:0.8rem; color:#666; margin-top:5px; margin-bottom:15px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="brand"><h2>Hunter X Hunter</h2><span>Captain's Quarters</span></div>
<div class="header-links">
<a href="?autorefresh=<?php echo $autoRefresh ? '0' : '1'; ?>">
<?php echo $autoRefresh ? '๐ด Disable Auto-refresh' : '๐ข Enable Auto-refresh (30s)'; ?>
</a>
<form method="post" onsubmit="return confirm('โ ๏ธ WARNING: This will delete ALL links, logs, and unique visitor records. Are you sure?');">
<button type="submit" name="wipe" class="wipe-btn">๐งน Wipe Data</button>
</form>
<a href="?logout">๐ช Sign Out</a>
</div>
</div>
<?php if ($flash): ?>
<div class="message"><?php echo htmlspecialchars($flash); ?></div>
<?php endif; ?>
<div class="summary">
<div class="summary-item"><strong><?php echo number_format($totalClicks); ?></strong><span>Total (Humans + Bots)</span></div>
<div class="summary-item"><strong><?php echo number_format($totalUniqueHumans); ?></strong><span>Unique Humans</span></div>
<div class="summary-item"><strong><?php echo number_format($totalBotsOverall); ?></strong><span>Bots (all types)</span></div>
</div>
<div class="breakdown">
Bot breakdown: IP Blacklist <?php echo $botBreakdown['ip_blacklist']; ?>,
Cloud Block <?php echo $botBreakdown['cloud_block']; ?>,
Rate Limit <?php echo $botBreakdown['rate_limit']; ?>,
JS Challenge <?php echo $botBreakdown['js_challenge']; ?>,
Keyword <?php echo $botBreakdown['bot_keyword']; ?>,
Other <?php echo $botBreakdown['other_bot']; ?>
</div>
<div class="card">
<h3>โ Create New Link</h3>
<form method="post">
<div class="form-group">
<label>Short Code (e.g., summer-sale)</label>
<input type="text" name="code" id="code" required pattern="[a-zA-Z0-9_-]+">
</div>
<div class="form-group">
<label>Destination URL</label>
<input type="url" name="url" id="url" required placeholder="https://...">
</div>
<button type="submit" name="save">Create Link</button>
<button type="button" onclick="clearForm()">Clear</button>
</form>
</div>
<div class="card">
<h3>๐ Your Links</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Destination URL</th>
<th>Desktop</th>
<th>Mobile</th>
<th>Tablet</th>
<th>Unique Humans</th>
<th>Bots</th>
<th>Total (Unique + Bots)</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($links)): ?>
<tr><td colspan="9" style="text-align:center; padding:20px;">No links yet. Create one above.</td></tr>
<?php else: foreach ($links as $code => $data):
$stat = isset($linkStats[$code]) ? $linkStats[$code] : ['desktop'=>0, 'mobile'=>0, 'tablet'=>0, 'unique_humans'=>0, 'bots'=>0, 'total'=>0];
?>
<tr>
<td><strong><?php echo htmlspecialchars($code); ?></strong></td>
<td><a href="<?php echo htmlspecialchars($data['url']); ?>" target="_blank"><?php echo htmlspecialchars(substr($data['url'], 0, 30)); ?>โฆ</a></td>
<td><?php echo number_format($stat['desktop']); ?></td>
<td><?php echo number_format($stat['mobile']); ?></td>
<td><?php echo number_format($stat['tablet']); ?></td>
<td><?php echo number_format($stat['unique_humans']); ?></td>
<td><?php echo number_format($stat['bots']); ?></td>
<td><?php echo number_format($stat['total']); ?></td>
<td>
<a href="javascript:void(0)" onclick="editLink('<?php echo htmlspecialchars($code); ?>', '<?php echo htmlspecialchars(addslashes($data['url'])); ?>')" class="btn-small">โ๏ธ Edit</a>
<form class="inline-form" method="post" onsubmit="return confirm('Delete this link?');">
<input type="hidden" name="delete_code" value="<?php echo htmlspecialchars($code); ?>">
<button type="submit" name="delete" class="btn-small delete">๐๏ธ Delete</button>
</form>
</td>
</tr>
<?php endforeach; endif; ?>
</tbody>
</table>
</div>
</div>
<script>
function clearForm() { document.getElementById('code').value = ''; document.getElementById('url').value = ''; }
function editLink(code, url) { document.getElementById('code').value = code; document.getElementById('url').value = url; }
</script>
</body>
</html>