- // ==UserScript==
- // @name fsfb scripts
- // @namespace http://tampermonkey.net/
- // @version 0.1
- // @description a script for agma.io with features such as Copy Chat, Linesplit Toggle, Anti-AFK, Show Portal Mass, Change Food/Virus Color, and more!
- // @author fishy & firebone
- // @match *://agma.io/*
- // @run-at document-start
- // @icon https://i.imgur.com/8AASK55.png
- // @license GPL-3.0-or-later
- // @grant unsafeWindow
- // @grant GM_setValue
- // @grant GM_getValue
- // ==/UserScript==
-
- /* settings that you can't change in UI but might interfere with other scripts */
- let hideAds = true,
- improvedShop = true,
- extraBotPacks = true,
- rightClickCopyChat = true,
- rightClickCopyInfo = true,
- showRemainingAbilityTime = true,
- unlockFreeSkins = true,
- hoverShowSkinID = true,
- coinXPstats = true,
- quickBuy = false,
- whiteBorder4BlackCells = true;
-
-
- let settings = {
- hotkeys: [
- {title: "Shoot 7 Ejected", id: "fsfb-key7Feed", key: 0, active: false},
- {title: "Linesplit Lock", id: "fsfb-linesplit", key: 0, active: false},
- {title: "Macro Split Bots", id: "fsfb-MacroSplitBots", key: 0, active: false},
- {title: "Hide UI", id: "fsfb-hideUI", key: 0, active: false}
- ],
- checkboxes: [
- {title: "Chat Copy/Cut/Paste", id: "fsfb-copycutpaste", active: false},
- {title: "Anti-AFK", id: "fsfb-antiAFK", active: false},
- {title: "Anti-Invis", id: "fsfb-anticloak", active: false},
- {title: "Linesplit Toggle", id: "fsfb-linetoggle", active: false},
- {title: "Change Page Title", id: "fsfb-changetitle", active: false},
- {title: "Hide Shouts", id: "fsfb-hideshouts", active: false},
- {title: "Hold To Spam Rec", id: "fsfb-reco", active: false},
- {title: "Hold To Spam Speed", id: "fsfb-speed", active: false},
- {title: "Show Portal Mass", id: "fsfb-portalmass", active: false}
- ],
- slowFeed: [
- {title: "Toggle Feed", id: "fsfb-slowFeed", key: 0, active: false},
- {title: "Feed Speed", id: "fsfb-slowfeedtimer", val: 100, active: false}
- ],
- quickSettings: [
- {id: "fsfb-quick-hotkey1", id1: "fsfb-quick-select1", set: "cSkins", key: 0, active: false},
- {id: "fsfb-quick-hotkey2", id1: "fsfb-quick-select2", set: "cWearables", key: 0, active: false},
- {id: "fsfb-quick-hotkey3", id1: "fsfb-quick-select3", set: "cFood", key: 0, active: false},
- {id: "fsfb-quick-hotkey4", id1: "fsfb-quick-select4", set: "cBubbleCells", key: 0, active: false}
- ],
- theme: [
- {title: "Food Color", id: "fsfb-check-foodcolor", id1: "fsfb-color-foodcolor", color: "#FFFFFF", active: false},
- {title: "Virus Color", id: "fsfb-check-viruscolor", id1: "fsfb-color-viruscolor", color: "#00ff00", active: false},
- {title: "Virus Stroke", id: "fsfb-check-virusstroke", id1: "fsfb-color-virusstroke", color: "#00ff00", active: false},
- {title: "Mothercell Color", id: "fsfb-check-msColor", id1: "fsfb-color-msColor", color: "#cd5564", active: false},
- {title: "Mothercell Stroke", id: "fsfb-check-msStroke", id1: "fsfb-color-msStroke", color: "#cd5564", active: false}
- ],
- theme_boxes: [
- {title: "Fancy Bubble Cells", id: "fsfb-bublecell", active: false},
- {title: "Show Player Mass", id: "fsfb-showmass", active: false},
- {title: "Spiked Cells", id: "fsfb-spikedcells", active: false}
- ],
- export_import: [
- {title: "Game Settings", id: "fsfb-game-settings", active: false},
- {title: "Game Controls", id: "fsfb-game-controls", active: false},
- {title: "Script Settings", id: "fsfb-script-settings", active: false},
- {title: "Script Theme", id: "fsfb-theme-settings", active: false}
- ]
- }
-
- const txtMappings = { "": 0, "BACKSPACE": 8, "TAB": 9, "ENTER": 13, "SHIFT": 16, "CTRL": 17, "ALT": 18, "PAUSE": 19, "CAPSLOCK": 20, "ESC": 27, "SPACE": 32, "PAGEUP": 33, "PAGEDOWN": 34, "END": 35, "HOME": 36, "LEFT": 37, "UP": 38, "RIGHT": 39, "DOWN": 40, "PRTSCN": 44, "INS": 45, "DEL": 46, "WIN": 91, "CONTEXTMENU": 93, "NUM 0": 96, "NUM 1": 97, "NUM 2": 98, "NUM 3": 99, "NUM 4": 100, "NUM 5": 101, "NUM 6": 102, "NUM 7": 103, "NUM 8": 104, "NUM 9": 105, "NUM *": 106, "NUM +": 107, "NUM -": 109, "NUM .": 110, "NUM /": 111, "F1": 112, "F2": 113, "F3": 114, "F4": 115, "F5": 116, "F6": 117, "F7": 118, "F8": 119, "F9": 120, "F10": 121, "F11": 122, "F12": 123, "F13": 124, "F14": 125, "F15": 126, "F16": 127, "F17": 128, "F18": 129, "F19": 130, "F20": 131, "F21": 132, "F22": 133, "F23": 134, "F24": 135, "NUMLOCK": 144, "SCROLLLOCK": 145, ";": 186, "=": 187, ",": 188, "-": 189, ".": 190, "/": 191, "`": 192, "[": 219, "\\": 220, "]": 221, "'": 222 }
- const keyCodeMappings = { 0: "", 8: "BACKSPACE", 9: "TAB", 12: "CLEAR", 13: "ENTER", 16: "SHIFT", 17: "CTRL", 18: "ALT", 19: "PAUSE", 20: "CAPSLOCK", 27: "ESC", 32: "SPACE", 33: "PAGEUP", 34: "PAGEDOWN", 35: "END", 36: "HOME", 37: "LEFT", 38: "UP", 39: "RIGHT", 40: "DOWN", 44: "PRTSCN", 45: "INS", 46: "DEL", 91: "WIN", 92: "WIN", 93: "CONTEXTMENU", 96: "NUM 0", 97: "NUM 1", 98: "NUM 2", 99: "NUM 3", 100: "NUM 4", 101: "NUM 5", 102: "NUM 6", 103: "NUM 7", 104: "NUM 8", 105: "NUM 9", 106: "NUM *", 107: "NUM +", 109: "NUM -", 110: "NUM .", 111: "NUM /", 112: "F1", 113: "F2", 114: "F3", 115: "F4", 116: "F5", 117: "F6", 118: "F7", 119: "F8", 120: "F9", 121: "F10", 122: "F11", 123: "F12", 124: "F13", 125: "F14", 126: "F15", 127: "F16", 128: "F17", 129: "F18", 130: "F19", 131: "F20", 132: "F21", 133: "F22", 134: "F23", 135: "F24", 144: "NUMLOCK", 145: "SCROLLLOCK", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'"};
-
- const set = (name, obj) => typeof GM_setValue != "function" ? localStorage.setItem(name, JSON.stringify(obj)) : GM_setValue(name, obj),
- get = (name, default_obj) => typeof GM_getValue != "function" ? localStorage.getItem(name) != null ? JSON.parse(localStorage.getItem(name)) : set(name, default_obj) : GM_getValue(name, default_obj);
-
- if(typeof unsafeWindow === 'undefined') unsafeWindow = window;
- const saveSettings = () => set("fsfb-scripts", settings);
- const getSettings = () => {
- let settingsPrev = get("fsfb-scripts", settings);
- for(let i in settingsPrev) {
- for(let j in settingsPrev[i]) {
- for(let x in settings){
- for(let y in settings[x]){
- if(settingsPrev[i][j].id == settings[x][y].id) settings[x][y] = settingsPrev[i][j];
- }
- }
- }
- }
- }
- getSettings();
-
- const getKey = id => {
- const name = $("#" + id).text();
- return txtMappings[name] == null ? name.charCodeAt(0) : txtMappings[name];
- }
-
- const getName = key => keyCodeMappings[key] == null ? String.fromCharCode(key) : keyCodeMappings[key];
-
- const levelSum = lvl => lvl * (lvl - 1) / 2,
- range = arr => Math.max(...arr) - Math.min(...arr),
- sigma = arr => arr.reduce((a, b) => a + b),
- mean = arr => sigma(arr) / arr.length,
- variance = arr => arr.reduce((a, b) => a + (b - mean(arr)) ** 2, 0) / arr.length,
- standardDeviation = arr => Math.sqrt(variance(arr)),
- ascending = arr => arr.sort((a, b) => a - b),
- getIQR = arr => quartile(arr, .75) - quartile(arr, .25),
- round = (num, places) => Math.round(num * +("1e" + places)) / +("1e" + places);
- const median = arr => {
- const mid = ~~(arr.length / 2),
- asc = ascending(arr);
- return arr.length % 2 !== 0 ? asc[mid] : (asc[mid - 1] + asc[mid]) / 2;
- }
- const getProperty = (arr, property) => {
- let newArr = [];
- for (let i of arr) newArr.push(i[property]);
- return newArr;
- }
- const quartile = (arr, q) => {
- const sorted = ascending(arr),
- pos = (sorted.length - 1) * q,
- base = ~~pos,
- rest = pos - base;
- return sorted[base + 1] !== null ? sorted[base] + rest * (sorted[base + 1] - sorted[base]) : sorted[base]
- }
- const checkOutliers = (arr, returnOutliers) => {
- let nonOutliers = [], outliers = [];
- const IQR = getIQR(arr),
- Q1 = quartile(arr, .25),
- Q3 = quartile(arr, .75);
- for (let i of arr) i < Q1 - 1.5 * IQR || i > Q3 + 1.5 * IQR ? outliers.push(i) : nonOutliers.push(i);
- return returnOutliers ? outliers : nonOutliers;
- }
- const msToTime = ms => {
- let dur = ~~(ms / 1e3),
- sec = ~~(dur % 60),
- min = ~~((dur / 60) % 60),
- hr = ~~(dur / 3600);
- return (hr < 10 ? "0" + hr : hr) + ":" + (min < 10 ? "0" + min : min) + ":" + (sec < 10 ? "0" + sec : sec);
- }
- const changeTitle = title => {
- if(document.title != title) document.title = title;
- };
-
- if(!settings.checkboxes[5].active) changeTitle('Agma.io');
-
- if(unlockFreeSkins){
- const ytSkins = ["", 56, 1657, 2281, 2282, 2297, 2331, 2529, 2626, 2683, 2816, 2832];
- for (let i of ytSkins) localStorage.setItem('ytSkin' + i, '1');
- localStorage.setItem('fbSkin', '1');
- }
-
- ['paste', 'copy', 'cut'].forEach(a => {
- unsafeWindow.addEventListener(a, e => {
- if(!$('#fsfb-copycutpaste').is(':checked')) return;
- e.stopImmediatePropagation();
- }, true)
- });
-
- const afterLoaded = () => {
- // attempt to prevent the script from being active on subpages of agma.io
- if($('#friendResizer').length < 1 || $('#megaholder').length < 1 || $('#preroll').length < 1) return;
-
- $('.setting-tablink').css({'width' : '30%', "font-size" : "font-size: calc(0.3vw + 7.5px);"});
- $('#settingTab2').after(`<button id="settingTab4" class="setting-tablink" onclick="openSettingPage(4);" style="width: 9%; font-size: calc(0.3vw + 7.5px);"><div class="fa fa-cogs fa-lg" style="font-size: 1.25em; color: lightgray;"></div></button>`);
- $('#settingPage3').after(`<div id="settingPage4" class="setting-tabcontent"><div class="row"><div class="col-md-10 col-md-offset-1 stng" id="fsfb-settings-main" style="padding:0"><div id="fsfb-settings-left"><section id="fsfb-sect-checkbox" class="padbot10 fsfb-sect-ch"></section><section id="fsfb-sect-theme" class="fsfb-sect-ch"></section></div><div id="fsfb-settings-right"><section id="fsfb-sect-hotkeys" class="padbot10"></section><section id="fsfb-sect-slowfeed" class="padbot10"></section><section id="fsfb-sect-quickSettings" class="padbot10"></section><section id="fsfb-sect-imexport" class="fsfb-sect-ch"></section></div></div></div></div>`);
- $('.container').eq(0).css("max-width", "1250px");
- $('#fsfb-sect-checkbox').append(`<p class="hotkey-paragraph">Script Features</p>`);
-
- // add checkbox HTML
- for(let i of settings.checkboxes){
- $('#fsfb-sect-checkbox').append(`<label><input id="${i.id}" type="checkbox"><p> ${i.title} </p></label>`);
- $( "#" + i.id).change(function() {
- changeSettings(this.id, $(this).is(':checked'));
- });
- }
-
- // add import/export HTML
- $('#fsfb-sect-imexport').append(`<p class="hotkey-paragraph">Import/Export</p>`);
- for(let i of settings.export_import){
- $('#fsfb-sect-imexport').append(`<label><input id="${i.id}" type="checkbox"><p> ${i.title} </p></label>`);
- $( "#" + i.id).change(function() {
- changeSettings(this.id, $(this).is(':checked'));
- });
- }
- $('#fsfb-sect-imexport').append(`<div id="fsfb-ximport-cont"><div id="fsfb-export-btn" class="fsfb-eximport">Export</div><div id="fsfb-import-btn" class="fsfb-eximport">Import</div></div>`);
-
- $('#fsfb-sect-theme').append(`<p class="hotkey-paragraph">Game Theme</p`)
- for(let i of settings.theme){
- $('#fsfb-sect-theme').append(`<label><input id="${i.id}" type="checkbox"><p> ${i.title}</p><div style="background-color: black;"><input id="${i.id1}"type="color"></div></label>`);
- $( "#" + i.id).change(function() {
- changeSettings(this.id, $(this).is(':checked'));
- });
- $( "#" + i.id1).change(function() {
- changeSettings(this.id, this.value);
- $(this).parent().css('background-color', this.value); // bcs the regular [input="color"] looks rly shit, change color of overlayed div instead
- });
- }
- for(let i of settings.theme_boxes){
- $('#fsfb-sect-theme').append(`<label><input id="${i.id}" type="checkbox"><p> ${i.title} </p></label>`);
- $( "#" + i.id).change(function() {
- changeSettings(this.id, $(this).is(':checked'));
- });
- }
-
- $('#fsfb-sect-hotkeys').append(`<p class="hotkey-paragraph">Script Hotkeys</p>`);
-
- const checkHotkeyClicked = (e, thing) => {
- if (e.target.id == thing.id && !thing.active){
- $('#' + thing.id).addClass('selected');
- thing.active = true;
- keysChanging = true; // prevent features from triggering when setting hotkey
- } else {
- thing.active = false;
- $('#' + thing.id).removeClass('selected');
- }
- }
- const checkNewHotkey = (e, thing) => {
- if (!thing.active) return;
- thing.key = e.keyCode;
- $('#' + thing.id).text(getName(e.keyCode));
- $('#' + thing.id).removeClass('selected');
- thing.active = false;
- saveSettings();
- e.preventDefault();
- }
-
- const checkPowerupClicked = e => {
- if(!quickBuying || $(e.target).attr('class') == 'purchase-btn confirmation') return;
- let pwID;
- switch (e.target.id) {
- case 'invWall':
- pwID = 33;
- break;
- case 'invAntiFreeze':
- pwID = 35;
- break;
- case 'invAntiRecombine':
- pwID = 34;
- break;
- case 'invShield':
- pwID = 38;
- break;
- case 'invFrozenVirus':
- pwID = 36;
- break;
- case 'invRecombine':
- pwID = 1;
- break;
- case 'invSpeed':
- pwID = 2;
- break;
- case 'invGrowth':
- pwID = 6;
- break;
- case 'invSpawnVirus':
- pwID = 7;
- break;
- case 'invSpawnMothercell':
- pwID = 8;
- break;
- case 'invSpawnPortal':
- pwID = 9;
- break;
- case 'invSpawnGoldOre':
- pwID = 10;
- break;
- case 'invFreeze':
- pwID = 5;
- break;
- case 'inv360Shot':
- pwID = 30;
- break;
- case 'inv360Shot':
- pwID = 30;
- break;
- case 'fsfb-quickbuy-img':
- quickBuying = true;
- return;
- default:
- quickBuying = false;
- $('.inventory-box').removeClass('fsfb-shown').find('p').css('display', 'block');
- $('#fsfb-quickbuy').removeClass('activatedInv')
- curserMsg('Quick buy deactivated.', 'red');
- return;
- }
- $('.purchase-btn.confirmation[item="' + pwID + '"]')[0].click();
- $('.inventory-box').removeClass('fsfb-shown').find('p').css('display', 'block');
- $('#fsfb-quickbuy').removeClass('activatedInv')
- quickBuying = false;
- }
-
- const slowfeedhotkey = settings.slowFeed[0];
- for(let i of settings.hotkeys){
- $('#fsfb-sect-hotkeys').append(`<br><p>${i.title}</p><div id="${i.id}" class="fsfb-hotkey"></div>`);
- $('#' + i.id).on('contextmenu', e => {
- $('#' + i.id).text('');
- i.key = 0;
- saveSettings();
- e.preventDefault();
- });
- }
-
- const typing = () => $('input').is(':focus') || $('textarea').is(':focus');
- const press = key => {
- unsafeWindow.onkeydown({ keyCode: key });
- unsafeWindow.onkeyup({ keyCode: key });
- }
- let slowfeeding = !1, linesplitting = !1, hiddenUI = !1, splittingbots = !1, spamRec = !1, spamSpeed = !1;
-
- const pressed = e => {
- const key = e.which ? e.which : e.keyCode;
- if(typing() || keysChanging) return;
- if(key == settings.hotkeys[0].key){ // 7 feed
- let i = 1;
- let interval = setInterval(() => {
- press(getKey("keyMacroFeed"));
- if(++i > 7) clearInterval(interval);
- }, 70);
- e.preventDefault();
- }
- if(key == settings.hotkeys[1].key && !$('#fsfb-linetoggle').is(':checked')){ // linesplit lock
- linesplitting = true;
- linesplit();
- $("#linesplit-markers div").css('display', 'block');
- e.preventDefault();
- }
- if(key == settings.hotkeys[1].key && $('#fsfb-linetoggle').is(':checked')){ // linesplit lock
- linesplitting = !linesplitting;
- if(linesplitting){
- $("#linesplit-markers div").css('display', 'block');
- linesplit();
- } else $("#linesplit-markers div").css('display', 'none');
- e.preventDefault();
- }
- if(key == settings.hotkeys[2].key){ // macro split bots
- splittingbots = true;
- const splittingBots = () => {
- if(!splittingbots) return;
- press(getKey("keySplitBots"));
- setTimeout(splittingBots, 40);
- }
- splittingBots();
- e.preventDefault();
- }
-
- if(key == settings.hotkeys[3].key){ // hide ui
- hiddenUI = !hiddenUI;
- hiddenUI ? _replaceCSS('hideUI-css', '.hideUI{ display: none !important;}') : _replaceCSS('hideUI-css', ''); // replacing CSS bcs class is less likely to be overriden
- e.preventDefault();
- }
- if(key == settings.slowFeed[0].key){ // toggle feed
- slowfeeding = !slowfeeding;
- const feeding = () => {
- if(!slowfeeding) return;
- press(getKey("keyMacroFeed"));
- setTimeout(feeding, settings.slowFeed[1].val);
- }
- feeding();
- e.preventDefault();
- }
- if(key == settings.quickSettings[0].key){ // quick settings 1
- $('#' + settings.quickSettings[0].set).unbind().click();
- e.preventDefault();
- }
- if(key == settings.quickSettings[1].key){ // quick settings 2
- $('#' + settings.quickSettings[1].set).unbind().click();
- e.preventDefault();
- }
- if(key == settings.quickSettings[2].key){ // quick settings 3
- $('#' + settings.quickSettings[2].set).unbind().click();
- e.preventDefault();
- }
- if(key == settings.quickSettings[3].key){ // quick settings 4
- $('#' + settings.quickSettings[3].set).unbind().click();
- e.preventDefault();
- }
- if($('#fsfb-reco').is(':checked') && key == getKey("keyRecombine")){
- spamRec = true;
- const spammingRec = () => {
- if(!spamRec) return;
- press(getKey("keyRecombine"));
- setTimeout(spammingRec, 10);
- }
- spammingRec();
- e.preventDefault();
- }
- if($('#fsfb-speed').is(':checked') && key == getKey("keySpeed")){
- spamSpeed = true;
- const spammingSpeed = () => {
- if(!spamSpeed) return;
- press(getKey("keySpeed"));
- setTimeout(spammingSpeed, 10);
- }
- spammingSpeed();
- e.preventDefault();
- }
- }
-
- const released = key => {
- if(typing() || keysChanging) return;
- if(key == settings.hotkeys[2].key) splittingbots = false; // macro split bots
- if(key == settings.hotkeys[1].key && !$('#fsfb-linetoggle').is(':checked')){ // linesplit lock
- linesplitting = false;
- $("#linesplit-markers div").css('display', 'none');
- }
- if(key == getKey("keyRecombine")) spamRec = false;
- if(key == getKey("keySpeed")) spamSpeed = false;
- }
-
- const changeSettings = (ID, a) => {
- for(let i of settings.checkboxes) if(i.id == ID) i.active = a;
- for(let i of settings.export_import) if(i.id == ID) i.active = a;
- for(let i of settings.theme_boxes) if(i.id == ID) i.active = a;
- for(let i of settings.theme){
- if(i.id == ID) i.active = a
- if(i.id1 == ID) i.color = a;
- }
- customCells = $("#fsfb-sect-theme>label>input").is(":checked") || $("#fsfb-portalmass").is(":checked") || $("#fsfb-anticloak").is(":checked");
- if(ID == "fsfb-hideshouts") a ? $('#megaholder').addClass('hideMegaphone') : $('#megaholder').removeClass('hideMegaphone');
- saveSettings();
- }
- // add slowfeed HTML
- $('#fsfb-sect-slowfeed').append(`<p class="hotkey-paragraph">Slow-Feed</p>`);
- $('#fsfb-sect-slowfeed').append(`<br><p>${slowfeedhotkey.title}</p><div id="${slowfeedhotkey.id}" class="fsfb-hotkey"></div>`);
- $('#fsfb-sect-slowfeed').append(`<br><p>${settings.slowFeed[1].title}</p><input id="${settings.slowFeed[1].id}" class="fsfb-hotkey" onkeypress="return onlyNumberKey(event)" maxlength="3"></input>`);
-
- $('#' + slowfeedhotkey.id).on('contextmenu', e => {
- $('#' + slowfeedhotkey.id).text('');
- slowfeedhotkey.key = 0;
- saveSettings();
- e.preventDefault();
- });
-
- document.getElementById(settings.slowFeed[1].id).addEventListener("keypress", function(e){
- setTimeout(() => { // goes too fast or smth
- settings.slowFeed[1].val = +$('#' + settings.slowFeed[1].id).val();
- if($('#' + settings.slowFeed[1].id).val() == "") settings.slowFeed[1].val = 0;
- saveSettings();
- }, 5);
- });
-
- // add quick settings HTML
- $('#fsfb-sect-quickSettings').append(`<p class="hotkey-paragraph">Quick Settings</p>`);
-
- for(let i of settings.quickSettings){
- $('#fsfb-sect-quickSettings').append(`<select id="${i.id1}" class="fsfb-quickchange"><option value="cDark">Dark Theme</option><option value="cFancyGrid">Fancy Grid</option><option value="cSectionGrid">Section Grid</option><option value="cGrid">Gridlines</option><option value="cSkins">Skins</option><option value="cWearables">Wearables</option><option value="cNames">Show Names</option><option value="cMinionNames">Minion Names</option><option value="cLargeNames">Large Names</option><option value="cNameOutlines">Name Outline</option><option value="cMass">Show Mass</option><option value="cFood">Show Food</option><option value="cCellAnimations">Cell Anim...</option><option value="cSkinAnimations">Skin Anim...</option><option value="cMapBorder">Map Border</option><option value="cCustomBack">Custom BG</option><option value="aCustomBack">Sounds</option><option value="cZoom">Infinite Zoom</option><option value="cFixedZoom">Fixed Zoom</option><option value="cSlowMotion">Slow-Motion</option><option value="cMinionUi">Minion Panel</option><option value="cLeaderboard">Leaderboard</option><option value="cChat">Chat</option><option value="cMinimap">Minimap</option><option value="cFPS">FPS/Ping</option><option value="cColors">Cell Colors</option><option value="cCellBorders">Cell Borders</option><option value="cCellSpikes">Cell Spikes</option><option value="cClassicViruses">Classic Virus</option><option value="cPolygonShapes">Polygon Cells</option><option value="cLineShapes">Line Cells</option><option value="cBubbleCells">Bubble Cells</option></select><div id="${i.id}" class="fsfb-hotkey"></div>`);
- $('#' + i.id).on('contextmenu', e =>{
- $('#' + i.id).text('');
- i.key = 0;
- saveSettings();
- e.preventDefault();
- });
- };
-
- $('.fsfb-quickchange').on("change", function(){
- settings.quickSettings[+this.id.replace('fsfb-quick-select', '') - 1].set = this.value;
- saveSettings();
- });
-
- // add event listeners
- let mosX, mosY;
- let keys = {};
- let keysChanging = false;
-
- $(document).on('click', e => {
- for(let i = 0; i < settings.hotkeys.length; i++) checkHotkeyClicked(e, settings.hotkeys[i]);
- for(let i = 0; i < settings.quickSettings.length; i++) checkHotkeyClicked(e, settings.quickSettings[i]);
- checkHotkeyClicked(e, settings.slowFeed[0]);
- checkPowerupClicked(e);
- })
- .on('mousemove', e => {
- if(e.originalEvent == null || !e.originalEvent.isTrusted) return;
- ({clientX: mosX, clientY: mosY} = e);
- if (linesplitting) linesplit();
- })
- .on("keydown", e => {
- if(e.originalEvent == null || !e.originalEvent.isTrusted) return;
- for(let i = 0; i < settings.hotkeys.length; i++) checkNewHotkey(e, settings.hotkeys[i]);
- for(let i = 0; i < settings.quickSettings.length; i++) checkNewHotkey(e, settings.quickSettings[i]);
- checkNewHotkey(e, settings.slowFeed[0]);
- if (!(e.keyCode in keys)){
- keys[e.keyCode] = !0;
- pressed(e);
- }
- keysChanging = false;
- })
- .on("keyup", e => {
- if(e.originalEvent == null || !e.originalEvent.isTrusted) return;
- delete keys[e.keyCode];
- released(e.keyCode);
- });
-
- $('#fsfb-export-btn').on('click', () => {
- let script_settings = {},
- script_themes = {};
- for (let i in settings) { // put the settings & themes into different objects
- if (i == "theme" || i == "theme_boxes") script_themes[i] = settings[i];
- else if(i == "export_import") {}
- else script_settings[i] = settings[i];
- }
- let obj = {
- selected: {
- game_settings: $('#fsfb-game-settings').is(':checked'),
- game_controls: $('#fsfb-game-controls').is(':checked'),
- script_settings: $('#fsfb-script-settings').is(':checked'),
- script_theme: $('#fsfb-theme-settings').is(':checked')
- },
- game_settings: localStorage.settings,
- game_controls: localStorage.hotkeys,
- script_settings: script_settings,
- script_theme: script_themes
- }
- // if the setting is turned off, then dont need to export it - set it to null
- if(!obj.selected.game_settings) obj.game_settings = null;
- if(!obj.selected.game_controls) obj.game_controls = null;
- if(!obj.selected.script_settings) obj.script_settings = null;
- if(!obj.selected.script_theme) obj.script_theme = null;
-
- const a = document.createElement('a'),
- file = new Blob([JSON.stringify(obj)], {type: "text/plain"});
- a.href = URL.createObjectURL(file), a.download = "fishy & firebone script settings", a.click(), URL.revokeObjectURL(a.href); // download a txt file of exported settings
- });
-
- $('#fsfb-import-btn').on('click', () => {
- swal({
- title: "Import Settings",
- text: "Add your exported settings below and press OK to continue.",
- type: "input",
- showCancelButton: true,
- closeOnConfirm: false,
- animation: "slide-from-top",
- inputPlaceholder: "Paste exported settings here"
- },
- function(inputVal){
- if (inputVal == null) return false;
- if (inputVal == "") {
- swal.showInputError("Please don't leave the input empty!");
- return false
- }
- try {
- let val = JSON.parse(inputVal);
- if(val.selected.script_settings && $('#fsfb-script-settings').is(':checked')){
- for (let i in val.script_settings) {
- for (let j in val.script_settings[i]) {
- for(let x in settings){
- for(let y in settings[x]){
- if(val.script_settings[i][j].id == settings[x][y].id) settings[x][y] = val.script_settings[i][j];
- }
- }
- }
- }
- }
- if(val.selected.script_theme && $('#fsfb-theme-settings').is(':checked')){
- for (let i in val.script_theme) {
- for (let j in val.script_theme[i]) {
- for(let x in settings){
- for(let y in settings[x]){
- if(val.script_theme[i][j].id == settings[x][y].id) settings[x][y] = val.script_theme[i][j];
- }
- }
- }
- }
- }
- if(val.selected.game_settings && $('#fsfb-game-settings').is(':checked')) localStorage.setItem('settings', val.game_settings);
- if(val.selected.game_controls && $('#fsfb-game-controls').is(':checked')) localStorage.setItem('hotkeys', val.game_controls);
- // if any agma controls were imported, need to refresh bc it's set using localstorage
- if((val.selected.game_settings && $('#fsfb-game-settings').is(':checked')) || (val.selected.game_controls && $('#fsfb-game-controls').is(':checked'))){
- swal({
- title: "Please Refresh!",
- text: "Refreshing the page is required for your imported agma settings to take effect",
- type: "warning",
- });
- } else swal({ title: "Settings Successfully Imported!", type: "success" });
- saveSettings();
- updateScriptSettingsUI();
-
- } catch (error){
- swal({
- title: "Something went wrong!",
- text: "Please make sure you've entered in valid settings",
- type: "error"
- });
- }
- });
-
- });
-
- $('#fsfb-settings-right').append(`<div class="fa fa-2x fa-info-circle" id="fsfb-extra-info" data-toggle="modal" data-target=".fsfb-bug-modal"></div>`)
- // PUT MODAL HERE
-
-
- localStorage.ad_l_time = "9e99"; // smth like time since last ad
- $('[id^="agma-io_"], [id^="adWrapper"], #preroll').addClass("fuckAds"); // move ads way off the screen
-
- let width = unsafeWindow.innerWidth, height = unsafeWindow.innerHeight,
- points = [{n: "#linesplit-top", x: width / 2, y: 0, nx: width / 2, ny: -10e6}, {n: "#linesplit-bottom", x: width / 2, y: height, nx: width / 2, ny: 10e6}, {n: "#linesplit-left", x: 0, y: height / 2, nx: -10e6, ny: height / 2}, {n: "#linesplit-right", x: width, y: height / 2, nx: 10e6, ny: height / 2}];
-
- $(unsafeWindow).on('resize', function(){
- width = unsafeWindow.innerWidth, height = unsafeWindow.innerHeight;
- points = [{n: "#linesplit-top", x: width / 2, y: 0, nx: width / 2, ny: -10e6}, {n: "#linesplit-bottom", x: width / 2, y: height, nx: width / 2, ny: 10e6}, {n: "#linesplit-left", x: 0, y: height / 2, nx: -10e6, ny: height / 2}, {n: "#linesplit-right", x: width, y: height / 2, nx: 10e6, ny: height / 2}];
- });
-
- let pointMove;
- const linesplit = () => {
- if(!linesplitting) return;
- const distance = p => Math.sqrt(Math.pow(mosX - p.x, 2) + Math.pow(mosY - p.y, 2));
- let closest = points.reduce((a, b) => distance(a) < distance(b) ? a : b);
- for (let i = 0; i < points.length; i++) {
- if (closest.x == points[i].x && closest.y == points[i].y) {
- pointMove = {nx: points[i].nx, ny: points[i].ny}; // set var to the closest point so antiafk can access it and won't mess the linesplit up
- $('canvas').trigger($.Event('mousemove', {
- clientX: points[i].nx,
- clientY: points[i].ny
- }));
- }
- }
- $("#linesplit-markers div").css('background-color', 'transparent');
- $(closest.n).css('background-color', '#e25615');
- }
-
- let confBtns = document.getElementsByClassName('purchase-btn confirmation');
- const btnsArr = Array.from(document.getElementsByClassName('purchase-btn confirmation'));
-
- const changeHTML = (index, price, id, name) => {
- setTimeout(() => {
- const amtDropdown = document.getElementById('shopAmountDropdown')
- document.getElementsByClassName('sweet-alert showSweetAlert')[0].childNodes[7].firstChild.textContent = 'If you click "Buy", you will purchase this item. It will cost ' + price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + ' in total.';
- const dropdownChange = () => {
- if (amtDropdown.value == "custom") return buyCstmAmt(price, id, name);
- let priceSum = (amtDropdown.value * price).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
- document.getElementsByClassName('sweet-alert showSweetAlert')[0].childNodes[7].firstChild.textContent = 'If you click "Buy", you will purchase this item. It will cost ' + priceSum + ' in total.';
- };
- try { // try to remove old event listener before adding new one so they don't stack (no idea if this does anything bcs the event listener might be deleted anyway)
- amtDropdown.removeEventListener('change', dropdownChange);
- amtDropdown.addEventListener('change', dropdownChange);
- }
- catch (error){
- amtDropdown.addEventListener('change', dropdownChange);
- };
- }, 30);
- };
- const buyCstmAmt = (price, id, name) => {
- swal({
- title: "Enter Purchase Amount",
- text: "<span>How many <b>" + name + "</b> would you like to buy?</span>",
- html: true,
- type: "input",
- showCancelButton: true,
- closeOnConfirm: false,
- inputPlaceholder: "Input amount here"
- },
- function(input){
- let pwAmt = +input,
- priceTotal = pwAmt * price;
- if (input == null) return false;
- if (input == "") {
- swal.showInputError("Please don't leave the input empty!");
- return false
- }
- if(!/^[0-9]+$/.test(input) || !(+input >>> 0 === parseFloat(+input))){
- swal.showInputError("Please only enter positive integers!");
- return false
- }
- swal({
- title: 'Confirm',
- text: '<p>If you click "Buy", you will purchase this item. It will cost ' + priceTotal.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + ' in total.<br><small>You chose to purchase ' + pwAmt.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + ' <b>' + name + '</b></small></p>',
- html: true,
- type: 'warning',
- showCancelButton: true,
- closeOnConfirm: false,
- confirmButtonColor: '#4CAF50',
- confirmButtonText: 'Yes, confirm purchase',
- cancelButtonText: 'No, cancel purchase'
- }, function(confirmed){
- if(confirmed) buyPw(id, pwAmt);
- })
-
- });
- };
- // buy a certain amount of powers including > 255
- const buyPw = (shopID, pwAmt) => {
- if (pwAmt < 1) return;
- if (pwAmt > 255) {
- for (let i = 0; i < ~~(pwAmt / 255); i++) setTimeout(() => purchaseItem(shopID, 255), 250 * i + 250);
- purchaseItem(shopID, pwAmt % 255);
- } else purchaseItem(shopID, pwAmt);
- };
-
-
- if(improvedShop){
- // add event listeners to dropdown buttons
- for (let i = 0; i < confBtns.length; i++) {
- confBtns[i].onclick = function () {
- setTimeout(() => {
- if (document.getElementById('shopAmountDropdown') != null) document.getElementById('shopAmountDropdown').innerHTML += '<option value="20">20</option> <option value="50">50</option> <option value="100">100</option> <option value="250">250</option> <option value="custom">Pick</option>';
- }, 5);
- }
- }
- // add event listeners to shop buttons
- for (let i = 0; i < 16; i++) {
- if (i != 10 && i != 11){
- btnsArr[i].addEventListener('click', () => {
- let index = i;
- changeHTML(index, btnsArr[index].getAttribute('price'), btnsArr[index].getAttribute('item'), $('.purchase-btn.confirmation[item="' + btnsArr[index].getAttribute('item') + '"]').prev().find('h3').eq(0).text());
- });
- }
- }
- }
-
-
- // add extra bot packs
- const newBots = [
- {title: "100 Bots", time: "24 HOURS", price: "700,000", id: 9},
- {title: "125 Bots", time: "48 HOURS", price: "800,000", id: 10},
- {title: "300 Bots", time: "24 HOURS", price: "900,000", id: 7},
- {title: "100 MASS Bots", time: "1 HOURS", price: "800,000", id: 8},
- {title: "300 Bots", time: "72 HOURS", price: "2,000,000", id: 11},
- {title: "100 MASS Bots", time: "24 HOURS", price: "2,500,000", id: 12}
- ]
-
- const minul = document.getElementsByClassName('tab-container-section minion scroll')[0].children[0].children[0]
- $('.confirm-minion[item=7], .confirm-minion[item=8]').parent().hide();
- document.getElementById('extraTab').childNodes[0].setAttribute('onclick', '');
-
- function createEl(i) {
- const botEl = document.createElement('li');
- botEl.setAttribute('class', 'masterTooltip extra-min');
- botEl.setAttribute('title', 'Spawns bots/minions which suicide into your playercell to make you big in no time! Minions follow your mouse and split upon your command! Minions start immediately after you buy them.');
- minul.appendChild(botEl);
- botEl.innerHTML = `
- <div class="title_prch">
- <img src="img/store/minions/minions_tab.png" width="70px" height="60px">
- <div class="minionDescription">
- <h4 style="font-size: 18px;">` + i.title + `</h4>
- <h3 style="margin-top:10px;color:white;"> ` + i.time + `</h3>
- </div> <span class="win-price">` + i.price + `</span>
- </div>
- <a href="#" price="` + i.price + `" item="` + i.id + `" class="purchase-btn2 confirm-minion extra-min">Buy</a>
- `;
- }
- if(extraBotPacks){
- for(let i of newBots) createEl(i);
- }
-
- // $('.confirm-minion.extra-min').click(function(e) {
- // e.preventDefault(); // Prevent the href from redirecting directly
- // var linkURL = $(this).attr("href");
- // var priceK = $(this).attr("price");
- // var itemId = $(this).attr("item");
- // setMinionUi(true);
- // warnBeforeMinion(linkURL,priceK,itemId);
- // });
-
- function warnBeforeMinion(linkURL, priceK,itemId) {
- swal({
- title: "Confirm",
- text: 'If you click "Buy", you will purchase these minions. They cost ' + priceK,
- type: "warning",
- showCancelButton: true,
- confirmButtonColor: "#4CAF50",
- confirmButtonText: "Yes, confirm purchase",
- cancelButtonText: "No, cancel purchase"
- }, function() {
- purchaseMinion(itemId);
- });
- }
-
-
- // context menu: click on skin -> skin ID to clipboard, click on name -> name to clipboard
- $('#contextPlayer').on('click', e => {
- if(!rightClickCopyInfo) return;
- if($('#contextPlayerSkin').width() + $('#contextPlayerSkin').offset().left + 5 > e.pageX){ // bcs #contextMenu event :dog:
- // cell was clicked
- if($('#contextPlayerSkin').css('background-image') != "none"){
- let skinID = $('#contextPlayerSkin').css('background-image').match(/\/skins\/[0-9]+/g)[0].substring(7); // get the skin image, then match only the skin's ID
- navigator.clipboard.writeText(skinID).then(function() {
- curserMsg('Skin ID of ' + skinID + ' was copied to your clipboard.', 'green');
- }, function() {
- curserMsg('Something went wrong. Nothing was added to your clipboard.', 'red');
- });
- } else if($('#contextPlayerSkin').css('background-color') == 'rgb(51, 51, 51)') curserMsg('No player selected. Nothing was added to your clipboard.', 'red');
- else curserMsg('No skin equipped. Nothing was added to your clipboard.', 'red');
- } else { // name was clicked
- if($('#contextPlayerSkin').css('background-color') == 'rgb(51, 51, 51)') curserMsg('No player selected. Nothing was added to your clipboard.', 'red');
- else {
- navigator.clipboard.writeText($('#contextPlayerName').text()).then(function() {
- curserMsg('Nickname: "' + $('#contextPlayerName').text() + '" was copied to your clipboard', 'green');
- }, function() {
- curserMsg("Something went wrong. Nothing was added to your clipboard.", "red");
- });
- }
- }
- });
-
-
- // little bar at the top of the screen that tells u stuff
- const curserMsg = (msg, color) => {
- if(color == "green") color = "rgb(0, 192, 0)";
- if(color == "red") color = "rgb(255, 0, 0)";
- if(color == "gray") color = "rgb(153, 153, 153)";
- $('#curser').text(msg).show().css('color', color)
- setTimeout(() => $('#curser').fadeOut(400), 4e3);
- }
-
-
- // ability time remaining
- let acc_abil = get("fsfb-abil", {});
- let lastClickedPrice, currentPrice, lastID;
-
- const confirmClicked = () => {
- setTimeout(() => {
- if($('.sweet-alert.showSweetAlert.visible h2').text() != "Success!" || lastClickedPrice != currentPrice) return;
- acc_abil[currentUser] = {...acc_abil[currentUser], ...{[lastID] : Date.now()}};
- set("fsfb-abil", acc_abil);
- }, 1200);
- };
-
- [18, 20, 22, 23].forEach(el => {
- if(!showRemainingAbilityTime) return;
- let h5 = $(`.purchase-btn.confirmation[item="${el}"]`).parents().eq(0).find('div h5');
- h5.clone().insertAfter(h5).addClass('fsfb-fake').hide();
- $(`.purchase-btn[item="${el}"]`).on('click', function () {
- lastClickedPrice = this.getAttribute('price');
- lastID = this.getAttribute('item');
- $('.confirm').attr('disabled', 'true'); // disable so user doesn't buy early - swal is slow to load text
- setTimeout(() => {
- $('.confirm').removeAttr('disabled');
- currentPrice = $('.sweet-alert.showSweetAlert.visible p').eq(0).text().replaceAll(/\D+/g, '');
- }, 750);
- setTimeout(() => $('.confirm')[0].addEventListener('click', confirmClicked), 500);
- })
- });
-
- /* xp/coins statistics */
-
- const updateTimeXP = 12e3; // xp bar updates every 12 seconds, don't change
- let lastMinXP = [];
- let lastHrXP = [];
- let currentPercent, currentLevel, currentXP, currentCoins;
-
- unsafeWindow.logStatsScriptXP = !1;
- unsafeWindow.logStatsScriptCoins = !1;
- let scriptStart = Date.now();
- let accounts = {};
- const guiDisplay = "none";
- let coinsHTMLactive = false;
-
- const updateTimeCoins = 6e3;
- let lastMinCoins = [];
- let lastHrCoins = [];
-
- // add stats box html
- const statsBody = document.createElement('div');
- statsBody.setAttribute('id', 'stats-container');
- statsBody.style.display = guiDisplay;
- statsBody.innerHTML = `<div id="stats-main"><div id="stats-title"><title id="stats-extra-info">XP Stats - Updating Every 12s</title><div title="Reset Stats" class="fa fa-refresh" id="stats-reset-btn"></div></div><div><div><section id="stats-info"><div><p class="stats-label">Lvl Completed:</p><span>0/0</span></div><div><p class="stats-label">Remaining:</p><span>0</span></div><div><p class="stats-label">Projected (hr):</p><span>0</span></div><div><p class="stats-label">Last Hour:</p><span>0</span><span class="stats-completed">(0/60)</span></div><div><p class="stats-label">Last Minute:</p><span>0</span><span class="stats-completed">(0/5)</span></div><div><p class="stats-label">Last 12s:</p><span>0</span></div><div><p class="stats-label">Minute Mean:</p><span>0</span></div><div><p class="stats-label">Minute Median:</p><span>0</span></div><div><p class="stats-label">Minute Sd:</p><span>0</span></div><div style="display:none"><p class="stats-label">Latest Outliers:</p><span style="display:none">0, 200, 500</span></div><div><p class="stats-label">Session XP:</p><span>0</span></div><div><p class="stats-label">Session Length:</p><span>00:00:00</span></div><div><p class="stats-label" id="stats-sesh-length">Lifetime XP:</p><span>0</span></div><p style="font-size:0" id="last-updated">0</p></section></div></div>`;
- document.querySelector('body').append(statsBody)
-
- $('#stats-reset-btn').on('click', () => {
- lastMinCoins = [];
- lastHrCoins = [];
- lastMinXP = [];
- lastHrXP = [];
- scriptStart = Date.now();
- accounts = {};
- updateUI();
- });
-
-
- class record {
- constructor(val, user, arr) {
- // this.type = this.findWhich(arr); // mostly for debugging
- this.id = this.getID(arr);
- this.user = user;
- this.amount = val;
- this.gained = this.calcGain(val, arr, this.id);
- // this.timestamp = Date.now(); // mostly for debugging
- }
- findWhich(arr) {
- return ((arr == lastMinXP || arr == lastHrXP ? "xp " : "coins " ) + (arr == lastHrXP || arr == lastHrCoins ? "hour" : "minute"));
- }
- calcGain(val, arr, id){
- const prevObj = arr[arr.length - 1];
- if(arr == lastHrXP && id == 1) return round(sigma(getProperty(lastMinXP, "gained")), 3);
- if(arr == lastHrCoins && id == 1) return round(sigma(getProperty(lastMinCoins, "gained")), 3);
- return prevObj && val - prevObj.amount >= 0 && prevObj.user == this.user && prevObj.amount != 0 ? round(val - prevObj.amount, 3) : 0;
- }
- getID(arr) {
- return arr[arr.length - 1] ? arr[arr.length - 1].id + 1 : 1;
- }
-
- }
-
- const xpInfo = () => {
- currentPercent = $('.progress-bar[role=progressbar]')[0].style.width.slice(0, -1) / 100;
- currentLevel = $('#level.user-level')[0].textContent;
- currentXP = (levelSum(currentLevel) + currentLevel * currentPercent) * 1e3;
- }
- const coinsInfo = () => {
- currentCoins = +($('#coinsDash')[0].textContent.replaceAll(' ', ''));
- }
-
- const updateUI = () => {
- if(!coinsHTMLactive){
- const xpHr = lastHrXP.length,
- xpMin = lastMinXP.length,
- lvlCompleted = currentPercent ? String(Math.round(currentPercent * currentLevel * 1e3, 1)).replace(/\B(?=(\d{3})+(?!\d))/g, ",") + "/" + (currentLevel * 1e3).toLocaleString('en-US') : "0/0",
- xpRemaining = currentLevel ? Math.round(currentLevel * 1e3 - currentPercent * currentLevel * 1e3) : 0,
- projectedHr = xpHr > 0 ? Math.round(sigma(getProperty(lastHrXP.slice(-5), "gained")) * 12) : 0,
- lastHr = xpHr > 0 ? Math.round(sigma(getProperty(lastHrXP, "gained"))) : 0,
- lastHrCompleted = xpHr > 0 ? xpHr : 0,
- lastMin = xpMin > 0 ? Math.round(sigma(getProperty(lastMinXP, "gained"))) : 0,
- lastMinCompleted = xpMin > 0 ? xpMin : 0,
- lastMinTotal = 6e4 / updateTimeXP,
- last12sec = xpMin > 0 ? Math.round(lastMinXP[lastMinXP.length - 1].gained) : 0,
- xBar = xpHr > 0 ? Math.round(mean(getProperty(lastHrXP, "gained"))) : 0,
- xTilde = xpHr > 0 ? Math.round(median(getProperty(lastHrXP, "gained"))) : 0,
- standardDev = xpHr > 0 ? Math.round(standardDeviation(getProperty(lastHrXP, "gained"))) : 0,
- outliers = xpHr > 0 ? checkOutliers(getProperty(lastHrXP, "gained")) : 0,
- sessionXP = currentXP && accounts[currentUser] ? Math.round(currentXP - accounts[currentUser].xp): 0,
- sessionLength = msToTime(Date.now() - scriptStart),
- lifetimeXP = currentXP ? Math.round(currentXP) : 0,
- updateTime = updateTimeXP;
- document.getElementById('stats-info').innerHTML = `<div><p class="stats-label">Lvl Completed:</p><span>${lvlCompleted.toLocaleString('en-US')}</span></div><div><p class="stats-label">Remaining:</p><span>${xpRemaining.toLocaleString('en-US')}</span></div><div><p class="stats-label">Projected (hr):</p><span>${projectedHr.toLocaleString('en-US')}</span></div><div><p class="stats-label">Last Hour:</p><span>${lastHr.toLocaleString('en-US')}</span><span class="stats-completed">(${lastHrCompleted}/60)</span></div><div><p class="stats-label">Last Minute:</p><span>${lastMin.toLocaleString('en-US')}</span><span class="stats-completed">(${lastMinCompleted + "/" + lastMinTotal})</span></div><div><p class="stats-label">Last 12s:</p><span>${last12sec.toLocaleString('en-US')}</span></div><div><p class="stats-label">Minute Mean:</p><span>${xBar.toLocaleString('en-US')}</span></div><div><p class="stats-label">Minute Median:</p><span>${xTilde.toLocaleString('en-US')}</span></div><div><p class="stats-label">Minute Sd:</p><span>${standardDev.toLocaleString('en-US')}</span></div><div><p class="stats-label" style="display:none">Latest Outliers:</p><span style="display:none">${outliers}</span></div><div><p class="stats-label">Session XP:</p><span>${sessionXP.toLocaleString('en-US')}</span></div><div><p class="stats-label">Session Length:</p><span id="stats-sesh-length">${sessionLength}</span></div><div><p class="stats-label">Lifetime XP:</p><span>${lifetimeXP.toLocaleString('en-US')}</span></div>`;
- $('#stats-extra-info').text(`XP Stats - Updating Every ${updateTime / 1e3}s`).css('color', '#00bbff');
- } else {
- const coinsHr = lastHrCoins.length,
- coinsMin = lastMinCoins.length,
- coinGoalCompleted = currentCoins ? currentCoins.toLocaleString('en-US') + "/" + Math.ceil(currentCoins / 25e4).toLocaleString('en-US') * 25e4 : 0,
- coinsRemaining = currentCoins ? 25e4 - currentCoins % 25e4 : 0,
- projectedHr = coinsHr > 5 ? Math.round(sigma(getProperty(lastHrCoins.slice(-5), "gained")) * 12) : 0,
- lastHr = coinsHr > 0 ? Math.round(sigma(getProperty(lastHrCoins, "gained"))) : 0,
- lastHrCompleted = coinsHr > 0 ? coinsHr : 0,
- lastMin = coinsMin > 0 ? Math.round(sigma(getProperty(lastMinCoins, "gained"))) : 0,
- lastMinCompleted = coinsMin > 0 ? coinsMin : 0,
- lastMinTotal = 6e4 / updateTimeCoins,
- last12sec = coinsMin > 0 ? getProperty(lastHrCoins.slice(-5), "amount")[0] : 0,
- xBar = coinsHr > 0 ? Math.round(mean(getProperty(lastHrCoins, "gained"))) : 0,
- xTilde = coinsHr > 0 ? Math.round(median(getProperty(lastHrCoins, "gained"))) : 0,
- standardDev = coinsHr > 0 ? Math.round(standardDeviation(getProperty(lastHrCoins, "gained"))) : 0,
- outliers = coinsHr > 0 ? checkOutliers(getProperty(lastHrCoins, "gained")) : 0,
- sessionXP = currentCoins && accounts[currentUser] ? Math.round(currentCoins - accounts[currentUser].coins): 0,
- sessionLength = msToTime(Date.now() - scriptStart),
- updateTime = updateTimeCoins;
- document.getElementById('stats-info').innerHTML = `<div style="display:none"><p class="stats-label">Coins Completed:</p><span>${coinGoalCompleted}</span></div><div><p class="stats-label">Remaining:</p><span>${coinsRemaining.toLocaleString('en-US')}</span></div><div><p class="stats-label">Projected (hr):</p><span>${projectedHr.toLocaleString('en-US')}</span></div><div><p class="stats-label">Last Hour:</p><span>${lastHr.toLocaleString('en-US')}</span><span class="stats-completed">(${lastHrCompleted}/60)</span></div><div><p class="stats-label">Last Minute:</p><span>${lastMin.toLocaleString('en-US')}</span><span class="stats-completed">(${lastMinCompleted + "/" + lastMinTotal})</span></div><div style="display:none"><p class="stats-label">Last 12s:</p><span></span></div><div><p class="stats-label">Minute Mean:</p><span>${xBar.toLocaleString('en-US')}</span></div><div><p class="stats-label">Minute Median:</p><span>${xTilde.toLocaleString('en-US')}</span></div><div><p class="stats-label">Minute Sd:</p><span>${standardDev.toLocaleString('en-US')}</span></div><div><p class="stats-label" style="display:none">Latest Outliers:</p><span style="display:none">${outliers}</span></div><div><p class="stats-label">Session Coins:</p><span>${sessionXP.toLocaleString('en-US')}</span></div><div><p class="stats-label">Session Length:</p><span id="stats-sesh-length">${sessionLength}</span></div>`;
- $('#stats-extra-info').text(`Coin Stats - Updating Every ${updateTime / 1e3}s`).css('color', '#ffc800');
- }
- }
-
- $('.progress-bar').eq(1).parent()[0].style.cursor = "pointer";
-
- if(coinXPstats){
- $('.progress-bar').eq(1).parent().on("click", () => {
- const statsCont = $('#stats-container');
- if(statsCont[0].style.display == "none") statsCont.fadeIn(400);
- else if(!coinsHTMLactive) statsCont.fadeOut(400);
- coinsHTMLactive = false;
- updateUI();
- }), [$(".dash-coin.dcTopBar").eq(0), $("#coinsTopLeft"), $(".progress-bar-coins").eq(1)].forEach(el => {
- el.on('click', (e) => {
- const statsCont = $('#stats-container');
- if(statsCont[0].style.display == "none") statsCont.fadeIn(400);
- else if(coinsHTMLactive) statsCont.fadeOut(400);
- coinsHTMLactive = true;
- updateUI();
- e.stopImmediatePropagation();
- });
- });
- }
-
- // copy chat msgs
- if(rightClickCopyChat){
- $('#contextSpectate').after(`<li id="contextCopyChat" class="contextmenu-item enabled"><div class="fa fa-clipboard fa-2x context-icon"></div><p>Copy Chat Messages</p></li>`)
- $('#contextCopyChat').on('click', () => {
- let arr = chatmsgs, str = "";
- if(arr != null){
- for(let i of arr.reverse()) str += ((new Date(i.time).toLocaleTimeString()) + " " + i.name + i.cache.oe + "\n")
- navigator.clipboard.writeText(str).then(function() {
- curserMsg('Chat messages were successfully added to clipboard.', 'green');
- }, function() {
- curserMsg('Something went wrong. Nothing was added to your clipboard.', 'red');
- });
- }
- $('#contextMenu').fadeOut(100);
- });
- }
-
- let quickBuying = false;
- if(quickBuy){
- $('#inv360Shot').after(`<div class="inventory-box" id="fsfb-quickbuy"><img id="fsfb-quickbuy-img" height="80%" src="https://i.imgur.com/tAjoEyU.png"></div>`);
- $('#fsfb-quickbuy').on('click', function(){
- quickBuying = !quickBuying;
- if (quickBuying){
- $(this).addClass('activatedInv');
- curserMsg('Quick buy activated, click the powerup you would like to buy.', 'green');
- $('.inventory-box').addClass('fsfb-shown').find('p').css('display', 'none');
- $('#invCloak').removeClass('fsfb-shown');
- } else {
- $(this).removeClass('activatedInv');
- curserMsg('Quick buy deactivated.', 'red');
- $('.inventory-box').removeClass('fsfb-shown').find('p').css('display', 'block');
- }
- });
-
- }
- // add linesplit bubbles
- $('body').append(`<div id="linesplit-markers"><div id="linesplit-top"></div><div id="linesplit-right"></div><div id="linesplit-bottom"></div><div id="linesplit-left"></div></div>`); // linesplit html
- // add class to all elements that need to behidden
- $('#inventory, #chat, #minionUi, #infection_remain_zombie, #party, #challengeInfoBox, #gamemodeBox, #infoBox, #brGameContainer, #infGameContainer, #curser, #leaderboard, #minimap, #btnFriends, .innerBoxDashboard2, #fpsBox, #settingsBtn, #megaholder').addClass("hideUI");
-
-
- let pushFn = Array.prototype.push,
- spliceFn = Array.prototype.splice,
- prop = null,
- customCells = !0,
- specialCells = !0,
- customDc = !1,
- avgFps = 0,
- fpsArr = [],
- chatmsgs, r1Portal = {
- portal: null,
- lastMass: 0,
- lastMassChange: 0,
- lastValue: 0,
- room: 1
- },
- r2Portal = {
- portal: null,
- lastMass: 0,
- lastMassChange: 0,
- lastValue: 0,
- room: 2
- },
- svInfo = {
- default: {
- ejPortalMass: 12,
- r1Id: 1,
- r2Id: 7,
- r3Id: null,
- r1StartMass: 500,
- r2StartMass: 500
- },
- 2: {
- ejPortalMass: 20,
- r1Id: 1,
- r2Id: 14,
- r3Id: 6,
- r1StartMass: 500,
- r2StartMass: 500
- },
- 4: {
- ejPortalMass: 20,
- r1Id: 1,
- r2Id: 14,
- r3Id: 6,
- r1StartMass: 500,
- r2StartMass: 500
- },
- 6: {
- ejPortalMass: 12,
- r1Id: 1,
- r2Id: 6,
- r1StartMass: 500,
- r2StartMass: 500
- },
- 13: {
- ejPortalMass: 13.5,
- r1Id: 12,
- r2Id: 11,
- r1StartMass: 500,
- r2StartMass: 500
- },
- 14: {
- ejPortalMass: 13.5,
- r1Id: 12,
- r2Id: 11,
- r1StartMass: 500,
- r2StartMass: 500
- },
- 38: {
- ejPortalMass: 12,
- r1Id: 1,
- r2Id: 6,
- r1StartMass: 500,
- r2StartMass: 400
- },
- 39: {
- ejPortalMass: 11,
- r1Id: 1,
- r2Id: 13,
- r3Id: 7,
- r1StartMass: 1004,
- r2StartMass: 250,
- r3StartMass: 1004
- }
- },
- noPortalSvIdList = [11, 19, 23, 24, 37, 36, 31, 29, 40, 41, 16, 15, 21, 35, 12, 25, 42, 28, 32, 22, 18, 26, 30],
- currentServerId = 0,
- currentServerName = "";
- for (let i of JSON.parse(localStorage.gameservers)) i.isCurrent && (currentServerId = +i.address.substr(1, 2), currentServerName = i.name);
- let ss = unsafeWindow.setserver;
-
- function getServerValue(a) {
- return svInfo[currentServerId] && svInfo[currentServerId][a] ? svInfo[currentServerId][a] : svInfo.default[a]
- }
-
- function customize(a) {
- let b = a.__proto__.de;
- a.__proto__.de = function () {
- let a = this,
- c = a[prop[46]];
- return 0 == c && ((settings.theme_boxes[1].active || settings.checkboxes[2].active) && (a[prop[45]] = !0), settings.theme_boxes[2].active ? (void 0 === a.oSpiked && (a.oSpiked = a[prop[56]]), a[prop[56]] = settings.theme_boxes[2].active) : void 0 != a.oSpiked && (a[prop[56]] = a.oSpiked)), 1 == c && ("#00ff00" == a.color && (a.color = "#00ff01"), settings.theme[0].active ? (a.oColor || (a.oColor = a.color), a.color = settings.theme[0].color) : a.oColor && (a.color = a.oColor)), b.apply(this, arguments)
- }, customDc = !0
- }
-
- function dimmColor(d) {
- var a = (~~(.5 * parseInt(d.substr(1, 2), 16))).toString(16),
- b = (~~(.5 * parseInt(d.substr(3, 2), 16))).toString(16),
- c = (~~(.5 * parseInt(d.substr(5, 2), 16))).toString(16);
- return 1 == a.length && (a = "0" + a), 1 == b.length && (b = "0" + b), 1 == c.length && (c = "0" + c), "#" + a + b + c
- }
- unsafeWindow.setserver = (a, b) => {
- currentServerId = +a.substr(1, 2), currentServerName = b, r1Portal.portal = null, r2Portal.portal = null, ss(a, b)
- }, Array.prototype.push = function () {
- if (this.length > 0 && this[0].hasOwnProperty("goldMember") && (chatmsgs = this), customCells && this.length && "number" == typeof this[0].id && "string" == typeof this[0].color) {
- let b = this[this.length - 1],
- a = arguments[0];
- prop || (prop = Object.keys(b)), a.id === getServerValue("r1Id") ? r1Portal.portal = a : a.id === getServerValue("r2Id") && (r2Portal.portal = a), customDc || customize(b)
- }
- return pushFn.apply(this, arguments)
- }, Array.prototype.splice = function () {
- if (customCells && this.length && "number" == typeof this[0].id && "string" == typeof this[0].color) {
- let a = this[arguments[0]];
- a == r1Portal.portal ? r1Portal.portal = null : a == r2Portal.portal && (r2Portal.portal = null)
- }
- return spliceFn.apply(this, arguments)
- };
- let fillFn = CanvasRenderingContext2D.prototype.fill;
- CanvasRenderingContext2D.prototype.fill = function () {
- return settings.theme_boxes[0].active && "canvas" === this.canvas.id && .4 == this.globalAlpha && (this.globalAlpha = .15), settings.theme[1].active && "#00ff00" == this.fillStyle && (this.fillStyle = settings.theme[1].color), settings.theme[3].active && "#cd5564" == this.fillStyle && (this.fillStyle = settings.theme[3].color), whiteBorder4BlackCells && "#000000" == this.fillStyle && (this.strokeStyle = "#FFFFFF", this.lineWidth = 20, this.stroke()), fillFn.apply(this, arguments)
- };
- let strokeFn = CanvasRenderingContext2D.prototype.stroke;
- CanvasRenderingContext2D.prototype.stroke = function () {
- return "canvas" === this.canvas.id && (settings.checkboxes[2].active && ("#dddddd" == this.strokeStyle || "#333333" == this.strokeStyle) && (this.strokeStyle = $("#cDark").prop("checked") ? "#FFFFFF" : "#000000"), settings.theme_boxes[0].active && 4 != this.lineWidth && $("#cBubbleCells").prop("checked") && (this.lineWidth = 15 + Math.min(Math.max(avgFps - 25, 0), 10)), (settings.theme[1].active || settings.theme[2].active) && ("#00ff00" == this.strokeStyle || "#00cc00" == this.strokeStyle) && (this.strokeStyle = settings.theme[2].active ? settings.theme[2].color : settings.theme_boxes[0].active && $("#cBubbleCells").prop("checked") ? settings.theme[1].color : dimmColor(settings.theme[1].color)), (settings.theme[3].active || settings.theme[4].active) && ("#cd5564" == this.strokeStyle || "#a44450" == this.strokeStyle) && (this.strokeStyle = settings.theme[4].active ? settings.theme[4].color : settings.theme_boxes[0].active && $("#cBubbleCells").prop("checked") ? settings.theme[3].color : dimmColor(settings.theme[3].color))), strokeFn.apply(this, arguments)
- };
- let drawImgFn = CanvasRenderingContext2D.prototype.drawImage;
- CanvasRenderingContext2D.prototype.drawImage = function () {
- if (drawImgFn.apply(this, arguments), -1 == noPortalSvIdList.indexOf(currentServerId) && "AS | MegaSplit" != currentServerName && "canvas" == this.canvas.id && settings.checkboxes[8].active && ("https://agma.io/skins/objects/1_lo.png?v=2" == arguments[0].src || "https://agma.io/skins/objects/1.png?v=2" == arguments[0].src) && (r1Portal.portal || r2Portal.portal)) {
- let a = a => {
- a.portal.nSize * a.portal.nSize / 100 != a.lastMass && (a.lastMassChange = Date.now()), a.lastMass = a.portal.nSize * a.portal.nSize / 100;
- let b = Date.now() - a.lastMassChange > 200 ? ~~((a.portal.nSize * a.portal.nSize / 100 - getServerValue("r" + a.room + "StartMass")) / getServerValue("ejPortalMass")).toString() : a.lastValue;
- a.lastValue = b, this.fillStyle = "7" == b ? "#FFCC12" : "#FFFFFF", this.globalAlpha = 1, this.font = "72px Ubuntu, serif", this.fillText(b, a.portal.x - this.measureText(b).width / 2, a.portal.y + 20)
- };
- r1Portal.portal && a(r1Portal), 39 != currentServerId && r2Portal.portal && a(r2Portal)
- }
- }
-
-
- // const oldFillText = CanvasRenderingContext2D.prototype.fillText;
- // CanvasRenderingContext2D.prototype.fillText = function() {
- // if (hiddenUI && arguments[0].includes("Mass: ")) arguments[0] = "";
- // oldFillText.apply(this, arguments);
- // }
-
- let intervalCount = 0, currentUser, lastLoggedOut = Date.now();
- const mainInterval = setInterval(() => {
- intervalCount++;
- if(hoverShowSkinID && $('#publicSkinsPage').children().length > 0){ // check if skins have loaded
- $('[id^="skinContainer"]').each(function(){
- $(this).find('img').attr('title', $(this).attr('id').replace('skinContainer', '')); // make hover show skin ID
- })
- $('.publicskins-nav-btn').on('click', () => {
- $('[id^="skinContainer"]').each(function(){
- $(this).find('img').attr('title', $(this).attr('id').replace('skinContainer', ''));
- })
- })
- }
- currentUser = $('#userCoins2')[0].innerText;
- let user_abil = currentUser == 'Please Login First' ? null : acc_abil[currentUser];
- if(user_abil != undefined && showRemainingAbilityTime){
- for(let i in user_abil){
- let text = $(`.purchase-btn.confirmation[item="${i}"]`).parents().eq(0).find('div h5'),
- active = $('#' + $(`.purchase-btn.confirmation[item="${i}"]`).parents().eq(0)[0].id + ' img').eq(1).css('display') != "none";
- // has been 24h+ and the player hasn't logged out since it's expired
- if(Date.now() - user_abil[i] > 8.64e7 && active){
- text.eq(1).text('EXPIRED IF UNLOG');
- text.eq(0).find('div h5').hide();
- }
- // has been >24h
- else if(Date.now() - user_abil[i] < 8.64e7 && active){
- text.eq(0).hide();
- text.eq(1).text(msToTime(8.64e7 - (Date.now() - user_abil[i]))).show();
- }
- else { // has been 24h+ & player has logged out
- text.eq(1).find('div h5').hide();
- text.eq(0).find('div h5').show();
- }
-
- }
- } else {
- $('.white_shopdesc').show();
- $('.white_shopdesc.fsfb-fake').hide();
- }
- if(accounts[currentUser] == null && currentUser !== 'Please Login First'){
- xpInfo();
- coinsInfo();
- accounts = {...accounts, ...{[currentUser] : {coins: currentCoins, xp: currentXP}}};
- }
- if(coinXPstats && intervalCount % 12 == 0){
- xpInfo();
- lastMinXP.push(new record(round(currentXP, 3), currentUser, lastMinXP));
- const prevObjXP = lastMinXP[lastMinXP.length - 1];
- if (prevObjXP && prevObjXP.id % (6e4 / updateTimeXP) == 0) lastHrXP.push(new record(currentXP, currentUser, lastHrXP));
- if (lastMinXP.length > 6e4 / updateTimeXP) lastMinXP.shift();
- if (lastHrXP.length > 60) lastHrXP.shift();
- if(!coinsHTMLactive && $('#stats-container').css('display') == 'block') updateUI();
- }
- if(coinXPstats && intervalCount % 6 == 0){
- coinsInfo();
- lastMinCoins.push(new record(currentCoins, currentUser, lastMinCoins));
- const lastObjCoins = lastMinCoins[lastMinCoins.length - 1];
- if (lastObjCoins && lastObjCoins.id % (6e4 / updateTimeCoins) == 0) lastHrCoins.push(new record(currentCoins, currentUser, lastHrCoins));
- if (lastMinCoins.length > 6e4 / updateTimeCoins) lastMinCoins.shift();
- if (lastHrCoins.length > 60) lastHrCoins.shift();
- if(coinsHTMLactive && $('#stats-container').css('display') == 'block') updateUI();
- }
- $('#stats-sesh-length').text(msToTime(Date.now() - scriptStart));
-
- if(currentUser == 'Please Login First' || $('#level').text() == 0) lastLoggedOut = Date.now();
- changeTitle(settings.checkboxes[4].active ? currentUser == 'Please Login First' ? "Agma.io" : "Agma.io - " + currentUser : "Agma.io - A free multiplayer MMO game");
-
- fpsArr.push(+document.getElementById("fps").innerText);
- if(fpsArr.length == 6) fpsArr.shift();
- avgFps = mean(fpsArr);
- }, 1e3);
-
- const antiAFK = () => {
- setTimeout(antiAFK, 3e4);
- if(!$('#fsfb-antiAFK').is(':checked'))return; // move mouse every 30sec
- if(linesplitting){
- $('#canvas').trigger($.Event('mousemove', {clientX: pointMove.nx + 1, clientY: pointMove.ny}));
- $('#canvas').trigger($.Event('mousemove', {clientX: pointMove.nx - 1, clientY: pointMove.ny}));
- } else {
- $('#canvas').trigger($.Event('mousemove', {clientX: mosX + 1, clientY: mosY}));
- $('#canvas').trigger($.Event('mousemove', {clientX: mosX - 1, clientY: mosY}));
- }
- }
- setTimeout(antiAFK, 3e4);
-
-
- const updateScriptSettingsUI = () => {
- for(let i of settings.checkboxes){
- $('#' + i.id).prop("checked", i.active);
- $('#' + i.id).trigger("change");
- }
- for(let i of settings.hotkeys) $('#' + i.id).text(getName(i.key));
- for(let i of settings.quickSettings){
- $('#' + i.id1).val(i.set);
- $('#' + i.id).text(getName(i.key));
- }
- $('#' + settings.slowFeed[0].id).text(getName(settings.slowFeed[0].key));
- $('#' + settings.slowFeed[1].id).val(settings.slowFeed[1].val);
- for(let i of settings.export_import){
- $('#' + i.id).prop("checked", i.active);
- $('#' + i.id).trigger("change");
- }
- for(let i of settings.theme){
- $('#' + i.id).prop("checked", i.active);
- $('#' + i.id).trigger("change");
- $('#' + i.id1).val(i.color);
- $('#' + i.id1).trigger("change");
- }
- for(let i of settings.theme_boxes){
- $('#' + i.id).prop("checked", i.active);
- $('#' + i.id).trigger("change");
- }
- }
- setTimeout(() => updateScriptSettingsUI(), 1e3);
-
- $('body').append('<div id="fsfb-css-styles"><style id="hideUI-css" type="text/css"></style></div>');
-
- const _replaceCSS = (a,b) => {
- document.getElementById(a).innerHTML = b;
- }
- $('body').append(`
- <div class="modal fade fsfb-bug-modal" tabindex="-1" role="dialog" aria-hidden="true">
- <div class="modal-dialog modal-lg">
- <div class="modal-content">
- <div class="modal-interior">
- <h2 class="fsfb-modal-title">Script Documentation</h2>
- <button type="button" class="close fsfb-btn" data-dismiss="modal">×</button>
- <section class="fsfb-modal-body">
- <!-- Checkboxes -->
- <div><span>Chat Copy/Cut/Paste</span> - allows you to use the commands in chat (e.g. Ctrl + V becomes avaiable inside chat)</div>
- <div><span>Anti-AFK</span> - prevents you from automatically disconnecting after 10 minutes</div>
- <div><span>Anti-Invis</span> - shows you players even when they have the invisibility ability active</div>
- <div><span>Linesplit Toggle</span> - enabled means that if you press the linesplit hotkey, it will turn linesplitting on until the key is pressed again (in contrast to stopping the linesplit when key is released)</div>
- <div><span>Change Page Title</span> - changes the tab's title to just "Agma.io" with the current username</div>
- <div><span>Hide Shouts</span> - prevent megaphone shouts from showing up at all</div>
- <div><span>Hold To Spam</span> - while the powerup's hotkey is held, it will continuously use the powerup</div>
- <div><span>Show Portal Mass</span> - displays the predicted amount of times the portals in rooms 1 & 2 have been fed by players (not 100% accurate & doesn't work at all servers)</div>
- <div><span>Copy Chat Messages</span> - when you right click, there is an extra option called "Copy Chat Messages", when clicked, it will add the currently displayed chat messages to your clipboard</div>
- <!-- Theme -->
- <div><span>Food/Virus/Mothercell Color</span> - changes the color that's filling these to a custom one</div>
- <div><span>Virus/Mothercell Stroke</span> - changes the color of the stroke (border/outline) to a custom one</div>
- <div><span>Spiked Cells</span> - render all cells with the spikes from the infecton gamemode</div>
- <div><span>Show Mass</span> - show the mass of all players' cells</div>
- <!-- Hotkeys -->
- <div><span>Shoot 7 Ejected</span> - press ejected mass hotkey 7 times (useful to prime room 1 or 2 portal when it's been reset</div>
- <div><span>Linesplit Lock</span> - finds which direction your mouse is the closest to & puts mouse way off the map (towards that direction) so you can perform perfect linesplits without zooming out or precisely placing your mouse (feature and design inspired by <a href="https://greasyfork.org/en/scripts/404559-agma-io-linesplit-overlay" target="_blank">Wynell's script</a></div>
- <div><span>Macrosplit Bots</span> - hold this key to macrosplit your bots without switching controls off of yourself</div>
- <div><span>Hide UI</span> - press this key to toggle showing the game UI (intended for recording/screenshots)</div>
- <div><span>Toggle Slow Feed</span> - (toggle) this presses eject mass hotkey at the defined interval (intended for feeding the gold block while AFK)</div>
- <div><span>Slow Feed Speed</span> - the speed at which eject mass is pressed when slow-feeding</div>
- <div><span>Quick Settings</span> - when the hotkey assigned is pressed, it will toggle the setting that is selected</div>
- <!-- (Ex/Im)port -->
- <div><span>Export</span> - select the boxes of the settings you wish to export and press the button, a .txt file will be downloaded with your settings inside</div>
- <div><span>Import</span> - select the boxes of the settings you wish to import and insert the exported settings into the input (note: settings will only be changed if they were selected in both export & import</div>
- <!-- Passive features -->
- <div><span>Hide Ads</span> - both video and image ads will be removed from the screen</div>
- <div><span>Improved Shop</span> - added larger amounts that can be purchased at a time, can also buy a specified amount at one time</div>
- <div><span>Extra Bot Packs</span> - added hidden bot packs that can be purchased with coins (originally discovered by firebone)</div>
- <div><span>Context Menu Copy Info</span> - right click on a player, then click on their cell icon to copy their skin ID to clipboard or click on their name to copy their nickname to clipboard</div>
- <div><span>Copy Chat</span> - right click on screen, then click "Copy Chat Messages" to copy the currently visible chat messages to your clipboard</div>
- <div><span>Abilities Remaining Time</span> - shows the remaining time left of abilities (only works if the abilities were purchased in the same browser)</div>
- <div><span>Unlock Free Skins</span> - gives you access to the facebook & youtube free skins</div>
- <div><span>Hover For Skin ID</span> - hovering skins in the skin menu will shop their ID</div>
- <div><span>In Depth XP/Coins Stats</span> - click on coins/xp progress bar in top left to view respective statistics</div>
- <div><span>Quick Buy</span> - click plus sign (+) next to your powers (only if you set it to true in the code), then click on the powerup you want to buy</div>
- <div><span>White Border For Black Cells</span> - show a white border around black cells (from minion nuker) so they're easier to see with dark backgrounds</div>
- <div><span>Custom Backgrounds</span> - a few <a href="https://imgur.com/a/sTANNBE" target="_blank">backgrounds</a></div>
- </section>
- </div>
- </div>`)
-
- const styles = document.createElement('style');
- styles.innerHTML = `
- .fsfb-shown{
- display: block !important;
- }
- #fsfb-quickbuy{
- display: flex !important;
- justify-content: center;
- align-items: center;
- }
- #fsfb-quickbuy-img{
- height: 80%
- }
- .fsfb-bug-modal>div>div{
- -webkit-box-shadow: 0 5px 15px rgb(0 0 0 / 50%);
- background: linear-gradient(to bottom,#3b414e 0,#302f33 100%);
- border: 3px solid #232630;
- }
- .close.fsfb-btn{
- position: absolute;
- right: 10px;
- top: 3px;
- font-size: 60px;
- }
- .fsfb-modal-body>div{
- color: ffffffb0;
- margin: 10px 20px
- }
- .fsfb-modal-body>div>span{
- color: white;
- }
- .fsfb-modal-body{
- margin: 10px 10px;
- font-size: 20px;
- max-height: 600px;
- overflow-y: auto;
- }
- .fsfb-modal-title{
- text-align: center;
- color: white;
- }
- .fsfb-hotkey{
- background-color: #df901c;
- color: #fff;
- cursor: pointer;
- text-align: center;
- min-width: 40px;
- max-width: 60px;
- height: 18px;
- line-height: 18px;
- vertical-align: middle;
- border-radius: 9px;
- right: 5px;
- position: absolute;
- display: inline-block;
- padding: 0 5px;
- overflow: hidden;
- opacity: 1;
- }
- .fsfb-modal-body::-webkit-scrollbar-thumb {
- background-color: #57595b;
- border: 1px solid black;
- border-radius: 12px;
- }
- .fsfb-modal-body::-webkit-scrollbar {
- border: 1px solid black;
- background-color: #2523239e;
- width: 15px;
- border-radius: 12px;
- }
- .fsfb-modal-body::-webkit-scrollbar-track {
- -webkit-box-shadow: inset 0px 0px 2px 2px rgba(0, 0, 0, 0.75);
- box-shadow: inset 0px 0px 2px 2px rgba(0, 0, 0, 0.75);
- border-radius: 12px;
- }
- .fsfb-hotkey:hover {
- background-color: #f1a02d;
- }
- .fsfb-hotkey.selected{
- background-color: #ff4;
- color: #444;
- }
- #fsfb-settings-main p{
- margin: 0;
- display: inline-block;
- margin-left: 4px;
- }
- #fsfb-settings-main{
- display: -ms-grid;
- display: grid;
- -ms-grid-columns: 50% 50%;
- grid-template-columns: 50% 50%;
- }
- #settingPage4{
- display: none;
- max-height: 600px;
- overflow-x: hidden;
- }
- .padbot10{
- padding-bottom: 10px;
- }
- #fsfb-slowfeedtimer{
- border: none;
- width: 40px;
- }
- select.fsfb-quickchange{
- background: none;
- border: none;
- height: 20px;
- }
- select.fsfb-quickchange:focus-visible{
- outline: none;
- }
- select.fsfb-quickchange option{
- background: #222;
- }
- .fsfb-sect-ch label{
- display: flex;
- align-items: center;
- }
- .fsfb-sect-ch label input{
- margin: 0 2px 0 0;
- }
- #fsfb-sect-theme label input[type="color"]{
- width: 14px;
- height: 14px;
- opacity: 0;
- border: none;
- background-color: white;
- margin: 0;
- cursor: pointer;
- }
- #fsfb-sect-theme label p{
- min-width: 120px;
- margin-left: 5px;
- }
- #fsfb-sect-theme label div{
- border-radius: 4px;
- border: 1px solid #ffffff29;
- }
- #fsfb-ximport-cont{
- display: flex;
- justify-content: space-around;
- margin-top: 7px;
- }
- .fsfb-eximport{
- background-color: #df901c;
- color: white;
- padding: 5px 17px;
- border-radius: 25px;
- cursor: pointer;
- }
- .hideMegaphone{
- display: none !important;
- }
- .fsfb-fake{
- color: #cbff4e;
- }
- #fsfb-extra-info{
- margin: 10% 0 0 90%;
- cursor: pointer;
- }
- #linesplit-markers div {
- background-color: transparent;
- height: 15px;
- aspect-ratio: 1;
- position: fixed;
- z-index: 999;
- border: 2px solid rgb(255 255 255 / 80%);
- border-radius: 50%;
- display: none;
- }#linesplit-top {
- top: -7.5px;
- transform: translateX(-50%);
- left: 50%;
- }
- #stats-container{
- background: rgba(0,0,0,.5);
- top: 200px;
- position: absolute;
- border: 1px white solid;
- border-radius: 12px;
- color:white;
- left:30px;
- }
- #stats-info{
- display: flex;
- flex-direction: column;
- justify-content: center;
- font-size: 1.5vh;
- }
- #stats-main{
- padding: 10px;
- }
- #stats-extra-info{
- color: #00bbff;
- font-size: 1.1vh;
- margin-bottom: 2px;
- display: block;
- }
- #stats-info div{
- display:flex;
- }
- #stats-info div p{
- margin: 0;
- }
- .stats-label{
- min-width: 12.5vh;
- }
- .stats-completed{
- margin: 0.35vh 0.3vh 0;
- font-size: 1vh;
- bottom: 0;
- color: rgb(255, 255, 255, .8);
- }
- #stats-title{
- display: flex;
- align-items: center;
- }
- #stats-title div{
- display: flex;
- margin-left: auto;
- font-size: 1.1vh;
- cursor: pointer;
- }
- #linesplit-right {
- right: -7.5px;
- transform: translateY(-50%);
- top: 50%;
- }
- #linesplit-bottom {
- bottom: -7.5px;
- transform: translateX(-50%);
- left: 50%;
- }
- #linesplit-left {
- left: -7.5px;
- transform: translateY(-50%);
- top: 50%;
- }
- .fuckAds{
- transform: translateX(9999%) !important;
- }
- `
- document.querySelector('body').append(styles);
-
- const scripts = document.createElement('script');
- scripts.innerHTML = `
- function onlyNumberKey(e) {
- const key = e.which ? e.which : e.keyCode;
- return !(key > 31 && (key < 48 || key > 57));
- }
- `
- document.querySelector('body').append(scripts);
- };
-
- document.readyState === 'complete' ? afterLoaded() : document.addEventListener("DOMContentLoaded", afterLoaded);
-