TravianStats

By FranMod Last update May 13, 2008 — Installed 5,412 times. Daily Installs: 2, 2, 2, 0, 0, 0, 6, 2, 0, 1, 0, 3, 2, 0, 3, 1, 0, 1, 0, 1, 0, 2, 1, 0, 0, 0, 0, 0, 2, 1, 1, 2
// ==UserScript==
// @name           Travian Stats
// @namespace      travianstats
// @description    Show statistics for players, allys and villages
// @include        http://*.travian*.*/karte.php*
// @include        http://*.travian*.*/spieler.php*
// @include        http://*.travian*.*/allianz.php*
// ==/UserScript==

var debugNum = 20;
var statsServer = 'http://travian.ping-timeout.de/';
var travianServer = getServerId();

window.addEventListener('DOMContentLoaded', main, false);
if (document.body) main();

function main() {
	GM_log(travianServer);

	var path = location.pathname;

	var typ;
	
	if (path == '/spieler.php') typ = 'uid';
	if (path == '/allianz.php') typ = 'aid';
	if (path == '/karte.php')   typ = 'vid';
	
	var id = getVarLocation(typ);
	if (hasStatistics()) addStatsTable(typ, id);
	
	function getVarLocation() {
		var var_id = typ;
		if (typ == 'vid') var_id = 'd';
		var href = location.search;
		if (href.indexOf(var_id + '=') == -1) return -1;
		return href.substring(href.indexOf(var_id + '=') + var_id.length + 1).split('&')[0];
	}

	function hasStatistics() {
		if (id == -1) return false;
		if (typ != 'vid') return true;
		var dom = new DOMUtils();
		var table = dom.xs('//div[@id="lmid2"]/div[@class="map_details_right"]/div');
		if (!table) return false;
		var link = dom.xs('//div[@id="lmid2"]/div[@class="map_details_right"]//a[contains(@href, "spieler")]');
		if (!link) return false;
		link.href.match(/.*uid\=([0-9]*)[\S]*/);
		id = RegExp.$1 + ',' + id;
		return true;
	}
}

function addStatsTable(typ, id) {
	var dom = new DOMUtils();
	var set, table, tbody, tr, td;

	set = dom.id('lmid2');
	set.style.width = '506px';

	var tableHTML = '<tbody id="ts_stats">' +
			'<tr><td class="rbg">Statistics: (<a id="ts_show_stats" href="javascript:void(0)" typ="' + typ + '" vid="' + id + '">Show</a>)</td></tr>' +
//			'<tr></tr>' +
			'</tbody>';

	table = dom.cn('table', tableHTML);
	table.className = 'tbg';
	table.cellPadding = '2';
	table.cellSpacing = '1';
	if (typ == 'vid') {
		table.style.position = 'absolute';
		table.style.top = getDistanceTop();
	}

	set.appendChild(dom.cn('p'));
	set.appendChild(table);

	dom.id('ts_show_stats').addEventListener('click', getStats, false);
	GM_log('added');

	function getDistanceTop() {
		var table = dom.xs('//div[@class="map_details_actions"]/table');
		return (380 + table.offsetHeight) + 'px';
	}
}

function getStats() {
	var typ = this.getAttribute('typ');
	var id = this.getAttribute('vid');

	var src;
	if (typ == 'uid') {
		src = getUserPic(id);
	}
	else if (typ == 'aid') {
		src = getAllyPic(id);
	}
	else {
		getUserStats(id.split(',')[0]);
		return;
	}
	
	GM_log(src);
	drawPic(src);
}

function drawPic(src) {
	var dom = new DOMUtils();
	var tbody = dom.id('ts_stats');
	var row, td, img;
	
	row = dom.cn('tr');
	td = dom.cn('td');
	td.className = 's7';
	img = dom.cn('img');
	img.src = src;
	img.setAttribute('style', 'margin-left: -5px; margin-bottom: -3px;');
	td.appendChild(img);
	row.appendChild(td);
	tbody.appendChild(row);

	td = dom.id('ts_show_stats').parentNode;
	td.innerHTML = 'Statistics:';
}

function getUserStats(uid) {
	debug(10, 'getUserStats: ' + uid);
	loadPage(getUserPage(uid), procUserStats, failUserStats);

	function procUserStats(resp) {
		var dom = new DOMUtils(resp.responseText);
		var table = dom.xa('//div[@class="content"]/table')[1];
//		debug(19, table.innerHTML);
		var village = new Array();
		var arefs = dom.xa('//td/table//a[contains(@href, "dorfinformationen") and contains(@href, "uid") and contains(@href, "did")]');
		for each (var a in arefs) {
			a.href.match(/.*did\=([0-9]*)[\S]*/);
			var vid = RegExp.$1;
			var sdom = new DOMUtils(a.parentNode.parentNode.innerHTML);
			var trav = sdom.xs('//a[contains(@href, "karte.php")]');
			trav.href.match(/.*[d|z]\=([0-9]*)[\S]*/);
			var id = RegExp.$1;
//			debug(15, 'Village found: ' + id + ', stats in: ' + vid);
			village.push({id:id,vid:vid});
		}
		setUserStats({inf:table,village:village});
	}

	function failUserStats(resp) {
		debug(0, 'Failure loading: ' + resp.statusText);
	}
}

function setUserStats(data) {
	var dom = new DOMUtils();
	var id = dom.id('ts_show_stats').getAttribute('vid').split(',')[1];
	var vid = null;
	
	GM_log(data.inf);
	for each (var v in data.village) {
		if (v.id == id) vid = v.vid;
	}

	if (vid) drawPic(getVillagePic(vid));
}

/***** STATS ADDRESS *****/

function getServerId() {
	var server = location.hostname;
	server.match(/([a-z]+[0-9]*)\.travian\.?.*?\.([a-z|A-Z]+)/);
	var name = RegExp.$1;
	var loc = RegExp.$2;
	
	if (loc == 'de') return name;
	if (loc == 'at' || loc == 'ch' || loc == 'org') return loc;
	if (name == 'speed') return loc + name;
	return loc + name.substring(1);
}

function getUserPage(uid) {
	return statsServer + 'index.php?m=spielersuche&uid=' + uid + '&w=' + travianServer;
}

function getUserPic(uid) {
	return statsServer + 'graph/uid/' + travianServer + '/' + uid + '.jpg';
}

function getAllyPic(aid) {
	return statsServer + 'graph/aid/' + travianServer + '/' + aid + '.jpg';
}

function getVillagePic(vid) {
	return statsServer + 'statsgraph/stats_graph3.php?welt=' + travianServer + '&did=' + vid;
}

/***** UTILS *****/

function debug(num, txt) {
	if (num < debugNum) GM_log(txt);
}

function loadPage(addr, onOk, onFailure) {
	GM_xmlhttpRequest({
		method:  'GET',
		url:     addr,
		onload:  onOk,
		onerror: onFailure
	});
}

function DOMUtils(doc) {
	this.cn = function(tag, html) {
		var elem = this.document.createElement(tag);
		if (html) elem.innerHTML = html;
		return elem;
	}

	this.ct = function(text) {
		return this.document.createTextNode(text);
	}

	this.id = function(id) {
		return this.document.getElementById(id);
	}

	this.tag = function(tag) {
		return this.document.getElementsByTagName(tag);
	}

	this.xs = function(xpath, ctxt) {
		if (!ctxt) ctxt = this.context;
		var res = this.document.evaluate(xpath, ctxt, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
		return res.singleNodeValue;
	}

	this.xa = function(xpath, ctxt) {
		if (!ctxt) ctxt = this.context;
		var arr = [];
		var xpr = this.document.evaluate(xpath, ctxt, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		for (var i = 0; item = xpr.snapshotItem(i); i++)
			arr.push(item);
		return arr.length == 0? null: arr;
	}

	if (typeof doc == 'string') {
		this.context = document.createElement('div');
		this.context.innerHTML = doc;
		this.document = document.implementation.createDocument('', '', null);
	        this.document.appendChild(this.context);
	}
	else {
		if (!doc) doc = document;
		this.document = doc;
		this.context = doc;
	}
}