b站显示评论区IP属地

显示评论区IP属地

// ==UserScript==
// @name         b站显示评论区IP属地
// @version      1.1
// @description  显示评论区IP属地
// @author       Akias
// @license      MIT
// @match        https://*.bilibili.com/*
// @icon         https://www.bilibili.com/favicon.ico
// @grant        unsafeWindow
// @run-at       document-start
// @noframes
// @namespace https://greasyfork.org/users/1094863
// ==/UserScript==

const originalXHROpen = XMLHttpRequest.prototype.open
XMLHttpRequest.prototype.open = function (...args) {
	originalXHROpen.apply(this, args)
	if (args[1] == '//api.bilibili.com/x/web-interface/nav') {
		this.addEventListener('readystatechange', function () {
			if (this.readyState == 4 && this.status == 200) {
				if (JSON.parse(this.response).code == 0) main()
			}
		})
		XMLHttpRequest.prototype.open = originalXHROpen
	}
}
const ipMap = new Map()
function main() {
	const originalFetch = fetch
	unsafeWindow.fetch = async function (...args) {
		let res = await originalFetch(...args)
		let url = args[0].split('?')[0]
		if (url == '//api.bilibili.com/x/v2/reply/wbi/main' || url == '//api.bilibili.com/x/v2/reply/reply') {
			for (let r of (await res.clone().json()).data.replies) {
				ipMap.set(r.member.mid, r.reply_control.location)
				for (let rr of r.replies) ipMap.set(rr.member.mid, rr.reply_control.location)
			}
		}
		return res
	}
	new MutationObserver(mutationsList => {
		for (let mutation of mutationsList) {
			let n = mutation.target
			if (n.nodeType == 1) {
				if (n.className == 'reply-list') {
					addReplyLocation(mutation.addedNodes[0], '')
				} else if (n.className == 'sub-reply-list') {
					addReplyLocation(mutation.addedNodes[0], 'sub-')
				}
			}
		}
	}).observe(document.body, { childList: true, subtree: true })
}
function addReplyLocation(node, s) {
	if (node && node.className == `${s}reply-item`) {
		let location = ipMap.get(node.querySelector(`.${s}user-name`).getAttribute('data-user-id'))
		if (!location) return
		let rt = node.querySelector(`.${s}reply-time`)
		let rl = rt.cloneNode(false)
		rl.className = `${s}reply-location`
		rl.innerHTML = location
		rt.insertAdjacentElement('afterend', rl)
		if (!s) {
			for (let sr of node.getElementsByClassName('sub-reply-item')) {
				addReplyLocation(sr, 'sub-')
			}
		}
	}
}