// ==UserScript== // @name V2rayA - Add country flag to Ip or domain // @namespace Violentmonkey Scripts // @description This script will convert ip or domain of "Server Address" column on V2rayA's web interface // @version 0.1 // @author thelostthing // @license MIT // // @match http://localhost:2017/ // @match http://127.0.0.1:2017/ // // @grant GM_xmlhttpRequest // @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js // // @downloadURL none // ==/UserScript== const ipFlag = () => { $('section.tab-content > .tab-item:not([style*="display: none"]) td[data-label="Server Address"]:not(.flagged)').each(function(index, element) { const domain_ip = $(element).html().split(':')[0].trim(); GM_xmlhttpRequest({ method: "GET", url: 'https://json.geoiplookup.io/'+domain_ip, onload: function(response) { if(response.status == 200 && !$(element).hasClass('flagged')) { const country_code = JSON.parse(response.responseText).country_code.toLowerCase(); $(element).prepend(''); $(element).addClass('flagged'); } } }); }) } const checkContent = (target) => new Promise((resolve, reject) => { new MutationObserver((mutations, self) => { for( let mutation of mutations) { if( !mutation.target.hidden && mutation.target.classList.contains('tab-item')) { self.disconnect(); resolve(); } } }).observe(target, { subtree: true, attributes: true, attributeOldValue : true, attributeFilter: ['style'] }); }); document.onreadystatechange = function () { if (document.readyState === 'complete') { ipFlag(); // for default server page $('.main-tabs > nav.tabs > ul > li').click(async () => { await checkContent(document.querySelector('.tab-content')); ipFlag(); }); } }