ip-checker

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

目前為 2024-06-05 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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(); // 移除自动触发
})();