var allRules = [ { hostname: ["agar.io"], scriptUriRe: /^http:\/\/agar\.io\/main_out\.js/, replace: function (m) { m.removeNewlines(); m.replace("var:allCells", /(=null;)(\w+)(.hasOwnProperty\(\w+\)?)/, "$1" + "$v=$2;" + "$2$3", "$v = {}"); m.replace("var:myCells", /(case 32:)(\w+)(\.push)/, "$1" + "$v=$2;" + "$2$3", "$v = []"); m.replace("var:top", /case 49:[^:]+?(\w+)=\[];/, "$&" + "$v=$1;", "$v = []"); m.replace("var:topTeams", /case 50:(\w+)=\[];/, "$&" + "$v=$1;", "$v = []"); var dr = "(\\w+)=\\w+\\.getFloat64\\(\\w+,!0\\);\\w+\\+=8;\\n?"; var dd = 7071.067811865476; m.replace("var:dimensions hook:dimensionsUpdated", RegExp("case 64:"+dr+dr+dr+dr), "$&" + "$v = [$1,$2,$3,$4],$H($1,$2,$3,$4),", "$v = " + JSON.stringify([-dd,-dd,dd,dd])); var vr = "(\\w+)=\\w+\\.getFloat32\\(\\w+,!0\\);\\w+\\+=4;"; m.save() && m.replace("var:rawViewport:x,y var:disableRendering:1", /else \w+=\(5\*\w+\+(\w+)\)\/6,\w+=\(5\*\w+\+(\w+)\)\/6,.*?;/, "$&" + "$v0.x=$1; $v0.y=$2; if($v1)return;") && m.replace("var:disableRendering:2 hook:skipCellDraw", /(\w+:function\(\w+\){)(if\(this\.\w+\(\)\){\+\+this\.[\w$]+;)/, "$1" + "if($v || $H(this))return;" + "$2") && m.replace("var:rawViewport:scale", /Math\.pow\(Math\.min\(64\/\w+,1\),\.4\)/, "($v.scale=$&)") && m.replace("var:rawViewport:x,y,scale", RegExp("case 17:"+vr+vr+vr), "$&" + "$v.x=$1; $v.y=$2; $v.scale=$3;") && m.reset_("window.agar.rawViewport = {x:0,y:0,scale:1};" + "window.agar.disableRendering = false;") || m.restore(); m.replace("reset hook:connect var:ws var:webSocket", /new WebSocket\((\w+)\);/, "$v1 = $&; $v0=$1;" + m.reset + "$H();", "$v0 = ''; $v1 = null;"); m.replace("property:scale", /function \w+\(\w+\){\w+\.preventDefault\(\);[^;]+;1>(\w+)&&\(\1=1\)/, `;${makeProperty("scale", "$1")};$&`); m.replace("var:minScale", /;1>(\w+)&&\(\1=1\)/, ";$v>$1 && ($1=$v)", "$v = 1"); m.replace("var:region", /console\.log\("Find "\+(\w+\+\w+)\);/, "$&" + "$v=$1;", "$v = ''"); m.replace("cellProperty:isVirus", /((\w+)=!!\(\w+&1\)[\s\S]{0,400})((\w+).(\w+)=\2;)/, "$1$4.isVirus=$3"); m.replace("var:dommousescroll", /("DOMMouseScroll",)(\w+),/, "$1($v=$2),"); m.replace("var:skinF hook:cellSkin", /(\w+.fill\(\))(;null!=(\w+))/, "$1;" + "if($v)$3 = $v(this,$3);" + "if($h)$3 = $h(this,$3);" + "$2"); m.replace("hook:afterCellStroke", /\((\w+)\.strokeStyle="#000000",\1\.globalAlpha\*=\.1,\1\.stroke\(\)\);\1\.globalAlpha=1;/, "$&" + "$H(this);"); m.replace("var:showStartupBg", /\w+\?\(\w\.globalAlpha=\w+,/, "$v && $&", "$v = true"); var vAlive = /\((\w+)\[(\w+)\]==this\){\1\.splice\(\2,1\);/.exec(m.text); var vEaten = /0(\w+)\*\1\+(\w+)\*\2/, ";if(!$v)return" + "$&", "$v = true"); m.replace("var:simpleCellDraw", /(:function\(\){)(var a=10;)/, "$1 if($v)return true;$2", "$v=false"); m.replace("hook:updateLeaderboard", /({\w+=null;)(if\(null!=)/, "$1 if($H())return; $2"); var template = (key,n) => `this\\.${key}=\\w+\\*\\(this\\.(\\w+)-this\\.(\\w+)\\)\\+this\\.\\${n};`; var re = new RegExp(template('x', 2) + template('y', 4) + template('size', 6)); var match = re.exec(m.text); if (match) { m.cellProp.nx = match[1]; m.cellProp.ny = match[3]; m.cellProp.nSize = match[5]; } else console.error("Expose: cellProp:x,y,size search failed!"); }}, ]; function makeProperty(name, varname) { return "'" + name + "' in window.agar || " + "Object.defineProperty( window.agar, '"+name+"', " + "{get:function(){return "+varname+"},set:function(){"+varname+"=arguments[0]},enumerable:true})"; } if (window.top != window.self) return; if (document.readyState !== 'loading') return console.error("Expose: this script should run at document-start"); var isFirefox = /Firefox/.test(navigator.userAgent); // Stage 1: Find corresponding rule var rules; for (var i = 0; i < allRules.length; i++) if (allRules[i].hostname.indexOf(window.location.hostname) !== -1) { rules = allRules[i]; break; } if (!rules) return console.error("Expose: cant find corresponding rule"); // Stage 2: Search for `main_out.js` if (isFirefox) { function bse_listener(e) { tryReplace(e.target, e) ;} window.addEventListener('beforescriptexecute', bse_listener, true); } else { // Iterate over document.head child elements and look for `main_out.js` for (var i = 0; i < document.head.childNodes.length; i++) if (tryReplace(document.head.childNodes[i])) return; // If there are no desired element in document.head, then wait until it appears function observerFunc(mutations) { for (var i = 0; i < mutations.length; i++) { var addedNodes = mutations[i].addedNodes; for (var j = 0; j < addedNodes.length; j++) if (tryReplace(addedNodes[j])) return observer.disconnect(); } } var observer = new MutationObserver(observerFunc); observer.observe(document.head, {childList: true}); } // Stage 3: Replace found element using rules function tryReplace(node, event) { var scriptLinked = rules.scriptUriRe && rules.scriptUriRe.test(node.src); var scriptEmbedded = rules.scriptTextRe && rules.scriptTextRe.test(node.textContent); if (node.tagName != "SCRIPT" || (!scriptLinked && !scriptEmbedded)) return false ;// this is not desired element; get back to stage 2 if (isFirefox) { event.preventDefault(); window.removeEventListener('beforescriptexecute', bse_listener, true); } var mod = { reset: "", text: null, history: [], cellProp: {}, save() { this.history.push({reset:this.reset, text:this.text}); return true; }, restore() { var state = this.history.pop(); this.reset = state.reset; this.text = state.text; return true; }, reset_(reset) { this.reset += reset; return true; }, replace(what, from, to, reset) { var vars = [], hooks = []; what.split(" ").forEach((x) => { x = x.split(":"); x[0] === "var" && vars.push(x[1]); x[0] === "hook" && hooks.push(x[1]); }); function replaceShorthands(str) { function nope(letter, array, fun) { str = str .split(new RegExp('\\$' + letter + '([0-9]?)')) .map((v,n) => n%2 ? fun(array[v||0]) : v) .join(""); } nope('v', vars, (name) => "window.agar." + name); nope('h', hooks, (name) => "window.agar.hooks." + name); nope('H', hooks, (name) => "window.agar.hooks." + name + "&&" + "window.agar.hooks." + name); return str; } var newText = this.text.replace(from, replaceShorthands(to)); if(newText === this.text) { console.error("Expose: `" + what + "` replacement failed!"); return false; } else { this.text = newText; if (reset) this.reset += replaceShorthands(reset) + ";"; return true; }