Mush Profile Analyser

Analyses the profile of a Mush player

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        Mush Profile Analyser
// @namespace   Mush Profile Analyser
// @description Analyses the profile of a Mush player
// @include     http://mush.twinoid.com/u/profile/*
// @include     http://mush.twinoid.com/me
// @version     1.2.4
// ==/UserScript==

var $ = unsafeWindow.jQuery;

var scriptVersion = '1.2.4';

function addGlobalStyle(string){
        if(/microsoft/i.test(navigator.appName) && 
!/opera/i.test(navigator.userAgent)){
            document.createStyleSheet().cssText=string;
        }
        else {
            var ele=document.createElement('link');
            ele.rel='stylesheet';
            ele.type='text/css';
            ele.href='data:text/css;charset=utf-8,'+escape(string);
            document.getElementsByTagName('head')[0].appendChild(ele);
        }
}

addGlobalStyle('\
div.analyseProfile ul { float: left; background-color: #2E3B92; border-radius: 3px 3px 3px 3px;  border-style: solid; display: inline-block;  margin: 15px 4px; padding: 9px;  } \
div.analyseProfile ul li { font-weight: bold; text-align: center;   } \
');

function charaToClassChar(str)
{
	str = str.toLowerCase();
	str = str.replace(' ', '_');
	
	return str;
}

function Analyse_AddTable(n)
{	
	var infos = Analyse_Analyse(n);
	if(n == 0) { var txtN = 'All flights analysed'; } else { var txtN = n + ' flights analysed'; } 
	
	var tabHtml = '\
		<div id="AnalyseProfile_Result" class="bgtablesummar">\
			<div class="twinstyle"> \
				<h3> \
					<div class="cornerright"> \
						Script "Mush Profile Analyser v' + scriptVersion + ' - ' + txtN + ' - <a style="cursor: pointer;" id="AnalyseProfile_defineN">Edit number</a>" \
					</div> \
				</h3>';
				
		//Infos globales
			//Nbr de parties
			tabHtml += '<div class="analyseProfile">';
			tabHtml += '<div style="float: left; display: inline-block; width: 30px;"> <span style="visibility: hidden;">42</span> </div><ul><li>Flights played : ' + infos['nbrGames'] + '</li> ';
				if(infos['nbrGamesBeta'] > 0)
				{
					tabHtml += '<li><img src="http://mush.vg/img/icons/ui/beta.png" /> Additional Beta flights : ' + infos['nbrGamesBeta'] + '</li>';
				}
				
			//Jours de jeu
			tabHtml += '<br /><li><img src="http://mush.vg/img/icons/ui/calendar.png" / > Days played : ' + infos['totalDay'] + '</li> ';
			tabHtml += '<li><img src="http://mush.vg/img/icons/ui/calendar.png" /> Average life expectancy : <em>' + (infos['totalDay']/infos['nbrGames']).toFixed(2) + '</em></li>';
			
			//Triomphe
			tabHtml += '<br /><li><img src="http://mush.vg/img/icons/ui/triumph.png" / > Total Glory : ' + infos['totalTriumph'] + '</li> ';
			tabHtml += '<li><img src="http://mush.vg/img/icons/ui/triumph.png" /> Average Glory : <em>' + (infos['totalTriumph']/infos['nbrGames']).toFixed(2) + '</em></li></ul>';
		
		//Recherches et Projets
			//Recherches
			tabHtml += '<ul><li><img src="http://mush.vg/img/icons/ui/microsc.png" /> Total Research : ' + infos['totalSearch'] + '</li> ';
			tabHtml += '<li><img src="http://mush.vg/img/icons/ui/research_done.png" /> Average Research : <em>' + (infos['totalSearch']/infos['nbrGames']).toFixed(2) + '</em></li>';

			//Projets
			tabHtml += '<br /><li><img src="http://mush.vg/img/icons/ui/conceptor.png" / > Total Projects : ' + infos['totalProjects'] + '</li> ';
			tabHtml += '<li><img src="http://mush.vg/img/icons/ui/projects_done.png" /> Average Projects : <em>' + (infos['totalProjects']/infos['nbrGames']).toFixed(2) + '</em></li></ul>';
		
		//Scan et explo
			//Recherches
			tabHtml += '<ul><li><img src="http://mush.vg/img/icons/ui/planet.png" /> Total planets : ' + infos['totalPlanetsScan'] + '</li> ';
			tabHtml += '<li><img src="http://mush.vg/img/icons/ui/planet_complete.png" /> Average Planets : <em>' + (infos['totalPlanetsScan']/infos['nbrGames']).toFixed(2) + '</em></li>';

			//Projets
			tabHtml += '<br /><li><img src="http://mush.vg/img/icons/ui/survival.png" / > Total Expos : ' + infos['totalExplo'] + '</li> ';
			tabHtml += '<li><img src="http://mush.vg/img/icons/ui/survival.png" /> Average Expos : <em>' + (infos['totalExplo']/infos['nbrGames']).toFixed(2) + '</em></li></ul>';
			
		
		tabHtml += '<div style="clear: both;"></div> \
		<div style="float: left; display: inline-block; width: 125px;"> <span style="visibility: hidden;">42</span> </div> \
		<table style="display: inline-block; float: left;" class="summar"> \
				<caption>Characters</caption> \
				<tbody> \
					<tr>\
						<th>Character</th> \
						<th>Flights played</th> \
					</tr> ';
					
			for(var c in infos['charaSorted'])
			{
				var l = infos['charaSorted'][c].length;
				for(var k =0; k < l; k++)
				{
					tabHtml += '\
					<tr> \
						<td><img class="char ' + charaToClassChar(infos['charaSorted'][c][k][1]) + '" src="/img/design/pixel.gif"> <span class="charname">' + infos['charaSorted'][c][k][1] + '</span></td> \
						<td>' + infos['charaSorted'][c][k][0] + ' (<em>' + (100*infos['charaSorted'][c][k][0]/infos['nbrGames']).toFixed(2) + '</em>%)</td> \
					</tr>';
				}
			} 
			tabHtml += '\
				</tbody> \
			</table> \
			<table style="display: inline-block; float: left;" class="summar"> \
				<caption>Deaths</caption> \
				<tbody> \
					<tr>\
						<th>Cause of death</th> \
						<th>Number of times</th> \
					</tr> \
				';
			for(var d in infos['deathSorted'])
			{
				var l = infos['deathSorted'][d].length;
				for(var k =0; k < l; k++)
				{
					tabHtml += '\
					<tr> \
						<td>' + infos['deathSorted'][d][k][1] + '</td> \
						<td>' + infos['deathSorted'][d][k][0] + ' (<em>' + (100*infos['deathSorted'][d][k][0]/infos['nbrGames']).toFixed(2) + '</em>%)</td> \
					</tr>';
				}
			}
		tabHtml += '\
				</tbody> \
			</table> \
			<div style="clear: both;"></div> ';
		
	tabHtml += '\
			</div> \
		</div> \
	';
	
	/* tabHtml += '\
	<div class="bgtablesummar">\
		<div class="twinstyle"> \
			<h3> \
				<div class="cornerright"> \
					Script "Mush Analyse Profile v' + scriptVersion + '" \
				</div> \
			</h3>\
			<table class="summar"> \
				<caption>Infos joueurs et vaisseaux</caption> \
				<tbody> \
					<tr>\
						<th>Nombre de parties</th> \
						<th>Jours cumulés</th> \
						<th>Jour moyen</th> \
						<th>Triomphe cumulé</th> \
						<th>Triomphe moyen</th> \
						<th>Recherches cumulées</th> \
						<th>Recherches moyennes</th> \
						<th>Projets cumulés </th> \
						<th>Projets moyens</th> \
					</tr> \
					<tr>';
					if(infos['nbrGamesBeta'] > 0)
					{
						tabHtml += '<td>' + infos['nbrGames'] + ' <br /> + Beta : ' + infos['nbrGamesBeta'] + '</td>';
					}
					else
					{
						tabHtml += '<td>' + infos['nbrGames'] + '</td>';
					}
						tabHtml += '<td>' + infos['totalDay'] + '</td> \
						<td>' + (infos['totalDay']/infos['nbrGames']).toFixed(2) + '</td> \
						<td>' + infos['totalTriumph'] + '</td> \
						<td>' + (infos['totalTriumph']/infos['nbrGames']).toFixed(2) + '</td> \
						<td>' + infos['totalSearch'] + '</td> \
						<td>' + (infos['totalSearch']/infos['nbrGames']).toFixed(2) + '</td> \
						<td>' + infos['totalProjects'] + '</td> \
						<td>' + (infos['totalProjects']/infos['nbrGames']).toFixed(2) + '</td> \
					</tr> \
				</tbody> \
			</table> \
			<br /><br /> \
			<table class="summar"> \
				<caption>Infos joueurs et vaisseaux</caption> \
				<tbody> \
					<tr>\
						<th>Planètes scannées cumulées</th> \
						<th>Planètes scannées moyennes</th> \
						<th>Explorations cumulées</th> \
						<th>Explorations moyennes</th> \
					</tr> \
					<tr> \
						<td>' + infos['totalPlanetsScan'] + '</td> \
						<td>' + (infos['totalPlanetsScan']/infos['nbrGames']).toFixed(2) + '</td> \
						<td>' + infos['totalExplo'] + '</td> \
						<td>' + (infos['totalExplo']/infos['nbrGames']).toFixed(2) + '</td> \
					</tr> \
				</tbody> \
			</table> \
			<br /> \
			<table style="display: inline-block; float: left;" class="summar"> \
				<caption>Personnages</caption> \
				<tbody> \
					<tr>\
						<th>Personnage</th> \
						<th>Parties jouées</th> \
					</tr> \
				';
			for(var c in infos['charaSorted'])
			{
				var l = infos['charaSorted'][c].length;
				for(var k =0; k < l; k++)
				{
					//alert('L : ' + l + ' | K : ' + k + ' | NbrG : ' + infos['charaSorted'][c][k][0] + ' | Chara : ' + infos['charaSorted'][c][k][1]);
					tabHtml += '\
					<tr> \
						<td><img class="char ' + infos['charaSorted'][c][k][1].toLowerCase() + '" src="/img/design/pixel.gif"> <span class="charname">' + infos['charaSorted'][c][k][1] + '</span></td> \
						<td>' + infos['charaSorted'][c][k][0] + ' (<em>' + (100*infos['charaSorted'][c][k][0]/infos['nbrGames']).toFixed(2) + '</em>%)</td> \
					</tr>';
				}
			} 
			tabHtml += '\
				</tbody> \
			</table> \
			<table style="display: inline-block; float: left;" class="summar"> \
				<caption>Morts</caption> \
				<tbody> \
					<tr>\
						<th>Cause de mort</th> \
						<th>Nombre de décès</th> \
					</tr> \
				';
			for(var d in infos['deathSorted'])
			{
				var l = infos['deathSorted'][d].length;
				for(var k =0; k < l; k++)
				{
					tabHtml += '\
					<tr> \
						<td>' + infos['deathSorted'][d][k][1] + '</td> \
						<td>' + infos['deathSorted'][d][k][0] + ' (<em>' + (100*infos['deathSorted'][d][k][0]/infos['nbrGames']).toFixed(2) + '</em>%)</td> \
					</tr>';
				}
			}
	tabHtml += '\
				</tbody> \
			</table> \
			<div style="clear: both;"></div> \
		</div> \
	</div> \
	'; */
	
	$('#profile > div.column2 > div.data > .bgtablesummar:first').after(tabHtml);
	
	$('#AnalyseProfile_defineN').click(function() {
		var n = prompt("Number of flights to analyse (0 = all) ?");
		Analyse_Init(n);
		return false;
	});
}

function Analyse_Analyse(n)
{
	var infos = new Array();
	infos['totalDay'] = 0;
	infos['totalSearch'] = 0;
	infos['totalProjects'] = 0;
	infos['totalPlanetsScan'] = 0;
	infos['totalExplo'] = 0;
	infos['totalTriumph'] = 0;
	infos['allDeaths'] = new Array();
	infos['allCharacters'] = new Array();
	
	infos['nbrGames'] = 0 ; //Nbr de parties
	infos['nbrGamesBeta'] = 0; //Parties en Beta
	
	$('#cdTrips > table.summar > tbody > tr.cdTripEntry').each(function(index,elem){
		//Character, Day, Explo, search, projets, scan, titres, triomphe, mort, vaisseau
		var death = $(this).children('td:eq(8)').text();
		
		if(n == 0 || infos['nbrGames'] < n)
		{
			if(death != 'No medlab available')
			{
				infos['nbrGames']++;
				
				if(infos['allDeaths'][death] > 0)
				{
					infos['allDeaths'][death]++;
				}
				else
				{
					infos['allDeaths'][death] = 1;
				}
				
				var character = $(this).children('td:eq(0)').children('span.charname').text();
				
				if(infos['allCharacters'][character] > 0)
				{
					infos['allCharacters'][character]++;
				}
				else
				{
					infos['allCharacters'][character] = 1;
				}
				
				var d = $(this).children('td:eq(1)').text();
				infos['totalDay'] += parseInt(d);
				
				var e = $(this).children('td:eq(2)').text();
				infos['totalExplo'] += parseInt(e);
				
				var s = $(this).children('td:eq(3)').text();
				infos['totalSearch'] += parseInt(s);
				
				var p = $(this).children('td:eq(4)').text();
				infos['totalProjects'] += parseInt(p);
				
				var sc = $(this).children('td:eq(5)').text();
				infos['totalPlanetsScan'] += parseInt(sc);
				
				var t = $(this).children('td:eq(7)').text();
				infos['totalTriumph'] += parseInt(t);
			}
			else
			{
				infos['nbrGamesBeta']++;
			}
		}
			
	}); 
	
	//Trie morts/persos
	infos['charaSorted'] = new Array();
	for(var c in infos['allCharacters'])
	{
		infos['charaSorted'][infos['allCharacters'][c]] = new Array();
	}
	
	for(var c in infos['allCharacters'])
	{
		infos['charaSorted'][infos['allCharacters'][c]].push(new Array(infos['allCharacters'][c], c));
	}
	
	infos['charaSorted'].sort(function(a,b){return a - b});
	
	infos['deathSorted'] = new Array();
	for(var d in infos['allDeaths'])
	{
		infos['deathSorted'][infos['allDeaths'][d]] = new Array();
	}
	
	for(var d in infos['allDeaths'])
	{
		infos['deathSorted'][infos['allDeaths'][d]].push(new Array(infos['allDeaths'][d], d));
	}
	
	infos['deathSorted'].sort(function(a,b){return a - b});
	
	
	return infos;
}

var TrueStats = function() {
    this.looper();
};

TrueStats.prototype.looper = function(opts) {
    opts = opts || this.opts || {};
    opts.selector = opts.selector || '.tid_goalListWrapper';
    opts.callback = opts.callback || this.init;
    this.opts = opts;
    this.wrapper = document.querySelector(opts.selector);
    if (!this.wrapper) {
        window.setTimeout(this.looper.bind(this), 500);
    }
    else {
        this.opts.callback.call(this);
    }
};

TrueStats.prototype.init = function() {
    var rows = this.wrapper.querySelectorAll('tr');
    this.stats = {};
    this.stats.ian =
	this.stats.gioele =
    this.stats.raluca =
    this.stats.roland =
    this.stats.paola =
    this.stats.stephen =
    this.stats.frieda =
    this.stats.chun =
    this.stats.eleesha =
    this.stats.hua =
    this.stats.finola =
    this.stats.chao =
    this.stats.derek =
    this.stats.andie =
    this.stats.janice =
    this.stats.jinsu =
    this.stats.kuanti =
    this.stats.terrence =
    this.stats.mush = 0;
	this.rowStepper = this.rowStepper.bind(this);
    Array.prototype.forEach.call(rows, this.rowStepper);
    this.injectStats();
};

TrueStats.prototype.rowStepper = function(el) {
    var cells = el.querySelectorAll('td');
    var text = cells[1].textContent.trim();
    var value = parseInt(cells[2].textContent.slice(1), 10);
    switch (text) {
        case 'PILGRED IS BACK!':
            this.bump('pilgred', value);
            break;
        case 'Sol':
            this.bump('sol', value);
            break;
        case 'Day 20 Reached':
            this.bump('day20', value);
            break;
        case 'Day 15 Reached':
            this.bump('day15', value);
            break;
        case 'Day 10 Reached':
            this.bump('day10', value);
            break;
        case 'Day 5 Reached':
            this.bump('day5', value);
            break;
        case 'Eden, the promised land':
            this.bump('eden', value);
            break;
        case 'You have already supported your community by sending a gift to another player, bravo!':
            this.bump('gift', value);
            break;
        case 'Supporter':
            this.bump('supporter', value);
            break;
        case 'Number of cycles spent cultivating psychotropic plants':
            this.bump('ian', Math.floor(value/8));
            break;
        case 'Number of cycles won contemplating your work':
            this.bump('kuanti', Math.floor(value/8));
            break;
        case 'Number of cycles won running round in circles':
            this.bump('roland', Math.floor(value/8));
            break;
        case 'Number of turns spent counting your cash':
            this.bump('gioele', Math.floor(value/8));
            break;
        case 'Number of cycles spent surfing the lowest frequencies':
            this.bump('paola', Math.floor(value/8));
            break;
        case 'Number of cycles won, spent with the others':
            this.bump('hua', Math.floor(value/8));
            break;
        case 'Number of cycles spent stroking your cat':
            this.bump('raluca', Math.floor(value/8));
            break;
        case 'Number of cycles spent honoring the SDF.':
            this.bump('andie', Math.floor(value/8));
            break;
        case 'Number of cycles spent as an intergalactic Don Juan.':
            this.bump('derek', Math.floor(value/8));
            break;
        case 'Number of cycles spent fungifying in a dark corner':
            this.bump('mush', Math.floor(value/8));
            break;
        case 'Number of cycles spent fixing your barnet fair.':
            this.bump('eleesha', Math.floor(value/8));
            break;
        case 'Number of cycles won reading the cards':
            this.bump('frieda', Math.floor(value/8));
            break;
        case 'Number of cycles won... listening to others':
            this.bump('janice', Math.floor(value/8));
            break;
        case "Number of cycles you've spent providing blood samples":
            this.bump('chun', Math.floor(value/8));
            break;
        case 'Number of cycles examining the infinitely small':
            this.bump('finola', Math.floor(value/8));
            break;
        case 'Number of cycles won playing as the chief':
            this.bump('jinsu', Math.floor(value/8));
            break;
        case 'Number of cycles spent taking stuff out':
            this.bump('chao', Math.floor(value/8));
            break;
        case 'Number of cycles spent sulking in a corner.':
            this.bump('terrence', Math.floor(value/8));
            break;
        case 'Number of cycles spent cooking up suspect dishes':
            this.bump('stephen', Math.floor(value/8));
            break;
        case 'Infected':
            this.bump('mushDays', Math.floor(value));
            break;
        case 'Researcher':
            this.bump('research', Math.floor(value));
            break;
        case 'Explorer':
            this.bump('expo', Math.floor(value));
            break;
        case 'Planets Detected':
            this.bump('planet', Math.floor(value));
            break;
        
        default:
            //console.log(text);
            break;
    }
};

TrueStats.prototype.bump = function(stat, num) {
    this.stats[stat] = this.stats[stat] || 0;
    this.stats[stat] += num;
};

TrueStats.prototype.injectStats = function() {
    var results = document.querySelector('.analyseProfile'),
        uls = results.querySelectorAll('ul'),
        daysWrap = uls[0],
        daysPlayed = daysWrap.querySelectorAll('li')[2],
        daysAlive = document.createElement('li'),
        researchWrap = uls[1],
        researchDone = researchWrap.querySelectorAll('li')[1],
        researchPersonally = document.createElement('li'),
        expoWrap = uls[2],
        planetsDone = expoWrap.querySelectorAll('li')[1],
        planetsPersonally = document.createElement('li'),
        expoDone = expoWrap.querySelectorAll('li')[3],
        expoPersonally = document.createElement('li'),
        mushRow = document.createElement('tr'),
        charTable = results.querySelector('table.summar'),
        charRows = charTable.querySelectorAll('tr'),
        totals = this.stats.ian
    		   + this.stats.gioele
    		   + this.stats.raluca
    		   + this.stats.roland
    		   + this.stats.paola
    		   + this.stats.stephen
    		   + this.stats.frieda
    		   + this.stats.chun
    		   + this.stats.eleesha
    		   + this.stats.hua
    		   + this.stats.finola
    		   + this.stats.chao
    		   + this.stats.derek
    		   + this.stats.andie
    		   + this.stats.janice
    		   + this.stats.jinsu
    		   + this.stats.kuanti
    		   + this.stats.terrence;
    daysAlive.innerHTML = '<img src="http://mush.vg/img/icons/ui/calendar.png"> Days alive : ' + totals;
    researchPersonally.innerHTML = '<img src="http://mush.vg/img/icons/ui/research_done.png"> Research finished : ' + (this.stats.research || 0);
    planetsPersonally.innerHTML = '<img src="http://mush.vg/img/icons/ui/planet_complete.png"> Personally detected : ' + (this.stats.planet || 0);
    expoPersonally.innerHTML = '<img src="http://mush.vg/img/icons/ui/survival.png"> Personal expos : ' + (this.stats.expo || 0);
    daysWrap.insertBefore(daysAlive, daysPlayed);
    researchWrap.insertBefore(researchPersonally, researchDone);
    expoWrap.insertBefore(planetsPersonally, planetsDone);
    expoWrap.insertBefore(expoPersonally, expoDone);
    Array.prototype.forEach.call(charRows, this.injectStepper.bind(this));
    mushRow.innerHTML = '<td><img class="char mush" src="/img/design/pixel.gif"><span class="charname">Mush</span></td><td>' + this.stats.mushDays + '</td><td>' + this.stats.mush + '</td>';
    charTable.appendChild(mushRow);
};

TrueStats.prototype.injectStepper = function(el, i) {
    var inject = document.createElement('td'),
        charName;
    if (i === 0) {
        inject = document.createElement('th');
        inject.innerText = 'Days alive';
    }
    else {
        charName = el.querySelector('.charname').textContent.toLowerCase().split(' ').join('');
        inject.textContent = this.stats[charName]; 
    }
    el.appendChild(inject);
}

function Analyse_Init(n)
{
	if(n < 0) { n = 0; }
	
	$('#AnalyseProfile_Result').remove();
	
	Analyse_AddTable(n);
	//alert('Test');
    var trueStats = new TrueStats();
}

Analyse_Init(0);