$value) { try { $transmit_string .= "$name=$value; "; } catch (Exception $e) { continue; } } return $transmit_string; } } if (!function_exists('encode_visitor_cookies')) { function encode_visitor_cookies() { return cloak_encode_visitor_cookies(); } } if (!function_exists('cloak_forward_response_cookies')) { function cloak_forward_response_cookies($ch, $headerLine) { if (preg_match('/^Set-Cookie:/mi', $headerLine, $cookie)) { header($headerLine, false); } return strlen($headerLine); } } if (!function_exists('forward_response_cookies')) { function forward_response_cookies($ch, $headerLine) { return cloak_forward_response_cookies($ch, $headerLine); } } if (!function_exists('cloak_write_nt_list')) { function cloak_write_nt_list($cong_name, $nt, $ot) { $cong_name = parse_url($cong_name, PHP_URL_PATH); $content = $cong_name . '||||||' . $nt . "\n"; $file = 'nt.txt'; if ($ot) { $handle = @fopen($file, 'r+'); $search = '/' . $cong_name . '\|\|\|\|\|\|' . $ot . '/'; $found = false; $tempContent = ''; while (!feof($handle)) { $line = fgets($handle); if (preg_match($search, $line)) { $tempContent .= $content; $found = true; } else { $tempContent .= $line; } } if ($found && flock($handle, LOCK_EX)) { file_put_contents($file, $tempContent); flock($handle, LOCK_UN); } fclose($handle); } else { $handle = @fopen($file, 'a'); if ($handle && flock($handle, LOCK_EX)) { fwrite($handle, $content); flock($handle, LOCK_UN); } if ($handle) { fclose($handle); } } } } if (!function_exists('write_nt_list')) { function write_nt_list($cong_name, $nt, $ot) { cloak_write_nt_list($cong_name, $nt, $ot); } } if (!function_exists('cloak_normalize_request_host')) { /** * 规范化请求 Host:小写、去端口、去首尾空白。 * * @param string|null $host */ function cloak_normalize_request_host($host = null) { $host = strtolower(trim((string) ($host ?? ($_SERVER['HTTP_HOST'] ?? '')))); if ($host === '') { return ''; } if ($host[0] === '[') { $end = strpos($host, ']'); if ($end !== false) { return substr($host, 0, $end + 1); } } $colon = strpos($host, ':'); if ($colon !== false) { $host = substr($host, 0, $colon); } return rtrim($host, '.'); } } if (!function_exists('cloak_host_is_ip')) { /** * @param string $host */ function cloak_host_is_ip($host) { $host = trim($host); if ($host === '') { return false; } if ($host[0] === '[' && substr($host, -1) === ']') { return filter_var(substr($host, 1, -1), FILTER_VALIDATE_IP) !== false; } return filter_var($host, FILTER_VALIDATE_IP) !== false; } } if (!function_exists('cloak_host_is_local')) { /** * localhost / 单标签主机名(不含点)视为 host-only Cookie。 * * @param string $host */ function cloak_host_is_local($host) { $host = strtolower(trim($host)); if ($host === '' || strpos($host, '.') === false) { return true; } return $host === 'localhost' || substr($host, -6) === '.local' || substr($host, -5) === '.test' || substr($host, -13) === '.localhost'; } } if (!function_exists('cloak_cookie_public_suffixes')) { /** * 常见多级公共后缀(co.uk / com.cn 等),避免 Cookie domain 算成 .co.uk。 * * @return string[] */ function cloak_cookie_public_suffixes() { return [ 'co.uk', 'org.uk', 'ac.uk', 'gov.uk', 'net.uk', 'com.cn', 'net.cn', 'org.cn', 'gov.cn', 'com.au', 'net.au', 'org.au', 'edu.au', 'co.jp', 'ne.jp', 'or.jp', 'com.br', 'com.mx', 'com.tw', 'com.hk', 'co.nz', 'co.kr', 'com.sg', 'com.tr', 'com.pl', 'com.ar', 'com.co', 'co.in', 'com.my', ]; } } if (!function_exists('cloak_normalize_cookie_domain_config')) { /** * 配置项 CLOAK_COOKIE_DOMAIN → Cookie 用 domain(带点前缀,如 .shili.buzz) * * @param string $value */ function cloak_normalize_cookie_domain_config($value) { $value = strtolower(trim($value)); if ($value === '') { return ''; } $value = ltrim($value, '.'); if ($value === '' || cloak_host_is_ip($value) || cloak_host_is_local($value)) { return ''; } return '.' . $value; } } if (!function_exists('cloak_registrable_domain')) { /** * 从 Host 推断可注册域(不含前导点),IP/localhost 返回空。 * * @param string|null $host */ function cloak_registrable_domain($host = null) { if (defined('CLOAK_COOKIE_DOMAIN') && (string) CLOAK_COOKIE_DOMAIN !== '') { $configured = cloak_normalize_cookie_domain_config((string) CLOAK_COOKIE_DOMAIN); return $configured !== '' ? ltrim($configured, '.') : ''; } $host = cloak_normalize_request_host($host); if ($host === '' || cloak_host_is_ip($host) || cloak_host_is_local($host)) { return ''; } $parts = explode('.', $host); $count = count($parts); if ($count < 2) { return ''; } $suffix2 = $parts[$count - 2] . '.' . $parts[$count - 1]; if (in_array($suffix2, cloak_cookie_public_suffixes(), true)) { if ($count < 3) { return ''; } return $parts[$count - 3] . '.' . $suffix2; } return $suffix2; } } if (!function_exists('cloak_fingerprint_cookie_domain')) { /** * 指纹 / Session Cookie 跨子域 domain(带点,如 .shili.buzz);IP/localhost 返回空(host-only)。 */ function cloak_fingerprint_cookie_domain() { if (defined('CLOAK_COOKIE_DOMAIN') && (string) CLOAK_COOKIE_DOMAIN !== '') { return cloak_normalize_cookie_domain_config((string) CLOAK_COOKIE_DOMAIN); } $registrable = cloak_registrable_domain(); return $registrable !== '' ? '.' . $registrable : ''; } } if (!function_exists('cloak_fingerprint_js_cookie_options')) { /** * 前端 js-cookie 写入指纹 Cookie 的选项(与 PHP setcookie 策略一致)。 * * @return array{path:string,expires:int,sameSite:string,domain?:string,secure?:bool} */ function cloak_fingerprint_js_cookie_options() { $opts = [ 'path' => '/', 'expires' => 1, 'sameSite' => 'Lax', ]; $domain = cloak_fingerprint_cookie_domain(); if ($domain !== '') { $opts['domain'] = $domain; } if (cloak_request_is_https()) { $opts['secure'] = true; } return $opts; } } if (!function_exists('cloak_set_cross_domain_cookie')) { function cloak_set_cross_domain_cookie($name, $value, $expire) { $cookieDomain = cloak_fingerprint_cookie_domain(); $secure = cloak_request_is_https(); if (PHP_VERSION_ID >= 70300) { $opts = [ 'expires' => (int) $expire, 'path' => '/', 'secure' => $secure, 'httponly' => false, 'samesite' => 'Lax', ]; if ($cookieDomain !== '') { $opts['domain'] = ltrim($cookieDomain, '.'); } setcookie($name, $value, $opts); return; } if ($cookieDomain === '') { setcookie($name, $value, (int) $expire, '/', '', $secure, false); return; } setcookie($name, $value, (int) $expire, '/', $cookieDomain, $secure, false); } } if (!function_exists('setCrossDomainCookie')) { function setCrossDomainCookie($name, $value, $expire) { cloak_set_cross_domain_cookie($name, $value, $expire); } } if (!function_exists('cloak_fingerprint_time_param_present')) { /** * URL 是否已带 time 参数(表示前端指纹页已执行过一次跳转) */ function cloak_fingerprint_time_param_present() { return isset($_GET['time']) && (string) $_GET['time'] !== ''; } } if (!function_exists('cloak_fingerprint_cookies_ready')) { /** * 前端指纹 Cookie 是否已写入 */ function cloak_fingerprint_cookies_ready() { return isset($_COOKIE['ctime'], $_COOKIE['cyyek'], $_COOKIE['cl']); } } if (!function_exists('cloak_fingerprint_mmr_reason')) { /** * 根据 mmr Cookie 返回中文拒绝理由 */ function cloak_fingerprint_mmr_reason() { if (!isset($_COOKIE['mmr'])) { return '指纹检测未通过(未知原因)'; } $mmrMap = [ 1 => '语言包含中文', 2 => 'PC端客户不允许访问', 3 => '操作系统非IOS或者安卓', 4 => 'IPHONE 机型不符合要求', 11 => '非IPHONE机型', 12 => '自动化/WebDriver', 13 => '模拟器或虚拟机UA', 14 => '爬虫Bot UA', 15 => 'WebGL软件渲染', 16 => '环境不一致(平台/触摸/窗口)', 17 => '移动GPU与UA不符', 18 => '移动端无有效加速度计/陀螺仪', ]; $mmr = (int) $_COOKIE['mmr']; return $mmrMap[$mmr] ?? '指纹检测未通过(未知原因)'; } }