WoTStatScript - Clanpage

More info for World of Tanks clan page.

当前为 2015-11-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WoTStatScript - Clanpage
  3. // @version 0.9.12.0.2
  4. // @description More info for World of Tanks clan page.
  5. // @author Orrie
  6. // @namespace http://forum.worldoftanks.eu/index.php?/topic/263423-
  7. // @icon http://dl.dropboxusercontent.com/u/12497046/wot/projects/statscript/img/icon.png
  8. // @include http://*.wargaming.net/clans/*/*
  9. // @grant GM_xmlhttpRequest
  10. // @license MIT License
  11. // ==/UserScript==
  12. /*
  13. Changelogs:
  14. Profilepage: http://dl.dropboxusercontent.com/u/12497046/wot/projects/statscript/WoTStatScript-changelog.txt
  15. Clanpage: http://dl.dropboxusercontent.com/u/12497046/wot/projects/statscript/WoTStatScript-Clanpage-changelog.txt
  16. */
  17. (function() {
  18. // global vars
  19. var d = document, c = d.cookie;
  20.  
  21. // get server info and webpage
  22. var wg = {host:d.location.host, href:d.location.href, clan:{}};
  23. wg.srv = wg.host.match(/(eu|ru|na|com|asia|kr)/)[0].replace(/com/,"na");
  24. wg.m = /players[\/wot#]+/i.test(wg.href);
  25.  
  26. // getting claninfo
  27. var emblemName = d.getElementsByClassName('page-header_emblem')[0],
  28. clanName = d.getElementsByClassName('clan_name')[0],
  29. sidebarName = d.getElementsByClassName('sidebar-clan_emblem')[0];
  30. wg.clan.id = wg.href.match(/\/(\d+)/)[1];
  31. wg.clan.name = (emblemName || clanName) ? ((clanName) ? clanName.firstElementChild.innerHTML.replace(/[\[\]]/g,"") : emblemName.alt) : sidebarName.alt;
  32. wg.p = new RegExp("\\["+wg.clan.name+"\\] \\|").test(d.title) && !/wowp/i.test(wg.href);
  33.  
  34. // script variables
  35. var sc = {
  36. vers: "0.9.12.0.2",
  37. host: "http://greasyfork.org/en/scripts/12137-wotstatscript-clans",
  38. user: "http://forum.wotlabs.net/index.php?/user/1618-orrie/",
  39. top: {
  40. eu: "http://forum.worldoftanks.eu/index.php?showtopic=263423",
  41. na: "http://forum.worldoftanks.com/index.php?showtopic=404652"
  42. },
  43. api: {
  44. ru: "98ca7c4fb108175b67d6505b9c3f3ebd",
  45. eu: "a7595640a90bf2d19065f3f2683b171c",
  46. na: "bf5dba0efd444d75147b6222dd903fd2",
  47. asia: "95f8713eccd322e52dbf521dbd28b19c",
  48. kr: "ffea0f1c3c5f770db09357d94fe6abfb"
  49. },
  50. wn: "http://www.wnefficiency.net/exp/expected_tank_values_latest.json",
  51. loc: c.match(/wgccfe_language=(\w+)/)[1],
  52. locSup: ["en", "ru", "cs", "de", "fr", "pl", "es", "tr"]
  53. };
  54. // script threadlink
  55. sc.link = "<div class='b-scriptlink'><a target='_blank' href="+sc.host+">Script</a> v"+sc.vers+" - <a target='_blank' href="+((wg.srv == "na") ? sc.top.na : sc.top.eu)+">Thread</a></div>";
  56.  
  57. // external site support
  58. var srv = {
  59. wl: false, // wotlabs
  60. nm: false, // noobmeter
  61. vb: false, // vbaddict
  62. ws: false, // wotstats
  63. cs: false, // wotcs
  64. wlf: false, // wot-life
  65. as: false, // away stats
  66. ct: false, // clan tools
  67. aos: false, // age of strife
  68. kttc: false, // kttc
  69. wots: false, // wots
  70. ch: false, // clan history
  71. wr: false // wotreplays
  72. };
  73.  
  74. // determine browser types
  75. var web = {
  76. gecko: typeof InstallTrigger !== 'undefined',
  77. opera: !!window.opera || /opera|opr/i.test(navigator.userAgent),
  78. chrome: !!window.chrome && !!window.chrome.webstore,
  79. safari: /constructor/i.test(window.HTMLElement)
  80. };
  81.  
  82. // fetch wnefficiency values - check if array exists in localStorage, otherwise fetch and reload page
  83. var statArr = [],
  84. wnExpValues = locStorage("wnExpValues", "", "get", "parse"),
  85. wnExpDate = locStorage("wnExpDate", "", "get", "parse")+12096e5 >= Date.now(), // true if timestamp is less than 2 weeks old, refresh list if false.
  86. wnExpVers = locStorage("wnExpVers", "", "get", "parse") || "";
  87. if (wnExpVers[0]==sc.vers && wnExpValues && wnExpDate) {
  88. statArr = wnExpValues.data;
  89. }
  90. else {
  91. reqHnd(sc.wn, wnHnd, wnHnd_error);
  92. }
  93.  
  94. // fetch stored clanlist stats - check if array exists in localStorage, otherwise tag fetching to true
  95. var s = {}, statFetch = false,
  96. ssValues = locStorage("statScriptValues_"+wg.clan.id, "", "get", "parse"),
  97. ssDate = locStorage("statScriptDate_"+wg.clan.id, "", "get", "parse")+6048e5 >= Date.now(); // true if timestamp is less than 1 weeks old, refresh list if false.
  98. if (ssValues && ssDate) {
  99. s = ssValues;
  100. }
  101. else {
  102. statFetch = true;
  103. }
  104.  
  105. // inserting style into head
  106. var style = elem("style", "wotstatscript", "", "text/css");
  107. d.head.appendChild(style);
  108.  
  109. // colour scale array
  110. var colArr = {
  111. // col wr bat sr hr dmg wgr wn8 wn7 eff nm
  112. sUni: [ "#5A3175", 65, 30000, 50, 80, 300, 9900, 2900, 2050, 2050, 2000 ], // 99.99% super unicum
  113. uni: [ "#83579D", 60, 25000, 46, 75, 270, 9000, 2450, 1850, 1800, 1950 ], // 99.90% unicum
  114. gr8: [ "#3972C6", 56, 21000, 42, 70, 240, 8500, 2000, 1550, 1500, 1750 ], // 99.00% great
  115. vGud: [ "#4099BF", 54, 17000, 38, 65, 210, 6500, 1600, 1350 ], // 95.00% very good
  116. good: [ "#4D7326", 52, 13000, 34, 60, 180, 5000, 1200, 1100, 1200, 1450 ], // 82.00% good
  117. aAvg: [ "#849B24", 50, 10000, 30, 55, 150, 4000, 900 ], // 63.00% above average
  118. avg: [ "#CCB800", 48, 7000, 25, 50, 120, 3000, 650, 900, 900, 1250 ], // 40.00% average
  119. bAvg: [ "#CC7A00", 47, 3000, 20, 45, 90, 2000, 450, 700, 600, 1150 ], // 20.00% below average
  120. bas: [ "#CD3333", 46, 1000, 15, 40, 60, 1500, 300, 500 ], // 6.00% basic
  121. beg: [ "#930D0D", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], // 0.00% beginner
  122. dft: [ "#6B6B6B" ], // default
  123. 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
  124. };
  125.  
  126. // localization
  127. // cz-czech - Crabtr33 and Ragnarocek
  128. // de-german - ArtiOpa, Crakker and multimill
  129. // fr-french - SuperPommeDeTerre
  130. // pl-polish - KeluMocy and pokapokami
  131. // es-spanish - Frodo45127
  132. // tr-turkish - Ufuko
  133. // ru-russian - dimon222
  134. var loc = [
  135. // thousands separator
  136. {en: ",", ru: " ", cs: " ", de: ".", fr: " ", pl: " ", es:" ", tr: "."},
  137. // clan page
  138. {en: "Clan Stats", ru: "Статистика клана", cs: "Stat. klanu", de: "Clanstatistiken", fr: "Statistiques du clan", pl: "Statystyki klanu", es: "Estadísticas del clan", tr: "Klan İstatistikleri" },
  139. {en: "Replays:", ru: "Реплеи:", cs: "Záznamy:", de: "Replays", fr: "Replays:", pl: "Powtórki:", es: "Repeticiones:", tr: "Replayler" },
  140. // memberlist
  141. {en: "Script Menu", ru: "Script Menu", cs: "Nastavení scriptu", de: "Script Menu", fr: "Script Menu", pl: "Script Menu", es:"Script Menu", tr: "Script Menu"},
  142. {en: "Load Stats Automatically", ru: "Load Stats Automatically", cs: "Nahrát stat. automaticky", de: "Load Stats Automatically", fr: "Load Stats Automatically", pl: "Load Stats Automatically", es:"Load Stats Automatically", tr: "Load Stats Automatically"},
  143. {en: "Use Whitelist", ru: "Use Whitelist", cs: "Použi whitelist", de: "Use Whitelist", fr: "Use Whitelist", pl: "Use Whitelist", es:"Use Whitelist", tr: "Use Whitelist"},
  144. {en: "Refresh WN8 Table", ru: "Refresh WN8 Table", cs: "Obnovit WN8 tabulku", de: "Refresh WN8 Table", fr: "Refresh WN8 Table", pl: "Refresh WN8 Table", es: "Refresh WN8 Table", tr: "Refresh WN8 Table" },
  145. {en: "Clean Script Database", ru: "Clean Script Database", cs: "Vyčisti db scriptu", de: "Clean Script Database", fr: "Clean Script Database", pl: "Clean Script Database", es: "Clean Script Database", tr: "Clean Script Database" },
  146. {en: "Average Winrate", ru: "Average Winrate", cs: "Průměrný winrate", de: "Average Winrate", fr: "Average Winrate", pl: "Average Winrate", es:"Average Winrate", tr: "Average Winrate"},
  147. {en: "Average WN8", ru: "Average WN8", cs: "Průměrné WN8", de: "Average WN8", fr: "Average WN8", pl: "Average WN8", es:"Average WN8", tr: "Average WN8"},
  148. {en: "Overall", ru: "Overall", cs: "Celkem", de: "Overall", fr: "Overall", pl: "Overall", es:"Overall", tr: "Overall"},
  149. {en: "Fetch WN8 for Clan", ru: "Fetch WN8 for Clan", cs: "Obnov WN8 pre klan", de: "Fetch WN8 for Clan", fr: "Fetch WN8 for Clan", pl: "Fetch WN8 for Clan", es:"Fetch WN8 for Clan", tr: "Fetch WN8 for Clan"},
  150. {en: "Fetching WN8 for Clan!", ru: "Fetching WN8 for Clan!", cs: "Obnovuju WN8 pro klan!", de: "Fetching WN8 for Clan!", fr: "Fetching WN8 for Clan!", pl: "Fetching WN8 for Clan!", es:"Fetching WN8 for Clan!", tr: "Fetching WN8 for Clan!"},
  151. {en: "WN8 Fetched for Clan!", ru: "WN8 Fetched for Clan!", cs: "WN8 obnoveno pro klan!", de: "WN8 Fetched for Clan!", fr: "WN8 Fetched for Clan!", pl: "WN8 Fetched for Clan!", es:"WN8 Fetched for Clan!", tr: "WN8 Fetched for Clan!"},
  152. {en: "Not Found", ru: "Not Found", cs: "Nenalezeno", de: "Not Found", fr: "Not Found", pl: "Not Found", es:"Not Found", tr: "Not Found"},
  153. {en: "New Members:", ru: "New Members:", cs: "Noví členové:", de: "New Members:", fr: "New Members:", pl: "New Members:", es:"New Members:", tr: "New Members:"},
  154. {en: "Banned Members:", ru: "Banned Members:", cs: "Noví členové:", de: "Banned Members:", fr: "Banned Members:", pl: "Banned Members:", es:"Banned Members:", tr: "Banned Members:"}
  155. // {en: "", ru: "", cs: "", de: "", fr: "", pl: "", es:"", tr: ""}
  156. ];
  157.  
  158. // region settings for external sites
  159. switch(wg.srv) {
  160. case ("eu"): // eu server
  161. srv.wl = srv.nm = srv.vb = srv.ws = srv.cs = srv.wlf = srv.as = srv.ct = srv.kttc = srv.aos = srv.ch = srv.wr = wg.srv;
  162. break;
  163. case ("ru"): // ru server
  164. srv.wl = srv.nm = srv.vb = srv.ws = srv.cs = srv.ct = srv.kttc = srv.wots = srv.aos = srv.ch = srv.wr = wg.srv;
  165. break;
  166. case ("na"): // na server - american english
  167. srv.wl = srv.nm = srv.vb = srv.ws = srv.cs = srv.wlf = srv.ct = srv.kttc = srv.aos = srv.ch = wg.srv; srv.wr = "com";
  168. break;
  169. case ("asia"): // asia server
  170. srv.wl = srv.nm = srv.vb = srv.ws = srv.cs = "sea"; srv.ct = srv.kttc = srv.aos = srv.ch = wg.srv; srv.wr = "com";
  171. break;
  172. case ("kr"): // korean server
  173. srv.wl = srv.nm = srv.vb = srv.ws = srv.cs = srv.ct = srv.aos = srv.ch = wg.srv; srv.wr = "com";
  174. break;
  175. default: break;
  176. }
  177.  
  178. // set script language to english if an unsupported language is detected
  179. if (sc.locSup.indexOf(sc.loc) == -1) {
  180. sc.loc = "en";
  181. }
  182. // process localization
  183. for (var _l=0, l_len = loc.length; _l<l_len; _l++) {
  184. loc[_l] = loc[_l][sc.loc];
  185. }
  186.  
  187. // add language to body classname for language based styling
  188. d.body.classList.add("lang-"+sc.loc);
  189.  
  190. // variables for dropbox, css and data uri
  191. var css = {
  192. u: {
  193. cIcons: "data:image/png;base64,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",
  194. arrow: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAECAMAAAB1GNVPAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAPUExURf///////////0xpcf///17pIXYAAAAEdFJOU393iAAiK7rGAAAAH0lEQVQI1w3GwQEAMBBEQBf6rzn7YeipxA0bXoU4LB8EgABGoTqNxwAAAABJRU5ErkJggg=="
  195. }
  196. };
  197.  
  198. // style contents
  199. var styleClan = [
  200. // script header rules
  201. "#common_menu .cm-menu__user > *:not(.cm-notifications):not(.js-cm-user-menu-dropdown) {display: inline-block}",
  202. "#common_menu .cm-layout_content {max-width: 1340px !important;}",
  203. "#common_menu .cm-parent-link:hover {cursor: inherit; color: #707273;}",
  204. "#common_menu .b-scriptlink a {color: #E5B12E;}",
  205. "#common_menu .b-scriptlink a:hover {color: #FFBE4C; text-shadow: 0px 0px 7px rgba(255, 126, 0, 0.7);}",
  206. ".profile__main {margin: 0; padding: 0;}",
  207. // fix width for header with low resolution
  208. "form.search {width: 25%;}",
  209. // links menu rules
  210. ".menu-clan_links {padding: 0;}",
  211. ".menu-clan_links.cm-parent-link__opened {border: 1px solid #313335;}",
  212. ".menu-clan_links .menu-top_link {cursor: pointer; padding: 0 8px 0 9px;}",
  213. ".menu-clan_links .menu-top_link.cm-parent-link__opened {background: #0E0E0E; border-left: 1px solid #313335; border-right: 1px solid #313335; margin-left: -1px;}",
  214. ".menu-clan_links .cm-arrow {background-image: url('"+css.u.arrow+"'); display: inline-block; margin-left: 5px; opacity: 0.5; vertical-align: middle; transition: opacity 0.2s ease 0s; height: 4px; width: 7px;}",
  215. ".menu-clan_links .cm-parent-link__opened .cm-arrow {opacity: 1; transform: rotate(180deg);}",
  216. ".menu-clan_links .clan-links {background: rgba(14, 14, 14, 0.99); border: 1px solid #313335; display: none; box-shadow: 0px 0px 25px rgba(0, 0, 0, 0.4); margin-left: -1px; padding: 14px 16px;}",
  217. ".menu-clan_links .cm-sublist__opened {display: block;}",
  218. ".menu-clan_links .clan-links td {padding: 0 10px;}",
  219. ".sl-icon {background: url('"+css.u.cIcons+"') no-repeat; display: inline-block; margin: -2px 8px 0px 0px; vertical-align: middle; height: 16px; width: 16px;}",
  220. ".sl-wl {background-position: 0px 0px;}",
  221. ".sl-nm {background-position: 0px -16px;}",
  222. ".sl-ct {background-position: 0px -32px;}",
  223. ".sl-cs {background-position: 0px -48px;}",
  224. ".sl-kttc {background-position: 0px -64px;}",
  225. ".sl-wlife {background-position: 0px -80px;}",
  226. ".sl-as {background-position: 0px -96px;}",
  227. ".sl-wr {background-position: 0px -112px;}",
  228. ".sl-vb {background-position: 0px -128px;}",
  229. // rating profile rules
  230. ".rating-profile {width: 70%; margin: 0px auto;}",
  231. // settings menu rules
  232. "#common_menu .menu-settings {text-align: left;}",
  233. "#common_menu .menu-settings .cm-parent-link:hover {cursor: pointer;}",
  234. "#common_menu .menu-settings .settingItem {margin: 6px 0px;}",
  235. "#common_menu .menu-settings label {display: table; line-height: normal; cursor: pointer;}",
  236. "#common_menu .menu-settings .l-box {display: none;}",
  237. "#common_menu .menu-settings .b-checkbox {height: 16px; width: 16px; float: left; margin-right: 5px;}",
  238. "#common_menu .menu-settings .b-checkbox span {height: 16px; width: 16px;}",
  239. "#common_menu .menu-settings .b-combobox-label__checked {color: #DCDCDC;}",
  240. "#common_menu .menu-settings .settingItem .b-combobox-label:hover {color: #DCDCDC;}",
  241. "#common_menu .menu-settings .settingItem .b-combobox-label:hover .b-checkbox {background-position: 0px -34px; box-shadow: 0px 0px 10px 1px rgba(191, 166, 35, 0.15), 0px 0px 3px 1px rgba(191, 166, 35, 0.25);}",
  242. "#common_menu .menu-settings .settingItem .b-combobox-label:hover .b-checkbox.b-checkbox__checked {background-position: 0px -68px;}",
  243. "#common_menu .menu-settings textarea.l-textarea {background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 2px; color: #FFFFFF; line-height: normal; padding: 5px; min-height: 50px; margin: 5px 0 5px 0; min-width: 175px;}",
  244. "#common_menu .menu-settings textarea::-webkit-input-placeholder {color: #FFFFFF;}",
  245. "#common_menu .menu-settings textarea::-moz-placeholder {color: #FFFFFF;}",
  246. "#common_menu .menu-settings .b-settingLink {line-height: 26px;}",
  247. "#common_menu .menu-settings .b-settingLink a {cursor: pointer; color: #B1B2B3; text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5);}",
  248. "#common_menu .menu-settings .b-settingLink a:hover {color: #FFFFFF; text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75);}",
  249. // memberpage rules
  250. ".page-header {padding: 30px 0 30px 0}",
  251. ".page-header_meminfo {display: table; margin: 0px auto; position: absolute; top: 3px; right: 0px; left: 0px;}",
  252. ".page-header_meminfo span {margin: 0 5px;}",
  253. ".page-header_ban {color: #E5B12E;}",
  254. ".page-header_mem {color: #E5B12E;}",
  255. ".js-page-header-view .page-header_mem {margin-left: 25px;}",
  256. // button fetch rules
  257. ".b-button-stats {border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 2px; position: absolute; right: 0; top: 9px;}",
  258. ".b-button-stats a {background: rgba(255, 255, 255, 0.1); color: #FFFFFF; cursor: pointer; font-size: 17px; line-height: 45px; display: block; padding: 0px 15px; transition: all 0.2s ease 0s;}",
  259. ".b-button-stats a:hover {background: rgba(229, 177, 46, 0.25);}",
  260. // rating players rules
  261. ".rating-players {height: 200px;}",
  262. ".rating-players tbody {width: 95%; display: table; margin: 0px auto;}",
  263. ".rating-players_item__data {padding-top: 25px; width: 14%;}",
  264. ".rating-players_item__average {padding-top: 10px; width: 16%;}",
  265. ".rating-players_stats {font-size: 40px;}",
  266. // membertable rules
  267. "#js-playerslist-table {margin-top: -40px;}",
  268. ".rating-table_wn a {cursor: pointer;}",
  269. ""
  270. ];
  271. style.textContent = styleClan.join("");
  272. // end style
  273.  
  274. // script link and settings
  275. var clanHead_div = elem("div", "cm-parent-link", sc.link),
  276. clanSet_div = elem("div", "menu-settings menu-top_item", "<span class='cm-parent-link js-cm-dropdown-link'>"+loc[3]+"<span class='cm-arrow'></span></span>"),
  277. clanSet_list = elem("ul", "cm-sublist", ""),
  278. enableOnPageload = locStorage("statScript_onPageload", "", "get", "parse"),
  279. enableWhitelist = locStorage("statScript_whitelist", "", "get", "parse"),
  280. enableWhiteList_list = locStorage("statScript_whitelist_list", "", "get"),
  281. whiteListArray = (enableWhiteList_list) ? enableWhiteList_list.split(",") : "",
  282. clanSet_list_items = [
  283. settingsHnd("onPageload", loc[4], enableOnPageload, false),
  284. settingsHnd("whitelist", loc[5], enableWhitelist, false, enableWhiteList_list),
  285. settingsHnd("wnRefresh", loc[6]+" [v"+wnExpVers[1]+"]"),
  286. settingsHnd("cleanStorage", loc[7]),
  287. ];
  288. linksHnd(clanSet_list, clanSet_list_items);
  289. clanSet_div.firstElementChild.addEventListener('click', function() {this.classList.toggle('cm-parent-link__opened'); this.nextSibling.classList.toggle('cm-sublist__opened');}, false);
  290. clanSet_div.appendChild(clanSet_list);
  291. // add script info and settings if user menu exists, else wait
  292. var navMenu = d.getElementById('common_menu'),
  293. navUser = navMenu.getElementsByClassName('cm-menu__user')[0];
  294. if (navUser) {
  295. navUser.insertBefore(clanHead_div, navUser.firstChild);
  296. navUser.insertBefore(clanSet_div, navUser.firstChild);
  297. }
  298. else {
  299. var setLook = new MutationObserver(function() {
  300. navUser = navMenu.getElementsByClassName('cm-menu__user')[0];
  301. navUser.insertBefore(clanHead_div, navUser.firstChild);
  302. navUser.insertBefore(clanSet_div, navUser.firstChild);
  303. setLook.disconnect();
  304. });
  305. setLook.observe(navMenu, {childList: true});
  306. }
  307.  
  308. // clan statistic links
  309. var menu_class = d.getElementsByClassName('menu-top')[0],
  310. clanMenu_div = elem("div", "menu-clan_links menu-top_item", "<span class='menu-top_link'>"+loc[1]+"<span class='cm-arrow'></span></span>"),
  311. clanMenu_list = elem("ul", "clan-links cm-sublist", ""),
  312. clanMenu_list_items = [
  313. [srv.wl, "<a target='_blank' href='http://wotlabs.net/"+srv.wl+"/clan/"+wg.clan.name+"'><span class='sl-icon sl-wl'></span>WoTLabs</a>"],
  314. [srv.nm, "<a target='_blank' href='http://noobmeter.com/clan/"+srv.nm+"/"+wg.clan.name+"/"+wg.clan.id+"'><span class='sl-icon sl-nm'></span>Noobmeter</a>"],
  315. [srv.vb, "<a target='_blank' href='http://vbaddict.net/clan/worldoftanks."+srv.vb+"/"+wg.clan.id+"/clan-"+wg.clan.name.toLowerCase()+"'><span class='sl-icon sl-vb'></span>vBAddict</a>"],
  316. [srv.ct, "<a target='_blank' href='http://clantools.us/servers/"+srv.ct+"/clans?id="+wg.clan.id+"'><span class='sl-icon sl-ct'></span>Clan Tools</a>"],
  317. [srv.cs, "<a target='_blank' href='http://wotcs.com/clan.php?wid="+wg.clan.id+"'><span class='sl-icon sl-cs'></span>WoT-CS</a>"],
  318. [srv.kttc, "<a target='_blank' href='http://"+((wg.srv=="ru") ? "" : srv.kttc+".")+"kttc.ru/clan/"+wg.clan.id+"/'><span class='sl-icon sl-kttc'></span>KTTC</a>"],
  319. [srv.wlf, "<a target='_blank' href='http://en.wot-life.com/"+srv.wlf+"/clan/"+wg.clan.name+"-"+wg.clan.id+"/'><span class='sl-icon sl-wlife'></span>WoT-Life</a>"],
  320. [srv.as, "<a target='_blank' href='http://stats.teamaway.net/clan/"+wg.clan.id+"/'><span class='sl-icon sl-as'></span>AWAY Stats</a>"],
  321. [srv.wr, "<a target='_blank' href='http://wotreplays."+srv.wr+"/clan/"+wg.clan.name+"'><span class='sl-icon sl-wr'></span>WoTReplays</a>"]
  322. ];
  323. linksHnd(clanMenu_list, clanMenu_list_items);
  324. clanMenu_div.firstElementChild.addEventListener('click', function() {this.classList.toggle('cm-parent-link__opened'); this.nextSibling.classList.toggle('cm-sublist__opened');}, false);
  325. clanMenu_div.appendChild(clanMenu_list);
  326. menu_class.appendChild(clanMenu_div);
  327.  
  328. // add clan total stats if they exist
  329. if (wg.p && s.clan) {
  330. var clanProfileValue = d.getElementsByClassName('rating-profile_item');
  331. if (s.clan.win) {
  332. clanProfileValue[1].innerHTML = "<i class='rating-profile_icon i i__rating-common i__wot-victories'></i><span class='rating-profile_value rating-players_stats js-format-number'>"+colStat(s.clan.win,"wr",2,"%")+"</span><span class='rating-profile_key'>"+loc[8]+"</span>";
  333. }
  334. if (s.clan.wn8) {
  335. clanProfileValue[3].innerHTML = "<i class='rating-profile_icon i i__rating-common i__wot-experience'></i><span class='rating-profile_value rating-players_stats js-format-number'>"+colStat(s.clan.wn8,"wn8",0)+"</span><span class='rating-profile_key'>"+loc[9]+"</span>";
  336. }
  337. }
  338.  
  339. // check if on memberlist page
  340. if (wg.m) {
  341. // formula calculations and variables
  342. var memObj = {
  343. cls: d.getElementsByClassName('rating-table_body')[0],
  344. ids: [],
  345. num: []
  346. };
  347.  
  348. // add manual stat fetching button
  349. var timeFrame_class = d.getElementsByClassName('timeframe')[0],
  350. refreshBtn_div = elem("div", "b-button-stats", "<a id='js-wn8-fetch'>"+loc[11]+"</a>");
  351. refreshBtn_div.addEventListener('click', function() {tableFetch();}, false);
  352. timeFrame_class.appendChild(refreshBtn_div);
  353.  
  354. // prepare stat fetcher, store stats in localStorage and reload page
  355. var ratLook = new MutationObserver(function() {
  356. tableFetch();
  357. ratLook.disconnect();
  358. });
  359.  
  360. // fetch stats automatically if enabled or check whitelist for whitelisted clan
  361. if (statFetch && (enableOnPageload || (enableWhitelist && whiteListArray.indexOf(wg.clan.id) > -1))) {
  362. ratLook.observe(memObj.cls, {childList: true});
  363. }
  364. else {
  365. // no stats fetching, check if stats already exist and add if they do, otherwise just add ban counter
  366. var clanPlayersValue = d.getElementsByClassName('rating-players')[0].rows[0],
  367. pageHeader = d.getElementsByClassName('page-header')[0],
  368. pageHeaderView = d.getElementsByClassName('js-page-header-view')[0],
  369. ratHead = d.getElementsByClassName('rating-table_head')[0].rows[0],
  370. ratHeadStatus = false;
  371. // add clan total stats if they exist
  372. clanPlayersValue.cells[1].getElementsByClassName('rating-players_key')[0].textContent = loc[8];
  373. if (s.clan) {
  374. if (s.clan.win) {
  375. var clanWinCell = clanPlayersValue.insertCell(2);
  376. clanWinCell.className = "rating-players_item rating-players_item__data";
  377. clanWinCell.innerHTML = "<i class='rating-players_icon i i__rating-common i__wot-victories'></i><span class='rating-players_value rating-players_stats'>"+colStat(s.clan.win,"wr",2,"%")+"</span><span class='rating-players_key'>"+loc[10]+" "+loc[8]+"</span>";
  378. }
  379. if (s.clan.wn8) {
  380. var clanWn8Cell = clanPlayersValue.insertCell(4);
  381. clanWn8Cell.className = "rating-players_item rating-players_item__data";
  382. clanWn8Cell.innerHTML = "<i class='rating-players_icon i i__rating-common i__wot-experience'></i><span class='rating-players_value rating-players_stats'>"+colStat(s.clan.wn8,"wn8",0)+"</span><span class='rating-players_key'>"+loc[10]+" "+loc[9]+"</span>";
  383. }
  384. }
  385. // add container for member counters
  386. memInfo_div = elem("div", "page-header_meminfo", "");
  387. pageHeader.appendChild(memInfo_div);
  388. // wait for table to be filled before adding wn8
  389. var ratInsert = new MutationObserver(function(muto) {
  390. if (muto[0].previousSibling === null) {
  391. var newMem = 0, banMem = d.getElementsByClassName('rating-table_tr__banned').length;
  392. // add a counter for amount of banned people in clan
  393. if (banMem > 0) {
  394. var banMem_span = d.getElementsByClassName('page-header_ban')[0];
  395. if (!banMem_span) {
  396. banMem_span = elem("span", "page-header_ban", loc[16]+" "+banMem);
  397. memInfo_div.appendChild(banMem_span);
  398. }
  399. else {
  400. banMem_span.textContent = loc[16]+" "+banMem;
  401. }
  402. }
  403. if (Object.keys(s).length !== 0) {
  404. if (s.clan) {
  405. // table header for wn8
  406. if (ratHeadStatus === false) {
  407. var wnHead = ratHead.insertCell((ratHead.childElementCount == 14) ? 4 : 3);
  408. wnHead.className = "rating-table_th rating-table_th__key rating-table_wn";
  409. wnHead.innerHTML = "<a class='table-sorter js-table-sorter js-sort-wn'><i class='table-sorter_icon table-sorter_icon__media i i__table-params i__wot-aeb'></i><span class='table-sorter_key'>WN8</span></a>";
  410. ratHeadStatus = true;
  411. }
  412. // add wn8 for each member and colorize stats
  413. for (var _rt=0, _rt_len = memObj.cls.rows.length; _rt<_rt_len; _rt++) {
  414. var row = memObj.cls.rows[_rt];
  415. if (!row.classList.contains("rating-table_tr__card")) {
  416. var id = row.getAttribute('data-account_id'),
  417. cellCheck = (ratHead.childElementCount == 14) ? 0 : 1,
  418. wnRow = row.insertCell(3+cellCheck),
  419. memWGR = row.cells[4+cellCheck],
  420. memWins = row.cells[6+cellCheck];
  421. wnRow.className = "rating-table_td rating-table_td__value";
  422. if (s[id]) {
  423. wnRow.innerHTML = colStat(s[id].wn8,"wn8",0);
  424. }
  425. else {
  426. newMem ++;
  427. wnRow.innerHTML = loc[14];
  428. }
  429. if (memWGR.innerHTML !== "0" && memWins.innerHTML !== "0.00%") {
  430. memWGR.innerHTML = colStat(filter(memWGR.innerHTML,1),"wgr",0);
  431. memWins.innerHTML = colStat(filter(memWins.innerHTML.replace(/[,]/g,"."),3),"wr",2,"%");
  432. }
  433. }
  434. }
  435. if (newMem > 0) {
  436. var newMem_span = d.getElementsByClassName('page-header_mem')[0];
  437. if (!newMem_span) {
  438. newMem_span = elem("span", "page-header_mem", loc[15]+" "+newMem);
  439. memInfo_div.appendChild(newMem_span);
  440. }
  441. else {
  442. newMem_span.textContent = loc[15]+" "+newMem;
  443. }
  444. }
  445. }
  446. }
  447. }
  448. });
  449. ratInsert.observe(memObj.cls, {childList: true});
  450. }
  451. }
  452.  
  453. function tableFetch() {
  454. d.getElementById('js-wn8-fetch').textContent = loc[12]; // change status to 'fetching'
  455. // find required info from table player rows
  456. for (var _rt=0, _rt_len = memObj.cls.rows.length; _rt<_rt_len; _rt++) {
  457. var id = memObj.cls.rows[_rt].getAttribute('data-account_id'),
  458. name = memObj.cls.rows[_rt].getElementsByClassName('player_name')[0].innerHTML.match(/[\w\_]+/)[0];
  459. if (!isNaN(id)) {
  460. var users = memObj.ids.length,
  461. index = memObj.ids.indexOf(id);
  462. s[id] = {u:{name:name,id:id}, v:{frag:0,dmg:0,spot:0,def:0,win:0}, wn8:""};
  463. if (index>-1) {
  464. memObj.num[index][memObj.num[index].length] = _rt;
  465. }
  466. else {
  467. memObj.ids[users] = id;
  468. memObj.num[users] = [_rt];
  469. }
  470. }
  471. }
  472. s.clan = {wn8:0, win:0, mem: memObj.ids.length};
  473. // request and retrieve statistics from API
  474. if (memObj.ids.length > 0) {
  475. sc.api.i = "http://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/account/info/?application_id="+sc.api[wg.srv]+"&account_id="+memObj.ids.join(',');
  476. sc.api.v = "http://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/account/tanks/?application_id="+sc.api[wg.srv]+"&account_id="+memObj.ids.join(',');
  477. reqHnd(sc.api.i, apiInfoHnd);
  478. }
  479. }
  480.  
  481. // processing information from player API
  482. function apiInfoHnd(resp) {
  483. var data = JSON.parse(resp).data;
  484. for (var a in data) {
  485. if (data.hasOwnProperty(a)) {
  486. var pData = data[a];
  487. if (pData !== null) {
  488. // store stats
  489. var pDataStats = pData.statistics.all;
  490. s[pData.account_id].u = {
  491. name: pData.nickname,
  492. id: pData.account_id,
  493. cid: pData.clan_id,
  494. bat: pDataStats.battles,
  495. win: (pDataStats.wins/pDataStats.battles)*100,
  496. dmg: pDataStats.damage_dealt/pDataStats.battles,
  497. frag: pDataStats.frags/pDataStats.battles,
  498. spot: pDataStats.spotted/pDataStats.battles,
  499. def: pDataStats.dropped_capture_points/pDataStats.battles,
  500. wgr: pData.global_rating,
  501. lng: pData.client_language
  502. };
  503. s.clan.win += (!isNaN(s[pData.account_id].u.win)) ? s[pData.account_id].u.win : 0;
  504. }
  505. }
  506. }
  507. reqHnd(sc.api.v, apiVehHnd);
  508. }
  509.  
  510. // processing information from vehicle API and calculate WN8
  511. function apiVehHnd(resp) {
  512. var data = JSON.parse(resp).data;
  513. for (var p in data) {
  514. if (data.hasOwnProperty(p)) {
  515. var vData = data[p];
  516. if (vData !== null) {
  517. var rWin, rDmg, rFrag, rSpot, rDef, wn8 = 0;
  518. if (s[p].u.bat > 0) {
  519. for (var v in vData) {
  520. if (vData.hasOwnProperty(v)) {
  521. // go through each vehicle to get expected stats
  522. for (var _so=0, _so_len = statArr.length; _so<_so_len; _so++) {
  523. if (statArr[_so].IDNum == vData[v].tank_id) {
  524. var vehStat = statArr[_so],
  525. dataBattles = vData[v].statistics.battles;
  526. s[p].v.frag += vehStat.expFrag * dataBattles;
  527. s[p].v.dmg += vehStat.expDamage * dataBattles;
  528. s[p].v.spot += vehStat.expSpot * dataBattles;
  529. s[p].v.def += vehStat.expDef * dataBattles;
  530. s[p].v.win += vehStat.expWinRate * dataBattles;
  531. break;
  532. }
  533. }
  534. }
  535. }
  536. // start calculating wn8
  537. rWin = Math.max(((s[p].u.win /(s[p].v.win /s[p].u.bat)-0.71)/(1-0.71)),0);
  538. rDmg = Math.max(((s[p].u.dmg /(s[p].v.dmg /s[p].u.bat)-0.22)/(1-0.22)),0);
  539. 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);
  540. 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);
  541. 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);
  542. wn8 = 980*rDmg + 210*rDmg*rFrag + 155*rFrag*rSpot + 75*rDef*rFrag + 145*Math.min(1.8,rWin);
  543. }
  544. // store wn8 and add to clan total
  545. s[p].wn8 = wn8;
  546. s.clan.wn8 += wn8;
  547. }
  548. }
  549. }
  550. // calculate average wn8 / winrate and store everything in localStorage, then reload page
  551. s.clan.wn8 = s.clan.wn8/s.clan.mem;
  552. s.clan.win = s.clan.win/s.clan.mem;
  553. locStorage("statScriptValues_"+wg.clan.id, s, "set", "string");
  554. locStorage("statScriptDate_"+wg.clan.id, Date.now(), "set");
  555. d.getElementById('js-wn8-fetch').textContent = loc[13]; // change status to 'fetched'
  556. location.reload();
  557. }
  558.  
  559. // helper functions
  560. // filter
  561. function filter(input, type) {
  562. var inputStr = input.toString();
  563. switch(type) {
  564. case (1): // input string into number
  565. return parseFloat(inputStr.replace(/[^\d]/g,""));
  566. case (2): // output number with locale symbol
  567. return inputStr.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1"+loc[0]);
  568. case (3): // input string into number - exclude dots
  569. return parseFloat(inputStr.replace(/[^\d\.]/g,""));
  570. default:
  571. console.error("Error filtering: ", input);
  572. return input;
  573. }
  574. }
  575.  
  576. // colouring
  577. function colStat(input, type, dec, sym) {
  578. var color = colArr.dft[0],
  579. output = input.toFixed(dec);
  580. if (input >= 1000) {
  581. output = filter(input.toFixed(dec),2);
  582. }
  583. for (var c in colArr) {
  584. if (colArr.hasOwnProperty(c)) {
  585. if (input >= colArr[c][colArr.id[type]]) {
  586. color = colArr[c][0]; break;
  587. }
  588. }
  589. }
  590. if (loc[0] !== "," && dec !== 0) {
  591. output = output.replace(/\.(\d+)*$/g,",$1");
  592. }
  593. if (sym) {
  594. output += sym;
  595. }
  596. return "<font color='"+color+"'>"+output+"</font>";
  597. }
  598.  
  599. // quick creation of element
  600. function elem(tag, name, html, type) {
  601. var element = d.createElement(tag);
  602. if (name) {
  603. element.className = name;
  604. }
  605. if (html) {
  606. if (/</.test(html)) {
  607. element.innerHTML = html;
  608. }
  609. else {
  610. element.textContent = html;
  611. }
  612. }
  613. if (type) {
  614. element.type = type;
  615. }
  616. return element;
  617. }
  618.  
  619. // settings handler
  620. function settingsHnd(name, text, state, dftState, wlist) {
  621. var listItem = elem("li", "settingItem", ""),
  622. listItems = d.createDocumentFragment();
  623. if (name == "wnRefresh") {
  624. var refreshBtn = elem("div", "b-settingLink", "<a>"+text+"</a>");
  625. refreshBtn.addEventListener('click', function() {localStorage.removeItem("wnExpValues"); location.reload();}, false);
  626. listItems.appendChild(refreshBtn);
  627. }
  628. else if (name == "cleanStorage") {
  629. var cleanBtn = elem("div", "b-settingLink", "<a>"+text+"</a>");
  630. cleanBtn.addEventListener('click', function() {localStorage.clear(); location.reload();}, false);
  631. listItems.appendChild(cleanBtn);
  632. }
  633. else {
  634. var optCheckDiv = elem("div", "b-checkbox", "<span class='b-checkbox_checker'></span>"),
  635. optLabel = elem("label", "b-combobox-label", text),
  636. optCheck = elem("input", "l-box", "", "checkbox");
  637. optLabel.htmlFor = name;
  638. optCheck.name = name;
  639. optCheck.id = name;
  640. if (state) {
  641. optCheckDiv.classList.add("b-checkbox__checked");
  642. optLabel.classList.add("b-combobox-label__checked");
  643. }
  644. optCheck.checked = (state !== undefined) ? state : dftState;
  645. optCheck.addEventListener('click', function() {
  646. locStorage('statScript_' + this.name, this.checked, "set");
  647. d[this.name] = this.checked;
  648. this.parentNode.classList.toggle('b-checkbox__checked');
  649. this.parentNode.parentNode.classList.toggle('b-combobox-label__checked');
  650. return this.checked;
  651. }, false);
  652. d[optCheck.name] = optCheck.checked;
  653. optCheckDiv.insertBefore(optCheck, optCheckDiv.firstChild);
  654. optLabel.appendChild(optCheckDiv);
  655. listItems.appendChild(optLabel);
  656. if (name == "whitelist") {
  657. var optText = elem("textarea", "l-textarea", "");
  658. optText.placeholder = "Add clanID seperated by comma without spaces: 500004502,500010805";
  659. if (wlist) {
  660. optText.value = wlist;
  661. }
  662. optText.addEventListener('input', function() {
  663. locStorage('statScript_whitelist_list', optText.value.split(","), "set");
  664. }, false);
  665. listItems.appendChild(optText);
  666. }
  667. }
  668. listItem.appendChild(listItems);
  669. return listItem;
  670. }
  671.  
  672. // links handler
  673. function linksHnd(parent, links) {
  674. var uRows = d.createDocumentFragment();
  675. for (var _l=0, _l_len = links.length; _l<_l_len; ++_l) {
  676. if (links[_l] instanceof HTMLElement) {
  677. uRows.appendChild(links[_l]);
  678. }
  679. else {
  680. uRows.appendChild((links[_l][0] && links[_l][1]) ? elem("li", "", links[_l][1]) : elem("li", "statname", links[_l][0]));
  681. }
  682. }
  683. parent.appendChild(uRows);
  684. }
  685.  
  686. // localStorage handler
  687. function locStorage(name, data, type, mode) {
  688. var storage;
  689. switch(type) {
  690. case ("set"):
  691. if (mode == "string") {
  692. data = JSON.stringify(data);
  693. }
  694. storage = localStorage.setItem(name, data);
  695. break;
  696. case ("get"):
  697. storage = localStorage.getItem(name);
  698. if (mode == "parse") {
  699. storage = JSON.parse(storage);
  700. }
  701. break;
  702. default: break;
  703. }
  704. return storage;
  705. }
  706. // end helper functions
  707.  
  708. // wnefficiency handler
  709. function wnHnd(resp) {
  710. locStorage("wnExpValues", resp, "set");
  711. locStorage("wnExpDate", Date.now(), "set");
  712. locStorage("wnExpVers", [sc.vers, JSON.parse(resp).header.version], "set", "string");
  713. location.reload();
  714. }
  715. function wnHnd_error(error) {
  716. console.error("Error accessing WNEfficiency.net", error);
  717. }
  718. // end wnefficiency handler
  719.  
  720. // retrieval function
  721. function reqHnd(url, handler, error) {
  722. GM_xmlhttpRequest({
  723. method: "GET",
  724. url: url,
  725. headers: {
  726. "Accept": "text/xml"
  727. },
  728. onload: function(resp) {
  729. if (resp.readyState == 4 && resp.status == 200 && resp.statusText == "OK") {
  730. handler(resp.responseText);
  731. }
  732. else {
  733. error(resp.responseText);
  734. }
  735. },
  736. onerror: function(resp) {
  737. error(resp.responseText);
  738. }
  739. });
  740. }
  741. }(window));