// ==UserScript== // @name WoTStatScript - Clanpage // @version 0.9.14.0.7 // @description More info for World of Tanks clan page. // @author Orrie // @namespace http://forum.worldoftanks.eu/index.php?/topic/263423- // @icon http://dl.dropboxusercontent.com/u/12497046/wot/projects/statscript/img/icon.png // @include http://*.wargaming.net/clans/*/* // @grant GM_xmlhttpRequest // @connect www.wnefficiency.net // @connect api.worldoftanks.eu // @connect api.worldoftanks.ru // @connect api.worldoftanks.com // @connect api.worldoftanks.asia // @connect api.worldoftanks.kr // @license MIT License // @downloadURL none // ==/UserScript== (function() { // global vars var d = document, c = d.cookie; // get server info and webpage var wg = {host:d.location.host, href:d.location.href, clan:{}}; wg.srv = wg.host.match(/(eu|ru|na|asia|kr)/)[0]; wg.m = (/players/i.test(wg.href) || /players\/wot/i.test(wg.href)) && !/wowp/i.test(wg.href); // getting claninfo var emblemName = d.getElementsByClassName('page-header_emblem')[0], clanName = d.getElementsByClassName('clan_name')[0], sidebarName = d.getElementsByClassName('sidebar-clan_emblem')[0]; wg.clan.id = wg.href.match(/\/(\d+)/)[1]; wg.clan.name = (emblemName || clanName) ? ((clanName) ? clanName.firstElementChild.innerHTML.replace(/[\[\]]/g,"") : emblemName.alt) : sidebarName.alt; wg.p = new RegExp("\\["+wg.clan.name+"\\] \\|").test(d.title) && !/wowp/i.test(wg.href); // script variables var sc = { vers: "0.9.14.0.7", host: "http://greasyfork.org/en/scripts/12137-wotstatscript-clans", user: { wl: "http://forum.wotlabs.net/index.php?/user/1618-orrie/", wot: "http://worldoftanks.eu/community/accounts/505838943-Orrie/" }, top: { eu: "http://forum.worldoftanks.eu/index.php?showtopic=263423", na: "http://forum.worldoftanks.com/index.php?showtopic=404652" }, cred: { // translators cs: "Crabtr33 , Ragnarocek , jViks" , de: "ArtiOpa , Crakker , multimill", fr: "SuperPommeDeTerre", pl: "KeluMocy , pokapokami", es: "Frodo45127", tr: "Ufuko", ru: "dimon222" }, api: { ru: "98ca7c4fb108175b67d6505b9c3f3ebd", eu: "a7595640a90bf2d19065f3f2683b171c", na: "bf5dba0efd444d75147b6222dd903fd2", asia: "95f8713eccd322e52dbf521dbd28b19c", kr: "ffea0f1c3c5f770db09357d94fe6abfb" }, srv: { wl: false, // wotlabs nm: false, // noobmeter vb: false, // vbaddict ws: false, // wotstats cs: false, // wotcs wlf: false, // wot-life as: false, // away stats ct: false, // clan tools aos: false, // age of strife kttc: false, // kttc wots: false, // wots ch: false, // clan history wr: false // wotreplays }, wn: "http://www.wnefficiency.net/exp/expected_tank_values_latest.json", loc: c.match(/wgccfe_language=(\w+)/)[1], locSup: ["en", "ru", "cs", "de", "fr", "pl", "es", "tr"], date: Date.now(), dateFormat: {ru: "ru-RU", eu: "en-GB", na: "en-US", asia: "en-AU", kr: "ko-KR"}, web: { gecko: typeof InstallTrigger !== 'undefined', opera: !!window.opera || /opera|opr/i.test(navigator.userAgent), chrome: !!window.chrome && !!window.chrome.webstore, safari: /constructor/i.test(window.HTMLElement) } }; // script functions var sf = { tableFetch: function () { // show animated loading gear loadGif.classList.remove("js-hidden"); // find required info from table player rows for (var _rt=0, _rt_len = memObj.cls.rows.length; _rt<_rt_len; _rt++) { var row = memObj.cls.rows[_rt]; if (!row.classList.contains("tbl-rating_tr__card")) { var id = row.getAttribute('data-account_id'), name = row.getElementsByClassName('player_name')[0].innerHTML.match(/[\w\_]+/)[0], role = row.getElementsByClassName('tbl-rating_td__rank')[0].firstElementChild.classList.item(4).match(/i__(\w+)/)[1]; if (!isNaN(id)) { memObj.ids.push(id); s.user[id] = {u:{name:name,id:id,role:role}, v:{frag:0,dmg:0,spot:0,def:0,win:0}, wn8:""}; } } } s.clan = {name:wg.clan.name, wn8:0, win:0, mem: _rt_len}; // request and retrieve statistics from API if (s.clan.mem > 0) { sf.request(sc.api.i+memObj.ids.join(','), sf.apiInfoHnd); } }, apiInfoHnd: function (resp) { // processing information from player API var data = JSON.parse(resp).data; for (var a in data) { if (data.hasOwnProperty(a)) { var pData = data[a]; if (pData !== null) { // store stats var pDataStats = pData.statistics.all; s.user[pData.account_id].u = { name: pData.nickname, id: pData.account_id, role: s.user[pData.account_id].u.role, cid: pData.clan_id, bat: pDataStats.battles, win: (pDataStats.wins/pDataStats.battles)*100, dmg: pDataStats.damage_dealt/pDataStats.battles, frag: pDataStats.frags/pDataStats.battles, spot: pDataStats.spotted/pDataStats.battles, def: pDataStats.dropped_capture_points/pDataStats.battles, wgr: pData.global_rating, lng: pData.client_language }; s.clan.win += (!isNaN(s.user[pData.account_id].u.win)) ? s.user[pData.account_id].u.win : 0; } } } d.getElementById('js-wn8-status').textContent = "50%"; sf.request(sc.api.v+memObj.ids.join(','), sf.apiVehHnd); }, apiVehHnd: function (resp) { // processing information from vehicle API and calculate WN8 var data = JSON.parse(resp).data; for (var p in data) { if (data.hasOwnProperty(p)) { var vData = data[p]; if (vData !== null) { var rWin, rDmg, rFrag, rSpot, rDef, wn8 = 0; if (s.user[p].u.bat > 0) { for (var v in vData) { if (vData.hasOwnProperty(v)) { // go through each vehicle to get expected stats for (var _so=0, _so_len = statArr.length; _so<_so_len; _so++) { if (statArr[_so].IDNum == vData[v].tank_id) { var vehStat = statArr[_so], dataBattles = vData[v].statistics.battles; s.user[p].v.frag += vehStat.expFrag * dataBattles; s.user[p].v.dmg += vehStat.expDamage * dataBattles; s.user[p].v.spot += vehStat.expSpot * dataBattles; s.user[p].v.def += vehStat.expDef * dataBattles; s.user[p].v.win += vehStat.expWinRate * dataBattles; break; } } } } // start calculating wn8 rWin = Math.max(((s.user[p].u.win /(s.user[p].v.win /s.user[p].u.bat)-0.71)/(1-0.71)),0); rDmg = Math.max(((s.user[p].u.dmg /(s.user[p].v.dmg /s.user[p].u.bat)-0.22)/(1-0.22)),0); rFrag = Math.max(Math.min(rDmg+0.2,((s.user[p].u.frag/(s.user[p].v.frag/s.user[p].u.bat)-0.12)/(1-0.12))),0); rSpot = Math.max(Math.min(rDmg+0.1,((s.user[p].u.spot/(s.user[p].v.spot/s.user[p].u.bat)-0.38)/(1-0.38))),0); rDef = Math.max(Math.min(rDmg+0.1,((s.user[p].u.def /(s.user[p].v.def /s.user[p].u.bat)-0.10)/(1-0.10))),0); wn8 = 980*rDmg + 210*rDmg*rFrag + 155*rFrag*rSpot + 75*rDef*rFrag + 145*Math.min(1.8,rWin); } // store wn8 and add to clan total s.user[p].wn8 = wn8; s.clan.wn8 += wn8; } } } // calculate average wn8 / winrate and store everything in localStorage, then reload page s.clan.wn8 = s.clan.wn8/s.clan.mem; s.clan.win = s.clan.win/s.clan.mem; sf.storage("statScriptValues_"+wg.clan.id, s, "set", "string"); sf.storage("statScriptDate_"+wg.clan.id, sc.date, "set"); d.getElementById('js-wn8-status').textContent = "100%"; location.reload(); }, apiBanHnd: function (resp) { // processing information from banned API var data; if (!memObj.bans.api) { data = JSON.parse(resp).data; memObj.bans.api = data; memObj.bans.f = true; } else { data = memObj.bans.api; } for (var a in data) { if (data.hasOwnProperty(a)) { var bData = data[a]; var memClass = "js-tooltip-id_js-playerslist-account-name-tooltip-"+a, memCell = d.getElementsByClassName(memClass)[0].parentNode; if (bData.ban_time !== null) { var banTime = (bData.ban_time > 0) ? new Date(bData.ban_time*1000).toLocaleString(sc.dateFormat[wg.srv]) : loc[18]; memCell.appendChild(sf.elem("p", "player_time", banTime)); } else { memCell.appendChild(sf.elem("p", "player_time", loc[19])); } } } }, format: function (input, type) { // input and output formatting var inputStr = input.toString(); switch(type) { case (1): // input string into number return parseFloat(inputStr.replace(/[^\d]/g,"")); case (2): // output number with locale symbol return inputStr.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1"+loc[0]); case (3): // input string into number - exclude dots return parseFloat(inputStr.replace(/[^\d\.]/g,"")); default: console.error("Error filtering: ", input); return input; } }, color: function (input, type, dec, sym) { // color formatting var color = colArr.dft[0], output = input.toFixed(dec); if (input >= 1000) { output = sf.format(input.toFixed(dec),2); } for (var c in colArr) { if (colArr.hasOwnProperty(c)) { if (input >= colArr[c][colArr.id[type]]) { color = colArr[c][0]; break; } } } if (loc[0] !== "," && dec !== 0) { output = output.replace(/\.(\d+)*$/g,",$1"); } if (sym) { output += sym; } return ""+output+""; }, elem: function (tag, name, html, type) { // element creation var element = d.createElement(tag); if (name) { element.className = name; } if (html) { if (/"+text+""); refreshBtn.addEventListener('click', function() {localStorage.removeItem("wnExpValues"); location.reload();}, false); listItems.appendChild(refreshBtn); } else if (name == "cleanStorage") { var cleanBtn = sf.elem("div", "b-settingParent b-"+name, ""+text+""); cleanBtn.addEventListener('click', function() {localStorage.clear(); location.reload();}, false); listItems.appendChild(cleanBtn); } else { var optCheckDiv = sf.elem("div", "b-checkbox", ""), optLabel = sf.elem("label", "b-combobox-label", text), optCheck = sf.elem("input", "l-box", "", "checkbox"); optLabel.htmlFor = name; optCheck.name = name; optCheck.id = name; if (state) { optCheckDiv.classList.add("b-checkbox__checked"); optLabel.classList.add("b-combobox-label__checked"); } optCheck.checked = (state !== undefined) ? state : dftState; optCheck.addEventListener('click', function() { sf.storage('statScript_' + this.name, this.checked, "set"); d[this.name] = this.checked; this.parentNode.classList.toggle('b-checkbox__checked'); this.parentNode.parentNode.classList.toggle('b-combobox-label__checked'); return this.checked; }, false); d[optCheck.name] = optCheck.checked; optCheckDiv.insertBefore(optCheck, optCheckDiv.firstChild); optLabel.appendChild(optCheckDiv); listItems.appendChild(optLabel); if (name == "whitelist") { var optText = sf.elem("textarea", "l-textarea", ""); optText.placeholder = "Add clanID seperated by comma without spaces: 500004502,500010805"; if (wlist) { optText.value = wlist; } optText.addEventListener('input', function() { sf.storage('statScript_whitelist_list', optText.value.split(","), "set"); }, false); listItems.appendChild(optText); } } listItem.appendChild(listItems); return listItem; }, links: function (parent, links) { // links handler var uRows = d.createDocumentFragment(); for (var _l=0, _l_len = links.length; _l<_l_len; ++_l) { if (links[_l] instanceof HTMLElement) { uRows.appendChild(links[_l]); } else { uRows.appendChild((links[_l][0] && links[_l][1]) ? sf.elem("li", "", links[_l][1]) : sf.elem("li", "statname", links[_l][0])); } } parent.appendChild(uRows); }, storage: function (name, data, type, mode) { // localStorage handler var storage; switch(type) { case ("set"): if (mode == "string") { data = JSON.stringify(data); } storage = localStorage.setItem(name, data); break; case ("get"): storage = localStorage.getItem(name); if (mode == "parse") { storage = JSON.parse(storage); } break; default: break; } return storage; }, wn: function (resp) { // wnefficiency handler sf.storage("wnExpValues", resp, "set"); sf.storage("wnExpDate", sc.date, "set"); sf.storage("wnExpVers", [sc.vers, JSON.parse(resp).header.version], "set", "string"); location.reload(); }, request: function (url, handler) { // request handler GM_xmlhttpRequest({ method: "GET", url: url, headers: { "Accept": "application/json" }, onload: function(resp) { if (resp.status == 200) { handler(resp.responseText); } else { console.error("Error accessing", url, resp.readyState, resp.status, resp.statusText); } }, onerror: function(resp) { console.error("Error accessing", url, resp.readyState, resp.status, resp.statusText); } }); } }; // api links without account id sc.api.i = "http://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/account/info/?application_id="+sc.api[wg.srv]+"&account_id="; sc.api.v = "http://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/account/tanks/?application_id="+sc.api[wg.srv]+"&account_id="; // fetch wnefficiency values - check if array exists in localStorage, otherwise fetch and reload page var wn = { values: sf.storage("wnExpValues", "", "get", "parse"), date: sf.storage("wnExpDate", "", "get", "parse")+12096e5 >= sc.date, // true if timestamp is less than 2 weeks old, refresh list if false. vers: sf.storage("wnExpVers", "", "get", "parse") || "" }, statArr = []; if (wn.vers[0]==sc.vers && wn.values && wn.date) { statArr = wn.values.data; } else { sf.request(sc.wn, sf.wn); } // fetch stored clanlist stats - check if array exists in localStorage, otherwise tag fetching to true var ss = { val: sf.storage("statScriptValues_"+wg.clan.id, "", "get", "parse"), date: sf.storage("statScriptDate_"+wg.clan.id, "", "get", "parse")+6048e5 >= sc.date // true if timestamp is less than 1 weeks old, refresh list if false. }, s = {clan:{},user:{}}, statFetch = false; if (ss.val && ss.date) { s = ss.val; } else { statFetch = true; } // inserting style into head var style = sf.elem("style", "wotstatscript", "", "text/css"); d.head.appendChild(style); // colour scale array var colArr = { // col wr bat sr hr dmg wgr wn8 wn7 eff nm sUni: [ "#5A3175", 65, 30000, 50, 80, 300, 9900, 2900, 2050, 2050, 2000 ], // 99.99% super unicum uni: [ "#83579D", 60, 25000, 46, 75, 270, 9000, 2450, 1850, 1800, 1950 ], // 99.90% unicum gr8: [ "#3972C6", 56, 21000, 42, 70, 240, 8500, 2000, 1550, 1500, 1750 ], // 99.00% great vGud: [ "#4099BF", 54, 17000, 38, 65, 210, 6500, 1600, 1350 ], // 95.00% very good good: [ "#4D7326", 52, 13000, 34, 60, 180, 5000, 1200, 1100, 1200, 1450 ], // 82.00% good aAvg: [ "#849B24", 50, 10000, 30, 55, 150, 4000, 900 ], // 63.00% above average avg: [ "#CCB800", 48, 7000, 25, 50, 120, 3000, 650, 900, 900, 1250 ], // 40.00% average bAvg: [ "#CC7A00", 47, 3000, 20, 45, 90, 2000, 450, 700, 600, 1150 ], // 20.00% below average bas: [ "#CD3333", 46, 1000, 15, 40, 60, 1500, 300, 500 ], // 6.00% basic beg: [ "#930D0D", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], // 0.00% beginner dft: [ "#6B6B6B" ], // default id: { "col": 0, "wr": 1, "bat": 2, "sr": 3, "hr": 4, "dmg": 5, "wgr": 6, "wn8": 7, "wn7": 8, "eff": 9, "nm": 10 } // type identifier }; // localization // cz-czech - Crabtr33 and Ragnarocek // de-german - ArtiOpa, Crakker and multimill // fr-french - SuperPommeDeTerre // pl-polish - KeluMocy and pokapokami // es-spanish - Frodo45127 // tr-turkish - Ufuko // ru-russian - dimon222 var loc = [ // thousands separator { en: ",", ru: " ", cs: " ", de: ".", fr: " ", pl: " ", es:" ", tr: "."}, // clan page { en: "Clan Stats", ru: "Статистика клана", cs: "Stat. klanu", de: "Clanstatistiken", fr: "Statistiques du clan", pl: "Statystyki klanu", es: "Estadísticas del clan", tr: "Klan İstatistikleri"}, { en: "Replays:", ru: "Реплеи:", cs: "Záznamy:", de: "Replays", fr: "Replays:", pl: "Powtórki:", es: "Repeticiones:", tr: "Replayler"}, // memberlist { en: "Script Menu", ru: "Script Menu", cs: "Nastavení scriptu", de: "Script Menu", fr: "Menu du script", pl: "Script Menu", es:"Script Menu", tr: "Script Menu"}, { en: "Load Stats Automatically", ru: "Load Stats Automatically", cs: "Nahrát stat. automaticky", de: "Charger les statistiques automatiquement", fr: "Load Stats Automatically", pl: "Load Stats Automatically", es:"Load Stats Automatically", tr: "Load Stats Automatically"}, { en: "Use Whitelist", ru: "Use Whitelist", cs: "Použi whitelist", de: "Use Whitelist", fr: "Utiliser la liste blanche", pl: "Use Whitelist", es:"Use Whitelist", tr: "Use Whitelist"}, { en: "Refresh WN8 Table", ru: "Refresh WN8 Table", cs: "Obnov WN8 Tabulku", de: "Refresh WN8 Table", fr: "Rafraîchir la table WN8", pl: "Refresh WN8 Table", es: "Refresh WN8 Table", tr: "Refresh WN8 Table"}, { en: "Clean Script Database", ru: "Clean Script Database", cs: "Vyčisti db scriptu", de: "Clean Script Database", fr: "Nettoyer la base de données du script", pl: "Clean Script Database", es: "Clean Script Database", tr: "Clean Script Database"}, { en: "Average Winrate", ru: "Average Winrate", cs: "Průměrný winrate", de: "Average Winrate", fr: "Ratio de victoire moyen", pl: "Average Winrate", es:"Average Winrate", tr: "Average Winrate"}, { en: "Average WN8", ru: "Average WN8", cs: "Průměrné WN8", de: "Average WN8", fr: "Average WN8", pl: "WN8 moyen", es:"Average WN8", tr: "Average WN8"}, { en: "Overall Average Winrate", ru: "Overall Average Winrate", cs: "Průměrný winrate", de: "Overall Average Winrate", fr: "Overall Average Winrate", pl: "Overall Average Winrate", es:"Overall Average Winrate", tr: "Overall Average Winrate"}, { en: "Overall Average WN8", ru: "Overall Average WN8", cs: "Overall Average WN8", de: "Overall Average WN8", fr: "Overall Average WN8", pl: "Overall Average WN8", es:"Overall Average WN8", tr: "Overall Average WN8"}, { en: "Fetch WN8 for Clan", ru: "Fetch WN8 for Clan", cs: "Obnov WN8 pre klan", de: "Fetch WN8 for Clan", fr: "Calculer le WN8 pour le clan", pl: "Fetch WN8 for Clan", es:"Fetch WN8 for Clan", tr: "Fetch WN8 for Clan"}, { en: "Fetching WN8 for Clan!", ru: "Fetching WN8 for Clan!", cs: "Obnovuju WN8 pro klan!", de: "Fetching WN8 for Clan!", fr: "Walcul du WN8 pour le clan !", pl: "Fetching WN8 for Clan!", es:"Fetching WN8 for Clan!", tr: "Fetching WN8 for Clan!"}, { en: "WN8 Fetched for Clan!", ru: "WN8 Fetched for Clan!", cs: "WN8 obnoveno pro klan!", de: "WN8 Fetched for Clan!", fr: "WN8 calculé pour le clan !", pl: "WN8 Fetched for Clan!", es:"WN8 Fetched for Clan!", tr: "WN8 Fetched for Clan!"}, { en: "Not Found", ru: "Not Found", cs: "Nenalezeno", de: "Not Found", fr: "Non trouvé", pl: "Not Found", es:"Not Found", tr: "Not Found"}, { en: "New Members:", ru: "New Members:", cs: "Noví členové:", de: "New Members:", fr: "Nouveaux membres :", pl: "New Members:", es:"New Members:", tr: "New Members:"}, { en: "Banned Members:", ru: "Banned Members:", cs: "Noví členové:", de: "Banned Members:", fr: "Membres bannis:", pl: "Banned Members:", es:"Banned Members:", tr: "Banned Members:"}, { en: "Currently Unavailable", ru: "Currently Unavailable", cs: "Currently Unavailable", de: "Currently Unavailable", fr: "Indisponible actuellement", pl: "Currently Unavailable", es:"Currently Unavailable", tr: "Currently Unavailable"}, { en: "Ban ended, but no login", ru: "Ban ended, but no login", cs: "Ban ended, but no login", de: "Ban ended, but no login", fr: "Ban terminé, mais aucune connexion", pl: "Ban ended, but no login", es:"Ban ended, but no login", tr: "Ban ended, but no login"}, { en: "Script Author:", ru: "Script Author:", cs: "Script Author:", de: "Script Author:", fr: "Auteur du script:", pl: "Script Author:", es:"Script Author:", tr: "Script Author:"}, { en: "Contributors (EN):", ru: "Contributors (RU):", cs: "Contributors (CZ):", de: "Contributors (DE):", fr: "Contributeurs (FR):", pl: "Contributors (PL):", es:"Contributors (ES):", tr: "Contributors (TR):"} // {en: "", ru: "", cs: "", de: "", fr: "", pl: "", es:"", tr: ""} ]; // region settings for external sites switch(wg.srv) { case ("eu"): // eu server sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = sc.srv.wlf = sc.srv.as = sc.srv.ct = sc.srv.kttc = sc.srv.aos = sc.srv.ch = sc.srv.wr = wg.srv; break; case ("ru"): // ru server sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = sc.srv.ct = sc.srv.kttc = sc.srv.wots = sc.srv.aos = sc.srv.ch = sc.srv.wr = wg.srv; break; case ("na"): // na server - american english sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = sc.srv.wlf = sc.srv.ct = sc.srv.kttc = sc.srv.aos = sc.srv.ch = wg.srv; sc.srv.wr = "com"; break; case ("asia"): // asia server sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = "sea"; sc.srv.ct = sc.srv.kttc = sc.srv.aos = sc.srv.ch = wg.srv; sc.srv.wr = "com"; break; case ("kr"): // korean server sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = sc.srv.ct = sc.srv.aos = sc.srv.ch = wg.srv; sc.srv.wr = "com"; break; default: break; } // set script language to english if an unsupported language is detected if (sc.locSup.indexOf(sc.loc) == -1) { sc.loc = "en"; } // process localization for (var _l=0, l_len = loc.length; _lProcessing..."); layoutHolder.appendChild(loadGif); // script link and settings var clanSet_div = sf.elem("div", "menu-settings menu-top_item", ""+loc[3]+""), clanSet_list = sf.elem("ul", "cm-user-menu", ""), enableOnPageload = sf.storage("statScript_onPageload", "", "get", "parse"), enableWhitelist = sf.storage("statScript_whitelist", "", "get", "parse"), enableWhiteList_list = sf.storage("statScript_whitelist_list", "", "get"), whiteListArray = (enableWhiteList_list) ? enableWhiteList_list.split(",") : "", clanSet_list_items = [ sf.settings("onPageload", loc[4], enableOnPageload, false), sf.settings("whitelist", loc[5], enableWhitelist, false, enableWhiteList_list), sf.settings("wnRefresh", loc[6]+" [v"+wn.vers[1]+"]"), sf.settings("cleanStorage", loc[7]), sf.elem("li", "b-settingItem settingCredits settingSepertor", "

"+loc[20]+" Orrie

"+((sc.cred[sc.loc]) ? "

"+loc[21]+"

"+sc.cred[sc.loc]+"

" : "")), sf.elem("li", "b-settingItem settingCredits", "

Version: "+sc.vers+"

"), sf.elem("li", "b-settingItem settingCredits", "

Greasy Fork

"), sf.elem("li", "b-settingItem settingCredits", "

Support Thread

") ]; sf.links(clanSet_list, clanSet_list_items); clanSet_div.firstElementChild.addEventListener('click', function() {this.classList.toggle('cm-user-menu-link__opened'); this.nextSibling.classList.toggle('cm-user-menu__opened');}, false); clanSet_div.appendChild(clanSet_list); // add script info and settings if user menu exists, else wait var navMenu = d.getElementById('common_menu'), navUser = navMenu.getElementsByClassName('cm-menu__user')[0]; if (navUser) { navUser.appendChild(clanSet_div); } else { var setLook = new MutationObserver(function() { navUser = navMenu.getElementsByClassName('cm-menu__user')[0]; navUser.appendChild(clanSet_div); setLook.disconnect(); }); setLook.observe(navMenu, {childList: true}); } // clan statistic links var menu_class = d.getElementsByClassName('menu-top')[0], clanMenu_div = sf.elem("div", "menu-clan_links menu-top_item", ""+loc[1]+""), clanMenu_list = sf.elem("ul", "clan-links cm-sublist", ""), clanMenu_list_items = [ [sc.srv.wl, "WoTLabs"], [sc.srv.nm, "Noobmeter"], [sc.srv.vb, "vBAddict"], [sc.srv.ct, "Clan Tools"], [sc.srv.cs, "WoT-CS"], [sc.srv.kttc, "KTTC"], [sc.srv.wlf, "WoT-Life"], [sc.srv.as, "AWAY Stats"], [sc.srv.wr, "WoTReplays"] ]; sf.links(clanMenu_list, clanMenu_list_items); clanMenu_div.firstElementChild.addEventListener('click', function() {this.classList.toggle('cm-parent-link__opened'); this.nextSibling.classList.toggle('cm-sublist__opened');}, false); clanMenu_div.appendChild(clanMenu_list); menu_class.appendChild(clanMenu_div); // add clan total stats if they exist if (wg.p && s.clan) { var clanProfileValue = d.getElementsByClassName('rating-profile_item'); if (s.clan.win) { clanProfileValue[1].innerHTML = ""+sf.color(s.clan.win,"wr",2,"%")+""+loc[8]+""; } if (s.clan.wn8) { clanProfileValue[3].innerHTML = ""+sf.color(s.clan.wn8,"wn8",0)+""+loc[9]+""; } } // check if on memberlist page if (wg.m) { // formula calculations and variables var memObj = { cls: d.getElementsByClassName('tbl-rating_body')[0], ids: [], bans: {ids:[],f:false} }; // add manual stat fetching button var filter_class = d.getElementsByClassName('filter')[0], refreshBtn_div = sf.elem("div", "b-button-stats", ""+loc[12]+""); refreshBtn_div.addEventListener('click', function() {sf.tableFetch();}, false); filter_class.appendChild(refreshBtn_div); // prepare stat fetcher, store stats in localStorage and reload page var ratLook = new MutationObserver(function() { sf.tableFetch(); ratLook.disconnect(); }); // fetch stats automatically if enabled or check whitelist for whitelisted clan if (statFetch && (enableOnPageload || (enableWhitelist && whiteListArray.indexOf(wg.clan.id) > -1))) { ratLook.observe(memObj.cls, {childList: true}); } else { // no stats fetching, check if stats already exist and add if they do var clanPlayersValue = d.getElementsByClassName('rating-players')[0].rows[0], pageHeader = d.getElementsByClassName('page-header')[0], ratHeadStatus = false; // add clan total stats if they exist clanPlayersValue.cells[1].getElementsByClassName('rating-players_key')[0].textContent = loc[8]; if (s.clan) { if (s.clan.win) { var clanWinCell = clanPlayersValue.insertCell(2); clanWinCell.className = "rating-players_item rating-players_item__data"; clanWinCell.innerHTML = ""+sf.color(s.clan.win,"wr",2,"%")+""+loc[10]+""; } if (s.clan.wn8) { var clanWn8Cell = clanPlayersValue.insertCell(4); clanWn8Cell.className = "rating-players_item rating-players_item__data"; clanWn8Cell.innerHTML = ""+sf.color(s.clan.wn8,"wn8",0)+""+loc[11]+""; } } // add container for member counters var memInfo_div = sf.elem("div", "page-header_meminfo", ""); pageHeader.appendChild(memInfo_div); // wait for table to be filled before adding wn8 var ratInsert = new MutationObserver(function(muto) { if (muto[0].previousSibling === null) { var newMem = 0, banMem = d.getElementsByClassName('tbl-rating_tr__state-banned').length; // add a counter for amount of banned people in clan if (banMem > 0) { var banMem_span = d.getElementsByClassName('page-header_ban')[0]; if (!banMem_span) { banMem_span = sf.elem("span", "page-header_ban", loc[17]+" "+banMem); memInfo_div.appendChild(banMem_span); } else { banMem_span.textContent = loc[17]+" "+banMem; } } // table header for wn8 if (ratHeadStatus === false && Object.keys(s.clan).length !== 0) { var headName = d.getElementsByClassName('tbl-rating_th__name')[0], wnHead = sf.elem("td", "tbl-rating_th tbl-rating_th__wn", "WN8"), colGroup = d.getElementsByTagName('colgroup')[0], newCol = sf.elem("col"); newCol.width = "1px"; headName.parentNode.insertBefore(wnHead, headName.nextSibling); colGroup.insertBefore(newCol, colGroup.children[5]); ratHeadStatus = true; } // add wn8 for each member and colorize stats var userCheck = Object.keys(s.user).length !== 0; for (var _rt=0, _rt_len = memObj.cls.rows.length; _rt<_rt_len; _rt++) { var row = memObj.cls.rows[_rt]; if (!row.classList.contains("tbl-rating_tr__card")) { var id = row.getAttribute('data-account_id'), memName = row.getElementsByClassName('tbl-rating_td__name')[0], memWGR = row.getElementsByClassName('tbl-rating_td__value')[0], memWins = row.getElementsByClassName('tbl-rating_td__value')[2]; if (userCheck) { var wnRow = sf.elem("td", "tbl-rating_td tbl-rating_td__value js-format-number", ""); memName.parentNode.insertBefore(wnRow, memName.nextSibling); if (s.user[id]) { wnRow.innerHTML = sf.color(s.user[id].wn8,"wn8",0); } else { wnRow.innerHTML = loc[15]; newMem ++; } } if (memWGR.innerHTML !== "0" && memWGR.innerHTML !== "—") { memWGR.innerHTML = sf.color(sf.format(memWGR.innerHTML,1),"wgr",0); } if (memWins.innerHTML !== "0.00%" && memWins.innerHTML !== "—") { memWins.innerHTML = sf.color(sf.format(memWins.innerHTML.replace(/[,]/g,"."),3),"wr",2,"%"); } } } // add a counter for new people in the clan, compared to store stats if (newMem > 0) { var newMem_span = d.getElementsByClassName('page-header_mem')[0]; if (!newMem_span) { newMem_span = sf.elem("span", "page-header_mem", loc[16]+" "+newMem); memInfo_div.appendChild(newMem_span); } else { newMem_span.textContent = loc[16]+" "+newMem; } } // check for length on bans if (memObj.bans.f) { sf.apiBanHnd(); } else { memObj.bans.cls = d.getElementsByClassName('js-banned'); for (var _bm=0, _bm_len = memObj.bans.cls.length; _bm<_bm_len; _bm++) { var bannedId = memObj.bans.cls[_bm].dataset.account_id; memObj.bans.ids.push(bannedId); } if (memObj.bans.ids.length > 0) { sc.api.b = sc.api.i+memObj.bans.ids.join(',')+"&fields=ban_time"; sf.request(sc.api.b , sf.apiBanHnd); } } } }); ratInsert.observe(memObj.cls, {childList: true}); } } }(window));