BvS Data Analyser

Collect information from miscellaneous pages and send it to a remote server for further statistics

// ==UserScript==
// @name           BvS Data Analyser
// @namespace      TheSpy
// @description    Collect information from miscellaneous pages and send it to a remote server for further statistics
// @include        http*://*animecubed.com/billy/bvs/playerstandings.html
// @include        http*://*animecubed.com/billy/bvs/playerstandings.html?rankid=*
// @include        http*://*animecubed.com/billy/bvs/playerstandings.html?rankname=*
// @include        http*://*animecubed.com/billy/bvs/vlookup.html
// @include        http*://*animecubed.com/billy/bvs/vlookup.html?village=*
// @include        http*://*animecubed.com/billy/bvs/lookup.html
// @include        http*://*animecubed.com/billy/bvs/lookup.html?player=*
// @include        http*://*animecubed.com/billy/bvs/arena.html
// @include        http*://*animecubed.com/billy/bvs/bingofight.html
// @include        http*://*animecubed.com/billy/
// @include        http*://*animecubedgaming.com/billy/bvs/playerstandings.html
// @include        http*://*animecubedgaming.com/billy/bvs/playerstandings.html?rankid=*
// @include        http*://*animecubedgaming.com/billy/bvs/playerstandings.html?rankname=*
// @include        http*://*animecubedgaming.com/billy/bvs/vlookup.html
// @include        http*://*animecubedgaming.com/billy/bvs/vlookup.html?village=*
// @include        http*://*animecubedgaming.com/billy/bvs/lookup.html
// @include        http*://*animecubedgaming.com/billy/bvs/lookup.html?player=*
// @include        http*://*animecubedgaming.com/billy/bvs/arena.html
// @include        http*://*animecubedgaming.com/billy/bvs/bingofight.html
// @include        http*://*animecubedgaming.com/billy/
// @version	   1.12
// @history        1.12 New domain - animecubedgaming.com - Channel28
// @history        1.11 Now https compatible (Updated by Channel28)
// @history        1.10 Added grant permissions (Updated by Channel28)
// @history        1.09 Fixed: top item count
// @history        1.08 Fixed: searching for a player threw an error
// @history        1.07 Fixed: sponsor awesome is now subtracted from total awesome
// @history        1.06 Fixed: asterisk on ranking broke the script (winsock)
// @history        1.05 Fixed: version string
// @history        1.04 Added: Protagonist rank (winsock)
// @history        1.03 Fixed: a DOM issue (temporary fix)
// @history        1.02 Added: this hour's top item count
// @history        1.02 Changed: exception handling
// @history        1.01 Fixed: A few bugs
// @history        1.00 Initial release
// @licence        MIT; http://www.opensource.org/licenses/mit-license.php
// @copyright      2011-2012, TheSpy
// @grant          GM_addStyle
// @grant          GM_xmlhttpRequest
// ==/UserScript==


/***************************************************************
* DOM Storage Wrapper Class
* 
* Public members:
*     ctor({"session"|"local"}[, <namespace>])
*     setItem(<key>, <value>)
*     getItem(<key>, <default value>)
*     removeItem(<key>)
*     keys()
***************************************************************/
function Storage(type, namespace) {
	var object = this;

	if(typeof(type) != "string")
		type = "session";

	switch(type) {
		case "local": {
			object.storage = localStorage;
		} break;

		case "session": {
			object.storage = sessionStorage;
		} break;

		default: {
			object.storage = sessionStorage;
		} break;
	}

	if (!namespace || (typeof(namespace) != "string" && typeof(namespace) != "number"))
		namespace = "ScriptStorage";

	object.namespace = [namespace, "."].join("");

	object.setItem = function(key, value) {
		try {
			object.storage.setItem(escape([object.namespace, key].join("")), uneval(value));
		}
		catch(e) {
		}
	}

	object.getItem = function(key, defaultValue) {
		try {
			var value = object.storage.getItem(escape([object.namespace, key].join("")));
			if(value)
				return eval(value);
			else
				return defaultValue;
		}
		catch(e) {
			return defaultValue;
		}
	}

	object.removeItem = function(key) {
		try {
			object.storage.removeItem(escape([object.namespace, key].join("")));
		}
		catch(e) {
		}
	}

	object.keys = function() {
		var array = [];
		var i = 0;
		do {
			try {
				var key = unescape(object.storage.key(i++));
				if(key.indexOf(object.namespace) == 0 && object.storage.getItem(key))
					array.push(key.slice(object.namespace.length));
			}
			catch(e) {
				break;
			}
		} while(true);
		return array;
	}
}

// UI (credits: http://userscripts.org/users/dtkarlsson)
function Window(id, storage) {
	var my = this;
	my.id = id;
	my.offsetX = 0;
	my.offsetY = 0;
	my.moving = false;
	my.element = document.createElement("div");
	my.elementContainer = document.createElement("div");

	// Window dragging events
	my.drag = function(event) {
		if (my.moving) {
			my.elementContainer.style.left = (event.clientX - my.offsetX)+'px';
			my.elementContainer.style.top = (event.clientY - my.offsetY)+'px';
			event.preventDefault();
		}
	}
	my.stopDrag = function(event) {
		if (my.moving) {
			my.moving = false;
			var x = parseInt(my.elementContainer.style.left);
			var y = parseInt(my.elementContainer.style.top);
			if(x < 0) x = 0;
			if(y < 0) y = 0;
			storage.setItem(my.id + ".coord.x", x);
			storage.setItem(my.id + ".coord.y", y);
			my.elementContainer.style.opacity = 1;
			my.elementContainer.removeEventListener('mouseup', my.stopDrag, true);
			my.elementContainer.removeEventListener('mousemove', my.drag, true);
		}
	}
	my.startDrag = function(event) {
		if (event.button != 0) {
			my.moving = false;
			return;
		}
		my.offsetX = event.clientX - parseInt(my.elementContainer.style.left);
		my.offsetY = event.clientY - parseInt(my.elementContainer.style.top);
		my.moving = true;
		my.elementContainer.style.opacity = 0.75;
		event.preventDefault();
		my.elementContainer.addEventListener('mouseup', my.stopDrag, true);
		my.elementContainer.addEventListener('mousemove', my.drag, true);
	}

	my.elementContainer.id = id;
	my.elementContainer.className = "drag";
	document.body.appendChild(my.elementContainer);
	my.elementContainer.appendChild(my.element);
	my.elementContainer.addEventListener('mousedown', my.startDrag, true);

	if (storage.getItem(my.id + ".coord.x"))
		my.elementContainer.style.left = storage.getItem(my.id + ".coord.x") + "px";
	else
		my.elementContainer.style.left = "6px";
	if (storage.getItem(my.id + ".coord.y"))
		my.elementContainer.style.top = storage.getItem(my.id + ".coord.y") + "px";
	else
		my.elementContainer.style.top = "6px";
}

function FloatingAnalyser() {
	var my = this;
	my.window = new Window("BvSDataAnalyser", analyserSettings);
	GM_addStyle("#BvSDataAnalyser {border: 2px solid #00FF00; position: fixed; z-index: 100; font-size: 12px; font-family: courier new; color: #00FF00; background-color: black; padding: 6px; text-align: left; min-height: 16px; cursor: move;} #BvSDataAnalyser div div {border: 2px solid #00FF00; margin-top: 6px;}");

	my.addText = function(text) {
		if(my.window.element.innerHTML.length > 0)
			my.window.element.innerHTML = [my.window.element.innerHTML, text].join("<br/>");
		else
			my.window.element.innerHTML = text;
	}

	my.setText = function(text) {
		my.window.element.innerHTML = text;
	}
}

var analyserSettings = new Storage("local", "BvSDataAnalyser");
var analyserWindow = new FloatingAnalyser();
analyserWindow.setText("<blink>Loading...</blink>");

// StripString(string)
function StripString(string) {
	string = string.replace(/^\s+/g, "");
	string = string.replace(/\s+$/g, "");
	string = string.replace(/\s+/g, " ");
	return string;
}

// QueryServer(arguments)
function QueryServer(arguments) {
	try {
		arguments = [arguments, "version=1.03"].join("&");
		GM_xmlhttpRequest({
			method: "POST",
			url: "http://bvs.ecansol.com/analyser/",
			headers: {
				"User-Agent": "Mozilla/5.0",
				"Accept": "text/xml",
				"Content-type": "application/x-www-form-urlencoded"
			},
			data: encodeURI(arguments),
			onerror: function(response) {
				analyserWindow.setText(["<b>Error:</b> ", response.status].join(""));
			},
			onload: function(response) {
				try {
					analyserWindow.setText(response.responseText);
				}
				catch(e) {
					throw ["QueryServer(arguments)|sub: ", e].join("");
				}
			}
		});
	}
	catch(e) {
		throw ["QueryServer(arguments): ", e].join("");
	}
}

// AwesomeAnalyser()
function AwesomeAnalyser() {
	try {
		var arguments = new Array();
		var players = new Array();
		var player;
		var deleted = true;
		var regexp = location.href.match(/playerstandings.html.rankname=(.*)$/i);
		if(regexp && regexp[1]) {
			player = decodeURI(regexp[1]).replace(/_/g, " ");
		}
		var snap = document.evaluate("//font/table[contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'ffffff')]/tbody/tr[position() > 1]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		for(var i = 0; i < snap.snapshotLength; i++) {
			try {
				var regexp = StripString(snap.snapshotItem(i).textContent.replace(/,/gi, "")).match(/^(\d+).\s([a-z0-9 ]{3,10})(\*?)\s(\d+)\s\d+\s\d+$/i);
				if(regexp) {
					players.push(["players[", regexp[2], "]=", regexp[3] == "*" ? regexp[4] - 11 : regexp[4]].join(""));
					if(regexp[2].toLowerCase() == player.toLowerCase()) {
						deleted = false;
					}
				}
			}
			catch(e) {
			}
		}
		if(players.length > 0) {
			arguments.push(players.join("&"));
		}
		else if(player) {
			arguments.push(["idle=", player].join(""));
		}
		if(deleted == true) {
			arguments.push(["deleted=", player].join(""));
		}
		arguments.push("page=playerstandings");
		QueryServer(arguments.join("&"));
	}
	catch(e) {
		throw ["AwesomeAnalyser(): ", e].join("");
	}
}

// VillageAnalyser()
function VillageAnalyser() {
	try {
		var arguments = new Array();
		var players = new Array();
		var village;
		var regexp = location.href.match(/vlookup.html.village=(.*)$/i);
		if(regexp && regexp[1]) {
			village = decodeURI(regexp[1]).replace(/_/g, " ");
		}
		var snap = document.evaluate("//b[contains(text(), 'Village') and contains(../text(), 'Village Hidden')]/..", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		if(snap.snapshotLength == 1) {
			try {
				var regexp = StripString(snap.snapshotItem(0).textContent.replace(/,/gi, "")).match(/^([a-z0-9 ]{3,10}) Village-The Village Hidden in ([a-z0-9 ]{3,15}) -/i);
				if(regexp) {
					arguments.push(["village=", regexp[1]].join(""));
					arguments.push(["description=", regexp[2]].join(""));
				}
			}
			catch(e) {
			}
		}
		else if(village) {
			arguments.push(["deleted=", village].join(""));
		}
		var snap = document.evaluate("//a[contains(@href, 'lookup.html')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		for(var i = 0; i < snap.snapshotLength; i++) {
			try {
				players.push(["players[]=", StripString(snap.snapshotItem(i).textContent)].join(""));
			}
			catch(e) {
			}
		}
		var snap = document.evaluate("//b[contains(../text(), 'Number of Upgrades')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		if(snap.snapshotLength == 1) {
			try {
				arguments.push(["upgrades=", StripString(snap.snapshotItem(0).textContent)].join(""));
			}
			catch(e) {
			}
		}
		if(players.length > 0) {
			arguments.push(players.join("&"));
		}
		arguments.push("page=vlookup");
		QueryServer(arguments.join("&"));
	}
	catch(e) {
		throw ["VillageAnalyser(): ", e].join("");
	}
}

// PlayerAnalyser()
function PlayerAnalyser() {
	try {
		var arguments = new Array();
		var stringArray = new Array();
		var player;
		var regexp = location.href.match(/lookup.html.player=(.*)$/i);
		if(regexp && regexp[1]) {
			player = decodeURI(regexp[1]).replace(/_/g, " ");
		}
		var snap = document.evaluate("//center/table/tbody/tr[2]/td/font/table//text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		for(var i = 0; i < snap.snapshotLength; i++) {
			try {
				if(snap.snapshotItem(i).nodeValue.length > 0)
					stringArray.push(snap.snapshotItem(i).nodeValue);
			}
			catch(e) {
			}
		}
		if(stringArray.length > 0) {
			var string = StripString(stringArray.join(" ")).replace(/,/gi, "");
			if(/The slightest thought of them has you quaking in fear!/.test(string)) {
				if(!player) {
					player = document.evaluate("//center/i/b/font/text()", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue.nodeValue.replace(/,/gi, "");
				}
				arguments.push(["player=", player].join(""));
				var match = null;
				if(match = string.match(new RegExp(["The (\\d+).. Immortal Kaiju ", player, " (.*) Village - The Village Hidden in (.*) - "].join(""), "i"))) {
					arguments.push(["kaiju=", match[1]].join(""));
					arguments.push(["village=", match[2]].join(""));
					arguments.push(["description=", match[3]].join(""));
				}
				else if(match = string.match(new RegExp(["The (\\d+).. Immortal Kaiju ", player, " No Village "].join(""), "i"))) {
					arguments.push(["kaiju=", match[1]].join(""));
				}

				if(match = string.match(/Permanent Items: (\d+)/i))
					arguments.push(["permanent=", match[1]].join(""));
				if(match = string.match(/Trophies: (\d+)/i))
					arguments.push(["trophies=", match[1]].join(""));
				if(match = string.match(/Season (\d+)/i))
					arguments.push(["season=", match[1]].join(""));
				if(match = string.match(/Player Ranking: Idle/i))
					arguments.push("idle=1");
				if(match = string.match(/Students: (\d+)/i))
					arguments.push(["students=", match[1]].join(""));
			}
			else {
				arguments.push("kaiju=0");
				if(!player) {
					player = document.evaluate("//td[contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'04470a')]/font[contains(translate(@color, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'ffffff')]/b/text()", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue.nodeValue.replace(/,/gi, "");
				}
				arguments.push(["player=", player].join(""));
				var ranks = new Array("Genin", "Chunin", "Special Jonin \\(Genjutsu\\)", "Special Jonin \\(Ninjutsu\\)", "Special Jonin \\(Taijutsu\\)", "Jonin", "Sannin", "R00t", "Protagonist");
				var match = null;
				for(var i = 0; i < ranks.length; i++) {
					if(match = string.match(new RegExp(["Level: (\\d+) - ", ranks[i], " (.*) Village - The Village Hidden in (.*) - "].join(""), "i"))) {
						arguments.push(["level=", match[1]].join(""));
						arguments.push(["village=", match[2]].join(""));
						arguments.push(["description=", match[3]].join(""));
						arguments.push(["rank=", ranks[i]].join(""));
						break;
					}
					else if(match = string.match(new RegExp(["Level: (\\d+) - ", ranks[i], " No Village "].join(""), "i"))) {
						arguments.push(["level=", match[1]].join(""));
						arguments.push(["rank=", ranks[i]].join(""));
						break;
					}
				}

				if(match = string.match(/Permanent Items: (\d+)/i))
					arguments.push(["permanent=", match[1]].join(""));
				if(match = string.match(/Trophies: (\d+)/i))
					arguments.push(["trophies=", match[1]].join(""));
				if(match = string.match(/Season (\d+)!/i))
					arguments.push(["season=", match[1]].join(""));
				if(match = string.match(/Player Ranking: Idle/i))
					arguments.push("idle=1");
				if(match = string.match(/Students: (\d+)/i))
					arguments.push(["students=", match[1]].join(""));
				if(match = string.match(/Genjutsu: (\d+)/i))
					arguments.push(["gen=", match[1]].join(""));
				if(match = string.match(/Ninjutsu: (\d+)/i))
					arguments.push(["nin=", match[1]].join(""));
				if(match = string.match(/Taijutsu: (\d+)/i))
					arguments.push(["tai=", match[1]].join(""));
				if(match = string.match(/Doujutsu: (\d+)/i))
					arguments.push(["dou=", match[1]].join(""));

				var snap = document.evaluate("//td[contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'008010') or contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'006000')]/text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
				for(var i = 0; i < snap.snapshotLength; i++) {
					try {
						if(snap.snapshotItem(i).nodeValue.length > 0)
							if(match = StripString(snap.snapshotItem(i).nodeValue).match(/^([A-Za-z]+): (\d)$/i))
								arguments.push(["zombja[", match[1], "]=", match[2]].join(""));
					}
					catch(e) {
					}
				}

				var snap = document.evaluate("//td[contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'c0efc5') or contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'dcf8db')]/text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
				for(var i = 0; i < snap.snapshotLength; i++) {
					try {
						if(snap.snapshotItem(i).nodeValue.length > 0)
							if(match = StripString(snap.snapshotItem(i).nodeValue).match(/^([A-Za-z0-9 ]+) Missions: (\d+)$/i))
								arguments.push(["mission[", match[1], "]=", match[2]].join(""));
					}
					catch(e) {
					}
				}
			}
		}
		else if(player && player.length > 0 && /\/billy\/layout\//.test(document.body.innerHTML))
			arguments.push(["deleted=", player].join(""));
		else
			analyserWindow.setText("Can't detect player's name.");

		arguments.push("page=playerinfo");
		if(player && player.length > 0)
			QueryServer(arguments.join("&"));
	}
	catch(e) {
		throw ["PlayerAnalyser(): ", e].join("");
	}
}

// ArenaAnalyser()
function ArenaAnalyser() {
	try {
		var arguments = new Array();
		var stringArray = null;
		var string = null;
		var player = null;
		var snap = document.evaluate("//td[./table/tbody/tr/td/img[@src='/billy/layout/blank.gif']]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		for(var i = 0; i < snap.snapshotLength; i++) {
			try {
				stringArray = new Array();
				var snapPlayer = document.evaluate(".//text()", snap.snapshotItem(i), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
				for(var j = 0; j < snapPlayer.snapshotLength; j++) {
					try {
						if(snapPlayer.snapshotItem(j).nodeValue.length > 0)
							stringArray.push(snapPlayer.snapshotItem(j).nodeValue);
					}
					catch(e) {
					}
				}
				string = StripString(stringArray.join(" ")).replace(/,/gi, "");
				var ranks = new Array("Genin", "Chunin", "Sp. Jonin \\(Gen\\)", "Sp. Jonin \\(Nin\\)", "Sp. Jonin \\(Tai\\)", "Jonin", "Sannin", "R00t", "Protagonist");
				var match = null;
				for(var k = 0; k < ranks.length; k++) {
					if(match = string.match(new RegExp(["^(.{3,10}) (BillyClub! )?(Attunement: [^ ]+ Moon ([^ ]+ )?)?Season (\\d+)! Level (\\d+) : ", ranks[k], " (.{1,30}) Village"].join(""), "i"))) {
						player = match[1];
						arguments.push(["player[", player, "][bc]=", match[2] ? 1 : 0].join(""));
						arguments.push(["player[", player, "][season]=", match[5] ? match[5] : 1].join(""));
						arguments.push(["player[", player, "][level]=", match[6]].join(""));
						arguments.push(["player[", player, "][rank]=", ranks[k]].join(""));
						arguments.push(["player[", player, "][village]=", match[7]].join(""));
						break;
					}
					else if(match = string.match(new RegExp(["^(.{3,10}) (BillyClub! )?(Attunement: [^ ]+ Moon ([^ ]+ )?)?Season (\\d+)! Level (\\d+) : ", ranks[k], " Rogue Ninja"].join(""), "i"))) {
						player = match[1];
						arguments.push(["player[", player, "][bc]=", match[2] ? 1 : 0].join(""));
						arguments.push(["player[", player, "][season]=", match[5] ? match[5] : 1].join(""));
						arguments.push(["player[", player, "][level]=", match[6]].join(""));
						arguments.push(["player[", player, "][rank]=", ranks[k]].join(""));
						break;
					}
				}

				if(player) {
					if(match = string.match(/Genjutsu: (\d+)/i))
						arguments.push(["player[", player, "][gen]=", match[1]].join(""));
					if(match = string.match(/Ninjutsu: (\d+)/i))
						arguments.push(["player[", player, "][nin]=", match[1]].join(""));
					if(match = string.match(/Taijutsu: (\d+)/i))
						arguments.push(["player[", player, "][tai]=", match[1]].join(""));
					if(match = string.match(/Doujutsu: (\d+)/i))
						arguments.push(["player[", player, "][dou]=", match[1]].join(""));
					if(match = string.match(/Ryo: (\d+)/i))
						arguments.push(["player[", player, "][ryo]=", match[1]].join(""));

					var snapItems = document.evaluate(".//td/span/text()", snap.snapshotItem(i), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
					for(var j = 0; j < snapItems.snapshotLength; j++) {
						arguments.push(["player[", player, "][items][]=", snapItems.snapshotItem(j).nodeValue.replace(/,/gi, "")].join(""));
					}
				}
			}
			catch(e) {
				throw ["ArenaAnalyser()|sub: ", e].join("");
			}
		}
		arguments.push("page=arena");
		QueryServer(arguments.join("&"));
	}
	catch(e) {
		throw ["ArenaAnalyser(): ", e].join("");
	}
}

// TopItemAnalyser()
function TopItemAnalyser() {
	try {
		var arguments = new Array();
		var snap = document.evaluate("//table[contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'e7cea9')]/tbody/tr/td/b/font/i/text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		if(snap.snapshotLength == 1) {
			arguments.push(["item=", StripString(snap.snapshotItem(0).nodeValue)].join(""));

			var snapItems = document.evaluate("//table[contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'e7cea9') and contains(., 'Item Count')]/tbody/tr[position()>1]/td[1]/a/text() | //table[contains(translate(@bgcolor, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'e7cea9') and contains(., 'Item Count')]/tbody/tr[position()>1]/td[2]/text()", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			if(snapItems.snapshotLength == 20 || snapItems.snapshotLength == 22) {
				for(var i = 0; i < snapItems.snapshotLength; i += 2) {
					arguments.push(["itemcount[", StripString(snapItems.snapshotItem(i).nodeValue.replace(/\d+\. /i, "")), "]=", parseInt(snapItems.snapshotItem(i + 1).nodeValue)].join(""));
				}
			}
		}
		arguments.push("page=main");
		QueryServer(arguments.join("&"));
	}
	catch(e) {
		throw ["TopItemAnalyser(): ", e].join("");
	}
}

try {
	if(/animecubed.com.billy.bvs.playerstandings.html/i.test(location.href)) {
		var awesomeAnalyser = new AwesomeAnalyser();
	}

	if(/animecubed.com.billy.bvs.vlookup.html/i.test(location.href)) {
		var villageAnalyser = new VillageAnalyser();
	}

	if(/animecubed.com.billy.bvs.lookup.html/i.test(location.href)) {
		var playerAnalyser = new PlayerAnalyser();
	}

	if(/animecubed.com.billy.bvs.arena.html/i.test(location.href) || /animecubed.com.billy.bvs.bingofight.html/i.test(location.href)) {
		var arenaAnalyser = new ArenaAnalyser();
	}

	if(/animecubed.com.billy.$/i.test(location.href)) {
		var topItemAnalyser = new TopItemAnalyser();
	}
}
catch(e) {
	analyserWindow.setText(["<b>Caught exception:</b> ", e].join(""));
}