句插入记录,防止SQL注入 $db->exec("REPLACE INTO {$db->tablepre}iqismart_access_log (tid, uid, ip, create_date) VALUES ($tid, $uid, '$ip', $create_date)"); } // 检查用户访问权限 function accesslimit_check($uid){ global $db, $time; static $result_cache = array(); // 添加静态缓存 // 已经检查过的用户,直接返回缓存结果 if(isset($result_cache[$uid])) { return $result_cache[$uid]; } // 获取用户信息 $user = user_read($uid); $gid = empty($user) ? 0 : $user['gid']; // 获取配置信息 static $kv = NULL; if($kv === NULL) { $kv = kv_get('accesslimit'); // 检查是否需要每日清理 accesslimit_check_daily_reset(); } // 如果插件未启用,直接返回true if(empty($kv['enabled'])) { return $result_cache[$uid] = true; } // 获取用户组信息 static $groups = NULL; if($groups === NULL) { $grouplist = group_list_cache(); $groups = array(); $i = 0; foreach($grouplist as $group) { $groups[$group['gid']] = array('index' => $i, 'name' => $group['name']); $i++; } } // 无法找到用户组信息 if(!isset($groups[$gid])) { return $result_cache[$uid] = true; } $group_index = $groups[$gid]['index']; // 检查是否无限制 if(!empty($kv['unlimit'][$group_index]) && $kv['unlimit'][$group_index] == $gid) { return $result_cache[$uid] = true; } // 检查是否设置了时间和数量限制 $time_limit = isset($kv['time'][$group_index]) ? intval($kv['time'][$group_index]) : 0; $count_limit = isset($kv['count'][$group_index]) ? intval($kv['count'][$group_index]) : 0; if(empty($time_limit) || empty($count_limit)) { return $result_cache[$uid] = true; } // 计算时间范围 - 修正日期计算逻辑 $start_time = $time - ($time_limit * 86400); // 使用86400秒/天的固定值更准确 // 检查用户访问数量 if($gid == 0) { $ip = accesslimit_get_real_ip(); $sql = "SELECT COUNT(DISTINCT tid) AS count FROM {$db->tablepre}iqismart_access_log WHERE create_date > $start_time AND ip = '$ip'"; } else { $sql = "SELECT COUNT(DISTINCT tid) AS count FROM {$db->tablepre}iqismart_access_log WHERE create_date > $start_time AND uid = $uid"; } $res = $db->sql_find_one($sql); $used_count = $res['count']; // 超过限制 if($used_count >= $count_limit) { return $result_cache[$uid] = false; } // 针对非新用户的额外检查 if($gid > 0 && isset($user['create_date']) && $user['create_date'] < $time - 60 * 60 * 24) { static $thread_count = NULL; if($thread_count === NULL) { $thread_count = $db->sql_find_one("SELECT COUNT(DISTINCT tid) AS count FROM {$db->tablepre}thread WHERE create_date > $start_time")['count']; } if($thread_count <= 0) { return $result_cache[$uid] = false; } } return $result_cache[$uid] = true; } // 获取用户真实IP function accesslimit_get_real_ip() { static $ip = NULL; // 添加静态缓存 if($ip !== NULL) { return $ip; } // 更安全的IP获取方式 $client_ip = ''; if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { // Cloudflare支持 $client_ip = $_SERVER['HTTP_CF_CONNECTING_IP']; } elseif(!empty($_SERVER["HTTP_CLIENT_IP"])) { $client_ip = $_SERVER["HTTP_CLIENT_IP"]; } elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = explode(",", $_SERVER['HTTP_X_FORWARDED_FOR']); $client_ip = trim($ips[0]); // 只取第一个IP } elseif(!empty($_SERVER['REMOTE_ADDR'])) { $client_ip = $_SERVER['REMOTE_ADDR']; } // 验证IP是否有效 if(!empty($client_ip) && filter_var($client_ip, FILTER_VALIDATE_IP)) { $ip = $client_ip; } else { $ip = '0.0.0.0'; // 默认IP } return $ip; } ?>