WoTStatScript - Clans

More info for World of Tanks clan page.

当前为 2015-09-02 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        WoTStatScript - Clans
// @version     0.9.9.0.1
// @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://worldoftanks.eu/*/accounts/*/*
// @include     http://worldoftanks.ru/*/accounts/*/*
// @include     http://worldoftanks.com/*/accounts/*/*
// @include     http://worldoftanks.asia/*/accounts/*/*
// @include     http://worldoftanks.kr/*/accounts/*/*
// @include     http://*.wargaming.net/clans/*/*
// @grant       GM_xmlhttpRequest
// @license     MIT License
// ==/UserScript==
/*
	Changelog: http://dl.dropboxusercontent.com/u/12497046/wot/projects/statscript/WoTStatScript-changelog.txt
*/
(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|com|asia|kr)/)[0].replace(/com/,"na");

	// script variables
	var sc = {
		vers: "0.9.9.0.1",
		host: "http://greasyfork.org/scripts/661-wotstatscript",
		user: "http://forum.wotlabs.net/index.php?/user/1618-orrie/",
		top: {
			eu: "http://forum.worldoftanks.eu/index.php?showtopic=263423",
			na: "http://forum.worldoftanks.com/index.php?showtopic=404652"
		},
		wn: "http://www.wnefficiency.net/exp/expected_tank_values_latest.json",
		nm: {
			id: "orrie_js_174043" // noobmeter api id
		},
		loc: c.match(/wgccfe_language=(\w+)/)[1],
		locSup: ["en", "ru", "cz", "de", "fr", "pl", "es", "tr"]
	};
	// script threadlink
	sc.link = "<div class='b-scriptlink'><a target='_blank' href="+sc.host+">Script</a> version "+sc.vers+" - <a target='_blank' href="+((wg.srv == "na") ? sc.top.na : sc.top.eu)+">Thread</a></div>";

	// external site support
	var srv = {
		wl: false,    // wotlabs
		nm: false,    // noobmeter
		ws: false,    // wotstats
		cs: false,    // wotcs
		wlife: false, // wot-life
		as: false,    // away stats
		//wn: false,  // wot-numbers
		//tb: false,  // tomatobot
		ct: false,    // clan tools
		aos: false,   // age of strife
		kttc: false,  // kttc
		wots: false,  // wots
		ch: false,    // clan history
		wr: false     // wotreplays
	};

	// determine browser types
	var 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)
	};

	// 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"))+12096e5 >= Date.now(), // true if timestamp is less than 2 weeks 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, wnHnd_error);
	}

	// inserting style into head
	var style = 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
		sym: { en: ",", ru: " ", cz: " ", de: ".", fr: " ", pl: " ", es:".", tr: "."},
		// clan page
		c01: { en: "Clan Stats", ru: "Статистика клана", cz: "Stat. klanu", de: "Clanstatistiken", fr: "Statistiques du clan", pl: "Statystyki klanu", es: "Estadísticas del clan", tr: "Klan İstatistikleri" },
		c02: { en: "Replays:", ru: "Реплеи:", cz: "Záznamy:", de: "Replays", fr: "Replays:", pl: "Powtórki:", es: "Repeticiones:", tr: "Replayler" }
		//p00: { en: "", ru: "", cz: "", de: "", fr: "", pl: "", es:"", tr: ""},
	};

	// region settings for external sites
	switch(wg.srv) {
		case ("eu"): // eu server
			srv.wl = srv.nm = srv.ws = srv.cs = srv.wlife = srv.as = srv.wn = srv.tb = srv.ct = srv.kttc = srv.aos = srv.ch = srv.wr = wg.srv;
			break;
		case ("ru"): // ru server
			srv.wl = srv.nm = srv.wn = srv.ws = srv.cs = srv.tb = srv.ct = srv.kttc = srv.wots = srv.aos = srv.ch = srv.wr = wg.srv;
			break;
		case ("na"): // na server - american english
			srv.wl = srv.nm = srv.ws = srv.cs = srv.wlife = srv.wn = srv.tb = srv.ct = srv.kttc = srv.aos = srv.ch = wg.srv; srv.wr = "com"; srv.wn = "us";
			loc.p27.en = "Defence";
			loc.p55.en = "Base Defence Points:";
			break;
		case ("asia"): // asia server
			srv.wl = srv.nm = srv.wn = srv.ws = srv.cs = "sea"; srv.ct = srv.kttc = srv.aos = srv.ch = wg.srv; srv.wr = "com";
			break;
		case ("kr"): // korean server
			srv.wl = srv.nm = srv.ws = srv.cs = srv.ct = srv.aos = srv.ch = wg.srv; 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 in loc) {
		if (loc.hasOwnProperty(_l)) {
			loc[_l] = loc[_l][sc.loc];
		}
	}

	// add language to body classname for language based styling
	d.body.classList.add("lang-"+sc.loc);

	// variables for dropbox, css and data uri
	var css = {
		u: {
			cIcons: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAACACAMAAAA1SxkQAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAADeUExURUxpcTofR0GwyRsZGiIgHyYmJkqkxV1WazJn0f9qAECxyTyqwXAxlhsaGjNly0hTtRERER8dHEq0ynAxlvehhdrhhem/hSwqKhgXFUKwyBkXFEKxyTFlyzAoKHI1lHQron8axT+vxv+GhTJlzP+Chf+AhfR0Wdj9hUOxyf9sAZBKGvVhCv+BhX8axWJUZTFly6DqheicAP/nhf9rAPhrBf9/hfvxhf+phWFoIpNYHdU5LqNdenAxliQjI/9qACEXFjAiISkoKDgrKVBBN0UyMHlMR2tGQqWZlfn5+Xh0a6/IXu8AAAA8dFJOUwAYicrr9hMF/vZU+uiAhjUuqzGBEE4j1mqeVrO3nr1S+tCh04HDQcRvykLwX4b2V9f1s5+A233QvoXq0Fvc5mgAAANrSURBVEjHvZUJc6JMEIabQyaCKCCICGjUGHO4mjv59nM0HGLy///Q9swg6B5VW1tb25UM3c+83dMDIwD8mWny2DCcOnYwNHSw4tNY82PQOAgNQ9aA2IkFX1isY0xY7BM4HyEIDAOVcZKYMDpnEsMIAPpJwjLOzznABTD24QgwgXkAzCQ/8aWTXolE4B9aW4xR1G53Vm1mHJxxax9UUTTlIIrE/WmjD9G0045QtALgs+3VmbbinhBMp6tpxBRnUZlysLJu52B/bzvd1vpg/LZ2q3Dd5YJ6viXus/ArAeGg26kEQwQt7HBYCrprWA9Z7ZFYAi8glKQ1ZE8UawHPQC07Kpi4ZkWZz54tb4mvMhJHoFWBNc8armvQwiU6ot+y9SEpBa3D5rqjaoPl9vnY6n53b3reycki3t1d7xhgfOeBVzO3N/fmMJ/Xad7c9cCd15KXF5wkD15VVLgvL9WiD1zce0Wdx+a8B17Ofe3h/6sLMBHJZLKAxeTiAtxZWX4xcWeX7nPvclY20JstJgQumKhscPZ8eRiFXUyYdvHsVnvgHun9+shIfdsCYsZW9ZOkdICAqn2+rmQn1LYkybKpOmC1cMbs26of922qWBIQhdoDdbnfZw01oaoNlkobjeQz+/xMVJUqJtgULUmzfcYcWwKTXWn6uUw4IGApXJKlfAIXJgPMVJSlryjosN4kE0v1zT4uXXbGkhppA9c0xTuEWCaqsYWBVL1NrL5iDqxfvFNitXFkagwqPbIkUaFxHC+X/gnwh//fCJDwjaiDp+Y1B0mWsYt5ebtpcuC/vQ0Uqtxcb0pgPt0+3bz997gpAZtqXt/fN0uAtdDb3N9vOFBojLUqa8JNzHNrcP31a/MENG+PEjjYbE7BY/PEHn/vY/K9K9eAuY4mV58aJ9Ac/Ppo4zJJGzs4qcuBHnKihXog6yDLV8FVyH5JITqyDA5KnFAjBBNQgDWuglAPQQ4AL8EVS9ZlWdfCUGNX8aw1WZd1/JOd6nGTMSFj7bh7h3X4u69TSdnimRcjN2W73dJy5LZlVo7cVO6qNUCfVuNP7b02jMx3eE/TdJ+nAtg4pHmef+wzxO+gMppnWfaBJE9Tng5ZURQfSPI8BZSlUOx2O4yLLM8hZ3THwL4osiwHX4CiwBhBBlJcKnaMIsA+0h8a/QZnvrDP+ki71wAAAABJRU5ErkJggg==",
			arrow: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAECAMAAAB1GNVPAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAPUExURf///////////0xpcf///17pIXYAAAAEdFJOU393iAAiK7rGAAAAH0lEQVQI1w3GwQEAMBBEQBf6rzn7YeipxA0bXoU4LB8EgABGoTqNxwAAAABJRU5ErkJggg=="
		}
	};

	// 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;

	// style contents
	var styleClan = [
		"#common_menu .cm-menu__user > *:not(.cm-notifications) {display: inline-block}",
		"#common_menu .b-scriptlink a {color: #E5B12E;}",
		"#common_menu .b-scriptlink a:hover {color: #FFBE4C; text-shadow: 0px 0px 7px rgba(255, 126, 0, 0.7);}",
		"#common_menu .b-login-msg:hover, #common_menu .b-scriptlink:hover {color: #707273; cursor: initial;}",
		"#common_menu .cm-link__get-gold {margin: 0 12px;}",
		".profile__main {margin: 0; padding: 0;}",
		".menu-clan_links {padding: 0;}",
		".menu-clan_links.cm-parent-link__opened {border: 1px solid #313335;}",
		".menu-clan_links .menu-top_link {cursor: pointer; padding: 0 8px 0 9px;}",
		".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;}",
		".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;}",
		".menu-clan_links  .cm-parent-link__opened .cm-arrow {opacity: 1; transform: rotate(180deg);}",
		".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;}",
		".menu-clan_links .cm-sublist__opened {display: block;}",
		".menu-clan_links .clan-links td {padding: 0 10px;}",
		".sl-icon {background: url('"+css.u.cIcons+"') no-repeat; display: inline-block; margin: -2px 8px 0px 0px; vertical-align: middle; height: 16px; width: 16px;}",
		".sl-wl {background-position: 0px 0px;}",
		".sl-nm {background-position: 0px -16px;}",
		".sl-ct {background-position: 0px -32px;}",
		".sl-cs {background-position: 0px -48px;}",
		".sl-kttc {background-position: 0px -64px;}",
		".sl-wlife {background-position: 0px -80px;}",
		".sl-as {background-position: 0px -96px;}",
		".sl-wr {background-position: 0px -112px;}"
	];
	style.textContent = styleClan.join("");
	// end style

	// script link
	var clanHead_div = elem("div", "cm-parent-link", sc.link),
	navMenu = d.getElementById('common_menu'),
	navUser = navMenu.getElementsByClassName('cm-menu__user')[0];
	// add script info if user menu exists, else wait
	if (navUser) {
		navUser.insertBefore(clanHead_div, navUser.firstChild);
	}
	else {
		var navLook = new MutationObserver(function() {
			navUser = navMenu.getElementsByClassName('cm-menu__user')[0];
			navUser.insertBefore(clanHead_div, navUser.firstChild);
			navLook.disconnect();
		});
		navLook.observe(navMenu, {childList: true});
	}

	// clan statistic links
	var menu_class = d.getElementsByClassName('menu-top')[0],
	clanMenu_div = elem("div", "menu-clan_links menu-top_item", "<span class='menu-top_link'>"+loc.c01+"<span class='cm-arrow'></span></span>"),
	clanMenu_list = elem("ul", "clan-links cm-sublist", ""),
	clanMenu_list_items = [
		[srv.wl, "<a target='_blank' href='http://wotlabs.net/"+srv.wl+"/clan/"+wg.clan.name+"'><span class='sl-icon sl-wl'></span>WoTLabs</a>"],
		[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>"],
		[srv.ct, "<a target='_blank' href='https://clantools.us/servers/"+srv.ct+"/clans?id="+wg.clan.id+"'><span class='sl-icon sl-ct'></span>Clan Tools</a>"],
		[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>"],
		[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>"],
		[srv.wlife, "<a target='_blank' href='http://en.wot-life.com/"+srv.wlife+"/clan/"+wg.clan.name+"-"+wg.clan.id+"/'><span class='sl-icon sl-wlife'></span>WoT-Life</a>"],
		[srv.as, "<a target='_blank' href='http://stats.teamaway.net/clan/"+wg.clan.id+"/'><span class='sl-icon sl-as'></span>AWAY Stats</a>"],
		[srv.wr, "<a target='_blank' href='http://wotreplays."+srv.wr+"/clan/"+wg.clan.name+"'><span class='sl-icon sl-wr'></span>WoTReplays</a>"]
	];
	linksHnd(clanMenu_list, clanMenu_list_items, "list");
	clanMenu_div.addEventListener('click', function() {this.firstElementChild.classList.toggle('cm-parent-link__opened'); this.lastElementChild.classList.toggle('cm-sublist__opened');}, false);
	clanMenu_div.appendChild(clanMenu_list);
	menu_class.appendChild(clanMenu_div);

	// helper functions
	// filter
	function filter(input, type) {
		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.sym);
			case (3): // remove all symbols
				return inputStr.replace(/[^\w]/g,"");
			default:
				console.error("Error filtering: ", input);
				return input;
		}
	}

	// quick creation of element
	function elem(tag, name, html, type) {
		var element = d.createElement(tag);
		if (name) {
			element.className = name;
		}
		if (html) {
			if (/</.test(html)) {
				element.innerHTML = html;
			}
			else {
				element.textContent = html;
			}
		}
		if (type) {
			element.type = type;
		}
		return element;
	}

	// links handler
	function linksHnd(parent, links, type) {
		var uRows = d.createDocumentFragment();
		for (var _l=0, _l_len = links.length; _l<_l_len; ++_l) {
			if (type == "table") {
			var uRow = elem("tr", "", "");
			for (var _lr=0, _lr_len = links[_l].length; _lr<_lr_len; ++_lr) {
				uRow.appendChild((links[_l][_lr][0] && links[_l][_lr][1]) ? elem("td", "", links[_l][_lr][1]) : elem("td", "", links[_l][_lr][0]));
			}
			uRows.appendChild(uRow);
			}
			else if (type == "list") {
			  uRows.appendChild((links[_l][0] && links[_l][1]) ? elem("li", "", links[_l][1]) : elem("li", "statname", links[_l][0]));
			}
		}
		parent.appendChild(uRows);
	}
	// end helper functions

	// wnefficiency handler
	function wnHnd(resp) {
		localStorage.setItem("wnExpValues", resp);
		localStorage.setItem("wnExpDate", Date.now());
		localStorage.setItem("wnExpVers", JSON.stringify([sc.vers, JSON.parse(resp).header.version]));
		location.reload();
	}
	function wnHnd_error(error) {
		console.error("Error accessing WNEfficiency.net", error);
	}
	// end wnefficiency handler

	// retrieval function
	function reqHnd(url, handler, error) {
		GM_xmlhttpRequest({
			method: "GET",
			url: url,
			headers: {
				"Accept": "text/xml"
			},
			onload: function(resp) {
				if (resp.readyState == 4 && resp.status == 200 && resp.statusText == "OK") {
					handler(resp.responseText);
				}
				else {
					error(resp.responseText);
				}
			},
			onerror: function(resp) {
				error(resp.responseText);
			}
		});
	}
}(window));