summaryrefslogblamecommitdiffstats
path: root/uftow-stats.user.js
blob: cf48162692db3ac86eb298e0929411df01b270ed (plain) (tree)
1
2
3
4
5
6
7
8
9


                           
                                                                  
                     

                                               

                                   
                                     





                                              
                                 
                                                          

                                                                





















                                                                                                       
                         
                        
                    
                         
                                                                                     

                                                                                                                                                               

                                                      
                                                
                      
                                                
                 






                                                                                                                     
          
                                         
                               
                                                             
                             

                                                                                               


                                                                       
                                                                          
                                                        
                                                         
                                                                                                               






                                                         
                                               

                                      
                                                                                           
                 
                            





                                                                                                                             
                                                                                                                    




















                                                                                                                                   











                                                                                                                       




















                                                                                                                                                               
                         

                                                     
                                                                                              











                                                                                                                            
                              


                                                                             
                         







                                                                                          


                                                                                                       
                                                  
                                                        

                                                                                       
                         
                 

                                                                                             




                                                               
                                 

                               


















                                                                                                                



                                                                                                                                                   
                                                          
                                                                                        







                                                              






                                                                                       
                                     


                                  









                                                                                      

                                                        

                                                        
                 


                                                                    
                                                 
                                           

                                     













                                                              
                                          


                              
                                                                         
                                                                  

                                                                    
                                                  
                                                                

                                                                       
                                                          

                                                  
          


                                                        

                                     









                                                                            
          


                                        
                                      
                                     
                                 


                                                         
                 


         
                
// ==UserScript==
// @name        uftow-stats
// @namespace   uftow-stats
// @include     https://ubuntuforums.org/showthread.php?t=1579442*
// @version     1.4.0
// @Description Generates stats for Tug of War.
// @grant		GM_log
// @grant		GM_getValue
// @grant		GM_setValue
// @grant		GM_listValues
// @grant		GM_deleteValue
// @grant		GM_registerMenuCommand
// ==/UserScript==

var towConfig = {
	multipliers:new Array(
		//Forum Moderator
		'images/rank_uf_moderator_2013-07.png',-2,
		//Forum Super Moderator
		'images/rank_uf_super_moderator_2014_12.png',-3,
		//Forum Admin
		'images/rank_uf_admin_2013-07.png',-4,
		//LoCo mods
		'font-weight: bold; color: #339900;',2,
		//Ubuntu Member
		'images/rank_ubuntumember_2013-02.png',2,
		//Kubuntu Member - unchanged (2013.02.17)
		'images/rebrand/ranks/rankkubuntumember.png',2,
		//Staff Emeritus
		'images/rank_oldstaff_2013-02.png',3,
		//Forum Donators - unchanged (2013.02.13)
		'images/rank_forum_donators.png',4,
		//Ubuntu Developers - unchanged (2013.02.13)
		'images/rank_ubuntudeveloper.png',4,
		//Ubuntu One Developers - Unable to verify whether or not this has changed (2013.02.13)
		'http://kryogenix.org/random/u1-forums-rank-logo.png',4
	)
};
var towStats = {
	alreadyHasStartCounting:false,
	scores:new Array(),
	currentScore:0,
	lastPostNumber:0,
	lastPoster:null,
	winner:null,
	init: function(){
		this.postContainers=document.getElementsByClassName('postcontainer');
		this.firstPostNumber=parseInt(this.postContainers[0].getElementsByClassName('postcounter')[0].textContent.substr(1));
		this.lastPostNumber=parseInt(this.postContainers[this.postContainers.length-1].getElementsByClassName('postcounter')[0].textContent.substr(1));
		this.currentScore=0;
		if(!GM_getValue("statsActive",false)){
			this.addStartCounting();
		}else{
			this.continueCounting();
		}
		GM_registerMenuCommand("Tug of War: Clear counter",function(){towStats.clearStats();},'A');
	},
	addStartCounting: function(){
		GM_registerMenuCommand("Tug of War: Start counting",function(){towStats.startCounting();},'S');
		GM_registerMenuCommand("Tug of War: Continue counting",function(){towStats.continueCounting();},'C');
		GM_registerMenuCommand("Tug of War: Show last results",function(){towStats.showSummary();},'R');
		this.alreadyHasStartCounting=true;
	},
	recordPosts: function(startPost){
		var postNumber;
		var startDiff=startPost-this.firstPostNumber;
		var postInfo;
		if(startDiff<0 || startPost>this.firstPostNumber+this.postContainers.length-1){
			alert("Post #"+startPost+" is not on this page.");
			return false;
		}
		for (var i=startDiff;i<this.postContainers.length;i++){
			postInfo=this.getPostInfo(this.postContainers[i]);
			this.lastPostNumber=postInfo[3];
			if(this.lastPoster==postInfo[0]){
				//GM_log("Post #"+this.lastPostNumber+" is a duplicate and has been skipped.");
				continue;
			}
			this.scorePost(postInfo);
			if(this.currentScore<=-200){
				this.winner='mods';
			}else if(this.currentScore>=200){
				this.winner='community';
			}if(this.winner!=null){
				break;
			}
			//GM_log("Post: "+postInfo[3]+", Round score: "+this.currentScore);
		}
		return true;
	},
	getPostInfo: function(postElement){
		var userSpanTag=postElement.getElementsByClassName('username')[0].getElementsByTagName('span')[0];
		var userName=userSpanTag.textContent;
		var css=userSpanTag.getAttribute('style');
		var rankURL=postElement.getElementsByClassName('rank')[0].getElementsByTagName('img')[0].getAttribute('src');
		var postNumber=parseInt(postElement.getElementsByClassName('postcounter')[0].textContent.substr(1));
		return new Array(userName,css,rankURL,postNumber);
	},
	scorePost: function(postInfo){
		this.lastPoster=postInfo[0];
		var groupImgIndex=towConfig.multipliers.indexOf(postInfo[2]);
		if(groupImgIndex==-1){
			groupImgIndex=towConfig.multipliers.indexOf(postInfo[1]);
		}
		multiplier=(groupImgIndex==-1)?1:towConfig.multipliers[groupImgIndex+1];
		this.currentScore+=multiplier;
		userIndex=this.scores.indexOf(postInfo[0]);
		//The second check in the if statement makes sure users with usernames being actual numbers don't break this script
		if(userIndex!=-1&&userIndex%3==0){
			this.scores[userIndex+2]++;
		}else{
			this.scores.push(postInfo[0]);
			this.scores.push(multiplier);
			this.scores.push(1);
		}
	},
	getSummary: function(){
		if(this.winner!=null){
			window.alert("Counting complete.\n"+
				"The "+((this.currentScore<0)?'-':'')+"200 mark is at post #"+this.lastPostNumber+"\n"+
				"Stats will be displayed in the next dialog box.");
		}else if(this.scores.length>=3){
			window.alert("Tug of War is yet to be completed.\n"+
				"Its score is "+this.currentScore+" points as of post #"+this.lastPostNumber+"\n"+
				"Intermediate stats will be displayed in the next dialog box.");
		}else{
			window.alert("Tug of War is yet to be completed.");
			return false;
		}
		var alertText="[B]TUG OF WAR LAST ROUND STATS[/B]\n";
		var totalPoints=0;
		var totalPosts=0;
		var totalModPoints=0;
		var totalModPosts=0;
		var totalCommunityPoints=0;
		var totalCommunityPosts=0;
		var totalWinningPoints=0;
		var minimumRequiredMVP;
		var mvpList=new Array();
		var communityParticipants=new Array();
		var modParticipants=new Array();
		for(var i=1;i<this.scores.length;i+=3){
			//GM_log("STATS: User: "+this.scores[i-1]+", Multiplier: "+this.scores[i]+", Points: "+this.scores[i+1]+", Is Mod: "+this.scores[i+2]);
			totalPoints+=(this.scores[i+1]*(Math.abs(this.scores[i])));
			if(this.scores[i]<0){
				totalModPoints+=this.scores[i+1]*(Math.abs(this.scores[i]));
				totalModPosts+=this.scores[i+1];
			}else if(this.scores[i]>0){
				totalCommunityPoints+=this.scores[i+1]*this.scores[i];
				totalCommunityPosts+=this.scores[i+1];
			}
			totalPosts+=this.scores[i+1];
		}
		totalWinningPoints=(this.currentScore>=0)?totalCommunityPoints:totalModPoints;
		minimumRequiredMVP=Math.round(totalWinningPoints*0.15);
		alertText+="[B]Total points:[/B] "+totalPoints+" from "+totalPosts+" posts\n";
		alertText+="[B]Total community points:[/B] ";
		alertText+=((totalCommunityPosts>0)?totalCommunityPoints+" from "+totalCommunityPosts+" posts":"None")+"\n";
		alertText+="[B]Total mod points:[/B] ";
		alertText+=((totalModPosts>0)?totalModPoints+" from "+totalModPosts+" posts":"None")+"\n";
		alertText+="[B]Minimum required for MVP* ("+totalWinningPoints+" x 0.15):[/B] "+minimumRequiredMVP+"\n\n";
		for(var i=0;i<this.scores.length;i+=3){
			if(this.scores[i+1]<0){
				modParticipants.push(this.scores[i]);
				modParticipants.push(Math.abs(this.scores[i+1]));
				modParticipants.push(this.scores[i+2]);
			}else{
				communityParticipants.push(this.scores[i]);
				communityParticipants.push(this.scores[i+1]);
				communityParticipants.push(this.scores[i+2]);
			}
		}
		alertText+="[B]COMMUNITY PARTICIPANTS[/B]\n";
		communityStats=this.getListText(communityParticipants,minimumRequiredMVP);
		alertText+=communityStats[0]+"\n";
		alertText+="[B]MODERATOR PARTICIPANTS[/B]\n";
		modStats=this.getListText(modParticipants,minimumRequiredMVP);
		alertText+=modStats[0]+"\n";
		alertText+="[B]LAST ROUND MVPs[/B]\n";
		alertText+="- "+this.lastPoster+" (at post #"+this.lastPostNumber+")\n";
		//GM_log("MVP order: "+this.lastPoster+" made the mark at post #"+this.lastPostNumber);
		mvpList=(this.currentScore>=0)?communityStats[1]:modStats[1];
		for(var i=0;i<mvpList.length;i++){
			if(mvpList[i]!=this.lastPoster){
				alertText+="- "+mvpList[i]+"\n";
				//GM_log("MVP order: "+mvpList[i]+" has spot #"+(i+2));
			}
		}
		alertText+="\n*Starting with second place. The marker gets first place MVP.";
		window.alert(alertText);
	},
	getListText: function(participants,minimumRequiredMVP){
		var statsText="";
		var thisScore;
		var mvpList=new Array();
		var reCheck=true;
		var tempSpot;
		while(reCheck){
			reCheck=false;
			for(var i=0;i<participants.length;i+=3){
				if(i+3>=participants.length){
					break;
				}
				if(participants[i+2]*participants[i+1]<participants[i+5]*participants[i+4]){
					tempSpot=new Array(participants[i],participants[i+1],participants[i+2]);
					participants[i]=participants[i+3];
					participants[i+1]=participants[i+4];
					participants[i+2]=participants[i+5];
					participants[i+3]=tempSpot[0];
					participants[i+4]=tempSpot[1];
					participants[i+5]=tempSpot[2];
					reCheck=true;
				}
			}
		}
		for(var i=0;i<participants.length;i+=3){
			thisScore=participants[i+2]*participants[i+1];
			statsText+="[B]"+participants[i]+":[/B] "+participants[i+2]+" x "+participants[i+1]+" = "+
				thisScore+" point"+((thisScore!=1)?"s":"")+"\n";
			//GM_log("Added "+participants[i]+" to the stats list DEBUG: Posts: "+participants[i+2]+", Multiplier: "+participants[i+1]+
			//	", Total Score: "+thisScore+", minimumRequiredMVP: "+minimumRequiredMVP);
			if(thisScore>=minimumRequiredMVP){
				//GM_log("Adding "+participants[i]+" to the MVP list.");
				mvpList.push(participants[i]);
			}
		}
		if(participants.length==0){
			statsText+="None\n";
		}
		return new Array(statsText,mvpList);
	},
	goToNextPage: function(){
		var pageLinks=document.getElementsByClassName('pagination_top')[0];
		var nextLinkContainer=pageLinks.getElementsByClassName('prev_next')[1];
		if(nextLinkContainer!=undefined){
			nextLinkContainer.getElementsByTagName('a')[0].click();
			return true;
		}else{
			return false;
		}
	},
	startCounting: function(){
		this.clearStats();
		theAnswer=window.prompt("Specifiy a post number to begin counting.\n"+
			"If you do not know the post number, click Cancel.");
		if(theAnswer!=null){
			startPost=parseInt(theAnswer);
			GM_setValue("statsActive",true);
			this.doCounting(startPost);
		}
	},
	continueCounting: function(){
		if(this.restoreStats()){
			startPost=this.lastPostNumber+1;
			GM_setValue("statsActive",true);
			this.doCounting(startPost);
		}
	},
	doCounting: function(startPost){
		//GM_log("Current round score: "+this.currentScore);
		if(!this.recordPosts(startPost)){
			this.endCounting();
			return false;
		}
		this.saveStats();
		if(this.winner!=null || !this.goToNextPage()){
			this.getSummary();
			this.endCounting();
		}
	},
	endCounting: function(){
		GM_setValue("statsActive",false);
		if(!this.alreadyHasStartCounting){
			this.addStartCounting();
		}
	},
	showSummary: function(){
		if(this.restoreStats()){
			this.getSummary();
		}
	},
	saveStats: function(){
		//GM_log("Last post on this page: "+this.lastPostNumber);
		GM_setValue("lastPostNumber",this.lastPostNumber);
		//GM_log("Current round score: "+this.currentScore);
		GM_setValue("currentScore",this.currentScore);
		for(i=0;i<this.scores.length;i++){
			GM_setValue("scores."+i,this.scores[i]);
			GM_setValue("scores.count",this.scores.length);
		}
		GM_setValue("lastPoster",this.lastPoster);
		GM_setValue("winner",this.winner);
		GM_setValue("statsCached",true);
	},
	restoreStats: function(){
		if(!GM_getValue("statsCached",false)){
			window.alert("No cached stats.")
			return false;
		}
		var scoresCount=GM_getValue("scores.count",0);
		this.lastPoster=GM_getValue("lastPoster",null);
		this.winner=GM_getValue("winner",null);
		this.currentScore=parseInt(GM_getValue("currentScore"));
		this.lastPostNumber=parseInt(GM_getValue("lastPostNumber"));
		this.scores=new Array();
		for(i=0;i<scoresCount;i++){
			this.scores.push(GM_getValue("scores."+i));
		}
		return true;
	},
	clearStats: function(){
		this.scores=new Array();
		this.currentScore=0;
		this.lastPostNumber=0;
		this.lastPoster=null;
		this.winner=null;
		keys=GM_listValues();
		for (var i=0,key=null; key=keys[i];i++) {
			GM_deleteValue(key);
		}
	}
};

towStats.init();