Travian Server Village

By Orekaria Uploaded Aug 19, 2009
// ==UserScript==
// @name            Travian Server Village
// @autor           Orekaria
// @version         1.0.1
// @namespace       TravianSV
// @description     Shows the village active in the Travian server
// @include         http://*travian*
// ==/UserScript==

// if you get the error "Error: GadrmGeneralWrapper is not defined..." is becouse the ad-blocker, not this code
var useFireBugConsole = false; 

var XPFirst = XPathResult.FIRST_ORDERED_NODE_TYPE;
var XPList = XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE;
var XPIterate = XPathResult.UNORDERED_NODE_ITERATOR_TYPE;
var XPListO = XPathResult.ORDERED_NODE_SNAPSHOT_TYPE;
var XPIter = XPathResult.UNORDERED_NODE_ITERATOR_TYPE;
var dom = new DOMUtils();

var cookieLoadedVillage = getServer() + "_loadedVillage";
var xPathVillageUrls = "//table[contains(@id,'vlist')]//a[contains(@href,'newdid')]";
var isSynchronizedColor = "green"; // '#A4FE9A';
var isDeSynchronizedColor = "red"; // '#FE9A9A';
var urltoCheck = "http://" + document.domain + "/nachrichten.php?t=1";
var checkInterval = 3000;
var mozillaAgent = (navigator.userAgent) ? navigator.userAgent : 'Mozilla/5.0 (Windows; U; Windows NT 5.1; pl-PL; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11';

main();

return;

function main(){
	// if you are using FireBug, redirect logging to the FireBug console
	if(unsafeWindow.console){
		if(useFireBugConsole)
			GM_log = unsafeWindow.console.log;
	}


	// one or more villages
	var villageTable = dom.id('vlist');
	if(villageTable == null){
		// log("the players owns one village. no need for this script.")
		return;
	}
	
	// get the current village and color it
	var currentVillageId = getCurrentVillageId(document);
	saveCurrentVillageId(currentVillageId);
	colorVillage(currentVillageId, isSynchronizedColor);

	// inject AJAX
	window.setInterval(checkIfVillageChangedAJAX, checkInterval);
}


function colorVillage(villageIdToColor, color){
	var villageAs = dom.find(xPathVillageUrls);
	var villageCount = villageAs.snapshotLength;
	for(var i = 0; i < villageCount; i++){
		var url = villageAs.snapshotItem(i);
		villageId = getParameterFromUrl(url, 'newdid');
		if(villageIdToColor == villageId){
			url.parentNode.setAttribute("style", "background: " + color + ";");
		} else {
			url.parentNode.setAttribute("style", "background: transparent;");
		}
	}
}

function saveCurrentVillageId(villageId){
	setGMCookie(cookieLoadedVillage, villageId);
}

function getCurrentVillageId(doc){
	// log(".getCurrentVillageId");
	// var villageAs = document.getElementById('vlist');
	// GM_log(villageTable.rows[0].cells.item(0).innerHTML);
	var villageId = 0;
	var villageAs = dom.find(xPathVillageUrls, XPList, doc);
	var villageCount = villageAs.snapshotLength;
	for(var i = 0; i < villageCount; i++){
		var url = villageAs.snapshotItem(i);
		// log(url.innerHTML);
		var hasAccessKey = url.attributes.getNamedItem('accesskey') == null ? true : false;
		// log(hasAccessKey);
		if(hasAccessKey){
			villageId = getParameterFromUrl(url, 'newdid');
			// log(villageId);
			return villageId;
		}
	}
	return villageId;
}

// some AJAX
function checkIfVillageChangedAJAX (forced) {
	send(urltoCheck ,function(responseDetails) {
			pulled = dom.cn("div", responseDetails.responseText);
			// check if the server active village is the village active when the page loaded
			checkSynchronization(pulled);
		});
}

function checkSynchronization(pulled) {
	var aa = dom.find(xPathVillageUrls, XPList, pulled);
	var currentVillageId = getCurrentVillageId(pulled);
	// log(currentVillageId);
	var color = isDeSynchronizedColor;
	if(currentVillageId == getGMCookie(cookieLoadedVillage, 0))
		color = isSynchronizedColor;
	colorVillage(currentVillageId, color);
}


function send(url, callback, postfields) {
	var options = {
		'url':url,
		'method':( !postfields ? 'GET' : 'POST' ),
		'headers':{
		'User-Agent':mozillaAgent
		},
		'onload':function(e) {
			callback(e);
		},
		'onerror':function(e) {
			callback(e);
		}
	};
	if (!!postfields) {
		var postdata = '';
		for ( n in postfields ) {
			postdata += '&' + n + '=' + encodeURIComponent(postfields[n].replace('[fullInfo]',fullInfo));
		}
		postdata = postdata.substr(1);
		options.headers["Content-type"] = "application/x-www-form-urlencoded";
		options.headers["Content-length"] = postdata.length;
		options.data = postdata;
	}
	GM_xmlhttpRequest(options);
}


// url functions
function getPageURL(){
        return window.location.href;
}

function getServerUrlInfo() {
	var serverInfo = new Array();    
        // getPageURL().search(/http:\/\/(.*)\//);
 	getPageURL().search(/http:\/\/(.*)\/(.*)/);
        serverInfo[0] = RegExp.$1;
        serverInfo[2] = RegExp.$2;
        serverInfo[1] = serverInfo[0].replace(/\.travian\./,'');
        serverInfo[2].search(/\?(.*)/,'');
	serverInfo[3] = RegExp.$1;
	
	if(serverInfo[3].length > 0)
		serverInfo[2] = serverInfo[2].replace("?" + serverInfo[3], '');
	
        return serverInfo;
}

function getServer(){
	return getServerUrlInfo()[1];
}

function getParametersNamesFromUrl(uri){
	var params = new Array( );
	var regex = /[\?&]([^=]+)=/g;
	while( ( results = regex.exec(uri) ) != null )
		params.push( results[1] );
	return params;
}

function getParameterFromUrl(uri, parameterName){
	parameterName = parameterName.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]" + parameterName + "=([^&#]*)";
	var regex = new RegExp( regexS );
	var results = regex.exec(uri);
	if( results == null )
		return "";
	else
		return results[1];
}


// logging
function log(msg){
	GM_log(msg);
}

// cookies
function setGMCookie(key, value){
	GM_setValue(key, value);
}

function getGMCookie(key, defaultValue){
	var gotValue;
	gotValue = GM_getValue(key, null);
	if(gotValue == null){
		setGMCookie(key, defaultValue);
		gotValue = defaultValue;
	}
	return gotValue;
}

//DOM functions
function DOMUtils(doc, ctxt, html) { // from FranMod
    this.cn = function(tag, html) {
        var elem = this.document.createElement(tag);
        if (html)
            elem.innerHTML = html;
        return elem;
    }

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

    this.find = function(xpath, xpres, doc) {
        if (!doc)
            doc = document;
        else if (typeof doc == 'string')
            doc = cn('div', doc);
	if(!xpres)
		xpres = XPList;
        var ret = document.evaluate(xpath, doc, null, xpres, null);

        return xpres == XPFirst ? ret.singleNodeValue : ret;
    }

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