ip-checker

显示当前使用的公网IP地址,并带有折叠展开功能和刷新功能,以及IP风险查询功能

当前为 2024-06-05 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         ip-checker
// @namespace    http://tampermonkey.net/
// @version      1.1
// @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      ip-api.com
// @connect      scamalytics.com
// @connect      ping0.cc
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    function fetchCurrentIP() {
        console.log('Fetching current IP...');
        const refreshButton = document.getElementById('refreshIpInfo');
        if (refreshButton) {
            refreshButton.disabled = true;
            refreshButton.innerHTML = '正在刷新...';
        }

        GM_xmlhttpRequest({
            method: "GET",
            url: "https://api.ipify.org?format=json",
            onload: function(response) {
                console.log('IP fetched:', response.responseText);
                const ipInfo = JSON.parse(response.responseText);
                fetchIPDetails(ipInfo.ip);
            },
            onerror: function(error) {
                console.log('Error fetching IP:', error);
                if (refreshButton) {
                    refreshButton.disabled = false;
                    refreshButton.innerHTML = '点击刷新IP信息';
                }
            }
        });
    }

    function fetchIPDetails(ip) {
        console.log('Fetching IP details for:', ip);
        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, ipDetails);
            },
            onerror: function(error) {
                console.log('Error fetching IP details:', error);
                const refreshButton = document.getElementById('refreshIpInfo');
                if (refreshButton) {
                    refreshButton.disabled = false;
                    refreshButton.innerHTML = '点击刷新IP信息';
                }
            }
        });
    }

    function fetchIPRisk(ip, details) {
        console.log('Fetching IP risk for:', ip);
        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, details, riskData);
            },
            onerror: function(error) {
                console.log('Error fetching IP risk:', error);
                displayIPDetails(details, null, 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 fetchPing0Risk(ip, details, riskData) {
        console.log('Fetching Ping0 risk for:', ip);
        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(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(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(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(details, riskData, null);
                const refreshButton = document.getElementById('refreshIpInfo');
                if (refreshButton) {
                    refreshButton.disabled = false;
                    refreshButton.innerHTML = '点击刷新IP信息';
                }
            }
        });
    }

    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 createCopyButton(text) {
        const button = document.createElement('button');
        button.innerHTML = '复制';
        button.style.marginLeft = '5px';
        button.style.cursor = 'pointer';
        button.style.backgroundColor = '#007bff';
        button.style.color = '#fff';
        button.style.border = 'none';
        button.style.padding = '2px 5px';
        button.style.borderRadius = '3px';
        button.onclick = () => {
            navigator.clipboard.writeText(text).then(() => {
                alert('复制成功: ' + text);
            }).catch(err => {
                console.error('复制失败: ', err);
            });
        };
        return button;
    }

    function displayIPDetails(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 = '0';
            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.5)';
            ipElement.style.textAlign = 'left';
            ipElement.style.zIndex = '9999';
            ipElement.style.color = '#004085'; // 设置深蓝色字体颜色
            ipElement.style.transition = 'right 0.5s'; // 平滑过渡效果
            ipElement.style.width = '300px'; // 指定宽度
            ipElement.style.right = '-300px'; // 默认隐藏在屏幕边缘

            ipElement.innerHTML = `
                <div id="toggleIpInfo" style="position:absolute;left:-20px;top:0;width:20px;height:100%;background-color:#cfe6ff;cursor:pointer;z-index:10000;">
                    <span id="toggleIcon" style="position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);font-size:18px;color:white;">◀</span>
                </div>
                <button id="refreshIpInfo" style="cursor:pointer;background-color:#28a745;color:#fff;border:none;padding:5px 10px;border-radius:5px;width:100%;margin-bottom:10px;">点击刷新IP信息</button>
                <div id="ipDetails" style="display:none;">
                    <div>当前公网IP: ${details.query}<button id="copyIp" style="margin-left: 5px;">复制</button></div>
                    <div>组织: ${details.org}<button id="copyOrg" style="margin-left: 5px;">复制</button></div>
                    <div>城市: ${details.city}<button id="copyCity" style="margin-left: 5px;">复制</button></div>
                    <div>地区: ${details.regionName}<button id="copyRegion" style="margin-left: 5px;">复制</button></div>
                    <div>国家: ${details.country}<button id="copyCountry" style="margin-left: 5px;">复制</button></div>
                    <div>坐标: ${details.lon},${details.lat}<button id="copyCoords" style="margin-left: 5px;">复制</button></div>
                    <div>ISP: ${details.isp}<button id="copyIsp" style="margin-left: 5px;">复制</button></div>
                    <div>AS: ${details.as}<button id="copyAs" style="margin-left: 5px;">复制</button></div>
                    <div>风险分数: ${riskData ? riskData.score : '查询失败'}(${riskData ? riskData.risk : ''})<button id="copyRiskScore" style="margin-left: 5px;">复制</button></div>
                    <div>风控值: ${ping0Data ? ping0Data.riskValue : '查询失败'}<button id="copyRiskValue" style="margin-left: 5px;">复制</button></div>
                    <div>IP类型: ${ping0Data ? ping0Data.ipType : '查询失败'}<button id="copyIpType" style="margin-left: 5px;">复制</button></div>
                    <div>原生IP: ${ping0Data ? ping0Data.nativeIP : '查询失败'}<button id="copyNativeIp" style="margin-left: 5px;">复制</button></div>
                </div>
            `;

            document.body.appendChild(ipElement);

            // 绑定点击事件
            document.getElementById('toggleIpInfo').addEventListener('click', function() {
                var ipDetails = document.getElementById('ipDetails');
                var toggleIcon = document.getElementById('toggleIcon');
                ipElement.style.right = (ipElement.style.right == '0px') ? '-300px' : '0px'; // 切换贴边隐藏
                if (ipDetails.style.display === 'none') {
                    ipDetails.style.display = 'block';
                    toggleIcon.innerHTML = '▶';
                } else {
                    ipDetails.style.display = 'none';
                    toggleIcon.innerHTML = '◀';
                }
            });

            document.getElementById('refreshIpInfo').addEventListener('click', fetchCurrentIP);

            // 初始化变量用于记录拖拽状态
            let isDragging = false;
            let startY = 0;
            let startTop = 0;

            // 鼠标按下事件,在ipElement区域生效
            ipElement.addEventListener('mousedown', function(e) {
                if (e.target.id !== 'refreshIpInfo' && e.target.id !== 'toggleIcon') {
                    isDragging = true;
                    startY = e.clientY;
                    startTop = parseInt(window.getComputedStyle(ipElement).top, 10);
                    ipElement.style.transition = 'none'; // 去除过渡效果以便拖拽时立即反应
                }
            });

            // 鼠标移动事件
            document.addEventListener('mousemove', function(e) {
                if (isDragging) {
                    const moveY = e.clientY - startY;
                    ipElement.style.top = `${startTop + moveY}px`;
                }
            });

            // 鼠标松开事件
            document.addEventListener('mouseup', function() {
                if (isDragging) {
                    isDragging = false;
                    ipElement.style.transition = 'right 0.5s'; // 恢复过渡效果
                    GM_setValue('ipInfoTop', ipElement.style.top); // 记录当前位置
                }
            });

            // 绑定复制按钮点击事件
            document.getElementById('copyIp').addEventListener('click', () => copyToClipboard(details.query));
            document.getElementById('copyOrg').addEventListener('click', () => copyToClipboard(details.org));
            document.getElementById('copyCity').addEventListener('click', () => copyToClipboard(details.city));
            document.getElementById('copyRegion').addEventListener('click', () => copyToClipboard(details.regionName));
            document.getElementById('copyCountry').addEventListener('click', () => copyToClipboard(details.country));
            document.getElementById('copyCoords').addEventListener('click', () => copyToClipboard(`${details.lon},${details.lat}`));
            document.getElementById('copyIsp').addEventListener('click', () => copyToClipboard(details.isp));
            document.getElementById('copyAs').addEventListener('click', () => copyToClipboard(details.as));
            document.getElementById('copyRiskScore').addEventListener('click', () => copyToClipboard(riskData ? riskData.score : '查询失败'));
            document.getElementById('copyRiskValue').addEventListener('click', () => copyToClipboard(ping0Data ? ping0Data.riskValue : '查询失败'));
            document.getElementById('copyIpType').addEventListener('click', () => copyToClipboard(ping0Data ? ping0Data.ipType : '查询失败'));
            document.getElementById('copyNativeIp').addEventListener('click', () => copyToClipboard(ping0Data ? ping0Data.nativeIP : '查询失败'));
        } else {
            var ipDetails = document.getElementById('ipDetails');
            ipDetails.innerHTML = `
                    <div>当前公网IP: ${details.query}<button id="copyIp" style="margin-left: 5px;">复制</button></div>
                    <div>组织: ${details.org}<button id="copyOrg" style="margin-left: 5px;">复制</button></div>
                    <div>城市: ${details.city}<button id="copyCity" style="margin-left: 5px;">复制</button></div>
                    <div>地区: ${details.regionName}<button id="copyRegion" style="margin-left: 5px;">复制</button></div>
                    <div>国家: ${details.country}<button id="copyCountry" style="margin-left: 5px;">复制</button></div>
                    <div>坐标: ${details.lon},${details.lat}<button id="copyCoords" style="margin-left: 5px;">复制</button></div>
                    <div>ISP: ${details.isp}<button id="copyIsp" style="margin-left: 5px;">复制</button></div>
                    <div>AS: ${details.as}<button id="copyAs" style="margin-left: 5px;">复制</button></div>
                    <div>风险分数: ${riskData ? riskData.score : '查询失败'}(${riskData ? riskData.risk : ''})<button id="copyRiskScore" style="margin-left: 5px;">复制</button></div>
                    <div>风控值: ${ping0Data ? ping0Data.riskValue : '查询失败'}<button id="copyRiskValue" style="margin-left: 5px;">复制</button></div>
                    <div>IP类型: ${ping0Data ? ping0Data.ipType : '查询失败'}<button id="copyIpType" style="margin-left: 5px;">复制</button></div>
                    <div>原生IP: ${ping0Data ? ping0Data.nativeIP : '查询失败'}<button id="copyNativeIp" style="margin-left: 5px;">复制</button></div>
            `;
            // 绑定复制按钮点击事件
            document.getElementById('copyIp').addEventListener('click', () => copyToClipboard(details.query));
            document.getElementById('copyOrg').addEventListener('click', () => copyToClipboard(details.org));
            document.getElementById('copyCity').addEventListener('click', () => copyToClipboard(details.city));
            document.getElementById('copyRegion').addEventListener('click', () => copyToClipboard(details.regionName));
            document.getElementById('copyCountry').addEventListener('click', () => copyToClipboard(details.country));
            document.getElementById('copyCoords').addEventListener('click', () => copyToClipboard(`${details.lon},${details.lat}`));
            document.getElementById('copyIsp').addEventListener('click', () => copyToClipboard(details.isp));
            document.getElementById('copyAs').addEventListener('click', () => copyToClipboard(details.as));
            document.getElementById('copyRiskScore').addEventListener('click', () => copyToClipboard(riskData ? riskData.score : '查询失败'));
            document.getElementById('copyRiskValue').addEventListener('click', () => copyToClipboard(ping0Data ? ping0Data.riskValue : '查询失败'));
            document.getElementById('copyIpType').addEventListener('click', () => copyToClipboard(ping0Data ? ping0Data.ipType : '查询失败'));
            document.getElementById('copyNativeIp').addEventListener('click', () => copyToClipboard(ping0Data ? ping0Data.nativeIP : '查询失败'));
        }
    }

    function copyToClipboard(text) {
        navigator.clipboard.writeText(text).then(() => {
            alert('复制成功: ' + text);
        }).catch(err => {
            console.error('复制失败: ', err);
        });
    }

    // 添加样式表
    const style = document.createElement('style');
    style.innerHTML = `
        #ipInfo button {
            cursor: pointer;
            background-color: #007bff;
            color: #fff;
            border: none;
            padding: 2px 5px;
            border-radius: 3px;
        }
    `;
    document.head.appendChild(style);

    // 初始创建ipElement,但不触发数据获取
    displayIPDetails({}, null, null);

    // fetchCurrentIP(); // 移除自动触发
})();