只要始皇想 那不轻轻松松
3 个赞
始皇实力过硬,随便搞个狠活就会重新回到宝座!
3 个赞
佬,ui好看是好看,但我想改变成常规字体要怎么搞?现有的字体看着别扭,不能一眼辨认信息。。。
1 个赞
搜关键字fontFamily,把Orbitron这个字体相关的注释掉,换成Arial字体,下面这个已经修改好了
// ==UserScript==
// @name ip-checker
// @namespace http://tampermonkey.net/
// @version 2.3
// @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
// ==/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...");
let 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 = "-1000px";
ipElement.style.backgroundColor = "#0a0a0a";
ipElement.style.padding = "15px";
ipElement.style.borderRadius = "0 0 0 10px";
ipElement.style.boxShadow = "0 0 20px rgba(0,255,255,0.3)";
ipElement.style.fontSize = "14px";
ipElement.style.color = "#00ffff";
ipElement.style.zIndex = "9999";
ipElement.style.transition = "right 0.3s ease, box-shadow 0.3s ease";
ipElement.style.fontFamily = "'Orbitron', sans-serif";
ipElement.style.border = "1px solid #00ffff";
const title = document.createElement("div");
title.style.fontWeight = "bold";
title.style.marginBottom = "10px";
title.style.fontSize = "18px";
title.style.textShadow = "0 0 5px #00ffff";
title.innerText = "IP检测信息";
const refreshButton = createButton("刷新IP信息", fetchCurrentIP);
refreshButton.id = "refreshIpInfo";
const toggleButton = createButton("展开信息", toggleIpInfo);
toggleButton.id = "toggleIpInfo";
toggleButton.style.display = "none";
const inputContainer = document.createElement("div");
inputContainer.style.marginTop = "10px";
const ipInput = document.createElement("input");
ipInput.id = "queryIpInput";
ipInput.type = "text";
ipInput.placeholder = "输入IP地址";
ipInput.style.marginRight = "5px";
ipInput.style.backgroundColor = "#1a1a1a";
ipInput.style.color = "#00ffff";
ipInput.style.border = "1px solid #00ffff";
ipInput.style.padding = "5px";
const queryButton = createButton("查询IP", queryIpInfo);
queryButton.id = "queryIpButton";
queryButton.innerHTML = "查询IP";
queryButton.style.width = "auto";
queryButton.style.backgroundColor = "#1a1a1a";
queryButton.style.color = "#00ffff";
queryButton.style.border = "1px solid #00ffff";
queryButton.style.borderRadius = "0";
queryButton.style.padding = "5px 10px";
queryButton.style.cursor = "pointer";
queryButton.style.fontSize = "12px";
queryButton.style.transition = "background-color 0.3s, box-shadow 0.3s";
queryButton.onclick = queryIpInfo;
const dragHandle = document.createElement("div");
dragHandle.style.width = "100%";
dragHandle.style.height = "10px";
dragHandle.style.backgroundColor = "#00ffff";
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 = createButton("展开信息", toggleIpInfo);
expandButton.id = "expandIpInfo";
expandButton.style.position = "fixed";
expandButton.style.top = GM_getValue("ipInfoTop", "10px");
expandButton.style.right = "0";
expandButton.style.display = "block";
document.body.appendChild(expandButton);
expandButton.style.zIndex = "999999999";
}
let contentElement = document.getElementById("ipInfoContent");
if (!contentElement) {
contentElement = document.createElement("div");
contentElement.id = "ipInfoContent";
ipElement.appendChild(contentElement);
}
const content = `
<div>
<strong>IPv4:</strong> ${
details.query
} <span id="copyButtonContainer1"></span>
</div>
<div>
<strong>IPv6:</strong> ${
ipv6 ? ipv6 : "N/A"
} <span id="copyButtonContainer2"></span>
</div>
<div style="word-wrap: break-word; max-width: 300px;">
<strong>城市:</strong> ${details.city}, ${details.regionName}
</div>
<div>
<strong>zip:</strong> ${details.zip ? details.zip : "N/A"}
</div>
<div>
<strong>国家:</strong> ${details.country}
</div>
<div style="word-wrap: break-word; max-width: 300px;">
<strong>ISP:</strong> ${details.isp}
</div>
<div style="word-wrap: break-word; max-width: 300px;">
<strong>AS:</strong> ${details.as}
</div>
<div>
<strong>风险评分:</strong> ${
riskData ? riskData.score : "N/A"
}
</div>
<div>
<strong>风险类型:</strong> ${riskData ? riskData.risk : "N/A"}
</div>
<div>
<strong>Ping0风险值:</strong> ${
ping0Data ? ping0Data.riskValue : "N/A"
}
</div>
<div>
<strong>IP类型:</strong> ${
ping0Data ? ping0Data.ipType : "N/A"
}
</div>
<div>
<strong>原生IP:</strong> ${
ping0Data ? ping0Data.nativeIP : "N/A"
}
</div>
<hr>
`;
contentElement.innerHTML = content; // Use innerHTML instead of insertAdjacentHTML to replace old content
// 添加复制按钮到 copyButtonContainer
const copyButtonContainer1 = document.getElementById(
"copyButtonContainer1"
);
copyButtonContainer1.appendChild(createCopyButton(details.query));
const copyButtonContainer2 = document.getElementById(
"copyButtonContainer2"
);
copyButtonContainer2.appendChild(createCopyButton(ipv6));
}
function isValidIPv4(ip) {
const ipv4Pattern =
/^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}$/;
return ipv4Pattern.test(ip);
}
function queryIpInfo() {
const queryIp = document.getElementById("queryIpInput").value.trim();
const queryButton = document.getElementById("queryIpButton");
if (!queryIp) {
alert("请输入一个有效的IP地址");
return;
}
if (!isValidIPv4(queryIp)) {
alert("请输入一个有效的IPv4地址");
return;
}
console.log("Querying IP info for:", queryIp);
// 禁用查询按钮并显示“正在查询”
queryButton.disabled = true;
queryButton.innerHTML = "正在查询...";
// 调用 fetchIPDetails 并传递回调函数以恢复按钮状态
fetchIPDetails(queryIp, null, function () {
// 查询完成后恢复按钮状态
queryButton.disabled = false;
queryButton.innerHTML = "查询IP";
});
}
function createButton(text, onClick) {
const button = document.createElement("button");
button.innerHTML = text;
button.style.backgroundColor = "#1a1a1a";
button.style.color = "#00ffff";
button.style.border = "1px solid #00ffff";
button.style.borderRadius = "0";
button.style.padding = "5px 10px";
button.style.cursor = "pointer";
button.style.fontSize = "12px";
button.style.marginLeft = "5px";
button.style.transition = "background-color 0.3s, box-shadow 0.3s";
// button.style.fontFamily = "'Orbitron', sans-serif";
button.onclick = onClick;
button.onmouseover = function () {
this.style.backgroundColor = "#00ffff";
this.style.color = "#1a1a1a";
this.style.boxShadow = "0 0 10px rgba(0,255,255,0.5)";
};
button.onmouseout = function () {
this.style.backgroundColor = "#1a1a1a";
this.style.color = "#00ffff";
this.style.boxShadow = "none";
};
return button;
}
function createCopyButton(text) {
const button = document.createElement("button");
button.innerHTML = "复制";
button.style.backgroundColor = "#1a1a1a";
button.style.color = "#00ffff";
button.style.border = "1px solid #00ffff";
button.style.borderRadius = "0";
button.style.padding = "2px 5px";
button.style.cursor = "pointer";
button.style.fontSize = "12px";
button.style.marginLeft = "5px";
button.style.transition = "background-color 0.3s, box-shadow 0.3s";
// button.style.fontFamily = "'Orbitron', sans-serif";
button.onclick = (event) => {
event.stopPropagation();
navigator.clipboard
.writeText(text)
.then(() => {
button.innerHTML = "已复制";
setTimeout(() => {
button.innerHTML = "复制";
}, 500);
})
.catch((err) => {
console.error("复制失败: ", err);
});
};
button.onmouseover = function () {
this.style.backgroundColor = "#00ffff";
this.style.color = "#1a1a1a";
this.style.boxShadow = "0 0 10px rgba(0,255,255,0.5)";
};
button.onmouseout = function () {
this.style.backgroundColor = "#1a1a1a";
this.style.color = "#00ffff";
this.style.boxShadow = "none";
};
return button;
}
function showQueryButton(ip, event) {
let queryButton = document.getElementById("floatingQueryButton");
if (!queryButton) {
queryButton = document.createElement("button");
queryButton.id = "floatingQueryButton";
queryButton.innerHTML = "查询IP";
queryButton.style.position = "fixed";
queryButton.style.zIndex = "10000";
queryButton.style.padding = "5px 10px";
queryButton.style.backgroundColor = "#1a1a1a";
queryButton.style.color = "#00ffff";
queryButton.style.border = "1px solid #00ffff";
queryButton.style.borderRadius = "0";
queryButton.style.cursor = "pointer";
queryButton.style.fontSize = "12px";
// queryButton.style.fontFamily = "'Orbitron', sans-serif";
queryButton.style.transition = "background-color 0.3s, box-shadow 0.3s";
document.body.appendChild(queryButton);
}
queryButton.style.left = `${event.clientX + 10}px`;
queryButton.style.top = `${event.clientY + 10}px`;
queryButton.style.display = "block";
queryButton.onclick = function () {
document.getElementById("queryIpInput").value = ip;
const ipElement = document.getElementById("ipInfo");
if (ipElement.style.right !== "0px") {
toggleIpInfo();
}
queryIpInfo();
this.style.display = "none";
};
queryButton.onmouseover = function () {
this.style.backgroundColor = "#00ffff";
this.style.color = "#1a1a1a";
this.style.boxShadow = "0 0 10px rgba(0,255,255,0.5)";
};
queryButton.onmouseout = function () {
this.style.backgroundColor = "#1a1a1a";
this.style.color = "#00ffff";
this.style.boxShadow = "none";
};
}
// 添加选择文本和显示查询按钮的功能
document.addEventListener("mouseup", handleTextSelection);
function handleTextSelection(event) {
// 检查点击是否发生在 IP 信息面板内
const ipElement = document.getElementById("ipInfo");
const expandIpButton = document.getElementById("expandIpInfo");
if (
(ipElement && ipElement.contains(event.target)) ||
(expandIpButton && expandIpButton.contains(event.target))
) {
return; // 如果点击在 IP 信息面板内,不执行后续操作
}
const selectedText = window.getSelection().toString().trim();
if (isValidIPv4(selectedText)) {
showQueryButton(selectedText, event);
}
}
// 修改 toggleIpInfo 函数
function toggleIpInfo() {
const ipElement = document.getElementById("ipInfo");
const expandButton = document.getElementById("expandIpInfo");
const toggleButton = document.getElementById("toggleIpInfo");
if (ipElement.style.right === "0px") {
ipElement.style.right = "-1000px";
toggleButton.innerHTML = "展开信息";
toggleButton.style.display = "none";
expandButton.style.display = "block";
} else {
ipElement.style.right = "0px";
toggleButton.innerHTML = "隐藏信息";
toggleButton.style.display = "inline-block";
expandButton.style.display = "none";
}
}
let initialTop = 10;
let initialY = 0;
let dragging = false;
function startDragging(e) {
console.log("Start dragging...");
dragging = true;
initialY = e.clientY;
const ipElement = document.getElementById("ipInfo");
const expandButton = document.getElementById("expandIpInfo");
initialTop = parseInt(ipElement.style.top, 10);
expandButton.style.top = ipElement.style.top; // 同步expandButton的位置
document.addEventListener("mousemove", handleDragging);
document.addEventListener("mouseup", stopDragging);
}
function handleDragging(e) {
if (dragging) {
console.log("Dragging...");
const deltaY = e.clientY - initialY;
const newTop = initialTop + deltaY;
const ipElement = document.getElementById("ipInfo");
const expandButton = document.getElementById("expandIpInfo");
ipElement.style.top = newTop + "px";
expandButton.style.top = newTop + "px"; // 同步expandButton的位置
}
}
function stopDragging() {
console.log("Stop dragging...");
dragging = false;
document.removeEventListener("mousemove", handleDragging);
document.removeEventListener("mouseup", stopDragging);
const ipElement = document.getElementById("ipInfo");
GM_setValue("ipInfoTop", ipElement.style.top);
const expandButton = document.getElementById("expandIpInfo");
GM_setValue("expandButtonTop", expandButton.style.top); // 同步保存expandButton的位置
}
// 添加全局样式
const style = document.createElement("style");
style.textContent = `
// @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');
#ipInfo, #expandIpInfo, #floatingQueryButton, #queryIpInput, #queryIpButton {
font-family: 'Arial', sans-serif;
}
#ipInfo:hover {
box-shadow: 0 0 30px rgba(0,255,255,0.5);
}
#queryIpInput {
background-color: #1a1a1a;
color: #00ffff;
border: 1px solid #00ffff;
padding: 5px;
font-size: 12px;
}
#queryIpButton {
background-color: #1a1a1a;
color: #00ffff;
border: 1px solid #00ffff;
border-radius: 0;
padding: 5px 10px;
cursor: pointer;
font-size: 12px;
transition: background-color 0.3s, box-shadow 0.3s;
}
#queryIpButton:hover {
background-color: #00ffff;
color: #1a1a1a;
box-shadow: 0 0 10px rgba(0,255,255,0.5);
}
`;
document.head.appendChild(style);
// 初始创建ipElement,但不触发数据获取
displayIPDetails(null, null, null, null);
})();
3 个赞
cool
2 个赞
感谢,拿gpt简单改了一下,
// @name IP Checker new
// @namespace http://tampermonkey.net/
// @version 1.8
// @description 显示当前使用的公网IP地址,并带有IP风险查询功能,UI设计参考蜜雪冰城脚本
// @author Your Name
// @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
// @run-at document-end
// ==/UserScript==
(function () {
"use strict";
let isDragging = false; // 是否正在拖动
let initialY = 0; // 初始Y坐标
let initialTop = 0; // 初始面板顶部位置
/**
* 创建浮动面板的主要结构和样式
*/
function createFloatingPanel() {
const style = document.createElement('style');
style.textContent = `
#blurContainer {
position: fixed !important;
top: 10px !important;
left: 0 !important;
width: 320px !important;
height: 480px !important;
z-index: 2147483647 !important;
transition: transform 0.3s ease !important;
font-family: Arial, sans-serif !important;
display: flex !important;
align-items: center !important;
transform: translateX(-300px); /* 默认隐藏面板 */
}
#blurContainer.visible {
transform: translateX(0); /* 显示面板 */
}
#panelContent {
width: 300px;
height: 100%;
background-color: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
overflow: hidden;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
border-radius: 0 10px 10px 0;
display: flex;
flex-direction: column;
color: black;
}
#toggleButton {
width: 15px !important; /* 缩小25% */
height: 75px !important; /* 缩小25% */
cursor: pointer !important;
position: relative !important;
overflow: visible !重要;
}
#toggleButton svg {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
filter: blur(10px);
}
#toggleButton::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
mask-image: url("data:image/svg+xml,%3Csvg width='20' height='100' viewBox='0 0 20 100' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0 H1 C10 0 20 10 20 20 V80 C20 90 10 100 1 100 H0 V0 Z' fill='black' /%3E%3C/svg%3E");
-webkit-mask-image: url("data:image/svg+xml,%3Csvg width='20' height='100' viewBox='0 0 20 100' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0 H1 C10 0 20 10 20 20 V80 C20 90 10 100 1 100 H0 V0 Z' fill='black' /%3E%3C/svg%3E");
mask-size: 100% 100%;
-webkit-mask-size: 100% 100%;
}
#toggleButton::after {
content: '';
position: absolute;
width: 6px; /* 缩小25% */
height: 30px; /* 缩小25% */
background-color: #888;
border-radius: 4px;
top: 50%;
left: 4.5px; /* 缩小25% */
transform: translateY(-50%);
transition: transform 0.3s ease;
z-index: 1;
}
#tabContainer {
display: flex;
border-bottom: 1px solid #ccc;
background-color: rgba(240, 240, 240, 0.3);
}
.tab {
padding: 10px;
cursor: pointer;
flex: 1;
text-align: center;
border-bottom: 2px solid transparent;
transition: border-bottom-color 0.3s;
}
.tab.active {
border-bottom-color: #4CAF50;
}
#contentArea {
flex-grow: 1;
overflow: hidden;
padding: 5px;
display: flex;
flex-direction: column;
}
.panel-title {
font-weight: bold !important;
font-size: 16px !important;
}
.section-title {
font-weight: bold !important;
font-size: 18px !important;
margin-bottom: 5px !重要;
}
#statusPage {
display: none;
height: 100%;
overflow-y: auto;
scrollbar-width: none;
-ms-overflow-style: none;
flex-direction: column;
}
#statusPage.active {
display: flex;
}
#scriptStatusDisplay {
background-color: rgba(0, 0, 0, 0.1);
color: black;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
flex-shrink: 0;
}
#responseLogContainer {
flex-grow: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
#responseLogHeader {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
}
#responseLogDisplay {
background-color: rgba(0, 0, 0, 0.1);
color: black;
padding: 13px;
border-radius: 5px;
overflow-y: auto;
font-size: 16px;
flex-grow: 1;
scrollbar-width: none;
-ms-overflow-style: none;
text-align: left;
}
#responseLogDisplay::-webkit-scrollbar {
display: none;
}
.input-group {
display: flex;
margin: 10px 0;
}
.input-group input {
flex: 1;
padding: 5px;
font-size: 16px;
border: 1px solid #000;
background-color: #fff;
border-radius: 5px 0 0 5px;
outline: none;
}
.input-group button {
padding: 5px 10px;
font-size: 16px;
border: none;
background-color: #4CAF50;
color: white;
cursor: pointer;
border-radius: 0 5px 5px 0;
outline: none;
}
.input-group button:hover {
background-color: #45a049;
}
`;
document.head.appendChild(style);
const blurContainer = document.createElement('div');
blurContainer.id = 'blurContainer';
const panelContent = document.createElement('div');
panelContent.id = 'panelContent';
// 创建收纳按钮并设置点击和拖动事件
const toggleButton = document.createElement('div');
toggleButton.id = 'toggleButton';
toggleButton.innerHTML = `
<svg width="15" height="75" viewBox="0 0 20 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0 H1 C10 0 20 10 20 20 V80 C20 90 10 100 1 100 H0 V0 Z" fill="rgba(255, 255, 255, 0.7)" />
</svg>
`;
toggleButton.addEventListener('click', togglePanel);
// 添加拖动功能
toggleButton.addEventListener('mousedown', startDrag);
document.addEventListener('mouseup', stopDrag);
document.addEventListener('mousemove', drag);
const tabContainer = createTabContainer();
const contentArea = document.createElement('div');
contentArea.id = 'contentArea';
const statusPage = createStatusPage();
contentArea.appendChild(statusPage);
panelContent.appendChild(tabContainer);
panelContent.appendChild(contentArea);
blurContainer.appendChild(panelContent);
blurContainer.appendChild(toggleButton);
document.body.appendChild(blurContainer);
switchTab('状态');
return blurContainer;
}
/**
* 切换面板显示/隐藏
*/
function togglePanel() {
const blurContainer = document.getElementById('blurContainer');
blurContainer.classList.toggle('visible');
}
/**
* 创建标签容器和默认标签
*/
function createTabContainer() {
const tabContainer = document.createElement('div');
tabContainer.id = 'tabContainer';
const statusTab = createTab('状态', true);
tabContainer.appendChild(statusTab);
return tabContainer;
}
/**
* 创建单个标签元素
*/
function createTab(text, isActive) {
const tab = document.createElement('div');
tab.textContent = text;
tab.className = `tab ${isActive ? 'active' : ''}`;
tab.addEventListener('click', () => switchTab(text));
return tab;
}
/**
* 切换标签页
*/
function switchTab(tabName) {
const tabs = document.querySelectorAll('.tab');
const statusPage = document.getElementById('statusPage');
tabs.forEach(tab => tab.classList.remove('active'));
statusPage.classList.remove('active');
if (tabName === '状态') {
tabs[0].classList.add('active');
statusPage.classList.add('active');
}
}
/**
* 创建状态页面
*/
function createStatusPage() {
const statusPage = document.createElement('div');
statusPage.id = 'statusPage';
const headerContainer = document.createElement('div');
headerContainer.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 5px;
margin-bottom: 8px;
padding: 0 5px;
`;
const versionInfo = document.createElement('span');
versionInfo.textContent = `IP Checker v1.8`;
versionInfo.className = 'panel-title';
versionInfo.style.marginLeft = '5px';
headerContainer.appendChild(versionInfo);
const refreshButton = createButton('刷新IP信息', fetchCurrentIP);
refreshButton.style.marginLeft = 'auto';
headerContainer.appendChild(refreshButton);
const statusDisplay = createStatusDisplay();
const responseLogContainer = document.createElement('div');
responseLogContainer.id = 'responseLogContainer';
const responseLogHeader = document.createElement('div');
responseLogHeader.id = 'responseLogHeader';
responseLogHeader.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
padding: 0 5px;
`;
const responseLogTitle = document.createElement('div');
responseLogTitle.textContent = 'IP检测信息';
responseLogTitle.className = 'section-title';
responseLogTitle.style.cssText = `
display: flex;
align-items: center;
margin: 0;
padding: 0;
margin-left: 5px;
`;
responseLogHeader.appendChild(responseLogTitle);
const inputGroup = createInputGroup();
const responseLog = createResponseLog();
responseLogContainer.appendChild(responseLogHeader);
responseLogContainer.appendChild(inputGroup);
responseLogContainer.appendChild(responseLog);
statusPage.appendChild(headerContainer);
statusPage.appendChild(statusDisplay);
statusPage.appendChild(responseLogContainer);
return statusPage;
}
/**
* 创建显示状态信息的容器
*/
function createStatusDisplay() {
const statusDiv = document.createElement('div');
statusDiv.id = 'scriptStatusDisplay';
return statusDiv;
}
/**
* 创建输入框和查询按钮
*/
function createInputGroup() {
const inputGroup = document.createElement('div');
inputGroup.className = 'input-group';
const input = document.createElement('input');
input.id = 'queryIpInput';
input.type = 'text';
input.placeholder = '输入IP地址';
const queryButton = document.createElement('button');
queryButton.textContent = '查询IP';
queryButton.onclick = queryIpInfo;
inputGroup.appendChild(input);
inputGroup.appendChild(queryButton);
return inputGroup;
}
/**
* 创建用于显示响应日志的容器
*/
function createResponseLog() {
const logDiv = document.createElement('div');
logDiv.id = 'responseLogDisplay';
return logDiv;
}
/**
* 创建通用按钮
*/
function createButton(text, onClick) {
const button = document.createElement('button');
button.textContent = text;
button.style.cssText = `
padding: 5px 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
`;
button.addEventListener('click', onClick);
return button;
}
/**
* 获取当前IP信息
*/
function fetchCurrentIP() {
let ipv6 = null;
// 获取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);
},
});
// 获取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);
},
});
}
/**
* 检查IP是否为IPv6格式
*/
function isIPv6(ip) {
const ipv6Pattern = new RegExp(
"^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$|^([0-9a-fA-F]{1,7}:)$|^([0-9a-fA-F]{1,6}:[0-9a-fA-F]{1,4})$|^([0-9a-fA-F]{1,5}(:[0-9a-fA-F]{1,4}){1,2})$|^([0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){1,3})$|^([0-9a-fA-F]{1,3}(:[0-9a-fA-F]{1,4}){1,4})$|^([0-9a-fA-F]{1,2}(:[0-9a-fA-F]{1,4}){1,5})$|^([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}:)((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3,3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$|^([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3,3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$"
);
return ipv6Pattern.test(ip);
}
/**
* 获取指定IP的详细信息
*/
function fetchIPDetails(ip, ipv6) {
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);
},
onerror: function (error) {
console.log("Error fetching IP details:", error);
},
});
}
/**
* 获取指定IP的风险信息
*/
function fetchIPRisk(ip, ipv6, details) {
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);
},
onerror: function (error) {
console.log("Error fetching IP risk:", error);
},
});
}
/**
* 获取Ping0网站的风险信息
*/
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);
},
onerror: function (error) {
console.log("Error fetching final Ping0 risk:", error);
},
});
} else {
console.log("Failed to retrieve window.x value.");
}
},
onerror: function (error) {
console.log("Error fetching initial Ping0 page:", error);
},
});
}
/**
* 解析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;
}
/**
* 解析Ping0风险数据中的window.x值
*/
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;
}
/**
* 解析Ping0风险数据
*/
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;
}
/**
* 根据Ping0风险值获取相应的颜色
*/
function getPing0RiskColor(riskValue) {
const risk = parseInt(riskValue.replace('%', ''));
if (risk <= 30) {
return 'green';
} else if (risk <= 50) {
return 'yellow';
} else {
return 'red';
}
}
/**
* 显示IP的详细信息
*/
function displayIPDetails(ipv6, details, riskData, ping0Data) {
const logDiv = document.getElementById('responseLogDisplay');
if (logDiv) {
logDiv.innerHTML = `
<div><strong>IPv4:</strong> ${details.query}</div>
<div><strong>IPv6:</strong> ${ipv6 ? ipv6 : "N/A"}</div>
<div><strong>城市:</strong> ${details.city}, ${details.regionName}</div>
<div><strong>zip:</strong> ${details.zip ? details.zip : "N/A"}</div>
<div><strong>国家:</strong> ${details.country}</div>
<div><strong>ISP:</strong> ${details.isp}</div>
<div><strong>AS:</strong> ${details.as}</div>
<div><strong>风险评分:</strong> ${riskData ? riskData.score : "N/A"}</div>
<div><strong>风险类型:</strong> ${riskData ? riskData.risk : "N/A"}</div>
<div><strong>Ping0风险值:</strong> <span style="color: ${getPing0RiskColor(ping0Data ? ping0Data.riskValue : "N/A")};">${ping0Data ? ping0Data.riskValue : "N/A"}</span></div>
<div><strong>IP类型:</strong> ${ping0Data ? ping0Data.ipType : "N/A"}</div>
<div><strong>原生IP:</strong> ${ping0Data ? ping0Data.nativeIP : "N/A"}</div>
`;
}
}
/**
* 查询指定IP的信息
*/
function queryIpInfo() {
const queryIp = document.getElementById("queryIpInput").value.trim();
if (!queryIp) {
alert("请输入一个有效的IP地址");
return;
}
if (!isValidIPv4(queryIp) && !isIPv6(queryIp)) {
alert("请输入一个有效的IP地址");
return;
}
console.log("Querying IP info for:", queryIp);
fetchIPDetails(queryIp, null);
}
/**
* 检查IP是否为有效的IPv4格式
*/
function isValidIPv4(ip) {
const ipv4Pattern = /^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}$/;
return ipv4Pattern.test(ip);
}
/**
* 开始拖动面板
*/
function startDrag(e) {
isDragging = true;
initialY = e.clientY;
initialTop = parseInt(window.getComputedStyle(document.getElementById('blurContainer')).top);
}
/**
* 停止拖动面板
*/
function stopDrag() {
isDragging = false;
}
/**
* 拖动过程中调整面板位置
*/
function drag(e) {
if (isDragging) {
const currentY = e.clientY;
const newTop = initialTop + (currentY - initialY);
document.getElementById('blurContainer').style.top = `${newTop}px`;
}
}
// 初始化UI和数据获取
function initScript() {
createFloatingPanel();
fetchCurrentIP();
}
initScript();
})();
2 个赞
欢迎在已有功能上进行优化或增加功能
2 个赞
常规字体舒服多了,一眼就能看辨认信息,更实用!
1 个赞
确实清晰多了,我也换成常规字体了 ,后面有空加一个切换字体的功能~
2 个赞