// ==UserScript== // @name SMTH BBS ip2loc // @namespace http://bbs.byr.cn/ // @description 显示水木论坛用户发贴IP的物理地址 // @match http://*.newsmth.net/* // @match https://*.newsmth.net/* // @version 0.1 // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/503380/SMTH%20BBS%20ip2loc.user.js // @updateURL https://update.greasyfork.icu/scripts/503380/SMTH%20BBS%20ip2loc.meta.js // ==/UserScript== async function addSpan(element) { const span = document.createElement("span") element.appendChild(span) return span } async function updateStatus(elements, message) { elements.forEach((e) => (e.textContent = `[${message}]`)) } function extractIpFromText(text) { const regex = /\[FROM:\D{0,5}([0-9a-fA-F\.:]+.)\]/ const result = text.match(regex) return result ? result[1].replace("*", "0") : null } async function onLoad() { const elements = document.querySelectorAll("font") const ipLocMap = new Map() for (const e of elements) { const ip = extractIpFromText(e.textContent) if (ip && e.lastChild.nodeName.toUpperCase() !== "SPAN") { const span = await addSpan(e) span.textContent = "[ LOADING... ]" if (!ipLocMap.has(ip)) { ipLocMap.set(ip, []) } ipLocMap.get(ip).push(span) } } await sendRequests(ipLocMap) } async function sendRequests(ipLocMap) { const requests = Array.from(ipLocMap.keys()).map(async (ip) => { const url = `https://pytool.sinaapp.com/geo?type=json&encoding=utf-8&ip=${ip}` const spans = ipLocMap.get(ip) try { const response = await fetch(url) const ret = await response.json() const loc = ret.geo.loc await updateStatus(spans, loc) } catch (error) { await updateStatus(spans, error.message) } }) await Promise.all(requests) } function left() { const x = document.querySelector("ol.page-main > li:first-child > a") if (x) { x.click() } } function right() { const x = document.querySelector("ol.page-main > li:last-child > a") if (x) { x.click() } } function keydown(event) { switch (event.key) { case "ArrowLeft": left() break case "ArrowRight": right() break } } window.addEventListener("load", onLoad, false) window.addEventListener("AutoPagerAfterInsert", onLoad, false) document.addEventListener("DOMNodeInserted", onLoad, false) document.addEventListener("keydown", keydown, false)