Agario Mod V1

A agario mod v1

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Agario Mod V1
// @namespace   http://agar.io/
// @version      V1
// @description  A agario mod v1
// @author       Odyis
// @match        http://*/*
// @grant        none
// ==/UserScript==

var ourskins = "Odyis;0chan;18-25;1up;8ball;UmguwJ0;ace;agariomods.com;al sahim;alaska;albania;algeria;anarchy;android;anonymous;aperture;apple;atari;avatar;awesome;awwmuffin;baka;bandaid;bane;baseball;basketball;batman;beats;belarus;belgium;bender;bert;bielarus;bitcoin;black widow;blobfish;bluh;bobross;bobsaget;boo;boogie2988;borg;bp;breakfast;breizh;buckballs;burgundy;butters;byzantium;c;catalonia;catalunya;catman;chaika;charmander;chechenya;checkpointplus;cheese;chickfila;chocolate;chrome;chucknorris;cirno;cj;cling on;coca cola;cokacola;colombia;colombiaa;controless;converse;cookie;coookie;cornella;cornellà;coruja;creeper;creepydoll;csfb;cuba;cyprus;czech;czechia;czechrepublic;darksideofmoon;deadpool;deal with it;deathly hallows;deathstar;demon;derp;desu;dhole;dickbutt;doge;doggie;dolan;domo;domokun;dong;donut;doraemon;dreamcast;drunken;ebin;egg;egoraptor;egypt;eksi;electrokitty;epicface;expand;eye;facebook;fast forward;fastforward;fbi;fidel;fiji;finn;firefox;fishies;flash;florida;fnatic;fnaticc;foe;forocoches;freeman;freemason;friesland;frogout;fuckfacebook;gaben;gabenn;garfield;gaston;generikb;getinmybelly;getinthebox;gimper;github;giygas;gnomechild;gonzo;grammar nazi;grayhat;grima;grumpy;hagrid;halflife;halflife3;halo;handicapped;hap;hatty;hawaii;hawkeye;hebrew;heisenburg;helix;hipsterwhale;hispachan;hitler;homestuck;honeycomb;hosokawa;hue;hydro;iceland;ie;illuminati;illuminatiii;imaqtpie;imgur;imperial japan;imperialists;imperialjapan;instagram;iron man;isaac;isis;isreal;itchyfeetleech;ivysaur;jahrein;james bond;java;jew;jewnose;jimmies;jupiter;kalmar union;kame;kappa;kenny;kingdomoffrance;kingjoffrey;kirby;kitty;klingon;knights templar;knightstemplar;knowyourmeme;kurdistan;kyle;ladle;le snake;lenny;lgbt;liberland;libertyy;liechtenstien;linux;llessur;loadingreadyrun;loki;love;luigi;macedonia;malta;mario;mars;maryland;masterball;mastercheif;mcdonalds;meatboy;meatwad;megamilk;mike tyson;mike;mlg;moldova;mortalkombat;mr burns;mr.bean;mr.popo;n64;naga;nasa;nauru;nazi;nick fury;nick;nickelodeon;nipple;northbrabant;northernlion;nosmoking;notch;nsa;obama;obey;osu;ouch;palau;pandaexpress;pedo;pedobear;peka;penguin;pepe;pepsi;pewdiepie;pi;pig;piggy;pika;pinkfloyd;pinkstylist;pirate;piratebay;pizza;pizzaa;playstation;poop;potato;pt;quantum leap;question;rageface;retard smile;rewind;rockstar;rolfharris;roomba;rss;ryukyu;s.h.e.i.l.d;samoa;satan;scream;seal;serbia;sharingan;shell;shine;shrek;sinistar;sir;skull;skype;skyrim;slack;slovakia;slovenia;slowpoke;smash;snafu;snapchat;soccer;soliare;solomid;somalia;space ace;space;spawn;spiderman;spongegar;spore;spqr;spy;squirtle;stalinjr;star wars rebel;starbucks;starchild;starrynight;stitch;stupid;summit1g;sunface;superman;taco;teamfortress;thor;tintin;tonga;transformer;transformers;triforce;trollface;tubbymcfatfuck;turkey;tv;twitch;twitter;uguu;ukip;uppercase;uruguay;utorrent;vatican;vietnam;virus;voat;voyager;wakawaka;wales;walrus;wazowski;wewlad;white  light;windows;wit my woes;wwf;wykop;xsk;ycm;yinyang;ylilauta;ylilautaa;yoba;yobaa;yobaaa;yourmom;youtube;zeon;zimbabwe;zoella;zoidberg";

var showsh = false;
var showt = localStorage.getItem("showt")=="true";

var ldown = false;

var showfps = false;
var showpio = false; //packets in/out per second


if(showt===null){localStorage.setItem("showt","true");showt=true;}

setInterval(function(){if(showsh)DrawStats(false);if(showt)count();},300);

var gamejs = "", modBlocking = true;
var tester = document.getElementsByTagName("script");
var i = 0, main_out_url = document.location.protocol+"//agar.io/main_out.js", discovered_mainouturl = 0;
var W = '';
var Ja = '';
var b = '';
var c3eg2 = '';
var in_game = false;
var pandb = '';		
/*bgm*/
var bgmusic = '';
$('#audiotemplate').clone()[0];
var tracks = ['BotB 17936 Isolation Tank.mp3','BotB 17934 bubblybubblebubblingbubbles.mp3','BotB 17935 bloblobloblboblbolboblboblbobolbloblob.mp3','BotB 17937 Woofytunes.mp3','BotB 17938 slowgrow.mp3'];
/*sfx*/
//sfx play on event (only one of each sfx can play - for sfx that won't overlap with itself)
var ssfxlist = [
    'spawn',
    'gameover'
];
var ssfxs = [];
for (i=0;i<ssfxlist.length;i++) {
	var newsfx = new Audio("//skins.agariomods.com/botb/sfx/" + ssfxlist[i] + ".mp3");
	newsfx.loop = false;
	ssfxs.push(newsfx);
}
function sfx_play(id) {
	if (document.getElementById("sfx").value==0) return;
	var event = ssfxs[id];
	event.volume = document.getElementById("sfx").value;
    event.play();
}

//sfx insertion on event (multiple of same sfx can be played simultaneously)
var sfxlist = [
    'pellet',
    'split',
    'eat',
    'bounce',
    'merge',
    'virusfeed',
    'virusshoot',
    'virushit'
];
var sfxs = [];
for (i=0;i<sfxlist.length;i++) {
	var newsfx = new Audio("//skins.agariomods.com/botb/sfx/" + sfxlist[i] + ".mp3");
	newsfx.loop = false;
	newsfx.onended = function() {
        $(this).remove();
    }
	sfxs.push(newsfx);
}
function sfx_event(id) {
    if (document.getElementById("sfx").value==0) return;
	var event = jQuery.clone(sfxs[id]);
	event.volume = document.getElementById("sfx").value;
	event.load();
    event.play();
}
/* lets start to deal with regressions */
var test = 0;
var passed = 0;
var failed = 0;

var chart_update_interval = 10;
var chart = null;
var chart_data = [];
var chart_counter = 0;
var chart_s = '';
var chart_m = '';
var chart_G = '';
var chart_Na= '';
var chart_k = '';

for (i=0; i<tester.length; i++ ){
	src = tester[i].src;
	if (src.substring(0, main_out_url.length ) == main_out_url) {
		discovered_mainouturl = src.replace("//agar.io/","");
	}
}

if(discovered_mainouturl != 0) {
	httpGet(discovered_mainouturl, function(data) {
		gamejs = "window.agariomods = " + data.replace("socket open","socket open (agariomods.com mod in place)");
		gamejs = gamejs.replace(/\n/g, "");
		offset = gamejs.search("..=\"poland;");
		Ja =  gamejs.substr(offset,2);
		offset = gamejs.search(".....src=\"skins");
		b = gamejs.substr(offset+2,1);
		offset = gamejs.search(".."+b+"..src");
		W = gamejs.substr(offset,1);
		//this.P&&b.strokeText
		var components = /this.(.)&&b.strokeText/.exec(gamejs);
		pandb = components[1];
		var components = /strokeText\((.{1,14})\);/.exec(gamejs);
		c3eg2 = components[1];
		var components = /\((.)\=..x,.\=..y\)/.exec(gamejs);		
		chart_s = components[1];
		var components = /\(.\=(.).x,.\=..y\)/.exec(gamejs);
		chart_m = components[1];
		var components = /(.)\=Math.max\(.,..\(\)\);/.exec(gamejs);
		chart_G = components[1];
		var components = /.\=Math.max\(.,(..)\(\)\);/.exec(gamejs);
		chart_Na = components[1];
		var components = /(.)\[0\]\.name\&\&\(/.exec(gamejs);
		chart_k = components[1];
		//console.log ("chartmod info: chart_m = "+chart_m+";  chart_s = "+chart_s+"; chart_G = "+chart_G+"; chart_Na = "+chart_Na+"; chart_k = "+chart_k);
		agariomodsRuntimeInjection();
	});
}

// XMLHttp, because apparently raven is doing funky stuff with jQuery
function httpGet(theUrl, callback) {
	var xmlHttp = new XMLHttpRequest();
	xmlHttp.open("GET", theUrl, true);
	xmlHttp.send(null);
	xmlHttp.onreadystatechange = function() {
		if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
			callback(xmlHttp.responseText);
		}
	};
}
function agariomodsRuntimeInjection() {
	var script = document.createElement("script");
	script.src='//cdnjs.cloudflare.com/ajax/libs/canvasjs/1.4.1/canvas.min.js';
        document.head.appendChild(script);
	var tester = document.getElementsByTagName("head");
	var oldhtml = tester[0].innerHTML;
	oldhtml = oldhtml.replace('width:350px;', '');
	oldhtml = oldhtml.replace('-webkit-transform:translate(-50%,-50%);', '');
	oldhtml = oldhtml.replace('-ms-transform:translate(-50%,-50%);', '');
	oldhtml = oldhtml.replace('transform:translate(-50%,-50%);', '');
	oldhtml = oldhtml.replace('top:50%;left:50%;','margin:10px;');
	tester[0].innerHTML = oldhtml;
	var script = document.createElement("script");
	agariomodsRuntimePatches();
	script.innerHTML = gamejs;
	document.head.appendChild(script);
	agariomodsRuntimeHacks();
	bgmusic = $('#audiotemplate').clone()[0];
    bgmusic.src = "//skins.agariomods.com/botb/" + tracks[Math.floor(Math.random() * tracks.length)];
    bgmusic.load();
    bgmusic.loop = false;
    bgmusic.onended = function() {
        var track = tracks[Math.floor(Math.random() * tracks.length)];
        bgmusic.src = "//skins.agariomods.com/botb/" + track;
        bgmusic.play();
    }
	window.onbeforeunload = function() {
		return 'Are you sure you want to quit agar.io?';
	};
	// as a trackpad user, this fix should reduce the frequency at which I am killed.
	$("#canvas").on('mousedown', function(event){
		event.preventDefault();
	});
	$("#chart-container").css("pointerEvents", "none");
	$("#chart-container-agariomods").css("pointerEvents", "none");
	$("#fps-agariomods").css("pointerEvents", "none");
	$("#pi-agariomods").css("pointerEvents", "none");

}
function agariomodsRuntimePatches() {
	gamejs_patch(")&&this",")&&(this","test");
	gamejs_patch(/\w>\w\/1\.1\?.*-50%\)"\);/,"","fixing menu on resize");
		gamejs_patch(';reddit;', ';reddit;'+ourskins+';', "add our skinlist to the original game skinlist.");
        gamejs_patch(b+'=this.name.toLowerCase();', b+'=this.name.toLowerCase();var agariomods="";var ourskins = "'+ourskins+'";if(('+b+'.length >0) && (ourskins.split(";").indexOf('+b+')>-1)) {agariomods="//skins.agariomods.com/i/"+'+b+'+".png";} else if ('+b+'.substring(0, 2) == "i/" && document.getElementById("imgur").checked) {agariomods="//i.imgur.com/"+this.name.substring(2)+".jpg";} else if (document.getElementById("imgur").checked) {agariomods="//agar.io/skins/" + this.name.toLowerCase() + ".png";}', "add check for which skin mode we are in. be it no skin, default skin, imgur skin, or an agariomods skin.");
		gamejs_patch('xa=!1', 'zz=!1,yq=!1,xx=!1,xz=!1,xa=!1', "adding variables");
        gamejs_patch(W +'['+b+'].src="skins/"+'+b+'+".png"', W+'['+b+'].src=agariomods', "check for agariomods img src variable");
        gamejs_patch("this."+pandb+"&&b.strokeText("+c3eg2+");b.fillText("+c3eg2+")", "if (String(c).substring(0, 2) != \"i/\") {this."+pandb+"&&b.strokeText("+c3eg2+");b.fillText("+c3eg2+")}", "add imgur check for hiding username when using imgur id aka c3eg2");
        gamejs_patch(b+"=this.name.toLowerCase();", b+"=this.name.toLowerCase(); if ("+b+".substring(0, 2) == \"i/\") {" +Ja+ "+="+b+";} ;", "add imgur check #2.");
    gamejs = addChartHooks(gamejs);
    gamejs = addOnCellEatenHook(gamejs);
	gamejs = addTeamMassHook(gamejs);
	gamejs = addCanvasBGHook(gamejs);
	gamejs = addVirusColorHook(gamejs);
	gamejs = addFunctions(gamejs);
    gamejs = addOnShowOverlayHook(gamejs);
    gamejs = addOnHideOverlayHook(gamejs); //Because I don't want to detect when we hide it, only when the game does.
    gamejs = addLeaderboardHook(gamejs);
	gamejs = addConnectHook(gamejs); 
	gamejs = addRecieveHook(gamejs);
	gamejs = addOnSendHook(gamejs);
    gamejs = addOnDrawHook(gamejs);
	//gamejs = gamejs.replace(/;/g, '\n');
	console.log("Testing complete, "+passed+" units passed and "+failed+" units failed.");
	if (failed) console.log(new Error("UNIT FAILED"));
}
function gamejs_patch(search, replace, purpose) {		
        gamejs = gamejs.replace(search,replace);		
        testCondition((-1 != gamejs.indexOf(replace)), test++, purpose);		
}
function testCondition (condition, id, comment) {
        if(condition) {
                console.log("test: #"+id+" PASSED - "+ comment);
                passed++;
        } else {
                console.error("test: #"+id+" FAILED - "+ comment);
		failed++;
        }
}


function agariomodsRuntimeHacks() {
	jQuery('#helloDialog').css({left: '5px'});
	jQuery('#helloDialog').css({top: '5px'});
	jQuery('#helloDialog').css({margin: '0px'});
	jQuery('#helloDialog').css({marginLeft: 'auto'});
	jQuery('#helloDialog').css({marginRight: 'auto'});
//   opacity: 0.5;
//

jQuery('#helloDialog').css({opacity: '0.85'});	
jQuery('#helloDialog').css({width: '450px'});
    document.body.style.backgroundSize = 'cover';
    document.body.style.backgroundRepeat = 'no-repeat';
	document.body.style.backgroundAttachment = "fixed";
	
	var nodeDiv = document.createElement("div");
	$( document ).ready(function() {
		hd = document.getElementById("helloDialog");
		cachedhd = hd.innerHTML;
		hd.innerHTML = cachedhd.replace("<center>Agar.io</center>", "<a target=\"_blank\" style=\"position:absolute; padding-left:435px;top:-10px; z-index: -1; height:120px;\" href=\"https://www.reddit.com/r/Agario/\"><img src=\"//i.imgur.com/TkTWOrc.png\" height=\"120px\"/></a>");
	});
	document.getElementById("nick").placeholder = "agariomods.com";
	nodeDiv.id = "includedContent";
	nodeDiv.style.width = "400px"
	nodeDiv.style.backgroundColor = "#000000";
	nodeDiv.style.zIndex = 999;
	nodeDiv.style.position = "relative";
	nodeDiv.style.padding = "8px";
	nodeDiv.style.borderRadius = "5px";
	nodeDiv.style.color = "#dddddd";
	nodeDiv.style.margin = "10px";
	nodeDiv.style.marginTop = "0";
	nodeDiv.style.maxHeight = "250px"; //The settings and the ad are being pushed down too far on some screens (1366*768). ~Mevin1
	nodeDiv.style.overflow = "auto"; //add scroll bar
	nodeDiv.innerHTML += '1.9.5: Go catch up with the <a target="_blank" href="http://agariomods.com/documentation.html">Documentation</a><br><h4><a href="http://www.agariomods.com/help.html" target="_blank"><font color="pink">CLICK HERE FOR HELP</font></a></h4>\
        <div style="background-color: #ffffff; color: #000000; padding: 2px; margin: 0px;">\
                <small><b>Disable ad blockers</b>&nbsp;- They are breaking the game and our modifications in random and unexpected ways.</small>\
        </div>';
	jQuery('#region').parent().get(0).appendChild(nodeDiv);
	jQuery(".form-group:first").replaceWith('<br>');
	var selector = jQuery('#region');
	var playBtn = jQuery('#playBtn');
	var nodeInput = document.createElement("span");
	var nodeSpan = document.createElement("span");
	var nodeBr = document.createElement("br");
	var nodeLinks = document.createElement("div");
	nodeLinks.innerHTML = "<big><a href='http://skins.agariomods.com' target='_blank'>SKINS</a> - <a href='http://agariomods.com/chat.html' target='_blank'>CHAT</a> - <a href='http://agariomods.com' target='_blank'>WEBSITE</a> - <a href='http://agariomods.com/help.html' target='_blank'>HELP</a> - <a href onclick=\"alert('---HOTKEYS---\\nHold Z - Show Stats In-Game\\nSuicide - Alt+Q\\nToggle Benchmarker - T\\nClear Benchmarks - Alt+T\\nFPS Counter - Alt+1\\nPackets In/Out Per Second - Alt+2\\nTry Script Lag Recover - Alt+R');return false;\" target='_blank'>HOTKEYS</a></big>";
	nodeLinks.style.marginLeft='10px';
	nodeSpan.className = "glyphicon glyphicon-refresh btn btn-info";
	nodeSpan.style.fontSize = "1.5em";
	nodeSpan.style.cssFloat = "left";
	nodeSpan.style.paddingTop = "2px";
	nodeSpan.style.width = "15%";
	nodeSpan.style.height = "33px";
	nodeSpan.addEventListener("click", function (e) {
		document.getElementById("iphack").value=document.getElementById("iphack").value.replace(/\s+/g, '');
		var ip = document.getElementById("iphack").value.replace("ws://","");
		if(ip.length>8)connect("ws://"+ip);
	});
//	nodeInput.className = "form-control";
	nodeInput.id = "iphack"
	nodeInput.style.width = "85%";
	nodeInput.style.cssFloat = "left";
	nodeInput.style.cssClear = "right";
	nodeInput.style.padding = "5px;";
	nodeInput.style.margin = "5px;";	
	nodeInput.style.border = "2px solid green";
	nodeInput.innerHTML = "Zeach, the owner of Agar.io has told us to remove this particular feature, he has banned the ability to connect to a server directly by it's IP which breaks all mods. ";
	jQuery('#locationUnknown').prepend(nodeLinks);
	jQuery(playBtn).parent().get(0).appendChild(nodeInput);
	jQuery(playBtn).parent().get(0).appendChild(nodeSpan);
	jQuery(playBtn).parent().get(0).appendChild(nodeBr);
	jQuery(playBtn).parent().prepend("<b>Current Server IP: </b><span id='ip'></span>");
	var nodeAudio = document.createElement("audio");		
	nodeAudio.id = 'audiotemplate';		
	jQuery(playBtn).parent().get(0).appendChild(nodeAudio);
	jQuery('#playBtn').off();
	$('.btn-needs-server').prop('disabled', true);
	jQuery('#playBtn').click(function() {
		setNick(document.getElementById('nick').value);
		return false;
	});
	jQuery('.form-group:first').after( "<hr style='margin: 7px; border-width: 2px'>" );
	jQuery('.form-group:first').removeAttr("class");
}

	
			



/* begin mikeys new code */
var chart_update_interval = 10;

var chart = null;
var chart_data = [];
var chart_counter = 0;
var stat_canvas = null;

var stats = null;
var my_cells = null;
var my_color = "#ff8888";
var pie = null;
var stats_chart;

var display_chart = LS_getValue('display_chart', 'true') === 'true';
var display_stats = LS_getValue('display_stats', 'false') === 'true';

/////////////////////////////////////////////////////////

var g_stat_spacing = 0;
var g_display_width = 220;
var g_layout_width = g_display_width;

////////////////////////////////////////////////////////////////
function addChartHooks(script) {
    var match = script.match(/max\((\w+),(\w+)\(/);
    var high = match[1];
    var current = match[2];
    match = script.match(/1==(\w+)\.length&&\(/);
    var my_cells = match[1];
    var split = script.split(match[0]);
    script = split[0] + '1=='+my_cells+'.length&&(OnGameStart('+my_cells+'),' + split[1];
    split = script.split(script.match(/"Score: "\+~~\(\w+\/100\)/)[0]);
    match = split[1].match(/-(\d+)\)\);/);
    var subSplit = split[1].split(match[0]);
    split[1] = subSplit[0] + '-'+match[1]+'),('+my_cells+'&&'+my_cells+'[0]&&OnUpdateMass('+current+'())));' + subSplit[1];
    return split[0] + '"Current: "+~~('+current+'()/100)+"  High: "+~~('+high+'/100)' + split[1];
}

function addTeamMassHook(script) {
	var match = script.match(/1==(\w+)\.length&&\(/);
    var my_cells = match[1];
	var match = script.match(/;(\w+)\.(\w+)\(this\.name\)/);
	var split = script.split(match[0]);
	var avar = match[2];
	script = split[0]+";"+match[1]+'.'+match[2]+'(this.name);if(yq){if(p[0]&&N==":teams"&&'+my_cells+'.indexOf(this)==-1){if(this.color.substr(p[0].color.search("ff"),2)=="ff"){this.k.'+match[2]+'(this.name+" ["+~~(this.size*this.size/100)+"]");}}}'+split[1];
	var match = script.match(/indexOf\((\w+)\)\)\)\{/);
	var split = script.split(match[0]);
	return split[0]+'indexOf('+match[1]+')))||(this.size>=32&'+my_cells+'[0]&&N==":teams"&&!this.d)){if(yq){if(this.name==""){this.k=new ka(this.h(),"#FFFFFF",true,"#000000");this.k.'+avar+'(this.name);}};'+split[1];
	var split = script.split(match[0]);
}


function addFunctions(script) {
    var match = script.match(/((\w)\.setAcid)/);
	var split = script.split(match[0]);
	script = split[0]+match[2]+'.Suicide=function(){var b=new ArrayBuffer(1);(new DataView(b)).setUint8(0, 20);q.send(b)};'+match[2]+'.setVColors=function(a){zz=a};'+match[2]+'.setTeamMass=function(a){yq=a;if(a){jQuery(\'#names\').attr(\'checked\',false);check(document.getElementById(\'names\'));}};'+match[2]+'.setBG=function(a){xx=a;if(a){var url=localStorage.getItem("bgurl");if(url==null){url=""};var promp=prompt("Image URL",url);if(null==promp){jQuery("#bgimg").attr("checked",false);check(document.getElementById("bgimg"));xx=!a;return;}localStorage.setItem("bgurl",promp);jQuery("#acid").attr("checked",false);check(document.getElementById("acid"));document.body.style.backgroundImage=\'url("\'+promp+\'")\';xz=confirm("Show Grid Lines?");}};'+match[1]+split[1]
	var split = script.split("setNames=function(a){");
	return split[0]+"setNames=function(a){if(!a){jQuery(\'#tmass\').attr(\'checked\',false);check(document.getElementById(\'tmass\'));}"+split[1];
}

function addCanvasBGHook(script) {
    var match = script.match(/rRect\(0,0,(\w),(\w)\)/);
	var split = script.split(match[0]);
	script = split[0]+'rRect(0,0,'+match[1]+','+match[2]+');xx&&!xz?g.clearRect(0, 0, r, s):'+split[1].substr(1);
    var match = script.match(/BFF";/);
	var split = script.split(match[0]);
	return split[0]+'BFF";xx&&xz?g.clearRect(0,0,r,s):'+split[1];
}

function addVirusColorHook(script) {
    var match = script.match(/(\?\(\w\.fillStyle=")/);
    var split = script.split(match[0]);
    return split[0]+'||zz&&this.d'+match[1]+split[1]   
}

function addLeaderboardHook(script) {
    var match = script.match(/(fillStyle="#FFAAAA")(.+)(\w+)(\+1\+"\. ")/);
    var split = script.split(match[0]);
    return split[0]+match[1]+',OnLeaderboard('+match[3]+'+1)'+match[2]+match[3]+match[4]+split[1]   
}

function addOnCellEatenHook(script) {
			 //   null!=p&&p.T();
			   // l&&k&&(k.S()
//    var match = script.match(/(\w+)&&(\w+)&&\((\w+)\.S/);
	var match = script.match(/(\w+)&&(\w+)&&\((\w+)\.(\w+)/);
    var split = script.split(match[0]);
    return split[0] + match[1] + '&&' + match[2] + '&&(OnCellEaten('+match[1]+','+match[2]+'),' + match[3] + '.' + match[4] + split[1];
}

function addOnShowOverlayHook(script) {
    var match = script.match(/\w+\("#overlays"\)\.fadeIn\((\w+)\?\w+:\w+\);/);    
    var split = script.split(match[0]);
    return split[0] + match[0] + 'OnShowOverlay(' + match[1] + ');' + split[1];
}

function addConnectHook(script) {
    var match = script.match(/console\.log\("Connecting to "\+a\);/);
    var split = script.split(match[0]);
    return split[0] + match[0] + 'document.getElementById("ip").innerHTML=a.replace(/wss?:\\/\\//,"");' + split[1];
}

function addRecieveHook(script) {
//		  	     Za(new DataView(a.data))    
var match = script.match(/\w\(new DataView\(..data\)\)/);    

    var split = script.split(match[0]);
    return split[0] + match[0] + ';Recieve();' + split[1];
}

function addOnSendHook(script) {
    var match = script.match(/\w+\.send\(\w+\.buffer\)/);    
    var split = script.split(match[0]);
    return split[0] + match[0] + ';OnSend();' + split[1];
}

function addOnHideOverlayHook(script) {
    var match = script.match(/\w+\("#overlays"\)\.hide\(\)/);    
    var split = script.split(match[0]);
    return split[0] + match[0] + ';OnHideOverlay()' + split[1];
}

function addOnDrawHook(script) {
    var match = script.match(/\w+\.width&&(\w+)\.drawImage\(\w+,\w+-\w+\.width-10,10\);/);
    var split = script.split(match[0]);
    return split[0] + match[0] + 'OnDraw(' + match[1] + ');' + split[1];
}

var __STORAGE_PREFIX = "mikeyk730__";

function LS_getValue(aKey, aDefault) {
	var val = localStorage.getItem(__STORAGE_PREFIX + aKey);
	if (null === val && 'undefined' != typeof aDefault) return aDefault;
	return val;
}
 
function LS_setValue(aKey, aVal) {
	localStorage.setItem(__STORAGE_PREFIX + aKey, aVal);
}

function GetRgba(hex_color, opacity)
{
    var patt = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/;
    var matches = patt.exec(hex_color);
    return "rgba("+parseInt(matches[1], 16)+","+parseInt(matches[2], 16)+","+parseInt(matches[3], 16)+","+opacity+")";
}

function secondsToHms(d) 
{
    d = Number(d);
    var h = Math.floor(d / 3600);
    var m = Math.floor(d % 3600 / 60);
    var s = Math.floor(d % 3600 % 60);
    return ((h > 0 ? h + ":" + (m < 10 ? "0" : "") : "") + m + ":" + (s < 10 ? "0" : "") + s);
}
////////////////////////////////////////////////////////////////
jQuery(document).ready(function() 
{
    jQuery('body').append('<div id="chart-container" style="display:none; position:absolute; height:176px; width:300px; left:10px; bottom:44px"></div>\
			   <div id="chart-container-agariomods" style="opacity: 0.7; position:absolute; height:20px; width:300px; right:10px; bottom:10px;">&nbsp;agariomods.com - modding <b>without</b> cheating</div>\
			   <div id="debug" style="position:absolute; top:5px; left:10px;">\
			   <div id="fps-agariomods" style="color: white; display: none; background-color: rgba(0,0,0,.5); padding:0 4px;"><b>FPS: </b><span>0</span></div>\
			   <div id="pio-agariomods" style="color: white; display: none;  background-color: rgba(0,0,0,.5); padding:0 4px;"><b>PI/O/s: </b><span>0</span>/<span>0</span></div>\
			   </div>\
			   <img src="http://kelvin.gq/agariomods?'+Date.now()+'" style="display:none;">');
	jQuery('#instructions').remove();
	//jQuery('.glyphicon-cog').addClass("glyphicon-refresh")
	//jQuery('.glyphicon-cog').removeClass("glyphicon-cog");
	//jQuery('.btn-settings').attr('onclick','connect("ws://"+document.getElementById("ip").innerHTML);if(in_game)OnShowOverlay(false);');
	//jQuery('.btn-settings').attr('type','button');
	//jQuery('#gamemode').removeAttr('required');
	//jQuery('.btn-settings').removeClass("btn-settings");
	jQuery('.btn-settings').hide();
	jQuery('#settings').show();
  	var checkbox_div = jQuery('#settings input[type=checkbox]').closest('div');
    checkbox_div.append('<label><input type="checkbox" id="acid" onchange="setAcid($(this).is(\':checked\'));if($(this).is(\':checked\')){$(\'#bgimg\').attr(\'checked\',false);check(document.getElementById(\'bgimg\'));}">Acid</label>');
	checkbox_div.append('<label><input type="checkbox" onchange="if(this.checked){jQuery(\'#chart-container\').show()}else{jQuery(\'#chart-container\').hide()}">Show chart</label>');
	checkbox_div.append('<label><input type="checkbox" onchange="setVColors($(this).is(\':checked\'));">Colorless Viruses</label>');
	checkbox_div.append('<label><input id="imgur" type="checkbox">Imgur Skins</label>');
	checkbox_div.append('<label><input type="checkbox" id="tmass" onchange="setTeamMass($(this).is(\':checked\'));">Show Teamed Mass</label>');
	checkbox_div.append('<label><input id="bgimg" type="checkbox" onchange="setBG($(this).is(\':checked\'));">Set Background</label>');
	checkbox_div.append('<div id="sliders"><label>SFX<input id="sfx" type="range" value="0" step=".1" min="0" max="1"></label><label>BGM<input type="range" id="bgm" value="0" step=".1" min="0" max="1" oninput="volBGM(this.value);"></label></div>');    jQuery('#overlays').append('<div id="stats" style="opacity: 0.85; position: absolute; top:330px; left: 460px; width: 480px; display: none; background-color: #FFFFFF; border-radius: 15px; padding: 5px 15px 5px 15px; transform: translate(0,-50%); white-space: nowrap; overflow:hidden;"><div id="statArea" style="vertical-align:top; width:250px; display:inline-block;"></div><div id="pieArea" style="vertical-align: top; width:200px; height:150px; display:inline-block; vertical-align:top"> </div><div id="gainArea" style="width:500px;  vertical-align:top"></div><div id="lossArea" style="width:500px; "></div><div id="chartArea" style="width:450px; display:inline-block; vertical-align:top"></div></div>');
    jQuery('#stats').hide(0);   
	jQuery('#playBtn').width('74%');
});

function ResetChart() 
{
    chart = null;
    chart_data.length = 0;
    chart_counter = 0;
    jQuery('#chart-container').empty();    
}

function UpdateChartData(mass)
{
    chart_counter++;
    if (chart_counter%chart_update_interval > 0) 
		return false;
	
	chart_data.push({
        x: chart_counter,
        y: mass/100
    });
	return true;
}

function CreateChart(e, color, interactive)
{
    return new CanvasJS.Chart(e,{
        interactivityEnabled: interactive,
        title: null,
        axisX:{      
            valueFormatString: " ",
            lineThickness: 0,
            tickLength: 0
        },
        axisY:{
            lineThickness: 0,
            tickLength: 0,
            gridThickness: 2,
            gridColor: "white",
            labelFontColor: "white"
        },
        backgroundColor: "rgba(0,0,0,0.2)",
        data: [{
            type: "area",
            color: color,
            dataPoints: chart_data
        }]
    });
}

function UpdateChart(mass, color) 
{
	my_color = color;	
	if (chart === null)
		chart = CreateChart("chart-container", color, false);	
	if (UpdateChartData(mass) && display_chart)
		chart.render();     
	jQuery('.canvasjs-chart-credit').hide();
};

function ResetStats()
{
    stats = {
        pellets: {num:0, mass:0},
        w: {num:0, mass:0},
        cells: {num:0, mass:0},
        viruses: {num:0, mass:0},

        birthday: Date.now(),
        time_of_death: null,
        high_score: 0,
        top_slot: Number.POSITIVE_INFINITY,

        gains: {},
        losses: {},
    };
}

function OnGainMass(me, other)
{
    var mass = other.size * other.size;
    if (other.d){
        stats.viruses.num++;
        if (document.getElementById("gamemode").value!=":teams") stats.viruses.mass += mass; /*DONE: shouldn't add if game mode is teams. TODO: Find a better way of doing this. ~Mevin1*/
		sfx_event(7);
    }
    else if (Math.floor(mass) <= 400 && !other.name){
        stats.pellets.num++;
        stats.pellets.mass += mass;
		sfx_event(0);
    }
	/* heuristic to determine if mass is 'w', not perfect */
    else if (!other.name && mass <= 1444 && (mass >= 1369 || (other.x == other.ox && other.y == other.oy))){
		/*console.log('w', mass, other.name, other);*/
        if (other.color != me.color){ /*don't count own ejections, again not perfect*/
            stats.w.num++;
            stats.w.mass += mass;
        }
		sfx_event(2);
    }
    else { 
	    /*console.log('cell', mass, other.name, other);*/
        var key = other.name + ':' + other.color;
        stats.cells.num++;
        stats.cells.mass += mass;
        if (stats.gains[key] == undefined)
            stats.gains[key] = {num: 0, mass: 0};
        stats.gains[key].num++;
        stats.gains[key].mass += mass;
		sfx_event(2);
    }
}

function OnLoseMass(me, other)
{
    var mass = me.size * me.size;
    var key = other.name + ':' + other.color;
    if (stats.losses[key] == undefined)
        stats.losses[key] = {num: 0, mass: 0};;
    stats.losses[key].num++;
    stats.losses[key].mass += mass;
    sfx_event(2);
}

function DrawPie(pellet, w, cells, viruses)
{
    var total = pellet + w + cells + viruses;
    pie = new CanvasJS.Chart("pieArea", {
        title: null,
        animationEnabled: false,
        legend:{
            verticalAlign: "center",
            horizontalAlign: "left",
            fontSize: 12,
            fontFamily: "Helvetica"        
        },
        theme: "theme2",
        data: [{        
            type: "pie",       
            startAngle:-20,      
            showInLegend: true,
            toolTipContent:"{legendText} {y}%",
            dataPoints: [
                {  y: 100*pellet/total, legendText:"pellets"},
                {  y: 100*cells/total, legendText:"cells"},
                {  y: 100*w/total, legendText:"w"},
                {  y: 100*viruses/total, legendText:"viruses"},
            ]
        }]
    });
	pie.render();   
}

function GetTopN(n, p)
{
	var r = [];
	var a = Object.keys(stats[p]).sort(function(a, b) {return -(stats[p][a].mass - stats[p][b].mass)});
    for (var i = 0; i < n && i < a.length; ++i){
        var key = a[i];
        var mass = stats[p][key].mass;
        var name = key.slice(0,key.length-8);
        if (!name) name = "An unnamed cell";
        var color = key.slice(key.length-7);
		r.push({name:name, color:color, mass:Math.floor(mass/100)});
    }	
	return r;
}

function AppendTopN(n, p, list)
{
	var a = GetTopN(n,p);
    for (var i = 0; i < a.length; ++i){
        var text = '<bdi>'+a[i].name + '</bdi> (' + (p == 'gains' ? '+' : '-') + a[i].mass + ' mass)';
        list.append('<li style="font-size: 12px; "><div style="width: 10px; height: 10px; border-radius: 50%; margin-right:5px; background-color: ' + a[i].color + '; display: inline-block;"></div>' + text + '</li>');
    }
	return a.length > 0;
}

function DrawStats(game_over)
{
    if (!game_over != in_game) return;
            
	jQuery('#statArea').empty();
    jQuery('#pieArea').empty();
    jQuery('#gainArea').empty();
    jQuery('#lossArea').empty();
    jQuery('#chartArea').empty();
    jQuery('#stats').show();
    
    if (game_over){
        sfx_play(1);
		StopBGM();
	}
	stats.time_of_death = Date.now();
    var time = stats.time_of_death ? stats.time_of_death : Date.now();
    var seconds = (time - stats.birthday)/1000;
	
	var list = jQuery('<ul>');
    list.append('<li style="font-size: 12px; ">Game time: ' + secondsToHms(seconds) + '</li>');
    list.append('<li style="font-size: 12px; ">High score: ' + ~~(stats.high_score/100) + '</li>');
    if (stats.top_slot == Number.POSITIVE_INFINITY){
        list.append('<li style="font-size: 12px; ">You didn\'t make the leaderboard</li>');
    }
    else{
        list.append('<li style="font-size: 12px; ">Leaderboard max: ' + stats.top_slot + '</li>');
    }
    list.append('<li style="font-size: 12px; padding-top: 15px">' + stats.pellets.num + " pellets eaten (" + ~~(stats.pellets.mass/100) + ' mass)</li>');
    list.append('<li style="font-size: 12px; ">' + stats.cells.num + " cells eaten (" + ~~(stats.cells.mass/100) + ' mass)</li>');
    list.append('<li style="font-size: 12px; ">' + stats.w.num + " masses eaten (" + ~~(stats.w.mass/100) + ' mass)</li>');
    list.append('<li style="font-size: 12px; ">' + stats.viruses.num + " viruses eaten (" + ~~(stats.viruses.mass/100) + ' mass)</li>');
    jQuery('#statArea').append('<b>Game Summary</b>');
    jQuery('#statArea').append(list);
	
    DrawPie(stats.pellets.mass, stats.w.mass, stats.cells.mass, stats.viruses.mass);

	jQuery('#gainArea').append('<b>Top Gains</b>');
	list = jQuery('<ol>');
    if (AppendTopN(5, 'gains', list))
		jQuery('#gainArea').append(list);
	else
		jQuery('#gainArea').append('<ul><li style="font-size: 12px; ">You have not eaten anybody</li></ul>');
	 
    jQuery('#lossArea').append('<b>Top Losses</b>');
	list = jQuery('<ol>');
	if (AppendTopN(5, 'losses', list))
		jQuery('#lossArea').append(list);
    else
		jQuery('#lossArea').append('<ul><li style="font-size: 12px; ">Nobody has eaten you</li></ul>');
	
	if (stats.time_of_death !== null){
		jQuery('#chartArea').width(450).height(150);
		stat_chart = CreateChart('chartArea', my_color, true);
		stat_chart.render();
	}
	else {
		jQuery('#chartArea').width(450).height(0);
	}
jQuery('.canvasjs-chart-credit').hide();
}

var styles = {
	heading: {font:"20px Ubuntu", spacing: 41, alpha: 1},
	subheading: {font:"18px Ubuntu", spacing: 31, alpha: 1},
	normal: {font:"12px Ubuntu", spacing: 21, alpha: 0.6}
}

function AppendText(text, context, style)
{
	context.globalAlpha = styles[style].alpha;
	context.font = styles[style].font;
	g_stat_spacing += styles[style].spacing;
    
    var width = context.measureText(text).width;
    g_layout_width = Math.max(g_layout_width, width);    
	context.fillText(text, g_layout_width/2 - width/2, g_stat_spacing);
}

function RenderStats(reset)
{
	if (reset) g_layout_width = g_display_width;
	if (!display_stats || !stats) return;
	g_stat_spacing = 0;	
	
	var gains = GetTopN(3, 'gains');
	var losses =  GetTopN(3, 'losses');
	var height = 30 + styles['heading'].spacing + styles['subheading'].spacing * 2 + styles['normal'].spacing * (4 + gains.length + losses.length);
		
	stat_canvas = document.createElement("canvas");
	var scale = Math.min(g_display_width, .3 * window.innerWidth) / g_layout_width;
	stat_canvas.width = g_layout_width * scale;
    stat_canvas.height = height * scale;
	var context = stat_canvas.getContext("2d");
	context.scale(scale, scale);
		
    context.globalAlpha = .4;
    context.fillStyle = "#000000";
    context.fillRect(0, 0, g_layout_width, height);
        
    context.fillStyle = "#FFFFFF";
	AppendText("Stats", context, 'heading');
		
	var text = stats.pellets.num + " pellets eaten (" + ~~(stats.pellets.mass/100) + ")";
	AppendText(text, context,'normal');		
	text = stats.w.num + " mass eaten (" + ~~(stats.w.mass/100) + ")";
	AppendText(text, context,'normal');
    text = stats.cells.num + " cells eaten (" + ~~(stats.cells.mass/100) + ")";
	AppendText(text, context,'normal');
	text = stats.viruses.num + " viruses eaten (" + ~~(stats.viruses.mass/100) + ")";
	AppendText(text, context,'normal');
		
	AppendText("Top Gains",context,'subheading');
	for (var j = 0; j < gains.length; ++j){
		text = (j+1) + ". " + gains[j].name + " (" + gains[j].mass + ")";
		context.fillStyle = gains[j].color;			
		AppendText(text, context,'normal');
	}
		
	context.fillStyle = "#FFFFFF";
	AppendText("Top Losses",context,'subheading');
	for (var j = 0; j < losses.length; ++j){
		text = (j+1) + ". " + losses[j].name + " (" + losses[j].mass + ")";
		context.fillStyle = losses[j].color;			
		AppendText(text, context,'normal');
	}
}  

jQuery(window).resize(function() {
    RenderStats(false);
});

window.OnGameStart = function(cells)
{
	initbench(false);
	in_game = true;
    my_cells = cells;
    ResetChart();
    ResetStats();
    RenderStats(true);
	DrawStats(false);
	if (kd == true) {
		showsh = false;
		document.getElementById("overlays").style.display = "none";
		document.getElementById("overlays").style.backgroundColor = "rgba(0,0,0,.498039)";
		document.getElementById("overlays").style.pointerEvents = "auto";
		document.getElementById("stats").style.opacity = 0.85;
		document.getElementById("helloDialog").style.display = "block";
		kd = false;
	}
	StartBGM();
	sfx_play(0);
}

window.StartBGM = function ()
{
    if (document.getElementById("bgm").value==0) return;
    if (bgmusic.src == "") bgmusic.src = "//skins.agariomods.com/botb/" + tracks[Math.floor(Math.random() * tracks.length)]; //i guess i'll leave this here ~mevin1
	bgmusic.volume = document.getElementById("bgm").value;
    bgmusic.play();
}

window.StopBGM = function ()
{
	if (document.getElementById("bgm").value==0) return;
	bgmusic.pause()
	bgmusic.src = "//skins.agariomods.com/botb/" + tracks[Math.floor(Math.random() * tracks.length)];
	bgmusic.load()
}

window.volBGM = function (vol)
{
    bgmusic.volume = document.getElementById("bgm").value;
}

window.OnShowOverlay = function(game_in_progress)
{
	bstyle(true);
	if (!game_in_progress) in_game = false;
    DrawStats(!game_in_progress);
	if (kd == true) {
		document.getElementById("overlays").style.display = "block";
		document.getElementById("overlays").style.backgroundColor = "rgba(0,0,0,.498039)";
		document.getElementById("overlays").style.pointerEvents = "auto";
		document.getElementById("stats").style.opacity = 1;
		document.getElementById("helloDialog").style.display = "block";
		kd = false;
	}
	if (in_game) {
		showsh = true;
		canvas.onmousedown(0,0);
	} 
	else
	{
		showsh = false;
		//document.getElementById("benchmarker").style.display = "none";
		//showt=false;
	}
}

var fired = false; //for some reason OnHideOverlay fires twice
window.OnHideOverlay = function()
{
	if (fired == true) {fired = false; return;} else {fired = true;} //Only continue on first fire
	bstyle(false);
	if (showsh == true) showsh = false;
}

window.OnUpdateMass = function(mass) 
{
    stats.high_score = Math.max(stats.high_score, mass);
    UpdateChart(mass, GetRgba(my_cells[0].color,0.4));
	benchcheck(mass);
}

window.OnCellEaten = function(predator, prey)
{
    if (!my_cells) return;

    if (my_cells.indexOf(predator) != -1){
        OnGainMass(predator, prey);
        RenderStats(false);
    }
    if (my_cells.indexOf(prey) != -1){
        OnLoseMass(prey, predator);
        RenderStats(false);
    }    
}

window.OnLeaderboard = function(position)
{
    stats.top_slot = Math.min(stats.top_slot, position);
}

window.OnDraw = function(context)
{
	if (showfps) document.getElementById("fps-agariomods").children[1].innerHTML = countFPS();
    display_stats && stat_canvas && context.drawImage(stat_canvas, 10, 10);   
}

window.Recieve = function()
{
	if (showpio) document.getElementById("pio-agariomods").children[1].innerHTML = countPI();
}

window.OnSend = function()
{
	if (showpio) document.getElementById("pio-agariomods").children[2].innerHTML = countPO();
}

window.countFPS = (function () {
  var lastLoop = (new Date()).getMilliseconds();
  var count = 1;
  var fps = 0;

  return function () {
    var currentLoop = (new Date()).getMilliseconds();
    if (lastLoop > currentLoop) {
      fps = count;
      count = 1;
    } else {
      count += 1;
    }
    lastLoop = currentLoop;
    return fps;
  };
}());

window.countPI = (function () {
  var lastLoop = (new Date()).getMilliseconds();
  var count = 1;
  var packet = 0;

  return function () {
    var currentLoop = (new Date()).getMilliseconds();
    if (lastLoop > currentLoop) {
      packet = count;
      count = 1;
    } else {
      count += 1;
    }
    lastLoop = currentLoop;
    return packet;
  };
}());

window.countPO = (function () {
  var lastLoop = (new Date()).getMilliseconds();
  var count = 1;
  var packet = 0;

  return function () {
    var currentLoop = (new Date()).getMilliseconds();
    if (lastLoop > currentLoop) {
      packet = count;
      count = 1;
    } else {
      count += 1;
    }
    lastLoop = currentLoop;
    return packet;
  };
}());

window.onpageshow = function() {
	initbench(true);
	document.getElementById("bgimg").checked=false;
		jQuery('#helloDialog').css({transform: ''});
		jQuery('#helloDialog').css({scale: ''});
    $("div#settings label").change(function() {
        $("div#settings.checkbox input").each(function() {
			if (this.id=="bgimg")return;
            localStorage.setItem("setting"+$(this).parent().text().replace(" ","_"),this.checked);
        });
        $("div#settings input[type=range]").each(function() {
            localStorage.setItem("setting"+$(this).parent().text().replace(" ","_"),this.value);
        });
    });
	$("div#settings input").each(function() {
            check(this);
	});
}

window.check = function(elem){
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent("change", false, true);
    elem.dispatchEvent(evt);
}

$(document).ready(function() {
	if (!localStorage.getItem("setting_Imgur Skins")) localStorage.setItem("settingImgur_Skins","true"); localStorage.setItem("settingShow_Chart","true");
	$("div#settings.checkbox input").each(function() {
		if (this.id=="bgimg")return;
		if ($(this).parent().text()==" No names")$(this).attr("id","names");
		$(this).attr("checked",(localStorage.getItem("setting"+$(this).parent().text().replace(" ","_")))=="true");
	});
	$("div#settings input[type=range]").each(function() {
		$(this).attr("value",(localStorage.getItem("setting"+$(this).parent().text().replace(" ","_"))));
	});
	});

var kd = false;
$(document).keydown(function(e) {
	//Stats Shortcut
	if (e.keyCode == 90) {
		if (kd == false && document.getElementById("overlays").style.display == 'none') {
			kd = true;
			document.getElementById("overlays").style.display = "block";
			document.getElementById("overlays").style.backgroundColor = "rgba(0,0,0,0)";
			document.getElementById("overlays").style.pointerEvents = "none";
			document.getElementById("stats").style.opacity = 1;
			document.getElementById("helloDialog").style.display = "none";
			showsh = true;
			DrawStats(false);
		}
	}
	//Benchmarker Shortcut
	if (e.keyCode == 84&&!e.altKey&&document.activeElement.type!="text") {
		showt = !showt;
		localStorage.setItem("showt",showt);
		document.getElementById("benchmarker").style.display = showt?"block":"none";
	}
	//Benchmarker Clear Shortcut
	if (e.keyCode == 84&&e.altKey) {
		deleteScores();
	}
	//FPS Hotkey
	if (e.altKey && e.keyCode == 49) {
		showfps = !showfps;
		document.getElementById("fps-agariomods").style.display = showfps?"block":"none";
	}
	//Packets In Per Second Hotkey
	if (e.altKey && e.keyCode == 50) {
		showpio = !showpio;
		document.getElementById("pio-agariomods").style.display = showpio?"block":"none";
	}
	//Suicide
	if (e.altKey && e.keyCode == 81 && in_game) {
		jQuery("#overlays").show()
		OnShowOverlay(false);
		Suicide();
	}
	//Firefox Fullscreen
	if (e.ctrlKey && e.keyCode === 70 && navigator.userAgent.match("Firefox")) {
		e.preventDefault();
		if (document.mozFullScreenElement)
		{
			document.mozCancelFullScreen();
		}
		else
		{
			document.getElementById("overlays").mozRequestFullScreen();
		}
	}
	//EXPERIMENTAL
	//Attempts to recover from lag by temporarily pausing Javascript
	//Alt+R
	if (e.keyCode == 82&&e.altKey) {
		if(ldown)return;
		ldown = true
		console.log("pausing");
		var currentTime = new Date().getTime();
		while (currentTime + 500 >= new Date().getTime()){} //0.5 Second Timeout
	}
});
$(document).keyup(function(e) {
	//Hide Stats
	if (e.keyCode == 90) {
		if (kd == true) {
			kd = false;
			document.getElementById("overlays").style.display = "none";
			document.getElementById("overlays").style.backgroundColor = "rgba(0,0,0,.498039)";
			document.getElementById("overlays").style.pointerEvents = "auto";
			document.getElementById("stats").style.opacity = 0.85;
			document.getElementById("helloDialog").style.display = "block";
			showsh = false;
		}
	}
	//EXPERIMENTAL
	//To prevent extreamly long pause times fron holding down Alt+R
	if (e.keyCode == 82&&e.altKey) {
		if(ldown)ldown=false;
	}
});


//Agar.io Benchmarker Mod
//Version 0.4 ~ Edited By Mevin1
/*
•Changes
-WTF? An entire other div just for background? nope
-using Date.now() instead of a benchmarker for timing
*/
//Create global vars
var m, benchmarker;
var benchmarks = ["250mass", "500mass", "1000mass", "2500mass", "5000mass"/*, "Rank10", "Rank1"*/];
var mass_benchmarks = [250, 500, 1000, 2500, 5000];
/*var rank_benchmarks = [10, 1];
var rankPrev = 11;//broken*/
var massPrev = 0;
//Create div
$("body").append('<div id="benchmarker"></div>');
function initbench(first) {
    //Style div
    $("div#benchmarker").css({
        "backgroundColor": "rgba(0,0,0,0.4)" /*"transparent"*/ ,
        "opacity": "1.0",
        "color": "white",
        "fontFamily": "Ubuntu,Arial,sans-serif",
        "position": "fixed",
        "padding": "10px",
        "text-align": "center",
		"pointer-events": "none"/*,
		"display": "none"*/
    });
	if(first){
		bstyle(true);
		showt?$("div#benchmarker").css({
			"display": "block"
		}):
		$("div#benchmarker").css({
			"display": "none"
		});
	}
    //Create HTML to be added to div
    var newHTML = '<table>' +
        '<h3>Benchmarker</h3>' +
        '<span>Time Elapsed: --:--</span>' +
        '<tr><th>Benchmark</th><th>Time</th><th>Best</th></tr>' + //Headers
        '<tr id="250mass"><td>250 Mass</td><td class="time">-----</td><td class="best">-----</td></tr>' + //250 Mass
        '<tr id="500mass"><td>500 Mass</td><td class="time">-----</td><td class="best">-----</td></tr>' + //500 Mass
        '<tr id="1000mass"><td>1000 Mass</td><td class="time">-----</td><td class="best">-----</td></tr>' + //1000 Mass
        '<tr id="2500mass"><td>2500 Mass</td><td class="time">-----</td><td class="best">-----</td></tr>' + //2500 Mass
        '<tr id="5000mass"><td>5000 Mass</td><td class="time">-----</td><td class="best">-----</td></tr>' + //5000 Mass
        //'<tr id="Rank10"><td>Rank 10</td><td class="time">-----</td><td class="best">-----</td></tr>' + //Rank 10
        //'<tr id="Rank1"><td>Rank 1</td><td class="time">-----</td><td class="best">-----</td></tr>' + //Rank 1
        '</table>';


    //Add HTML to div
    $("div#benchmarker").html(newHTML);

    //Load local storage --- best times
    for (var i = 0; i < benchmarks.length; i++) {
        if (localStorage.getItem("best_" + benchmarks[i])) {
            $("#" + benchmarks[i] + " .best").html(localStorage.getItem("best_" + benchmarks[i]));
        }
    }
    //Style the table
    $("table").css({
        "margin": "8px",
        "padding": "8px"
    });
    //Centering
    $("div#benchmarker h3").css("text-align", "center");
    $("div#benchmarker span").css({
        "text-align": "center",
        "display": "inline-block"
    });
    //Cells
    $("td,th").css({
        "padding": "5px",
        "text-align": "left"
    });
    //Margins
    //$("div#benchmarker span").css({"margin":"0px","padding":"0px"});
    $("div#benchmarker h3").css({
        "margin-top": "4px"
    });
}
function bstyle(over){
	over?$("div#benchmarker").css({
        "left": "",
        "top": "",
        "right": "5px",
        "bottom": "5px",
		"z-index": "1000"
	}):$("div#benchmarker").css({
        "left": "5px",
        "top": "5px",
        "right": "",
        "bottom": "",
		"z-index": "1"
	});
}
function count() { //Occurs every second
	if (showt&&in_game){
    $("div#benchmarker span").html("Time Elapsed: " + mToMs(Date.now() - stats.birthday));
}}
function mToMs(millis) {
    var minutes = Math.floor(millis / 60000);
    var seconds = ((millis % 60000) / 1000).toFixed(0);
    return minutes + ":" + (seconds < 10 ? '0' : '') + seconds;
}
function snp(y) { //Turns XX:XX to XXXX
    return y.replace(/[^0-9]+/g, '');
}
function logBenchmark(benchmark, time) {
    //Manuallly record benchmark.
    if ($("#" + benchmark + " .time").html() == "-----") { //Checks if the benchmark time is recorded yet
        console.log("Benchmark set: " + benchmark + " at " + time);
        $("#" + benchmark + " .time").html(time); //Record time
        if (($("#" + benchmark + " .best").html() == "-----") || (snp(time) < snp(localStorage.getItem('best_' + benchmark)))) { //Checks if best time is beaten or undefined
            console.log("Best time set: " + benchmark + " at " + time);
            $("#" + benchmark + " .best").html(time); //Record time
            localStorage.setItem("best_" + benchmark, time); //Save to local storage
        }
    }
}
function deleteScores() {
    var prompt = confirm("Are you sure you want to delete your best times?");
    if (prompt == true) {
        for (var i = 0; i < benchmarks.length; i++) {
            localStorage.removeItem("best_" + benchmarks[i]);
            $("#" + benchmarks[i] + " .best").html("-----");
        }
    }
}
function benchcheck(mass) {
    mass = Math.floor(mass / 100);
    for (var i = 0; i < mass_benchmarks.length; i++) {
        if ((massPrev < mass_benchmarks[i]) && (mass >= mass_benchmarks[i])) {
            //Check if mass has passed from below benchmark to above benchmark
            logBenchmark(mass_benchmarks[i] + "mass", mToMs(Date.now() - stats.birthday));
        }
    }
}