// ==UserScript== // @name ip-checker // @namespace http://tampermonkey.net/ // @version 2.0 // @description 显示当前使用的公网IP地址,并带有折叠展开功能和刷新功能,以及IP风险查询功能 // @author https://linux.do/u/snaily // @match http://*/* // @match https://*/* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @connect api.ipify.org // @connect api64.ipify.org // @connect ip-api.com // @connect scamalytics.com // @connect ping0.cc // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 检查是否为顶级窗口 if (window !== top) { console.log('Not in top window, exiting script.'); return; } function fetchCurrentIP() { console.log('Fetching current IP...'); const refreshButton = document.getElementById('refreshIpInfo'); if (refreshButton) { refreshButton.disabled = true; refreshButton.innerHTML = '正在刷新...'; } let ipv6 = null; // Fetch IPv6 GM_xmlhttpRequest({ method: "GET", url: "https://api64.ipify.org?format=json", onload: function(response) { console.log('IPv6 fetched:', response.responseText); const ipInfo = JSON.parse(response.responseText); ipv6 = isIPv6(ipInfo.ip)? ipInfo.ip: null; console.log(ipv6); }, onerror: function(error) { console.log('Error fetching IPv6:', error); if (refreshButton) { refreshButton.disabled = false; refreshButton.innerHTML = '刷新IP信息'; } } }); // Fetch IPv4 GM_xmlhttpRequest({ method: "GET", url: "https://api.ipify.org?format=json", onload: function(response) { console.log('IPv4 fetched:', response.responseText); const ipInfo = JSON.parse(response.responseText); fetchIPDetails(ipInfo.ip,ipv6); }, onerror: function(error) { console.log('Error fetching IPv4:', error); if (refreshButton) { refreshButton.disabled = false; refreshButton.innerHTML = '刷新IP信息'; } } }); } function isIPv6(ip) { // IPv6正则表达式 const ipv6Pattern = new RegExp('^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$|^([0-9a-fA-F]{1,4}:){1,7}:$|^([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}$|^([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}$|^([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}$|^([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})$|^:((:[0-9a-fA-F]{1,4}){1,7}|:)$|^fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}$|^::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9])?[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9])?[0-9])$|^([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9])?[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9])?[0-9])$'); return ipv6Pattern.test(ip); } function fetchIPDetails(ip,ipv6, callback) { console.log('Fetching IP details for:', ip); console.log(ipv6); GM_xmlhttpRequest({ method: "GET", url: "http://ip-api.com/json/" + ip, onload: function(response) { console.log('IP details fetched:', response.responseText); const ipDetails = JSON.parse(response.responseText); fetchIPRisk(ip,ipv6,ipDetails, callback); }, onerror: function(error) { console.log('Error fetching IP details:', error); const refreshButton = document.getElementById('refreshIpInfo'); if (refreshButton) { refreshButton.disabled = false; refreshButton.innerHTML = '刷新IP信息'; } if (callback) { callback(); // 查询失败后恢复按钮状态 } } }); } function fetchIPRisk(ip,ipv6,details,callback) { console.log('Fetching IP risk for:', ip); console.log(ipv6); GM_xmlhttpRequest({ method: "GET", url: `https://scamalytics.com/ip/${ip}`, onload: function(response) { console.log('IP risk fetched:', response.responseText); const riskData = parseIPRisk(response.responseText); fetchPing0Risk(ip,ipv6,details, riskData); if (callback) { callback(); // 查询成功后恢复按钮状态 } }, onerror: function(error) { console.log('Error fetching IP risk:', error); displayIPDetails(ipv6,details, null, null); const refreshButton = document.getElementById('refreshIpInfo'); if (refreshButton) { refreshButton.disabled = false; refreshButton.innerHTML = '刷新IP信息'; } } }); } function fetchPing0Risk(ip,ipv6, details, riskData) { console.log('Fetching Ping0 risk for:', ip); console.log(ipv6); GM_xmlhttpRequest({ method: "GET", url: `https://ping0.cc/ip/${ip}`, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" }, onload: function(response) { console.log('Initial Ping0 response:', response.responseText); const windowX = parseWindowX(response.responseText); if (windowX) { console.log('Parsed window.x value:', windowX); GM_xmlhttpRequest({ method: "GET", url: `https://ping0.cc/ip/${ip}`, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", "Cookie": `jskey=${windowX}` }, onload: function(response) { console.log('Final Ping0 response:', response.responseText); const ping0Data = parsePing0Risk(response.responseText); displayIPDetails(ipv6,details, riskData, ping0Data); const refreshButton = document.getElementById('refreshIpInfo'); if (refreshButton) { refreshButton.disabled = false; refreshButton.innerHTML = '刷新IP信息'; } }, onerror: function(error) { console.log('Error fetching final Ping0 risk:', error); displayIPDetails(ipv6,details, riskData, null); const refreshButton = document.getElementById('refreshIpInfo'); if (refreshButton) { refreshButton.disabled = false; refreshButton.innerHTML = '刷新IP信息'; } } }); } else { console.log('Failed to retrieve window.x value.'); displayIPDetails(ipv6,details, riskData, null); const refreshButton = document.getElementById('refreshIpInfo'); if (refreshButton) { refreshButton.disabled = false; refreshButton.innerHTML = '刷新IP信息'; } } }, onerror: function(error) { console.log('Error fetching initial Ping0 page:', error); displayIPDetails(ipv6,details, riskData, null); const refreshButton = document.getElementById('refreshIpInfo'); if (refreshButton) { refreshButton.disabled = false; refreshButton.innerHTML = '刷新IP信息'; } } }); } function parseIPRisk(html) { console.log('Parsing IP risk data...'); const scoreMatch = html.match(/"score":"(.*?)"/); const riskMatch = html.match(/"risk":"(.*?)"/); if (riskMatch) { const riskData = { score: scoreMatch[1], risk: riskMatch[1] }; console.log('Parsed risk data:', riskData); return riskData; } console.log('Failed to parse risk data.'); return null; } function parseWindowX(html) { console.log('Parsing window.x value...'); const match = html.match(/window\.x\s*=\s*'([^']+)'/); const windowX = match ? match[1] : null; console.log('Parsed window.x:', windowX); return windowX; } function parsePing0Risk(html) { console.log('Parsing Ping0 risk data...'); const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const riskValue = doc.evaluate('/html/body/div[2]/div[2]/div[1]/div[2]/div[9]/div[2]/span', doc, null, XPathResult.STRING_TYPE, null).stringValue; const ipType = doc.evaluate('/html/body/div[2]/div[2]/div[1]/div[2]/div[8]/div[2]/span', doc, null, XPathResult.STRING_TYPE, null).stringValue; const nativeIP = doc.evaluate('/html/body/div[2]/div[2]/div[1]/div[2]/div[11]/div[2]/span', doc, null, XPathResult.STRING_TYPE, null).stringValue; const ping0Data = { riskValue: riskValue.trim(), ipType: ipType.trim(), nativeIP: nativeIP.trim() }; console.log('Parsed Ping0 data:', ping0Data); return ping0Data; } function displayIPDetails(ipv6,details, riskData, ping0Data) { console.log('Displaying IP details...'); var ipElement = document.getElementById('ipInfo'); if (!ipElement) { ipElement = document.createElement('div'); ipElement.id = 'ipInfo'; ipElement.style.position = 'fixed'; ipElement.style.top = GM_getValue('ipInfoTop', '10px'); ipElement.style.right = '-500px'; ipElement.style.backgroundColor = '#fff'; ipElement.style.padding = '10px'; ipElement.style.borderRadius = '5px 0 0 5px'; // 仅左侧有圆角 ipElement.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)'; ipElement.style.fontSize = '14px'; ipElement.style.color = '#333'; ipElement.style.zIndex = '9999'; ipElement.style.transition = 'right 0.3s ease'; // 添加平滑过渡效果 const title = document.createElement('div'); title.style.fontWeight = 'bold'; title.style.marginBottom = '5px'; title.innerText = 'IP检测信息'; const refreshButton = document.createElement('button'); refreshButton.id = 'refreshIpInfo'; refreshButton.style.display = 'inline-block'; refreshButton.style.width = 'auto'; refreshButton.style.marginLeft = '10px'; refreshButton.style.backgroundColor = '#007bff'; refreshButton.style.color = '#fff'; refreshButton.style.border = 'none'; refreshButton.style.borderRadius = '3px'; refreshButton.style.padding = '2px 5px'; refreshButton.style.cursor = 'pointer'; refreshButton.style.fontSize = '12px'; refreshButton.innerHTML = '刷新IP信息'; refreshButton.onclick = fetchCurrentIP; const toggleButton = document.createElement('button'); toggleButton.id = 'toggleIpInfo'; toggleButton.style.display = 'none'; toggleButton.style.width = 'auto'; toggleButton.style.marginLeft = '10px'; toggleButton.style.backgroundColor = '#007bff'; toggleButton.style.color = '#fff'; toggleButton.style.border = 'none'; toggleButton.style.borderRadius = '3px'; toggleButton.style.padding = '2px 5px'; toggleButton.style.cursor = 'pointer'; toggleButton.style.fontSize = '12px'; toggleButton.innerHTML = '展开信息'; toggleButton.onclick = toggleIpInfo; const inputContainer = document.createElement('div'); inputContainer.style.marginTop = '10px'; const ipInput = document.createElement('input'); ipInput.type = 'text'; ipInput.placeholder = '输入IP地址'; ipInput.style.marginRight = '5px'; ipInput.id = 'queryIpInput'; const queryButton = document.createElement('button'); queryButton.id = 'queryIpButton'; queryButton.innerHTML = '查询IP'; queryButton.style.width = 'auto'; queryButton.style.backgroundColor = '#007bff'; queryButton.style.color = '#fff'; queryButton.style.border = 'none'; queryButton.style.borderRadius = '3px'; queryButton.style.padding = '2px 5px'; queryButton.style.cursor = 'pointer'; queryButton.style.fontSize = '12px'; queryButton.onclick = queryIpInfo; const dragHandle = document.createElement('div'); dragHandle.style.width = '100%'; dragHandle.style.height = '10px'; dragHandle.style.backgroundColor = '#ccc'; dragHandle.style.cursor = 'move'; dragHandle.style.marginBottom = '10px'; dragHandle.onmousedown = startDragging; const content = document.createElement('div'); content.id = 'ipInfoContent'; title.appendChild(refreshButton); title.appendChild(toggleButton); inputContainer.appendChild(ipInput); inputContainer.appendChild(queryButton); title.appendChild(inputContainer); ipElement.appendChild(title); ipElement.appendChild(dragHandle); ipElement.appendChild(content); document.body.appendChild(ipElement); // 创建展开按钮 const expandButton = document.createElement('button'); expandButton.id = 'expandIpInfo'; expandButton.style.position = 'fixed'; expandButton.style.top = GM_getValue('ipInfoTop', '10px'); expandButton.style.width = 'auto'; expandButton.style.right = '0'; expandButton.style.backgroundColor = '#007bff'; expandButton.style.color = '#fff'; expandButton.style.border = 'none'; expandButton.style.borderRadius = '3px 0 0 3px'; expandButton.style.padding = '2px 5px'; expandButton.style.cursor = 'pointer'; expandButton.style.fontSize = '12px'; expandButton.style.zIndex = '9999'; expandButton.innerHTML = '展开信息'; expandButton.onclick = toggleIpInfo; expandButton.style.display = 'block'; // 默认隐藏 document.body.appendChild(expandButton); } var contentElement = document.getElementById('ipInfoContent'); if (!contentElement) { contentElement = document.createElement('div'); contentElement.id = 'ipInfoContent'; ipElement.appendChild(contentElement); } const content = `