// ==UserScript== // @name WoTStatScript - ForumsExtendedStat // @version 1.06 // @description Adds stats and links for posts on official World of Tanks forums // @author Orrie // @contributor seriych // @namespace http://forum.worldoftanks.eu/index.php?/topic/263423- // @icon http://dl.dropboxusercontent.com/u/12497046/wot/projects/statscript/img/icon.png // @include /^http:\/\/forum\.worldoftanks\.(eu|com|ru|asia|kr)\/\S+(\/topic\/|\?showtopic=)/ // @include /^http:\/\/forum\.worldoftanks\.(eu|com|ru|asia|kr)\/index\.php\?app=members&module=messaging§ion=view&do=showConversation&topicID=\d+/ // @grant GM_xmlhttpRequest // @license MIT License // @downloadURL none // ==/UserScript== (function() { // server, API and cluster settings var sc = { vers: "1.06", host: "http://greasyfork.org/scripts/660-wotstatscript-forumsextendedstat", top: { eu: "http://forum.worldoftanks.eu/index.php?showtopic=263423", na: "http://forum.worldoftanks.com/index.php?showtopic=404652" }, srv: document.location.host.match(/\.(eu|ru|com|asia|kr)/)[1], api: { ru: "98ca7c4fb108175b67d6505b9c3f3ebd", eu: "a7595640a90bf2d19065f3f2683b171c", com: "bf5dba0efd444d75147b6222dd903fd2", asia: "95f8713eccd322e52dbf521dbd28b19c", kr: "ffea0f1c3c5f770db09357d94fe6abfb" }, sym: ",", wn: "http://www.wnefficiency.net/exp/expected_tank_values_latest.json" }; // script threadlink sc.link = "
"; // external site support - wotlabs, noobmeter, wot-news, wotstats, wotcs, wot-life, wotstats.com.au and wotreplays var srv = { s: "en", wl: false, nm: false, ws: false, wr: false, wn: false, cs: false, wlife: false }; switch(sc.srv) { case ("eu"): // eu server srv.wl = srv.nm = srv.ws = srv.wr = srv.wn = srv.cs = srv.wlife = sc.srv; break; case ("ru"): // ru server srv.wl = srv.nm = srv.ws = srv.wr = srv.wn = srv.cs = sc.srv; srv.s = "ru"; sc.sym = " "; break; case ("com"): // na server srv.wl = srv.nm = srv.ws = srv.cs = "na"; srv.wr = "com"; srv.wn = "us"; break; case ("asia"): // asia server srv.wl = srv.nm = srv.ws = srv.wn = srv.cs = "sea"; srv.wr = "com"; break; case ("kr"): // korean server srv.wl = srv.nm = srv.ws = srv.cs = srv.ch = sc.srv; srv.wr = "com"; break; default: break; } // data uri var uri = { icon_arrow:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPwAAAAJCAMAAAAhKrH/AAAAV1BMVEUAAAD///+TKCf9AQmTLiX9AQmTMir9AQmTLif9AQmTMSz9AQmTMir9AQmTMyn9AQmTMirvGgKTMirsIAGTMirwGQOTMiqTMirsIAGaNDGgNzfqJwDrJABtE0DNAAAAGnRSTlMAABERIiIzM0REVVVmZnd3iIqZmrvDzN3g7thzQuwAAACHSURBVHja5dVLDsIwDEXRCySlP0IMoXXs7H+dDBASA1bQ3B0cPclm2Fe2wrfTQeO3qwqqAKWek80HxfO/l1/EBRgtU2tf+KkJ7TO9hdVSV3jU42f6ZClY6Qt/d4n+BGol29jTwQN1pE2QbA610BVefImuwL7xsNAXXhVpEYY8kNfO/rwsyA3ekEsOT2YDLE8AAAAASUVORK5CYII=" }; // fetch wnefficiency values - check if array exists in localStorage, otherwise fetch and reload page var statObj = {}, wnExpValues = JSON.parse(localStorage.getItem("wnExpValues")), wnExpDate = JSON.parse(localStorage.getItem("wnExpDate"))+1728e5 >= Date.now(), // true if timestamp is less than 2 days old, refresh list if false. wnExpVers = JSON.parse(localStorage.getItem("wnExpVers")) || ""; if (wnExpVers[0]==sc.vers && wnExpValues && wnExpDate) { statObj = wnExpValues.data; } else { reqHnd(sc.wn, wnHnd); } // style contents var style = elem("style", "wotstatscript", "", "text/css"), styleText = [ ".b-scriptlink a {color: #E5B12E;}", ".cm-link__get-gold {margin: 0 12px;}", ".author_info {z-index: 1;}", ".user_details > br {display: none;}", ".basic_info {margin: 0 0 4px;}", ".post_count.margin-bottom {margin: 0 0 5px;}", ".battles_count {display: none;}", ".i-xvm-lang {vertical-align: text-top;}", ".t-table-stats {margin: 5px 0; width: auto;}", ".t-table-stats td {padding: 0 5px 0 0; line-height: 16px;}", ".t-table-stats td:last-of-type {font-weight: bold;}", ".t-tables-links {background: #EDEDED; border: 1px solid #d5d5d5; border-radius: 3px; box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1), 0 0 3px 3px rgba(255, 255, 255, 0.2); display: inline-block; margin: 5px 0 5px -3px; overflow: hidden; padding: 3px 3px 0; text-overflow: ellipsis; white-space: nowrap; width: 90px;}", ".t-tables-links:hover {border-color: #7D7D7D; width: 180px;}", ".t-tables-links tbody {display: table; width: 180px;}", ".t-tables-links td {padding: 0 0 2px; font-weight: bold;}", ".t-tables-links td a { background: url("+uri.icon_arrow+") no-repeat scroll 0 2px rgba(0, 0, 0, 0); padding: 0 0 0 10px; vertical-align: middle;}", ".t-tables-links td a:hover {background: url("+uri.icon_arrow+") no-repeat scroll -244px 2px rgba(0, 0, 0, 0);}", ".t-tables-links tr:last-of-type td {}", ".realm_kr .t-tables-links {width: 108px;}", ".realm_kr .t-tables-links:hover {width: 215px;}", ".realm_kr .t-tables-links tbody {width: 215px;}" ]; style.textContent = styleText.join(""); document.head.appendChild(style); // end style // colour scale array var colArr = { // col wr bat wn8 wn7 eff nm pr sUni: [ "#5A3175", 65, 30000, 2900, 2050, 2050, 2000 ], // 99.99% super unicum uni: [ "#83579D", 60, 25000, 2450, 1850, 1800, 1950, 9930 ], // 99.90% unicum gr8: [ "#3972C6", 56, 21000, 2000, 1550, 1500, 1750, 8525 ], // 99.00% great vGud: [ "#4099BF", 54, 17000, 1600, 1350 ], // 95.00% very good good: [ "#4D7326", 52, 13000, 1200, 1100, 1200, 1450, 6340 ], // 82.00% good aAvg: [ "#849B24", 50, 10000, 900 ], // 63.00% above average avg: [ "#CCB800", 48, 7000, 650, 900, 900, 1250, 4185 ], // 40.00% average bAvg: [ "#CC7A00", 47, 3000, 450, 700, 600, 1150, 2020 ], // 20.00% below average bas: [ "#CD3333", 46, 1000, 300, 500 ], // 6.00% basic beg: [ "#930D0D", 0, 0, 0, 0, 0, 0, 0 ], // 0.00% beginner dft: [ "#6B6B6B" ], // default id: { "col": 0, "wr": 1, "bat": 2, "wn8": 3, "wn7": 4, "eff": 5, "nm": 6, "pr": 7 } // type identifier }; // localization var loc = { f00: { en: "Client", ru: "Клиент"}, f01: { en: "Winrate:", ru: "Винрейт:"}, f02: { en: "Battles:", ru: "Боев:"}, f03: { en: "Rating:", ru: "Рейтинг:"}, f04: { en: "WN8:", ru: "WN8:"} //f00: { en: "f00_en", ru: "f00_ru"}, }; for (var l in loc) { if (loc.hasOwnProperty(l)) { loc[l] = loc[l][srv.s]; } } // script link var clanHead_div = elem("div", "cm-parent-link", sc.link), navService_class = document.getElementsByClassName('cm-menu')[1]; navService_class.insertBefore(clanHead_div, navService_class.firstChild); // formula calculations and variables // create global post variable var postObj = { cls: document.querySelectorAll(".post_wrap, .post_wrap__wg"), ids: [], num: [] }, s = {}, id, users, index; // fetch userids and store all posts into one obj for later use for (var _t=0, _t_len = postObj.cls.length; _t<_t_len; _t++) { id = postObj.cls[_t].getElementsByClassName("ipsUserPhotoLink")[0].getAttribute('href').match(/\-(\d+)\//)[1]; if (!isNaN(id)) { s[id] = {u:{},v:{frag:0,dmg:0,spot:0,def:0,win:0},wn8:""}; users = postObj.ids.length; index = postObj.ids.indexOf(id); if (index>-1) { postObj.num[index][postObj.num[index].length] = _t; } else { postObj.ids[users] = id; postObj.num[users] = []; postObj.num[users][0] = _t; } } } // request and retrieve statistics from API if (postObj.ids.length > 0) { sc.api.i = "http://api.worldoftanks."+sc.srv+"/wot/account/info/?application_id="+sc.api[sc.srv]+"&account_id="+postObj.ids.join(','); sc.api.v = "http://api.worldoftanks."+sc.srv+"/wot/account/tanks/?application_id="+sc.api[sc.srv]+"&account_id="+postObj.ids.join(','); reqHnd(sc.api.i, apiInfoHnd); } // processing information from player API function apiInfoHnd(resp) { var data = JSON.parse(resp).data; for (var a in data) { if (data.hasOwnProperty(a)) { // store stats s[data[a].account_id].u = { name: data[a].nickname, id: data[a].account_id, cid: data[a].clan_id, bat: data[a].statistics.all.battles, win: (data[a].statistics.all.wins/data[a].statistics.all.battles)*100, dmg: data[a].statistics.all.damage_dealt/data[a].statistics.all.battles, frag: data[a].statistics.all.frags/data[a].statistics.all.battles, spot: data[a].statistics.all.spotted/data[a].statistics.all.battles, def: data[a].statistics.all.dropped_capture_points/data[a].statistics.all.battles, wgr: data[a].global_rating, lng: data[a].client_language }; } } reqHnd(sc.api.v, apiVehHnd); } // processing information from vehicle API and calculate WN8 function apiVehHnd(resp) { var data = JSON.parse(resp).data; for (var p in data) { if (data.hasOwnProperty(p)) { var rWin, rDmg, rFrag, rSpot, rDef; if (s[p].u.bat > 0) { for (var v in data[p]) { if (data[p].hasOwnProperty(v)) { for (var _so=0, _so_len = statObj.length; _so<_so_len; _so++) { if (statObj[_so].IDNum == data[p][v].tank_id) { var vehStat = statObj[_so]; s[p].v.frag += vehStat.expFrag *data[p][v].statistics.battles; s[p].v.dmg += vehStat.expDamage *data[p][v].statistics.battles; s[p].v.spot += vehStat.expSpot *data[p][v].statistics.battles; s[p].v.def += vehStat.expDef *data[p][v].statistics.battles; s[p].v.win += vehStat.expWinRate *data[p][v].statistics.battles; break; } } } } rWin = Math.max(((s[p].u.win /(s[p].v.win /s[p].u.bat)-0.71)/(1-0.71)),0); rDmg = Math.max(((s[p].u.dmg /(s[p].v.dmg /s[p].u.bat)-0.22)/(1-0.22)),0); rFrag = Math.max(Math.min(rDmg+0.2,((s[p].u.frag/(s[p].v.frag/s[p].u.bat)-0.12)/(1-0.12))),0); rSpot = Math.max(Math.min(rDmg+0.1,((s[p].u.spot/(s[p].v.spot/s[p].u.bat)-0.38)/(1-0.38))),0); rDef = Math.max(Math.min(rDmg+0.1,((s[p].u.def /(s[p].v.def /s[p].u.bat)-0.10)/(1-0.10))),0); s[p].wn8 = colStat(980*rDmg + 210*rDmg*rFrag + 155*rFrag*rSpot + 75*rDef*rFrag + 145*Math.min(1.8,rWin),"wn8",0); } else { s[p].wn8 = colStat(0,"wn8",0); } } } statInsert(); } // insert stats and links to every post function statInsert() { for (var y in s) { if (s.hasOwnProperty(y)) { var iPost = postObj.ids.indexOf(y), userStats = [ "