酒店源查询工具及源码

<?php$target_path = "/iptv/live/1000.json?key=txiptv";$provinces = ["广西", "广东", "湖南", "湖北", "北京", "上海", "天津", "重庆", "河北", "山西", "辽宁", "吉林", "黑龙江", "江苏", "浙江", "安徽", "福建", "江西", "山东", "河南", "海南", "四川", "贵州", "云南", "陕西", "甘肃", "青海", "台湾", "内蒙古", "西藏", "宁夏", "新疆", "香港", "澳门"];set_time_limit(0);if (ob_get_level()) ob_end_clean();header('Content-Type: text/html; charset=utf-8');header('X-Accel-Buffering: no');?><!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>酒店源扫描列表</title><style>* { box-sizing: border-box; }body { font-family: -apple-system, "Helvetica Neue", sans-serif; background: #f4f7f9; margin: 0; padding: 10px; }.container { width: 100%; max-width: 600px; margin: 0 auto; }/* 表单区域 */.header-box { background: #fff; padding: 15px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); margin-bottom: 10px; }.form-row { display: flex; gap: 10px; margin-bottom: 10px; }select { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 15px; }.scan-btn { padding: 10px 20px; background: #007bff; color: #fff; border: none; border-radius: 4px; font-weight: bold; }input[type="text"] { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; font-family: monospace; }/* 日志窗口 */.log { background: #1e1e1e; color: #adbac7; padding: 10px; border-radius: 5px; height: 110px; overflow-y: auto; font-size: 12px; margin-bottom: 15px; font-family: 'Courier New', monospace; border-left: 4px solid #007bff; }/* 资源展示卡片 */.ip-card { background: #fff; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.08); margin-bottom: 15px; border: 1px solid #eee; overflow: hidden; }.ip-title { background: #f8f9fa; padding: 12px 15px; font-weight: bold; font-size: 14px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #eee; }.copy-all { background: #28a745; color: #fff; border: none; padding: 6px 12px; border-radius: 4px; font-size: 12px; cursor: pointer; transition: 0.3s; }.channel-item { padding: 12px 15px; border-bottom: 1px solid #f9f9f9; font-size: 14px; }.channel-item:last-child { border-bottom: none; }.ch-name { font-weight: 600; color: #2c3e50; display: block; margin-bottom: 3px; }.ch-link { color: #7f8c8d; font-size: 12px; word-break: break-all; font-family: 'Consolas', monospace; }.error-msg { color: #e74c3c; padding: 10px; text-align: center; font-weight: bold; }</style></head><body><div class="container"><div class="header-box"><form method="GET"><div class="form-row"><select name="province"><?php foreach ($provinces as $p): ?><option value="<?= $p ?>" <?= (isset($_GET['province']) && $_GET['province'] == $p) ? 'selected' : '' ?>><?= $p ?></option><?php endforeach; ?></select><button type="submit" class="scan-btn">开始</button></div><input type="text" name="token" placeholder="在此输入你的 Quake API Token" value="<?= isset($_GET['token']) ? htmlspecialchars($_GET['token']) : '' ?>" required></form></div><div class="log" id="log">>> 等待指令...</div><div id="results"><?phpif (isset($_GET['province']) && !empty($_GET['token'])) {$province = $_GET['province'];$quake_token = trim($_GET['token']);echo "<script>document.getElementById('log').innerHTML = '>> 正在验证 Token 并检索 $province ...<br>';</script>";flush();// 1. Quake API$quake_url = "https://quake.360.net/api/v3/search/quake_service";$query = 'response:"iptv/live/zh_cn.js" AND province_cn: "' . $province . '"';$post_fields = json_encode(["query" => $query, "start" => 0, "size" => 20, "latest" => true]);$ch = curl_init($quake_url);curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true,CURLOPT_POST => true,CURLOPT_POSTFIELDS => $post_fields,CURLOPT_HTTPHEADER => ["X-QuakeToken: $quake_token", "Content-Type: application/json"],CURLOPT_SSL_VERIFYPEER => false,CURLOPT_TIMEOUT => 15]);$res_raw = curl_exec($ch);$http_info = curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);$res = json_decode($res_raw, true);if ($http_info == 401) {echo "<div class='error-msg'>❌ Token 错误或已失效 (401)</div>";} elseif (isset($res['data']) && !empty($res['data'])) {foreach ($res['data'] as $asset) {$addr = $asset['ip'] . ":" . $asset['port'];echo "<script>document.getElementById('log').innerHTML += '拨测中: $addr ...<br>';</script>";flush();$test_url = "http://" . $addr . $target_path;$ch_test = curl_init($test_url);curl_setopt_array($ch_test, [CURLOPT_RETURNTRANSFER => true,CURLOPT_TIMEOUT => 5,CURLOPT_SSL_VERIFYPEER => false]);$content = curl_exec($ch_test);$status = curl_getinfo($ch_test, CURLINFO_HTTP_CODE);curl_close($ch_test);if ($status == 200) {$json = json_decode($content, true);if (isset($json['code']) && $json['code'] == 0) {$all_text = "";foreach ($json['data'] as $ch_data) {$all_text .= ($ch_data['name'] ?? '未知频道') . " ,http://" . $addr . ($ch_data['url'] ?? '') . "\\n";}?><div class="ip-card"><div class="ip-title"><span>🌐 <?= $addr ?></span><button class="copy-all" onclick="copyGroup('<?= $all_text ?>')">一键复制全部</button></div><div class="channel-list"><?php foreach ($json['data'] as $channel):$play_url = "http://" . $addr . ($channel['url'] ?? '');?><div class="channel-item"><span class="ch-name"><?= htmlspecialchars($channel['name'] ?? '未知') ?></span><span class="ch-link"><?= htmlspecialchars($play_url) ?></span></div><?php endforeach; ?></div></div><?php}}echo "<script>var d = document.getElementById('log'); d.scrollTop = d.scrollHeight;</script>";flush();}echo "<script>document.getElementById('log').innerHTML += '>> 任务执行完毕!';</script>";} else {echo "<div class='error-msg'>未找到相关资产,请尝试更换省份</div>";}}?></div></div><script>// 一键复制逻辑function copyGroup(text) {const el = document.createElement('textarea');el.value = text.replace(/\\n/g, '\n');document.body.appendChild(el);el.select();try {document.execCommand('copy');const btn = event.target;const oldText = btn.innerText;btn.innerText = "已复制";btn.style.background = "#155724";setTimeout(() => {btn.innerText = oldText;btn.style.background = "#28a745";}, 1000);} catch (err) {alert('复制失败,请手动选择');}document.body.removeChild(el);}</script></body></html>
夜雨聆风