feat: initial commit

This commit is contained in:
root
2026-06-14 14:00:24 +08:00
commit 72d388f642
118 changed files with 39015 additions and 0 deletions
+355
View File
@@ -0,0 +1,355 @@
<?php
/**
* 访客日志与 IP 名单数据访问
*/
require_once dirname(__DIR__) . '/DbHelper.php';
require_once dirname(__DIR__) . '/CloakHttpHelpers.php';
if (!function_exists('cloak_session_mark_real_visitor')) {
/**
* 后台「真实访客」:写入完整判定缓存,访问落地链接时走 Session 快速路径并直达真实页
*/
function cloak_session_mark_real_visitor()
{
$gcuid = !empty($_COOKIE['gfuid']) ? (string) $_COOKIE['gfuid'] : '132456789';
$_SESSION['check_result'] = 'true';
$_SESSION['visit_to_1'] = '1';
$_SESSION['visit_to_2'] = '2';
$_SESSION['visit_to_3'] = '3';
$_SESSION['gcuid'] = $gcuid;
$_SESSION['gcu_ip'] = $_SERVER['REMOTE_ADDR'] ?? '';
if (empty($_SESSION['gcu_country']) && defined('SHOW_SITE_COUNTRY')) {
$_SESSION['gcu_country'] = SHOW_SITE_COUNTRY;
}
setCrossDomainCookie('gfuid', $gcuid, time() + 3600 * 24);
}
}
if (!function_exists('cloak_session_clear_real_visitor')) {
function cloak_session_clear_real_visitor()
{
unset(
$_SESSION['check_result'],
$_SESSION['visit_to_1'],
$_SESSION['visit_to_2'],
$_SESSION['visit_to_3'],
$_SESSION['gcuid'],
$_SESSION['gcu_ip'],
$_SESSION['gcu_country'],
$_SESSION['gcu_Client'],
$_SESSION['gcu_Browser'],
$_SESSION['gcu_referer']
);
setCrossDomainCookie('gfuid', '', time() - 3600);
}
}
if (!function_exists('ip_group_list_addresses')) {
function ip_group_list_addresses($groupId)
{
$groupId = (int) $groupId;
if ($groupId <= 0) {
return [];
}
$conn = @new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME);
if ($conn->connect_error) {
return [];
}
$out = [];
$sql = 'SELECT ip_address FROM ip_list WHERE group_id = ' . $groupId;
if ($res = $conn->query($sql)) {
while ($row = $res->fetch_assoc()) {
$out[] = $row['ip_address'];
}
$res->free();
}
$conn->close();
return $out;
}
}
if (!function_exists('ip_visitor_matches_list_entry')) {
function ip_visitor_matches_list_entry($visitorIp, $entry)
{
$entry = trim($entry);
if ($entry === '') {
return false;
}
if ($visitorIp === $entry) {
return true;
}
if (mb_substr($entry, -1) === '*') {
return strpos($visitorIp, rtrim($entry, '*')) === 0;
}
return false;
}
}
if (!function_exists('ip_visitor_in_blacklist_entries')) {
function ip_visitor_in_blacklist_entries($visitorIp, array $entries)
{
foreach ($entries as $buffer) {
if (ip_visitor_matches_list_entry($visitorIp, $buffer)) {
return true;
}
}
return false;
}
}
if (!function_exists('cloak_visitor_log_request_meta')) {
function cloak_visitor_log_request_meta()
{
return [
'user_agent' => get_SERVER_value('HTTP_USER_AGENT'),
'http_referer' => get_SERVER_value('HTTP_REFERER'),
'accept_language_raw' => get_SERVER_value('HTTP_ACCEPT_LANGUAGE'),
];
}
}
if (!function_exists('cloak_visitor_log_enrich')) {
function cloak_visitor_log_enrich(array $logs)
{
$meta = cloak_visitor_log_request_meta();
foreach ($meta as $key => $value) {
if (!array_key_exists($key, $logs) || $logs[$key] === null || $logs[$key] === '') {
$logs[$key] = $value;
}
}
if (empty($logs['judge_timing']) && !empty($GLOBALS['__cloak_judge_timing'])) {
$logs['judge_timing'] = $GLOBALS['__cloak_judge_timing'];
}
return $logs;
}
}
if (!function_exists('cloak_visitor_log_async_enabled')) {
function cloak_visitor_log_async_enabled()
{
return defined('VISITOR_LOG_ASYNC') && strtoupper(VISITOR_LOG_ASYNC) === 'ON';
}
}
if (!function_exists('cloak_visitor_log_register_shutdown_drain')) {
function cloak_visitor_log_register_shutdown_drain()
{
static $registered = false;
if ($registered || !cloak_visitor_log_async_enabled()) {
return;
}
$registered = true;
register_shutdown_function(static function () {
if (function_exists('fastcgi_finish_request')) {
@fastcgi_finish_request();
}
VisitorLogQueue::drain(5);
});
}
}
if (!function_exists('cloak_write_log_db_sync')) {
function cloak_write_log_db_sync($logs)
{
return VisitorLogWorker::insertFull($logs);
}
}
if (!function_exists('cloak_write_log_db')) {
function cloak_write_log_db($logs)
{
$logs = cloak_visitor_log_enrich($logs);
if (defined('WRITE_LOG') && WRITE_LOG == '1') {
$my_url = $_SERVER['PHP_SELF'] ?? '';
$my_file_name = substr($my_url, strrpos($my_url, '/') + 1);
$config_name = str_replace('.php', '', $my_file_name);
$fp = fopen(dirname(__DIR__, 2) . '/jump.txt', 'a+');
fwrite($fp, date('Y-m-d H:i:s') . ' | 写入数据库 ' . ' | ' . ($_SESSION['check_result'] ?? '') . ' | ' . $config_name . ' | async=' . (cloak_visitor_log_async_enabled() ? '1' : '0') . "\n");
fclose($fp);
}
$result = isset($logs['result']) ? (string) $logs['result'] : '';
// 二次风控 wait:同步最小 INSERT 获取 log_idTEXT 字段异步 enrich
if ($result === 'wait') {
$logId = VisitorLogWorker::insertMinimal($logs);
if ($logId === null) {
return cloak_write_log_db_sync($logs);
}
if (cloak_visitor_log_async_enabled()) {
VisitorLogQueue::push([
'type' => 'enrich',
'log_id' => $logId,
'logs' => $logs,
]);
} else {
VisitorLogWorker::enrich($logId, $logs);
}
return $logId;
}
if (!cloak_visitor_log_async_enabled()) {
$conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME);
if ($conn->connect_error) {
$error = 'Connection failed: ' . $conn->connect_error;
$handle = fopen(dirname(__DIR__, 2) . '/err.txt', 'a+');
fwrite($handle, date('Y-m-d H:i:s') . ' | ' . $error . "\n");
fclose($handle);
return null;
}
VisitorLogSchema::ensureColumns($conn);
$data = [];
foreach ($logs as $key => $value) {
$data[$key] = cloak_db_escape($conn, $value);
}
$d = static function ($key) use ($data, $conn) {
return array_key_exists($key, $data) ? $data[$key] : cloak_db_escape($conn, '');
};
$sql = "INSERT INTO `visitor_logs`(`campagin_id`, `visit_md5_code`, `domain`, `visit_date`, `IP`, `country`, `result`, `reason`, `referer`, `client`, `browser`, `page`, `language`, `user_agent`, `http_referer`, `accept_language_raw`, `judge_timing`, `fp_url`, `device`) VALUES ('"
. $d('campagin_id') . "','"
. $d('visit_md5_code') . "','"
. $d('site_name') . "','"
. date('Y-m-d H:i:s') . "','"
. $d('customers_ip') . "','"
. $d('country') . "','"
. $d('result') . "','"
. $d('reason') . "','"
. $d('v_referer') . "','"
. $d('Client') . "','"
. $d('v_Browser') . "','"
. $d('v_PageURL') . "','"
. $d('accept_language') . "','"
. $d('user_agent') . "','"
. $d('http_referer') . "','"
. $d('accept_language_raw') . "','"
. $d('judge_timing') . "','"
. $d('fp_url') . "','"
. $d('device') . "')";
if ($conn->query($sql) === true) {
$last_id = $conn->insert_id;
$conn->close();
return $last_id;
}
$handle = fopen(dirname(__DIR__, 2) . '/err.txt', 'a+');
fwrite($handle, date('Y-m-d H:i:s') . ' | ' . 'Error: ' . $sql . '<br>' . $conn->error . "\n");
fclose($handle);
$conn->close();
return null;
}
if (!VisitorLogQueue::push(['type' => 'insert_full', 'logs' => $logs])) {
return cloak_write_log_db_sync($logs);
}
cloak_visitor_log_register_shutdown_drain();
return null;
}
}
if (!function_exists('write_log_db')) {
function write_log_db($logs)
{
return cloak_write_log_db($logs);
}
}
if (!function_exists('cloak_howmanytimesbyip')) {
function cloak_howmanytimesbyip($ip)
{
$row = ['total' => 0];
$conn = new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME);
if ($conn->connect_error) {
$handle = fopen(dirname(__DIR__, 2) . '/err.txt', 'a+');
fwrite($handle, date('Y-m-d H:i:s') . ' | Connection failed: ' . $conn->connect_error . "\n");
fclose($handle);
return 0;
}
$ipEsc = cloak_db_escape($conn, $ip);
$sql = "SELECT count(*) as `total` FROM `visitor_logs` WHERE `IP`='" . $ipEsc . "'";
if ($conn->query($sql) == true) {
$result = $conn->query($sql);
$row = $result->fetch_array();
$conn->close();
} else {
$handle = fopen(dirname(__DIR__, 2) . '/err.txt', 'a+');
fwrite($handle, date('Y-m-d H:i:s') . ' | Error: ' . $sql . '<br>' . $conn->error . "\n");
fclose($handle);
$conn->close();
return 0;
}
return $row['total'];
}
}
if (!function_exists('howmanytimesbyip')) {
function howmanytimesbyip($ip)
{
return cloak_howmanytimesbyip($ip);
}
}
if (!function_exists('cloak_write_black_list')) {
function cloak_write_black_list($ip)
{
if (!defined('BLACKLIST_GROUP_ID') || (int) BLACKLIST_GROUP_ID <= 0) {
return;
}
$gid = (int) BLACKLIST_GROUP_ID;
$conn = @new mysqli('localhost', DB_USERNAME, DB_PASSWORD, DB_NAME);
if ($conn->connect_error) {
return;
}
$stmt = $conn->prepare('INSERT IGNORE INTO ip_list (group_id, ip_address) VALUES (?, ?)');
if ($stmt) {
$stmt->bind_param('is', $gid, $ip);
$stmt->execute();
$stmt->close();
}
$conn->close();
}
}
if (!function_exists('write_black_list')) {
function write_black_list($ip)
{
cloak_write_black_list($ip);
}
}
if (!function_exists('browser_headers')) {
function browser_headers()
{
$headers = [];
foreach ($_SERVER as $name => $value) {
if (preg_match('/^HTTP_/', $name)) {
$name = strtolower(strtr(substr($name, 5), '_', '-'));
$headers[$name] = $value;
}
}
return $headers;
}
}
if (!function_exists('accept_lang_zh')) {
function accept_lang_zh()
{
if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
return false;
}
$lang = substr((string) $_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 4);
if (preg_match('/zh-c/i', $lang) or preg_match('/zh/i', $lang)) {
return true;
}
return false;
}
}
if (!function_exists('is_https')) {
function is_https()
{
return cloak_request_is_https();
}
}