// ==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(); // 移除自动触发
})();