您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
try to take over the world!
// ==UserScript== // @name cursors.io 300 bots hack // @namespace http://tampermonkey.net/ // @version 0.7 // @description try to take over the world! // @author You // @match http://cursors.io/ // @match http://kursors.io/ // @match http://cursors.io/?editor // @grant none // ==/UserScript== (function() { 'use strict'; "use strict" // Beta client for the Zursor Master project // Please do not paste this script itself into tampermonkey or cursors.io, instead please use the tampermonkey extension that I have provided here: https://pastebin.com/krbGjJ9v // Especially since this script is still in development, the tampermonkey extension provided is automatically updated // update as of oct. 13, 2020: Script has been updated to avoid any CORB/CORS errors. Change the __ip variable to the new server ip when it updates. Get the server ip by going to the 'Network' tab in inspect element, go to the 'WS' tab, and refresh the page. DM me on discord at 8y8x#5342 if the script should be updated window.zM = {}; window.zMDK = {}; async function wait(ms = 1000) { setTimeout(()=>{return new Promise(async resolve => resolve());},ms); } window.D = document; let __ip = '128.199.12.58'; (async function(styles, init, cfg, dependencies, elements) { zM.dependenciesLoaded = 0b000000; zM.version = '0.2'; zM.cfg = cfg.raw; zM.createConfig = cfg.createConfig; zM.saveConfig = cfg.saveConfig; zM.getConfig = cfg.getConfig; zM.returnAfterUndeployed = false; zM.antiIdle = true; // load developer kit for plugins // it isn't exactly done yet, I plan to only do it once I'm mostly done the whole script- and it's stable and everything /** * Tools for modifying the localStorage configuration * * .generate() - creates a default config, returns the result. Optionally, you can put the object pointer as a parameter. * .save() - saves the parameter provided. Returns true/false dependant if errors occur. * .get() - returns the saved config. Optionally, you can put the object pointer as a parameter. */ zMDK.config = { generate: cfg.createConfig, save: cfg.saveConfig, get: cfg.getConfig } // some useful shortcuts window.head = D.head, window.body = D.body; // disable all elements on page var temp = []; temp = body.getElementsByTagName('*'); for (var i = 0; i < temp.length; ++i) temp[i].style.display = 'none'; // delete all header elements head.innerHTML = '<title>Loading...</title>'; // add a container temp = D.createElement('div'); temp.style.cssText = 'background:linear-gradient(45deg, rgba(33,33,33,1) 0%, rgba(66,66,66,1) 100%);position:fixed;top:0px;left:0px;width:100vw;height:100vh;'; temp.id = 'zM-container' body.appendChild(temp); zM.el = zMDK.elements = {}; zM.el.container = temp; zM.fleet = []; zM.fSel = NaN; // NaN for news temp = styles(); zM.el.style = { fleetTopbarContainer: temp[0] } zM.pos = { mouseX: 400, mouseY: 300, lastMouseX: 400, lastMouseY: 300 } zM.useWallhack = true; zM.ease = function(n, o, upd) { var dist = n - o, prog = (Date.now() - upd) / 100, maxMin = Math.min(Math.max(0, prog), 1); return o + (maxMin ** 2 * (3 - 2 * maxMin)) * dist; } zM.isLoading = false; zM.game = { m28nCursorsIP: `${__ip}:2828` } zM.asyncWaitUntil = async function(toEval) { return new Promise(resolve => { var temp = setInterval(()=>{if (eval(toEval)) resolve(), clearInterval(temp);},1); }); } zM.origin = (location.hostname === 'cursors.io' || location.href.startsWith('file:///')) ? 'cursors' : location.hostname === 'kursors.io' ? 'kursors' : 'localhost'; zM.movement = 1; // I decided to load the loading bars before the loading API therefore it works for when the script is starting first var temp = [D.createElement('div'), D.createElement('div'), D.createElement('div'), D.createElement('div')]; temp[0].className = 'zM-loading-outer'; zM.el.container.appendChild(temp[0]); temp[1].className = 'zM-loading-title'; temp[0].appendChild(temp[1]); temp[1].textContent = 'Loading...' temp[2].className = 'zM-loading-bar-outer'; temp[0].appendChild(temp[2]); temp[3].className = 'zM-loading-bar-fill'; temp[2].appendChild(temp[3]); zM.el.loadingOuter = temp.shift(); zM.el.loadingTitle = temp.shift(); zM.el.loadingBarFill = temp.pop(); // loading bar API zM.setLoadingWidth = function(width = 50) { zM.el.loadingBarFill.style.width = 'calc(' + width + '%' + ' - 10px)'; } zM.showLoading = function() { zM.el.loadingOuter.style.display = 'block'; D.getElementsByTagName('title')[0].textContent = 'Loading...'; } zM.hideLoading = function() { zM.el.loadingOuter.style.display = 'none'; D.getElementsByTagName('title')[0].textContent = 'zM / No fleets yet'; } zM.setLoadingTitle = function(title) { zM.el.loadingTitle.textContent = title; } zM.clickQueue = 0; zM.updateTabs = function() { // updates fleet tabs zM.el.fleetTopbarOuter.innerHTML = ''; zM.el.fleetTopbarContainer.innerHTML = ''; zM.el.fleetTopbarOuter.appendChild(zM.el.fleetTopbarContainer); zM.el.fleetTopbarOuter.appendChild(zM.el.fleetTopbarAdd); zM.el.fleetTopbarAdd.appendChild(zM.el.fleetTopbarAddImg); zM.el.fleetTopbarOuter.appendChild(zM.el.fleetTopbarHint); for (var i = 0; i < zM.fleet.length; ++i) { var f = zM.fleet[i]; zM.fleet[i].el.container.style.display = 'none'; zM.el.fleetTopbarContainer.innerHTML += `<div style="position: absolute; top: 0px; left: ${100/zM.fleet.length*i}%; width: ${100/zM.fleet.length}%; height: 35px; border-right: 1px solid #fffc; background-color: ${i === zM.fSel ? '#fff3' : '#fff0'};transition: 0.3s;"><div style="position: absolute; top: 0px; left: 0px; width: 100%; height: 35px; background-color: #0000; transition: 0.3s;" onmouseenter="this.style.backgroundColor = '#0003';" onmouseout="this.style.backgroundColor = '#0000'" onclick="zM.fSel = ${i}; zM.updateTabs()"><div style="color:#fffc;font-family:\'Nova Flat\',Montserrat,sans-serif;font-weight:300;padding:8px;pointer-events:none;white-space:nowrap;overflow-x:hidden;user-select:none;">${zM.fSel === i ? '(Selected)' : ''} #${i} / (${f.botsOpened}/${f.maxBots}) / ${f.name}</div></div></div>`; } zM.fleet[zM.fSel].updateTabs(); } zM.createFleet = function(ip, port, ipv6, startbots, maxbots, name) { var nF; var temp2 = function() { clearInterval(temp[2]); clearInterval(temp[3]); clearInterval(temp[4]); zM.setLoadingWidth(0); zM.setLoadingTitle('Server isn\'t a valid cursors.io server.'); nF.bots.forEach(X => X.socket.close()); setTimeout(zM.hideLoading, 2000); }; var temp = [ setInterval(() => { if (!zM.isLoading) clearInterval(temp[0]), zM.isLoading = true, temp[1](); }, 50), function() { zM.el.fleetTopbarHint.style.display = 'none'; zM.el.fleetPromptOuter.style.display = 'none'; zM.setLoadingWidth(0); zM.setLoadingTitle('Creating fleet object...'); zM.showLoading(); nF = new zM.Fleet(ip, port, ipv6, startbots, maxbots, name); zM.fSel = zM.fleet.push(nF) - 1; nF.createGUI(zM.el.container) temp[2] = setInterval(() => { zM.setLoadingTitle('Connecting bots ('+nF.botsOpened+'/'+startbots+')'); zM.setLoadingWidth(100/startbots*nF.botsPinged); if (nF.verified === false) temp2(); else if (startbots <= nF.botsPinged) { clearInterval(temp[2]); setTimeout(async ()=>{ zM.isLoading = false; zM.hideLoading(), zM.updateTabs(), zM.el.game.style.display = 'block'; await zM.asyncWaitUntil('!(Date.now() % 50)'); nF.startTickLoop(); }, 800); } }, 50); } ] } // get IP if (window.m28n) { m28n.findServerPreference('cursors', (err, end ) => { if (err) { console.error(err); } else { zM.game.m28nCursorsIP = (end.ipv4 || ('[' + end.ipv6 + ']')) + ':2828'; } }); } zM.clog = [ // // // Beta v0.2 // // VVVVVVVVV { type: 'title', msg: 'Beta v0.2' }, { type: 'desc', msg: 'I added several new improvements, mostly to the GUI, a full list is below:<br><br>' }, { type: 'desc', msg: '• Added a changelog and a little information thingy at the bottom right. I plan to make it contain more information soon' }, { type: 'desc', msg: '• Cursor movements are now synchronized, they should no longer split up' }, { type: 'desc', msg: '• Script now loads the Nova Flat font used' }, ]; //dependencies.forEach(i => zM.el.container.appendChild(temp = D.createElement('script'), temp.src = 'http://pastebin.com/raw/'+i, temp)); dependencies.forEach(eval); zM.setLoadingWidth(0); zM.showLoading(); zM.setLoadingTitle('Loading dependencies...'); temp = setInterval(() => { if (zM.dependenciesLoaded == 0b111111) { zM.setLoadingWidth(100); clearInterval(temp); elements.forEach(i => i(zM.el.container)); head.getElementsByTagName('title')[0].textContent = 'zM / No fleets yet' // run all element functions setTimeout(zM.hideLoading,800); } else { var done = 0; for (var i = 0; i < temp.length; ++i) { done += (zM.dependenciesLoaded & 2**i) ? 1 : 0; } zM.setLoadingWidth((100 / 16 * done) | 0); } }, 50); init(); })( function() { // add <style> var out = []; var temp = [ // fleet topbar '.zM-' + 'fleet-topbar-outer {', ' position: fixed; top: 0px; left: 0px;', ' width: 100vw; height: 35px;', ' background-color: rgba(0,0,0,.2);', '}', '', '.zM-' + 'fleet-topbar-container {', ' position: fixed; top: 0px; left: 0px;', ' width: calc(100vw - 45px); height: 35px;', '}', '', '.zM-' + 'fleet-topbar-tab {', ' display: inline-block;', '}', '', '.zM-' + 'fleet-topbar-add {', ' position: fixed; top: 0px; right: 0px;', ' width: 45px; height: 35px;', ' background-color: rgba(0,0,0,.0);', ' transition: 0.3s;', ' cursor: pointer; user-select: none;', '}', '', '.zM-' + 'fleet-topbar-add:hover {', ' background-color: rgba(0,0,0,.2)', '}', '', '.zM-' + 'fleet-topbar-hint {', ' color: rgba(255, 255, 255, .3);', ' text-align: right; font-family: Montserrat, sans-serif;', ' font-weight: 200; font-size: 14px;', ' padding-right: 55px;', ' padding-top: 8px; user-select: none;', D.createElement('style') ]; // adds style element to "out" out[out.push(temp.pop()) - 1].innerHTML = temp.join('\n'); // -------------------------------------------------------- var temp = [ // fleet prompt '.zM-' + 'fleet-prompt-outer {', ' position: fixed; top: 85px; left: 50px;', ' width: calc( 100vw - 100px ); height: calc( 100vh - 135px );', ' background-color: #0003; display: none; border-radius: 20px; z-index: 5000;', '}', '', '.zM-' + 'fleet-prompt-container {', ' position: fixed; top: 85px; left: calc( 50vw - 300px );', ' width: 600px; height: calc( 100vh - 135px );', '}', '', '.zM-' + 'fleet-prompt-title {', ' text-align: center; font-family: \'Nova Flat\', Montserrat, sans-serif; font-weight: 300;', ' color: rgba(255, 255, 255, .8); font-size: 24px; padding-top: 10px; user-select: none;', '}', '', '.zM-' + 'fleet-prompt-entry {', ' width: 580px; height: 50px; ', ' background-color: rgba(0, 0, 0, .1);', ' border-radius: 10px;', ' margin-left: 10px; margin-top: 10px;', '}', '', '.zM-' + 'fleet-prompt-opt {', ' text-align: right; color: rgba(255, 255, 255, .5); font-family: \'Nova Flat\', Montserrat, sans-serif;', ' font-weight: 300; font-size: 14px;', ' padding-right: 20px; padding-top: 16px; width: 280px; display: inline-block; user-select: none;', '}', '', '.zM-' + 'fleet-prompt-create {', 'position: absolute; bottom: 10px; left: 95px;', 'width: 200px; height: 20px;', 'background-color: #0c6; font-family: \'Nova Flat\', Montserrat, sans-serif;', 'font-size: 16px; font-weight: 300; color: #0008; text-align: center;', 'border-top-left-radius: 10px; border-bottom-left-radius: 10px; user-select: none; cursor: pointer;', '}', '', '.zM-' + 'fleet-prompt-cancel {', 'position: absolute; bottom: 10px; left: 305px;', 'width: 200px; height: 20px;', 'background-color: #666; font-family: \'Nova Flat\', Montserrat, sans-serif;', 'font-size: 16px; font-weight: 300; color: #0008; text-align: center;', 'border-top-right-radius: 10px; border-bottom-right-radius: 10px; user-select: none; cursor: pointer;', '}', D.createElement('style') ]; // adds style element to "out" out[out.push(temp.pop()) - 1].innerHTML = temp.join('\n'); // -------------------------------------------------------- var temp = [ // loading bar stuff '.zM-' + 'loading-outer {', 'position: fixed; top: 0px; left: 0px;', 'width: 100vw; height: 100vh; background: linear-gradient(45deg, rgba(33,33,33,1) 0%, rgba(66,66,66,1) 100%);', 'z-index: 50000; display: none;', '}', '', '.zM-' + 'loading-title {', 'position: fixed; top: calc(50vh - 32px); left: 50vw;', 'color: #fffb; font-family: Montserrat, sans-serif; font-weight: 300; font-size: 24px;', 'transform: translateX(-50%); z-index: 50001; user-select: none;', '}', '', '.zM-' + 'loading-bar-outer {', 'position: fixed; top: 50vh; left: calc(50vw - 200px);', 'width: 400px; height: 30px; background-color: #0003; border-radius: 15px;', '}', '', '.zM-' + 'loading-bar-fill {', 'width: 0%; height: 20px; background-color: #3c5; border-radius: 10px; margin: 5px; transition: 0.5s;', '}', D.createElement('style') ]; // adds style element to "out" out[out.push(temp.pop()) - 1].innerHTML = temp.join('\n'); // -------------------------------------------------------- var temp = [ // fleet page '.zM-' + 'fleet-gui-container {', 'position: fixed; top: 35px; left: 0px; width: 100vw; height: calc(100vh - 35px); z-index:1000;', '}', '', '.zM-' + 'fleet-gui-topbarOuter {', 'position: fixed; top: 35px; left: 0px; width: 100vw; height: 35px; background-color: #0002; z-index:1001;', '}', '', '.zM-' + 'fleet-gui-topbar {', 'position: fixed; top: 35px; left: 0px; width: calc(100vw - 45px); height: 35px; z-index:1002;', '}', '', '.zM-' + 'fleet-gui-tabNew {', 'position: fixed; top: 35px; right: 0px; width: 45px; height: 35px; background-color: #0000; transition: 0.3s; z-index:1003; cursor: pointer;', '}', '', '.zM-' + 'fleet-gui-tabNew:hover {', ' background-color: rgba(0,0,0,.2)', '}', '', '.zM-' + 'fleet-gui-tabNewImg {', 'position: fixed; top: 35px; right: 0px; width: 45px; height: 35px; pointer-events: none; z-index:1004; user-select:none;', '}', D.createElement('style') ]; // adds style element to "out" out[out.push(temp.pop()) - 1].innerHTML = temp.join('\n'); // -------------------------------------------------------- var temp = [ // news page '.zM-' + 'news-outer {', 'position: fixed; top: 35px; left: 0px; width: 100vw; height: calc(100vh - 35px); z-index: 9000;', '}', '', '.zM-' + 'news-container {', 'position: absolute; top: calc(50vh - 190px); left: calc(50vw - 500px); width: 1000px; height: 380px; z-index 9001;', '}', '', '.zM-' + 'news-page-top {', 'z-index: 9002;', 'width: 1000px; margin-left: 0px; margin-bottom: 10px; height: 120px; background-color: #0003; border-top-left-radius: 75px; border-top-right-radius: 75px;', '}', '', '.zM-' + 'news-page-mid {', 'z-index: 9002;', 'width: 1000px; margin-left: 0px; margin-bottom: 10px; height: 120px; background-color: #0003', '}', '', '.zM-' + 'news-page-bottom {', 'z-index: 9002;', 'width: 1000px; margin-left: 0px; margin-bottom: 10px; height: 120px; background-color: #0003; border-bottom-left-radius: 75px; border-bottom-right-radius: 75px;', '}', '', D.createElement('style') ]; // adds style element to "out" out[out.push(temp.pop()) - 1].innerHTML = temp.join('\n'); // -------------------------------------------------------- var temp = [ // game '.zM-' + 'game {', 'position: fixed; top: 80px; left: 10px; width: 800px; height: 600px; background-color: #fff; z-index: 9000; display: none; cursor: none;', '}', D.createElement('style') ]; // adds style element to "out" out[out.push(temp.pop()) - 1].innerHTML = temp.join('\n'); // -------------------------------------------------------- var temp = [ // bottom-right info area '.zM-' + 'info-outer {', 'position: fixed; bottom: 10px; right: 10px; width: 200px; height: 40px; background-color: #0003; border-radius: 20px; z-index: 20000;', '}', '', '.zM-' + 'info-ver {', 'position: absolute; top: 10px; left: 10px; font-family: Montserrat, sans-serif; color: #fff8; user-select: none; z-index: 20001;', '}', '', '.zM-' + 'info-clog-button-outer {', 'position: absolute; top: 5px; right: 5px; width: 120px; height: 30px; background-color: #0003; user-select: none; z-index: 20002; border-radius: 15px; cursor: pointer;', '}', '', '.zM-' + 'info-clog-button {', 'position: absolute; top: 8px; left: 12px; font-size: 12px; color: #fff8; user-select: none; z-index: 20003; pointer-events: none; font-family: Montserrat;', '}', D.createElement('style') ]; // adds style element to "out" out[out.push(temp.pop()) - 1].innerHTML = temp.join('\n'); // -------------------------------------------------------- var temp = [ // changelog area '.zM-' + 'clog-outer {', 'position: fixed; top: 0px; left: 0px; width: 100vw; height: 100vh; background:linear-gradient(45deg, rgba(33,33,33,1) 0%, rgba(66,66,66,1) 100%); z-index: 15000; display: none;', '}', '', '.zM-' + 'clog-container {', 'position: fixed; top: 50px; left: calc(50vw - 400px); width: 800px; height: calc(100vh - 100px); background-color: #0003; border-radius: 50px; z-index: 15001;', '}', '', '.zM-' + 'clog-title {', 'color: #fffc; font-family: Montserrat; font-weight: 300; font-size: 36px; z-index: 15002; margin-bottom: 20px; margin-left: 30px; margin-top: 30px; user-select: none;', '}', '', '.zM-' + 'clog-desc {', 'color: #fff8; font-family: Montserrat; font-weight: 400; font-size: 14px; z-index: 15002; margin-bottom: 10px; margin-left: 30px; user-select: none;', '}', '', '.zM-' + 'clog-close {', 'position: fixed; top: 0px; right: 0px; width: 45px; height: 35px; cursor: pointer; user-select: none;', '}', '', D.createElement('style') ]; // adds style element to "out" out[out.push(temp.pop()) - 1].innerHTML = temp.join('\n'); for (var i = 0; i < out.length; ++i) head.appendChild(out[i]); return out; }, function() { // initialize, start different tasks zM.promptFleet = function() { if (isNaN(zM.fSel)) { zM.el.newsOuter.style.display = 'none'; } else { var temp = parseInt(zM.fSel); var f = zM.fleet[temp]; if (f) { f.el.container.style.display = 'none'; } } zM.el.game.style.display = 'none'; zM.el.fleetPromptOuter.style.display = 'block'; } zM.zWs = new WebSocket('ws://localhost:2882'); }, (function(cfg) { // loads configuration function createConfig(x) { // "x" is a pointer to the variable to change if (!x.keybinds) { x.keybinds = [] } return x; } function saveConfig(x) { try { var out = JSON.stringify(x); localStorage.setItem('zM', btoa(out)); return true; } catch(err) { switch (true) { case err instanceof TypeError: { console.error('[CFG Loader] Error with saving the configuration'); } default: { // other unhandled errors console.error('[CFG Loader] Error with loading the configuration: Unhandled error occured'); } } console.debug(err); return false; } } function getConfig(x) { try { var out = localStorage.getItem('zM'); // null if (!out) throw 'Undefined storage'; out = atob(out); // DOMException errors out = JSON.parse(out); // SyntaxErrors if (x) x = out; return out; } catch(err) { switch (true) { case err instanceof DOMException: { // atob error, invalid configuration console.error('[CFG Loader] Error with loading the configuration: Configuration was incorrectly saved'); } break; case err instanceof SyntaxError: { // JSON errors return syntax errors for some reason console.error('[CFG Loader] Error with loading the configuration: Configuration is not an object'); } break; default: { // other unhandled errors console.error('[CFG Loader] Error with loading the configuration: Unhandled error occured'); } } console.debug(err); if (x) x = {}; return null; } } if (cfg === null) { // if the localstorage has been erased or script has never been used before cfg = {}; createConfig(cfg); } else { try { cfg = getConfig(cfg); if (!cfg) saveConfig((createConfig(cfg), cfg)); } catch(err) { switch (true) { case err instanceof DOMException: { // atob error, invalid configuration console.error('[CFG Loader] Error with loading the configuration: Configuration was incorrectly saved'); } break; case err instanceof SyntaxError: { // JSON errors return syntax errors for some reason console.error('[CFG Loader] Error with loading the configuration: Configuration is not an object'); } break; default: { // other unhandled errors console.error('[CFG Loader] Error with loading the configuration: Unhandled error occured'); } } console.debug(err); // technically these functions don't need to be placed in each other, they use pointers anyway cfg = {}; saveConfig(createConfig(cfg)); } } return { raw: cfg, getConfig: getConfig, saveConfig: saveConfig, createConfig: createConfig } })(localStorage.getItem('zM')), // --- // list of dependencies (pastebin) below // edit as of oct. 13, 2020: pastebin now uses CORS and doesn't allow requests, so the scripts are now embedded here instead // --- [ /* zM external images */ `zM.dependenciesLoaded |= 0b000001; window.zMIMG = { add: {img:null,uri:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAjCAYAAAAAEIPqAAAAc0lEQVRYR+2VSQoAIAwDzf8fXRE8FqF1ozCetYQxSdUKHhXU3BD96tcgDekFAeyBPX7aw8xM0lEbHh3mwUH0pAJp7EF7OARGQ2QXS6YOCSJBJIjBxLHGWeNBy+xev97TuwK994i+QRXSr6hCGtJBAiUrrwPx1zwkY3UoxAAAAABJRU5ErkJggg=="}, close: {img:null,uri:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAjCAYAAAAAEIPqAAAAu0lEQVRYR+2VUQrAIAxD7f0P7fBDGLLZtKSCkP0a18czbtYufOxC5iboU6cm0zK9MaB6qB6qx6kOVJvuvXczgy91NL/yw4M8wSgImtvNo0GPIR6Qt+6JmetU6B04C3jMoEN/gTOBy6Df4GzgUmik42iHy74e64un4WtMr6BscPpF/ANkglOhPTBvHe04DRoFQnPlf8QoSDR/7OuBHnUmR6tHZnh2j6Cz5qL7ZDpqLJuX6ay56D6ZjhrL5h8i/mQkg2UCqwAAAABJRU5ErkJggg=="}, cursor: {img:null,uri:"data:image/png;base64,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"}, public: {img:null,uri:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAeCAYAAADHJYVoAAABrElEQVRIS7WWvU7DQBCEZw3hR6KhAImSnpqSiseghzcCet4OBSEh8R8bjb3jrM4kurOTk1Z27OSb3XN21oYtLtsiG//B47VmingE6TwVlECxUATynPELYM8zJjCN7GIivALA+PZfHwGoPRZ+lFCWgOCE7gDYNbP35qEGbttbxwAIZjU/pQIRPgMwM7O3Fs7VCZx6NayoSEBwZk34PoBXPDZ4vgFOnnqBMwAfLpItEOF8iAcAXgRn2lMEUvghgHmETxHIgo8VyIaPESiClwoUw0sERsFzBbLg7d9x1Vo22qf3AbuZXdgM4FVVzev7RdtESYY93szQNJ1JhnNaxVfo4npt5qGBrt1j6DMKdiphDHYvg+e0CX5nmLmZzeUtdlcxwysvkzCWLIfkkdckom1ZDVeHOvjS/ZxQlSy47FiOKaGVe955S7cu3N8JYzYpXN5OEW2VwIMHunRF4JzeHrIWXNsSh0YUaaGKgZ/7iKP1coDwyyqbAn3JyT8znbPt58Ek8oyZNe+p5EmTiCDNUA4OBtdGZqgmfzwSvpHpH7do4+8t8fls5Y1rjTuNu/UHX28RMaWkZ08AAAAASUVORK5CYII='}, movement: {img:null,uri:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAeCAYAAADHJYVoAAABr0lEQVRIS7WWzU7CUBCFz1TxJ3HjxsSle9cuXfkowL5Pwh6eEWNiIv5BzYE5dWjF3NuWJpNeSvnOzC1zpoYjHnZENv6Cx2tVH/EI0ropKIFsoQjkmvEN4MwzJrAZycVEeAGA8em/vgKw8Vj7WUJJAoITegLg1MzeNpMJbD4n4BoAwazmK1cgwkcARmb2SjgPF7jxalhRloDgzJrwcwAv1XQKzGZAWUrgFsDKRZIFIpwP8QLAcw1n+j0EmvBLAMs9eA+BNHhHgXR4B4E8eKZAPjxDoBs8USANXpYH2z002rv3AbuZtlG14EVRLNfj8a6J9jOsBcwMVbUzybCmVXyELt78n/lvAz25x9BnFOxUwhjsXgbXtAne087czJbylmKxYIaPXiZhLFkOyTOvSUTbchiuDnXwg/s5oSpZcNmxHFNCB/d86y2+uffu74QxmyZc3k4RbZXArQdauyKAO3p7yFpwbUscGlFkC1W0/NxHHK2XA4Q3q2wK1CU3/pvNObv93JpEnjGz5ncqudckIkgzlIODwWOQGarJH8+EDzL94xYN/t4Sn89R3riS3kVybvoBL+YcMQOUqAIAAAAASUVORK5CYII='}, local: {img:null,uri:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAeCAYAAADHJYVoAAABrklEQVRIS7WWvU7DQBCEZw3hR6KhCBIlPTUlFY9BD28E9Hk7ZISExH9sNGbH2dgY3dmJpZUvif3N7jk7a8MWD9siG3/B43f1FPEI0rorKIFsoQjkmvENYM8zJrAbycVEeAGA8el3HwGoPJZ+llCSgOCE7gDYNbPX6r6G3TT3HwMgmNV85QpE+AzAzMxeCOfhAideDSvKEhCcWRO+D+C5fgBw/Qgs5hI4BfDmIskCEc6HeADgqYUz/QkCXfghgHINPkEgDT5SIB0+QiAPnimQD88QGAdPFEiDL+aD7R4a7d37gN1M26h78KIoyuVd9dtE6xm2AmaGuvYuXq1pFR+hi6v/M1810JV7DH1GwU4ljMHuZXBNm+A1/czNrJS3FLdNhpdeJmEsWQ7JM7+TiLZlGK4OdfCF+zmhKllw2bEcU0KDe954i2/uufs7YcymC5e3U0RbJXDvgbauCOCM3h6yFlzbEodGFGmgip6f+4ij9XKA8GKVTYG25M5/sztnm8+9SeQZM2v+ppInTSKCNEM5OBg8NjJDNfnjmfCNTP+4RRt/b4nPZytvXEnvIjkX/QBfbxExMnV8VAAAAABJRU5ErkJggg=='}, follow: {img:null,uri:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAeCAYAAADHJYVoAAABwklEQVRIS7WWS07DQBBEawzhE7FBgkgs2bMBJJasWHAQYM9JWAcukkvAPfgEISGFf4zK6YpaY4xm4sRSy5PEedU9dlc7YIFHWCAbf8H9d2UbcQ/SOhaUQLaQB3LN+AawYhkTGEdyMR5eAGB82r83AIwtfuwsoSQBwQldArAcQhidPxzgevuWgE0ABLOar1wBD+8A6IQQXgnnYQI9q4YVZQkIzqwJXwXwcvF4iKutAS6fTiWwA+DNRJIFPJw3cQ3As+DMvo1ADF8HMPTwNgJJ8FkFkuGzCGTBcwWy4TkCM8FTBRrh/e4Ao+6ky/k4Nh2u0d6tD9jNtI2yBi+KYnh2v181UZThlB9CQFlOTNKtaRUfrovH/26La6AT8xj6jIKdShiD3cvgmjbBa+qZhxCG8pab3h0zPLYyCWPJckie+Z1EtC3NcHWogY/MzwlVyYLLjuWYEmrc88pbbHP3zN8JYzYxXN5OEW2VwLUbOnVFALv0dpe14NoWPzS8SAVV1PzcRhytlwOEF6tsCkxLjh7NeM5Wn2uTyDJm1vxNJbeaRARphnJwMHjMZYZq8vsz4XOZ/n6L5v7e4u/PQt64kt5Fci76BTTHKDGf8J1/AAAAAElFTkSuQmCC'}, admin: {img:null,uri:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAeCAYAAADHJYVoAAAB80lEQVRIS7WWuW7CUBBF7zghi5QmBZFSUlpKaaVMlc+ghvwDNXXKADWf494fgYgiRSIrftF1ZuDhBdkslkbez515z++OBUfc5IhslMH9a24fcR9kx3lBE2gs5AN5zPgFcKYZE5iP2sX48AAA41vfvgKQaix1b0K1BAxO6AmAUxFZpCMH6WfvXwMgmNX8NBXw4S0ALRF5J5ybCtxoNayokYDBmTXh5wDe3BhAdwZM2yZwC+BDRWoL+HBO4gWA1xWc6e8hkIdfApi7uAeEw/WkJQNINOF5owrqwYndQWAL/BnAYvOTayhQCo/jGGEYln7LSZIgiqJaQ1QK78UOw3J2JjhIgEmUvbp1DnaC1xWoBWemVZtWwIX2qeuAq5m24QrwIAjm6csSs+4/rj0F0N80ShGBc7qK18e0ii9vFaelmWPsMrgHflSPoc9YcKUSxuDqZfCYNsFnipmLyNyNWBUgTwEzfNAyCWPJ5pDc85qJ2LBUw7lCmbmC79XPCbWSDW52bI5pQpVjnnmLTt6d+jthzCYPN2+niA2VgQsTunJFAB16u5e1wW1Y/Kbhi2RQi4Kfa4uj9bKB8GErmwKrknOfZr7PZueFTqQZM2ves5L36kQEWQ9l42BwO0gPtc7v7wk/SPf3h+jg/y3+/Bzlj6vanXa88we7KRoxQlE4ggAAAABJRU5ErkJggg=='} } for (var i in zMIMG) { if (zMIMG.hasOwnProperty(i)) { zMIMG[i].img = new Image(); zMIMG[i].img.src = zMIMG[i].uri; } }`, /* zM fleet class */ `zM.dependenciesLoaded |= 0b000010; zM.Fleet = class { constructor (ip, port, ipv6, maxbots, startbots, name) { console.log(startbots); this.ip = ip; this.port = port; this.maxBots = maxbots; this.startBots = startbots; this.name = name; this.ipv6 = ipv6; this.cSel = 0; this.wsIp = 'ws://' + (this.ipv6?'['+this.ip+']':this.ip) + ':' + this.port; this.bots = []; this.ids = []; this.botsPinged = 0; this.botsOpened = 0; this.botsIds = 0; this.botsLevels = 0; this.botsBusy = 0; this.botsDeployed = 0; this.botsUpdated = 0; this.verified = true; this.isHelping = false; this.el = {}; this.helpers = []; var extF = this; this.helpIndex = 0; this.helpLoop = setInterval(()=>{ ++this.helpIndex; if (this.isHelping && this.helpers.length > 0) { for (var i = 0; i < this.helpers.length; ++i) { this.helpers[i].toHelp = []; this.helpers[i].helping = true; if (this.helpers[i].socket.readyState != 1) this.helpers.splice(i--, 1); } var todo = []; var obj = this.bots[this.cSel].obj; for (var i = 0; i < obj.length; ++i) { if (obj[i].type === 4) todo.push(obj[i]); } var amount = todo.length / this.helpers.length; var j = 0; var count = amount; for (var i = 0; i < this.helpers.length; ++i) { for (; j < count | 0; ++j) { var obj = todo[j]; var moves = zM.path(this.helpers[i].realX, this.helpers[i].realY, obj.x + (obj.w>>1), obj.y + (obj.h>>1), this.helpers[i].obj, this.helpers[i].grid); if ((this.helpers[i].realX === obj.x + (obj.w>>1) && this.helpers[i].realY === obj.y + (obj.h>>1)) ? true : moves.length > 1) this.helpers[i].toHelp.push(todo[j]); } count += amount; } var f = this; if (this.isHelping) for (var j = 0; j < this.helpers.length; ++j) { var index = this.helpIndex % this.helpers[j].toHelp.length; if (isNaN(index)) index = this.helpIndex % this.helpers[0].toHelp.length; // has nothing to do, copy off other bots if (isNaN(index)) index = 0; // still undefined, no buttons at all console.log(j, this.helpers[j]); console.log(index, this.helpers[j].toHelp[index]); if (this.helpers[j].toHelp.length <= index) continue; var moves = zM.path(this.helpers[j].realX, this.helpers[j].realY, this.helpers[j].toHelp[index].x + (this.helpers[j].toHelp[index].w>>1), this.helpers[j].toHelp[index].y + (this.helpers[j].toHelp[index].h>>1), this.helpers[j].obj, this.helpers[j].grid); moves.forEach(Y => { zM.packet.moveSocket([this.helpers[j].socket], Y[0], Y[1], [this.helpers[j]]); }); for (var k = 0; k < 10; ++k) zM.packet.clickSocket([this.helpers[j].socket], this.helpers[j].toHelp[index].x + (this.helpers[j].toHelp[index].w>>1), this.helpers[j].toHelp[index].y + (this.helpers[j].toHelp[index].h>>1), [this.helpers[j]]) } } },300); this.elTemplate = { tab: '<div style="width: ' } setTimeout(()=>{for (var i = 0; i < startbots; ++i) this.bots.push(new zM.Bot(this));},300); } createGUI(c) { var temp = this.el = { container: D.createElement('div'), topbarOuter: D.createElement('div'), topbar: D.createElement('div'), tabNew: D.createElement('div'), tabNewImg: D.createElement('img') } temp.container.className = 'zM-fleet-gui-container'; c.appendChild(temp.container); temp.topbarOuter.className = 'zM-fleet-gui-topbarOuter'; temp.container.appendChild(temp.topbarOuter); temp.topbar.className = 'zM-fleet-gui-topbar'; temp.topbarOuter.appendChild(temp.topbar); temp.tabNew.className = 'zM-fleet-gui-tabNew'; temp.topbarOuter.appendChild(temp.tabNew); temp.tabNewImg.className = 'zM-fleet-gui-tabNewImg'; temp.tabNewImg.src = zMIMG.add.uri; temp.tabNew.appendChild(temp.tabNewImg); temp.tabNew.addEventListener('click', ev => { this.bots.push(new zM.Bot(this)); }); this.updateTabs(); } updateTabs() { this.el.container.style.display = 'block'; this.el.topbar.innerHTML = ''; this.el.topbarOuter.appendChild(this.el.tabNew); this.el.tabNew.appendChild(this.el.tabNewImg); var nb = []; for (var i = 0; i < this.bots.length; ++i) { if (this.bots[i].socket.readyState == 1) nb.push(this.bots[i]); } for (var i = 0; i < nb.length; ++i) { var b = nb[i]; this.el.topbar.innerHTML += \`<div style="position: absolute; top: 0px; left: \${100/nb.length*i}%; width: \${100/nb.length}%; height: 35px; border-right: 1px solid #fffc; background-color: \${i === this.cSel ? '#fff3' : '#fff0'};transition: 0.3s;"><div style="position: absolute; top: 0px; left: 0px; width: 100%; height: 35px; background-color: #0000; transition: 0.3s;" onmouseenter="this.style.backgroundColor = '#0003';" onmouseout="this.style.backgroundColor = '#0000'" onclick="zM.fleet[zM.fSel].cSel = \${i}; zM.fleet[zM.fSel].updateTabs()"><div style="color:#fffc;font-family:\'Nova Flat\',Montserrat,sans-serif;font-weight:300;padding:8px;pointer-events:none;white-space:nowrap;overflow-x:hidden;user-select:none;">\${eval(\`zM.fleet[zM.fSel].cSel === \${i} ? '(Selected)' : ''\`)} #\${i} / ID \${b.id} / LVL \${b.level}</div></div></div>\`; } } /* depreciated, only solves for selected bot startTickLoop() { this.tickLoop = setInterval(()=>{ var b = this.bots[this.cSel]; var toMove = []; for (var i = 0; i < this.bots.length; ++i) { if (this.bots[i].level === b.level) if (zM.useWallhack) toMove.push(this.bots[i].socket); } if (zM.useWallhack) { var moves = zM.path(b.realX, b.realY, zM.pos.mouseX>>1, zM.pos.mouseY>>1, b.obj); moves.forEach(Y => { zM.packet.moveSocket(toMove, Y[0], Y[1]); }); } else { zM.packet.moveSocket(toMove, zM.pos.mouseX>>1, zM.pos.mouseY>>1); } for (;-1<zM.clickQueue;--zM.clickQueue) zM.packet.clickSocket(toMove, zM.pos.mouseX>>1, zM.pos.mouseY>>1); if (zM.drawing) zM.packet.drawSocket(toMove, zM.pos.lastMouseX>>1, zM.pos.lastMouseY>>1, zM.pos.mouseX>>1, zM.pos.mouseY>>1); zM.pos.lastMouseX = zM.pos.mouseX; zM.pos.lastMouseY = zM.pos.mouseY; }, 50); }*/ // alternative, solves for each bot- causes lots of lag without grid startTickLoop() { this.tickLoop = setInterval(()=>{ for (var i = 0; i < zM.fleet.length; ++i) { if (zM.fleet[i] === this) break; } if (i !== zM.fSel) return; var b = this.bots[this.cSel]; var toMoveSocket = []; var toMove = []; for (var i = 0; i < this.bots.length; ++i) { // disconnect after 90 min of AFK, should bypass any bans from AFKing if (Date.now() - this.bots[i].packets.lastSent > 5400000) this.bots[i].socket.close(); if ( this.bots[i].level === b.level && !this.bots[i].helping && !this.bots[i].deployed ) toMove.push(this.bots[i]), toMoveSocket.push(this.bots[i].socket); } if (zM.movement) { if (zM.useWallhack) { // solve first toMove.forEach(X => { // random here is anti-idle disconnect if (!(X.realX === zM.pos.mouseX>>1 && X.realY === zM.pos.mouseY>>1) || (Math.random() >= 0.99 && zM.antiIdle)) { var moves = zM.path(X.realX, X.realY, zM.pos.mouseX>>1, zM.pos.mouseY>>1, b.obj, b.grid); X.toDo = moves; X.realX = zM.pos.mouseX>>1; X.realY = zM.pos.mouseY>>1; } }); // then send packets synchronized, all together var count = 0; for (var i = 0; i < toMove.length; ++i) count = Math.max(count, toMove[i].toDo.length); for (var i = 0; i < count; ++i) { toMove.forEach(X => { if (i >= X.toDo.length) return; zM.packet.moveSocket([X.socket], X.toDo[i][0], X.toDo[i][1], [X]); }); } } else { zM.packet.moveSocket(toMoveSocket, zM.pos.mouseX>>1, zM.pos.mouseY>>1, toMove); } } else { if (zM.clickQueue >= 1) { toMove.forEach(X => { var moves = zM.path(X.realX, X.realY, zM.pos.mouseX>>1, zM.pos.mouseY>>1, b.obj, b.grid); moves.forEach(Y => { zM.packet.moveSocket([X.socket], Y[0], Y[1], [X]); }); }); } if (zM.antiIdle) { toMove.forEach(X => { // random here is anti-idle disconnect, if movement is disabled. if (Date.now() - X.packets.lastSent > 10000) zM.packet.moveSocket([X.socket], X.realX, X.realY, [X]); }); } } for (;0<zM.clickQueue;--zM.clickQueue) zM.packet.clickSocket(toMoveSocket, zM.pos.mouseX>>1, zM.pos.mouseY>>1, toMove); if (zM.drawing && zM.movement) zM.packet.drawSocket(toMoveSocket, zM.pos.lastMouseX>>1, zM.pos.lastMouseY>>1, zM.pos.mouseX>>1, zM.pos.mouseY>>1, toMove); zM.pos.lastMouseX = zM.pos.mouseX; zM.pos.lastMouseY = zM.pos.mouseY; }, 50); } }`, /* zM bot class */ `zM.dependenciesLoaded |= 0b000100 zM.Bot = class { constructor (fleet) { this.fleet = fleet; this.socket = new WebSocket(this.fleet.wsIp); this.socket.binaryType = 'arraybuffer'; this.opened = false; this.isOpen = false; this.level = -1; this.id = -1; this.obj = []; this.players = []; this.clicks = []; this.drawings = []; this.realX = 400; this.realY = 300; this.local = 0; this.packets = { receivedTotal: 0, sentTotal: 0, receivedPS: 0, sentPS: 0 } this.toHelp = []; this.toDo = []; this.timestampStart = 0; this.helping = false; this.deployed = false; this.prevLevels = []; this.socket.addEventListener('open', () => { ++this.fleet.botsOpened; this.opened = true; this.isOpen = true; ++this.fleet.botsPinged; zM.updateTabs(); }); this.socket.addEventListener('close', () => { if (this.opened) { --this.fleet.botsOpened; var i = this.fleet.ids.indexOf(this.id); if (i != -1) this.fleet.ids.splice(i, 1); } else ++this.fleet.botsPinged; this.isOpen = false; for (var i = 0; i < this.fleet.bots.length; ++i) if (this.fleet.bots[i] == this) { console.log('y'); this.fleet.bots.splice(i,1); break; } zM.updateTabs(); }); this.socket.addEventListener('message', ev => { var buf = ev.data, dat = new DataView(buf); ++this.packets.receivedTotal; ++this.packets.receivedPS; setTimeout(()=>{--this.packets.receivedPS},1000); var type = dat.getUint8(0); if (type === 0) this.id = dat.getUint32(1, 1), ++this.fleet.botsIds, this.fleet.ids.push(this.id); else if (type === 1) { var out = zM.parse.cursors(buf, 1); this.local = out.shift(); var players = out.shift(); var idsHere = []; // create players for all new ids for (var i = 0; i < players.length; ++i) { if (players[i].id === this.id) this.realX = players[i].x, this.realY = players[i].y; var index = -1; for (var j = 0; j < this.players.length; ++j) { if (this.players[j].id === players[i].id) {index = j; break;} } if (index === -1) this.players.push({ x: players[i].x, y: players[i].y, lastUpdate: Date.now(), ox: players[i].x, oy: players[i].y, id: players[i].id }); } for (var i = 0; i < players.length; ++i) { for (var j = 0; j < this.players.length; ++j) { if (this.players[j].id === players[i].id) { this.players[j].ox = zM.ease(this.players[j].x, this.players[j].ox, this.players[j].lastUpdate); this.players[j].oy = zM.ease(this.players[j].y, this.players[j].oy, this.players[j].lastUpdate); this.players[j].x = players[i].x; this.players[j].y = players[i].y; this.players[j].lastUpdate = Date.now(); idsHere.push(players[i].id); } } } var nPl = []; for (var i = 0; i < idsHere.length; ++i) { for (var j = 0; j < this.players.length; ++j) { if (idsHere[i] === this.players[j].id) nPl.push(this.players[j]); } } this.players = nPl; var off = out.shift(); out = zM.parse.clicks(buf, off); for (;0 < out[0].length;) { this.clicks.push(out[0].shift()); } off = out.pop(); out = zM.parse.remove(buf, off); for (var i = 0; i < out[0].length; ++i) { for (var j = 0; j < this.obj.length; ++j) { if (this.obj[j].id === out[0][i]) {this.obj.splice(j, 1); break;} } } off = out.pop(); out = zM.parse.objects(buf, off); var obj = zM.parse.objData(out.shift()); for (var i = 0; i < obj.length; ++i) { var index = -1; for (var j = 0; j < this.obj.length; ++j) { if (this.obj[j].id === obj[i].id) {index = j; break;}; } if (index === -1) this.obj.push(obj[i]); else this.obj[j] = obj[i]; } off = out.pop(); out = zM.parse.drawing(buf, off); for (var i = 0; i < out[0].length; ++i) { var todo = out[0][i]; this.drawings.push(todo); } this.online = dat.getUint32(dat.byteLength-4, true); } else if (type === 4) { if (this.level === -1) ++this.fleet.botsLevels; this.drawings = []; this.realX = dat.getUint16(1, true); this.realY = dat.getUint16(3, true); var objdata = zM.parse.objects(buf, 5); this.obj = zM.parse.objData(objdata[0]); var grid = 100; for (var i = 0; i < this.obj.length; ++i) { if (grid <= 1) {grid = 1; break;} if (this.obj[i].type === 1) if ( (this.obj[i].x/grid|0) != (this.obj[i].x/grid) || (this.obj[i].y/grid|0) != (this.obj[i].y/grid) || (this.obj[i].w/grid|0) != (this.obj[i].w/grid) || (this.obj[i].h/grid|0) != (this.obj[i].h/grid) ) --grid, i = -1; } this.grid = grid; var compare = []; for (var i = 0; i < this.obj.length; ++i) { var o = this.obj[i]; if (o.type === 0) { compare.push({ x: o.x, y: o.y, size: o.size, content: o.content }); } else if (o.type === 1) { if (o.color === '#000000') compare.push({ x: o.x, y: o.y, w: o.w, h: o.h }); } else if (o.type === 2) { compare.push({ x: o.x, y: o.y, w: o.w, h: o.h, isBad: o.isBad }); } else { compare.push({ x: o.x, y: o.y, w: o.w, h: o.h, color: o.color }); } } compare = JSON.stringify(compare); var i = this.prevLevels.indexOf(compare); if (i != -1) this.level = i; else ++this.level, this.prevLevels.push(compare); this.fleet.updateTabs(); } else if (type === 5) { this.realX = dat.getUint16(1, true); this.realY = dat.getUint16(3, true); } }); } }`, `zM.dependenciesLoaded |= 0b001000; let ctx; zM.reqLoad = function() { zM.r = { fps: 0, hudText: function(text, x, y, subLength = 0, color = '#fff') { ctx.font = '12px "Nova Flat"'; ctx.globalAlpha = .5; ctx.lineWidth = 3; ctx.strokeStyle = '#000'; ctx.strokeText(text, x-ctx.measureText(text).width*subLength, y); ctx.globalAlpha = 1; ctx.fillStyle = color; ctx.fillText(text, x-ctx.measureText(text).width*subLength, y); }, infLvl: 5 } ctx = zM.el.game.getContext('2d'); } zM.reqDo = function() { ctx.clearRect(0, 0, 800, 600); if (isNaN(zM.fSel)) { ctx.font = '60px "Nova Flat"'; ctx.fillStyle = '#000'; var t = 'No fleet selected'; ctx.fillText(t, 400 - ctx.measureText(t).width/2, 330); } else if (!zM.fleet[zM.fSel]) { ctx.font = '60px "Nova Flat"'; ctx.fillStyle = '#000'; var t = 'Undefined fleet selected'; ctx.fillText(t, 400 - ctx.measureText(t).width/2, 330); } else if (!zM.fleet[zM.fSel].bots[zM.fleet[zM.fSel].cSel]) { // you can get this if the bot no longer exists (or an invalid bot selected state) ctx.font = '60px "Nova Flat"'; ctx.fillStyle = '#000'; var t = 'Lost connection to server'; ctx.fillText(t, 400 - ctx.measureText(t).width/2, 330); } else { var b = zM.fleet[zM.fSel].bots[zM.fleet[zM.fSel].cSel]; if (b.socket.readyState == WebSocket.CONNECTING) { ctx.font = '60px "Nova Flat"'; ctx.fillStyle = '#000'; var t = 'Connecting'; ctx.fillText(t, 400 - ctx.measureText(t).width/2, 330); } else { // we don't need to handle closed states, the bot will be gone for (var i = 0; i < b.obj.length; ++i) { var o = b.obj[i]; switch (o.type) { case 0: ctx.globalAlpha = 1; ctx.font = o.size + 'px "Nova Flat"'; ctx.fillStyle = '#000'; var x = o.x*2; if (o.isCentered) x -= ctx.measureText(o.content).width/2; ctx.fillText(o.content, x, o.y*2); break; case 1: ctx.globalAlpha = 1; ctx.fillStyle = o.color; ctx.fillRect(o.x*2, o.y*2, o.w*2, o.h*2); ctx.globalAlpha = .2; ctx.strokeStyle = '#000'; ctx.lineWidth = 1; ctx.strokeRect(o.x*2+1, o.y*2+1, o.w*2-2, o.h*2-2); break; case 2: ctx.globalAlpha = .2; ctx.fillStyle = o.isBad?'#f00':'#0f0'; ctx.fillRect(o.x*2, o.y*2, o.w*2, o.h*2); break; case 3: ctx.globalAlpha = .2; ctx.fillStyle = o.color; ctx.fillRect(o.x*2, o.y*2, o.w*2, o.h*2); ctx.font = '24px "Nova Flat"'; ctx.fillStyle = '#000'; ctx.globalAlpha = .5; ctx.fillText(o.count, o.x*2 + o.w - ctx.measureText(o.count).width/2, o.y*2+o.h+9); break; case 4: ctx.globalAlpha = 1; ctx.fillStyle = o.color; ctx.fillRect(o.x*2, o.y*2, o.w*2, o.h*2); ctx.globalAlpha = .2; ctx.fillStyle = '#000'; ctx.fillRect(o.x*2, o.y*2, o.w*2, o.h*2); ctx.globalAlpha = 1; ctx.fillStyle = o.color; ctx.fillRect(o.x*2+8, o.y*2+8, o.w*2-16, o.h*2-16); var l = Date.now() - o.lastClickAt > 150 ? 8 : 16; ctx.globalAlpha = .2; ctx.lineWidth = 1; ctx.strokeStyle = '#000'; ctx.beginPath(), ctx.moveTo(o.x*2+1, o.y*2+1), ctx.lineTo(o.x*2+o.w*2-2, o.y*2+1), ctx.lineTo(o.x*2+o.w*2-2, o.y*2+o.h*2-2), ctx.lineTo(o.x*2+1, o.y*2+o.h*2-2), ctx.lineTo(o.x*2+1, o.y*2+1); ctx.lineTo(o.x*2+1+l, o.y*2+1+l); ctx.moveTo(o.x*2+o.w*2-2, o.y*2+1), ctx.lineTo(o.x*2+o.w*2-2-l, o.y*2+1+l); ctx.moveTo(o.x*2+o.w*2-2, o.y*2+o.h*2-2); ctx.lineTo(o.x*2+o.w*2-2-l, o.y*2+o.h*2-2-l); ctx.moveTo(o.x*2+1, o.y*2+o.h*2-2), ctx.lineTo(o.x*2+1+l, o.y*2+o.h*2-2-l); ctx.moveTo(o.x*2+l, o.y*2+l), ctx.lineTo(o.x*2+o.w*2-l, o.y*2+l), ctx.lineTo(o.x*2+o.w*2-l, o.y*2+o.h*2-l), ctx.lineTo(o.x*2+l, o.y*2+o.h*2-l), ctx.lineTo(o.x*2+l, o.y*2+l); ctx.stroke(); ctx.fillStyle = '#000'; ctx.globalAlpha = .5; ctx.font = '24px "Nova Flat"'; ctx.fillText(o.count, o.x*2 + o.w - ctx.measureText(o.count).width/2, o.y*2+o.h+9); } } ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5; for (var i = 0; i < b.clicks.length; ++i) { if (typeof b.clicks[i] === 'object') { if (Date.now() - b.clicks[i].time > 500) b.clicks.splice(i--, 1); else { ctx.beginPath(), ctx.globalAlpha = .5 - (Date.now() - b.clicks[i].time)/1000; var radius = (Date.now() - b.clicks[i].time)/20; if (radius < 0.1) radius = 0.1 // Anti-crash failsafe ctx.arc(b.clicks[i].x*2, b.clicks[i].y*2, radius, 0, 2*Math.PI); ctx.stroke(); } } } ctx.strokeStyle = '#000'; ctx.lineWidth = 1; ctx.globalAlpha = .3; for (var i = 0; i < b.drawings.length; ++i) { if (typeof b.drawings[i] === 'object') { if (Date.now() - b.drawings[i].time > 10000) b.drawings.splice(i--, 1); else { ctx.beginPath(), ctx.moveTo(b.drawings[i].x*2, b.drawings[i].y*2); ctx.lineTo(b.drawings[i].x2*2, b.drawings[i].y2*2); ctx.stroke(); } } } ctx.globalAlpha = 1; ctx.font = '12px "Nova Flat"'; for (var i = 0; i < b.players.length; ++i) { var img; if (zM.fleet[zM.fSel].ids.indexOf(b.players[i].id) != -1) { for (var j = 0; i < zM.fleet[zM.fSel].bots.length; ++j) { if (zM.fleet[zM.fSel].bots[j]) if (zM.fleet[zM.fSel].bots[j].id == b.players[i].id) break; } if (j < zM.fleet[zM.fSel].bots.length) { if (zM.fleet[zM.fSel].bots[j].helping || zM.fleet[zM.fSel].bots[j].deployed) img = zMIMG.movement.img; else img = zMIMG.local.img; } else img = zMIMG.local.img; } else img = zMIMG.cursor.img; var x = zM.ease(b.players[i].x, b.players[i].ox, b.players[i].lastUpdate)*2; var y = zM.ease(b.players[i].y, b.players[i].oy, b.players[i].lastUpdate)*2; ctx.drawImage(img, x-4, y-5); x += 5; y-= 2; if (x + ctx.measureText(\`\${b.players[i].id}\`).width > 790) x = 790 - ctx.measureText(\`\${b.players[i].id}\`).width; if (y - 12 < 10) y = 22; zM.r.hudText(\`\${b.players[i].id}\`, x, y); } switch (zM.r.infLvl) { case 5: zM.r.hudText(\`Received (tp/ps) \${b.packets.receivedTotal} / \${b.packets.receivedPS}\`, 790, 22, 1); zM.r.hudText(\`Sent (tp/ps) \${b.packets.sentTotal} / \${b.packets.sentPS}\`, 790, 36, 1); case 4: case 3: case 2: zM.r.hudText(\`Level \${b.level}\`, 10, 36); case 1: zM.r.hudText( b.local < 30 ? 'Use shift+click to draw ('+b.local+' > 0)' : b.local < 100 ? 'Too many cursors, drawing is disabled ('+b.local+' > 30)' : b.local < 1010 ? 'Too many cursors, not all cursors are shown ('+b.local+' > 100)' : 'Use shift+click to draw ('+b.local+' > 1010)' , 10, 590); zM.r.hudText(\`\${b.online} players online\`, 790, 590, 1); case 0: } } } if (zM.r.infLvl >= 2) zM.r.hudText('FPS ' + zM.r.fps,10,22); ctx.fillStyle = zM.movement?'#ff0':'#f00'; ctx.globalAlpha = 0.3; ctx.beginPath(); ctx.moveTo(zM.pos.mouseX+3, zM.pos.mouseY+6); ctx.arc(zM.pos.mouseX+3, zM.pos.mouseY+6, 20, 0, 2*Math.PI); ctx.fill(); ctx.globalAlpha = 1; ctx.drawImage(zMIMG.cursor.img, zM.pos.mouseX-4, zM.pos.mouseY-5); zM.reqAfter(); } zM.reqAfter = function() { ++zM.r.fps; requestAnimationFrame(zM.reqDo); setTimeout(()=>{--zM.r.fps},1000); }`, /* zM packet parsing */ `zM.dependenciesLoaded |= 0b010000; zM.parse = { /** * Returns an array as [local, players, offset] */ cursors: function(buffer, offset) { var dat = new DataView(buffer); var local = dat.getUint16(offset, true); offset += 2; var players = []; for (var i = 0; i < local; ++i) { players.push({ id: dat.getUint32(offset, true), x: dat.getUint16(offset + 4, true), y: dat.getUint16(offset + 6, true), }); offset += 8; } return [local, players, offset]; }, /** * Returns an array as [clicks, offset] */ clicks: function(buffer, offset) { var dat = new DataView(buffer); var count = dat.getUint16(offset, true); var clicks = []; offset += 2; for (var i = 0; i < count; ++i) { clicks.push({ x: dat.getUint16(offset, true), y: dat.getUint16(offset + 2, true), time: Date.now() }); offset += 4; } return [clicks, offset]; }, /** * Returns an array as [clicks, offset] */ drawing: function(buffer, offset) { var dat = new DataView(buffer); var count = dat.getUint16(offset, true); var drawings = []; offset += 2; for (var i = 0; i < count; ++i) { drawings.push({ x: dat.getUint16(offset, true), y: dat.getUint16(offset + 2, true), x2: dat.getUint16(offset + 4, true), y2: dat.getUint16(offset + 6, true), time: Date.now() }); offset += 8; } return [drawings, offset]; }, /** * Returns an array as [ids, offset] */ remove: function(buffer, offset) { var dat = new DataView(buffer); var count = dat.getUint16(offset, true); var ids = []; offset += 2; for (var i = 0; i < count; ++i) { ids.push(dat.getUint32(offset, true)); offset += 4; } return [ids, offset]; }, /** * Parses objdata (string) and outputs as objects. */ objData: function(objdata) { var obj = objdata; var nObj = []; for (var i = 0; i < obj.length; ++i) { var nO = {}; obj[i] = obj[i].split(/\\.+/g); nO.id = parseInt(obj[i].shift()); var type = obj[i].shift(); switch (type) { case '0': nO.type = 0; nO.x = parseInt(obj[i].shift()); nO.y = parseInt(obj[i].shift()); nO.size = parseInt(obj[i].shift()); nO.isCentered = obj[i].shift() === 'false'?false:true; nO.content = obj[i].join(''); break; case '1': nO.type = 1; nO.x = parseInt(obj[i].shift()); nO.y = parseInt(obj[i].shift()); nO.w = parseInt(obj[i].shift()); nO.h = parseInt(obj[i].shift()); nO.color = obj[i].shift(); break; case '2': nO.type = 2; nO.x = parseInt(obj[i].shift()); nO.y = parseInt(obj[i].shift()); nO.w = parseInt(obj[i].shift()); nO.h = parseInt(obj[i].shift()); nO.isBad = obj[i].shift()==='false'?false:true; break; case '3': nO.type = 3; nO.x = parseInt(obj[i].shift()); nO.y = parseInt(obj[i].shift()); nO.w = parseInt(obj[i].shift()); nO.h = parseInt(obj[i].shift()); nO.count = parseInt(obj[i].shift()); nO.color = obj[i].shift(); break; case '4': nO.type = 4; nO.x = parseInt(obj[i].shift()); nO.y = parseInt(obj[i].shift()); nO.w = parseInt(obj[i].shift()); nO.h = parseInt(obj[i].shift()); nO.count = parseInt(obj[i].shift()); nO.color = obj[i].shift(); nO.lastClickAt = 0; break; } nObj.push(nO); } return nObj; }, /** * Returns an array as [objdata, offset] * objdata is required to be further parsed with zM.parse.objData() */ objects: function(buffer, offset) { var dat = new DataView(buffer); var count = dat.getUint16(offset, true); var objdata = []; offset += 2; for (var i = 0; i < count; ++i) { var id = dat.getUint32(offset, true); offset += 4; var type = dat.getUint8(offset); var objdat = id+'.'; ++offset; switch (type) { case 0: objdat += '0.'; objdat += \`\${dat.getUint16(offset, true)}.\`; objdat += \`\${dat.getUint16(offset+2, true)}.\`; objdat += \`\${dat.getUint8(offset+4)}.\`; objdat += \`\${!!dat.getUint8(offset+5)}.\`; offset += 5; for (;1;) if (dat.getUint8(++offset) != 0) objdat += String.fromCharCode(dat.getUint8(offset)); else break; ++offset; break; case 1: objdat += '1.'; objdat += \`\${dat.getUint16(offset, true)}.\`; objdat += \`\${dat.getUint16(offset+2, true)}.\`; objdat += \`\${dat.getUint16(offset+4, true)}.\`; objdat += \`\${dat.getUint16(offset+6, true)}.\`; var color = dat.getUint32(offset+8, true).toString(16); for (; color.length < 6;) color = '0' + color; objdat += '#' + color + '.'; offset += 12; break; case 2: objdat += '2.'; objdat += \`\${dat.getUint16(offset, true)}.\`; objdat += \`\${dat.getUint16(offset+2, true)}.\`; objdat += \`\${dat.getUint16(offset+4, true)}.\`; objdat += \`\${dat.getUint16(offset+6, true)}.\`; objdat += \`\${!!dat.getUint8(offset+8)}.\`; offset += 9; break; case 3: objdat += '3.'; objdat += \`\${dat.getUint16(offset, true)}.\`; objdat += \`\${dat.getUint16(offset+2, true)}.\`; objdat += \`\${dat.getUint16(offset+4, true)}.\`; objdat += \`\${dat.getUint16(offset+6, true)}.\`; objdat += \`\${dat.getUint16(offset+8, true)}.\`; var color = dat.getUint32(offset+10, true).toString(16); for (; color.length < 6;) color = '0' + color; objdat += '#' + color + '.'; offset += 14; break; case 4: objdat += '4.'; objdat += \`\${dat.getUint16(offset, true)}.\`; objdat += \`\${dat.getUint16(offset+2, true)}.\`; objdat += \`\${dat.getUint16(offset+4, true)}.\`; objdat += \`\${dat.getUint16(offset+6, true)}.\`; objdat += \`\${dat.getUint16(offset+8, true)}.\`; var color = dat.getUint32(offset+10, true).toString(16); for (; color.length < 6;) color = '0' + color; objdat += '#' + color + '.'; offset += 14; break; } objdata.push(objdat); } return [objdata, offset]; } } zM.packet = { /** * * @param {array} sockets Array of sockets to move */ moveSocket(sockets, x, y, bots) { var buf = new ArrayBuffer(9), dat = new DataView(buf); dat.setUint8(0, 1); dat.setUint16(1, x, true); dat.setUint16(3, y, true); dat.setUint32(5, -1, true); sockets.forEach(X => typeof X.send === 'function' && X.send(buf)); bots.forEach(X => { ++X.packets.sentTotal; ++X.packets.sentPS; setTimeout(()=>{--X.packets.sentPS},1000); X.packets.lastSent = Date.now(); }); }, /** * * @param {array} sockets Array of sockets to click with */ clickSocket(sockets, x, y, bots) { var buf = new ArrayBuffer(9), dat = new DataView(buf); dat.setUint8(0, 2); dat.setUint16(1, x, true); dat.setUint16(3, y, true); dat.setUint32(5, -1, true); sockets.forEach(X => typeof X.send === 'function' && X.send(buf)); bots.forEach(X => { ++X.packets.sentTotal; ++X.packets.sentPS; setTimeout(()=>{--X.packets.sentPS},1000); X.packets.lastSent = Date.now(); }); }, /** * * @param {array} sockets Array of sockets to draw with */ drawSocket(sockets, x, y, x2, y2, bots) { var buf = new ArrayBuffer(9), dat = new DataView(buf); dat.setUint8(0, 3); dat.setUint16(1, x, true); dat.setUint16(3, y, true); dat.setUint16(5, x2, true); dat.setUint16(7, y2, true); sockets.forEach(X => typeof X.send === 'function' && (X.send(buf))); bots.forEach(X => { ++X.packets.sentTotal; ++X.packets.sentPS; setTimeout(()=>{--X.packets.sentPS},1000); X.packets.lastSent = Date.now(); }); } }`, /* zM Pathfinder */ `zM.dependenciesLoaded |= 0b100000; var visit = []; zM.dos = function(dx, dy, items, gridSpace) { var gridX = 400/gridSpace, gridY = 300/gridSpace; var grid = []; visit = []; for (var i = 0; i < gridY; i++) { grid[i] = []; visit[i] = []; for (var j = 0; j < gridX; j++) grid[i][j] = 0, visit[i][j] = 0; } items.forEach(function(d) { if (d.type === 1) { for (var i = 0; i < d.h; i+=gridSpace) { for (var j = 0; j < d.w; j+=gridSpace) { grid[(d.y+i)/gridSpace][(d.x+j)/gridSpace] = 3; } } } }); var bfs = [[dx,dy]], bfs2 = []; while (bfs.length) { bfs.forEach(function(dat) { var x = dat[0], y = dat[1]; if (grid[y][x] == 3) return; grid[y][x] = 3; for (var X = x + 1; X < gridX && !(grid[y][X] & 1); X++) { grid[y][X] |= 1; if (!visit[y][X]) { visit[y][X] = [x, y], bfs2.push([X, y]); } } for (var X = x - 1; X >= 0 && !(grid[y][X] & 1); X--) { grid[y][X] |= 1; if (!visit[y][X]) { visit[y][X] = [x, y], bfs2.push([X, y]); } } for (var Y = y + 1; Y < gridY && !(grid[Y][x] & 2); Y++) { grid[Y][x] |= 2; if (!visit[Y][x]) { visit[Y][x] = [x, y], bfs2.push([x, Y]); } } for (var Y = y - 1; Y >= 0 && !(grid[Y][x] & 2); Y--) { grid[Y][x] |= 2; if (!visit[Y][x]) { visit[Y][x] = [x, y], bfs2.push([x, Y]); } } }); bfs = bfs2; bfs2 = []; } } zM.path = function(ox, oy, dx, dy, items, grid) { var rdx = dx, rdy = dy; ox /= grid; oy /= grid; dx /= grid; dy /= grid; ox |= 0; oy |= 0; dx |= 0; dy |= 0; var mov = []; if (!(ox == dx && oy == dy)) { zM.dos(ox,oy,items,grid); var xy2 = [dx,dy]; while (visit[xy2[1]][xy2[0]]) { mov.push(xy2); xy2 = visit[xy2[1]][xy2[0]]; } mov.reverse(); } for (var i = 0; i < mov.length; ++i) { mov[i][0] *= grid; mov[i][0] += grid/2; mov[i][1] *= grid; mov[i][1] += grid/2; } mov.push([rdx, rdy]); return mov; }` ], // --- // add elements from functions below: // --- [ function(c) { var temp = [D.createElement('link')]; temp[0].href = 'https://fonts.googleapis.com/css?family=Montserrat:100,200,300,400'; temp[0].rel = 'stylesheet'; head.appendChild(temp[0]); temp[1] = D.createElement('link'); temp[1].href = 'https://fonts.googleapis.com/css?family=Nova+Flat&display=swap'; temp[1].rel = 'stylesheet'; head.appendChild(temp[1]); }, function(c) { // news area (null fleet selected) var temp = [D.createElement('div')]; temp[0].className = 'zM-news-outer'; temp[1] = D.createElement('div'); temp[1].className = 'zM-news-container'; temp[0].appendChild(temp[1]); temp[2] = D.createElement('div'); temp[2].className = 'zM-news-page-top'; temp[1].appendChild(temp[2]); temp[3] = D.createElement('div'); temp[3].className = 'zM-news-page-mid'; temp[1].appendChild(temp[3]); temp[4] = D.createElement('div'); temp[4].className = 'zM-news-page-bottom'; temp[1].appendChild(temp[4]); zM.el.newsOuter = temp[0]; zM.el.newsPageTop = temp[2]; zM.el.newsPageMid = temp[3]; zM.el.newsPageBottom = temp[4]; c.appendChild(temp[0]); }, function(c) { // fleet prompt var temp = [D.createElement('div')]; temp[0].className = 'zM-fleet-prompt-outer'; temp[1] = D.createElement('div'); temp[1].className = 'zM-fleet-prompt-container'; temp[0].appendChild(temp[1]); temp[2] = D.createElement('div'); temp[2].className = 'zM-fleet-prompt-title'; temp[2].textContent = 'Create new fleet'; temp[1].appendChild(temp[2]); temp[3] = D.createElement('div'); temp[3].className = 'zM-fleet-prompt-entry'; temp[1].appendChild(temp[3]); temp[4] = D.createElement('div'); temp[4].className = 'zM-fleet-prompt-opt'; temp[4].textContent = 'Use premade IPs' temp[3].appendChild(temp[4]); temp[5] = D.createElement('input'); temp[5].type = 'checkbox'; temp[5].checked = true; temp[5].addEventListener('change', () => { if (temp[5].checked) { temp[6].style.display = 'block'; temp[10].style.display = 'none'; temp[13].style.display = 'none'; temp[16].style.display = 'none'; if (temp[12].value + ':' + temp[15].value === `${ip}:2828`) temp[8].value = "0"; else if (temp[12].value + ':' + temp[15].value === 'kursors.io/ws:8080') temp[8].value = "1"; else if (temp[12].value + ':' + temp[15].value === 'localhost:9004') temp[8].value = "2"; } else { temp[6].style.display = 'none'; temp[10].style.display = 'block'; temp[13].style.display = 'block'; temp[16].style.display = 'block'; // set input values switch (temp[8].value) { case "0": { temp[12].value = __ip; temp[15].value = '2828'; break; } case "1": { temp[12].value = 'kursors.io/ws'; temp[15].value = '8080'; break; } case "2": { temp[12].value = 'localhost'; temp[15].value = '9004'; break; } } temp[18].checked = false; } }) temp[3].appendChild(temp[5]); temp[6] = D.createElement('div'); temp[6].className = 'zM-fleet-prompt-entry'; temp[1].appendChild(temp[6]); temp[7] = D.createElement('div'); temp[7].className = 'zM-fleet-prompt-opt'; temp[7].textContent = 'Select an IP to connect to:' temp[6].appendChild(temp[7]); // dropdown temp[8] = D.createElement('select'); temp[8].style.outline = 'none'; temp[6].appendChild(temp[8]); temp[9] = [D.createElement('option'), D.createElement('option'), D.createElement('option')]; temp[9][0].value = "0"; temp[9][0].textContent = `cursors.io ${__ip}:2828)`; temp[9][1].value = "1"; temp[9][1].textContent = 'kursors.io (kursors.io/ws:8080)'; temp[9][2].value = "2"; temp[9][2].textContent = 'local server (localhost:9004)'; temp[9].forEach(X => temp[8].appendChild(X)); temp[10] = D.createElement('div'); temp[10].className = 'zM-fleet-prompt-entry'; temp[10].style.display = 'none'; temp[1].appendChild(temp[10]); temp[11] = D.createElement('div'); temp[11].className = 'zM-fleet-prompt-opt'; temp[11].textContent = 'IP address:' temp[10].appendChild(temp[11]); temp[12] = D.createElement('input'); temp[12].type = 'text'; temp[12].style.outline = 'none'; temp[12].width = 200; temp[10].appendChild(temp[12]); temp[13] = D.createElement('div'); temp[13].className = 'zM-fleet-prompt-entry'; temp[13].style.display = 'none'; temp[1].appendChild(temp[13]); temp[14] = D.createElement('div'); temp[14].className = 'zM-fleet-prompt-opt'; temp[14].textContent = 'Port:' temp[13].appendChild(temp[14]); temp[15] = D.createElement('input'); temp[15].type = 'text'; temp[15].style.outline = 'none'; temp[15].width = 200; temp[13].appendChild(temp[15]); temp[16] = D.createElement('div'); temp[16].className = 'zM-fleet-prompt-entry'; temp[16].style.display = 'none'; temp[1].appendChild(temp[16]); temp[17] = D.createElement('div'); temp[17].className = 'zM-fleet-prompt-opt'; temp[17].textContent = 'Using IPv6:' temp[16].appendChild(temp[17]); temp[18] = D.createElement('input'); temp[18].type = 'checkbox'; temp[18].style.outline = 'none'; temp[16].appendChild(temp[18]); // max bots temp[19] = D.createElement('div'); temp[19].className = 'zM-fleet-prompt-entry'; temp[1].appendChild(temp[19]); temp[20] = D.createElement('div'); temp[20].className = 'zM-fleet-prompt-opt'; temp[20].textContent = 'Maximum bots to this fleet:'; temp[19].appendChild(temp[20]); temp[21] = D.createElement('input'); temp[21].type = 'number'; temp[19].appendChild(temp[21]); temp[21].addEventListener('change', ev => { var num = Math.min(100, Math.max(parseInt(temp[21].value), 0)); if (isNaN(num)) num = 3; temp[21].value = num; }); if (zM.origin === 'cursors') temp[21].value = 3; else temp[21].value = 20; // start bots temp[22] = D.createElement('div'); temp[22].className = 'zM-fleet-prompt-entry'; temp[1].appendChild(temp[22]); temp[23] = D.createElement('div'); temp[23].className = 'zM-fleet-prompt-opt'; temp[23].textContent = 'Start with # bots:'; temp[22].appendChild(temp[23]); temp[24] = D.createElement('input'); temp[24].type = 'number'; temp[22].appendChild(temp[24]); temp[24].addEventListener('change', ev => { var num = Math.min(100, Math.max(parseInt(temp[24].value), 0)); if (isNaN(num)) num = 3; temp[24].value = num; }); if (zM.origin === 'cursors') temp[24].value = 3; else temp[24].value = 20; // zursor username temp[25] = D.createElement('div'); temp[25].className = 'zM-fleet-prompt-entry'; temp[1].appendChild(temp[25]); temp[26] = D.createElement('div'); temp[26].className = 'zM-fleet-prompt-opt'; temp[26].textContent = 'Fleet name (public):'; temp[25].appendChild(temp[26]); temp[27] = D.createElement('input'); temp[27].type = 'text'; temp[25].appendChild(temp[27]); // confirmation buttons temp[28] = D.createElement('div'); temp[28].className = 'zM-fleet-prompt-create'; temp[28].textContent = 'Create fleet'; temp[1].appendChild(temp[28]); temp[29] = D.createElement('div'); temp[29].className = 'zM-fleet-prompt-cancel'; temp[29].textContent = 'Cancel'; temp[1].appendChild(temp[29]); temp[29].addEventListener('click', ev => { temp[0].style.display = 'none'; if (isNaN(zM.fSel)) zM.el.newsOuter.style.display = 'block'; else zM.updateTabs(); }); temp[28].addEventListener('click', () => { var ip, port, ipv6 = false; if (!temp[5].checked) ip = temp[12].value, port = temp[15].value, ipv6 = temp[18].checked; else { switch (temp[8].value) { case "0": ip = __ip; port = '2828'; break; case "1": ip = 'kursors.io/ws'; port = '8080'; break; default: ip = 'localhost'; port = '9004'; break; } } var maxBots = parseInt(temp[21].value), startBots = parseInt(temp[24].value); var name = temp[27].value; if (name.length === 0) name = 'Unnamed fleet'; zM.createFleet(ip, port, ipv6, maxBots, startBots, name); }); // give temp to zM.el zM.el.fleetPromptOuter = temp[0]; zM.el.fleetPromptContainer = temp[1]; c.appendChild(temp[0]); }, function(c) { // fleet topbar var temp = [D.createElement('div')]; temp[0].className = 'zM-fleet-topbar-outer'; c.appendChild(temp[0]); temp[4] = D.createElement('div'); temp[4].className = 'zM-fleet-topbar-container'; temp[0].appendChild(temp[4]); temp[1] = D.createElement('div'); temp[1].className = 'zM-fleet-topbar-add'; temp[4].appendChild(temp[1]); temp[1].addEventListener('click', ev => { zM.promptFleet(); }); temp[2] = D.createElement('img'); temp[2].src = zMIMG.add.uri; temp[2].width = 45, temp[2].height = 35, temp[2].style.cssText = 'position:absolute;top:0px;left:0px;opacity:0.8;' temp[1].appendChild(temp[2]); temp[3] = D.createElement('div'); temp[3].className = 'zM-fleet-topbar-hint'; temp[3].textContent = 'Add fleet here to start playing'; temp[0].appendChild(temp[3]); // give temp to zM.el zM.el.fleetTopbarOuter = temp.shift(); zM.el.fleetTopbarContainer = temp.pop(); zM.el.fleetTopbarAdd = temp.shift(); zM.el.fleetTopbarAddImg = temp.shift(); zM.el.fleetTopbarHint = temp.shift(); }, function(c) { var temp = document.createElement('canvas'); temp.className = 'zM-game'; temp.width = 800; temp.height = 600; c.appendChild(temp); temp.addEventListener('mousemove', ev => { zM.pos.mouseX = ev.offsetX; zM.pos.mouseY = ev.offsetY; }); temp.addEventListener('mousedown', ev => { if (ev.shiftKey || ev.ctrlKey) zM.drawing = true; else { ++zM.clickQueue; } }); temp.addEventListener('mouseup', ev => { zM.drawing = false; }); addEventListener('keydown', ev => { if (isNaN(zM.fSel)) return; console.log(ev.key); switch (ev.key) { // all possible keys that can be drawn case 'A': case 'a':case 'B':case 'b':case 'C':case 'c': case 'D':case 'd':case 'E':case 'e':case 'F': case 'f':case 'G':case 'g':case 'H':case 'h': case 'I':case 'i':case 'J':case 'j':case 'K': case 'k':case 'L':case 'l':case 'M':case 'm': case 'N':case 'n':case 'O':case 'o':case 'P': case 'p':case 'Q':case 'q':case 'R':case 'r': case 'S':case 's':case 'T':case 't':case 'U': case 'u':case 'V':case 'v':case 'W':case 'w': case 'X':case 'x':case 'Y':case 'y':case 'Z': case 'z':case '1':case '2':case '3':case '4': case '5':case '6':case '7':case '8':case '9': case '0':case '!':case '@':case '#':case '$': case '%':case '^':case '&':case '*':case '(': case ')':case '`':case '~':case '-':case '_': case '=':case '+':case '[':case ']':case '{': case '}':case '\\':case '|':case ';':case ':': case '\'':case '"':case '.':case ',':case '<': case '>':case '/':case '?': case '¡': case '¢':case '£':case '¤':case '¥':case '¦': case '§':case '¨':case '©':case 'ª':case '«': case '¬':case '®':case '¯':case '°':case '±': case '²':case '³':case '´':case 'µ':case '¶': case '·':case '¸':case '¹':case 'º':case '»': case '¼':case '½':case '¾':case '¿': case 'À': case 'Á':case 'Â':case 'Ã':case 'Ä':case 'Å': case 'Æ':case 'Ç':case 'È':case 'É':case 'Ê': case 'Ë':case 'Ì':case 'Í':case 'Î':case 'Ï': case 'Ð':case 'Ñ':case 'Ò':case 'Ó':case 'Ô': case 'Õ':case 'Ö':case 'Ø':case 'Ù':case 'Ú': case 'Û':case 'Ü':case 'Ý':case 'Þ':case 'ß': case 'à':case 'á':case 'â':case 'ã':case 'ä': case 'å':case 'æ':case 'ç':case 'è':case 'é': case 'ê':case 'ë':case 'ì':case 'í':case 'î': case 'ï':case 'ð':case 'ñ':case 'ò':case 'ó': case 'ô':case 'õ':case 'ö':case 'ø':case 'ù': case 'ú':case 'û':case 'ü':case 'ý':case 'þ': case 'ÿ': //zM.fleet[zM.fSel]. break; case 'F1': ev.preventDefault(); zM.movement ^= 1; break; case 'F2': var f = zM.fleet[zM.fSel]; ev.preventDefault(); var i = 0; for (; i < f.bots.length; ++i) { if (f.bots[i]) if (!f.bots[i].deployed && !f.bots[i].helping && i !== f.cSel && f.bots[i].level === f.bots[f.cSel].level) break; } if (f.bots[i]) { var b = f.bots[i]; b.deployed = true; } break; case 'F3': var f = zM.fleet[zM.fSel]; ev.preventDefault(); var i = 0; for (; i < f.bots.length; ++i) { if (f.bots[i]) if (f.bots[i].deployed && f.bots[i].level === f.bots[f.cSel].level) break; } if (i < f.bots.length) { var b = f.bots[i]; var s = f.bots[f.cSel]; b.deployed = false; if (zM.returnAfterUndeployed) { var moves = zM.path(b.realX, b.realY, s.realX, s.realY, b.obj, b.grid); moves.forEach(Y => { zM.packet.moveSocket([b.socket], Y[0], Y[1], [b]); }); } } break; case 'F4': ev.preventDefault(); var f = zM.fleet[zM.fSel]; if (f.isHelping) break; f.isHelping = true; var helpers = []; for (var i = 0; i < f.bots.length; ++i) { console.log(!f.bots[i].helping && !f.bots[i].deployed && i !== f.cSel && f.bots[i].level === f.bots[f.cSel].level); console.log('1 ' + !f.bots[i].helping); console.log('2 ' + !f.bots[i].deployed); console.log('3 ' + (i !== f.cSel)); console.log('4 ' + (f.bots[i].level === f.bots[f.cSel].level)); if (f.bots[i]) if (!f.bots[i].helping && !f.bots[i].deployed && i !== f.cSel && f.bots[i].level === f.bots[f.cSel].level) helpers.push(f.bots[i]); } f.helpers = helpers; break; case 'F5': ev.preventDefault(); for (var i = 0; i < zM.fleet[zM.fSel].helpers.length; ++i) { zM.fleet[zM.fSel].helpers[i].helping = false; } zM.fleet[zM.fSel].helpers = []; zM.fleet[zM.fSel].isHelping = false; break; } }); zM.el.game = temp; zM.reqLoad(); zM.reqDo(); }, function(c) { var temp = [D.createElement('div')]; temp[0].className = 'zM-info-outer'; c.appendChild(temp[0]); temp[1] = D.createElement('div'); temp[1].className = 'zM-info-ver'; temp[1].textContent = 'v' + zM.version; temp[0].appendChild(temp[1]); temp[2] = D.createElement('div'); temp[2].className = 'zM-info-clog-button-outer'; temp[0].appendChild(temp[2]); temp[3] = D.createElement('div'); temp[3].className = 'zM-info-clog-button'; temp[3].textContent = 'view changelog'; temp[2].appendChild(temp[3]); temp[4] = D.createElement('div'); temp[4].className = 'zM-clog-outer'; c.appendChild(temp[4]); temp[5] = D.createElement('div'); temp[5].className = 'zM-clog-container'; temp[4].appendChild(temp[5]); temp[6] = D.createElement('div'); temp[6].className = 'zM-clog-close'; temp[4].appendChild(temp[6]); temp[7] = D.createElement('img'); temp[7].src = zMIMG.close.uri; temp[6].appendChild(temp[7]); zM.el.clogOuter = temp[4]; zM.el.clogContainer = temp[5]; temp[2].addEventListener('click', ev => { zM.el.clogOuter.style.display = 'block'; }); temp[6].addEventListener('click', ev => { zM.el.clogOuter.style.display = 'none'; }); var out = []; for (var i = 0; i < zM.clog.length; ++i) { var temp = D.createElement('div'); if (zM.clog[i].type === 'title') { temp.className = 'zM-clog-title'; temp.innerHTML = zM.clog[i].msg; out.push(temp); } else { temp.className = 'zM-clog-desc'; temp.innerHTML = zM.clog[i].msg; out.push(temp); } } out.forEach(X => zM.el.clogContainer.appendChild(X)); } ] ); })();