您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
optimised multibox (no precise aim & move to mouse for now)
// ==UserScript== // @name r!PsAw Multibox public // @namespace http://tampermonkey.net/ // @version 1.0.5 // @description optimised multibox (no precise aim & move to mouse for now) // @author r!PsAw // @match https://diep.io/* // @icon https://www.google.com/s2/favicons?sz=64&domain=diep.io // @grant none // @license MIT // ==/UserScript== /* TODO-List: - finish importing world coordinates -> rework bot following other bots - add Player detection tracers - maybe add Tank upgrades option to auto upgrade to main tank */ //I do not recommend changing the code unless you understand it, since it might break //In this code player is the tank that is running this code and clone usually is the main tab //let other scripts know that this one is active window.ripsaw_multibox = true; const ctx = canvas.getContext('2d'); let you, him, inGame = false, connected = false; function windowScaling() { const a = canvas.height / 1080; const b = canvas.width / 1920; return b < a ? a : b; } function window_2_canvas(a) { let b = a * (canvas.width / window.innerWidth); return b; } //options let key_option = ["WASD", "Arrows"]; let mouse_modes = ["Copy", "Reversed"]; let movement_modes = ["Clump", "Copy"]; let repel_modes = ["long 50/50", "infinite 70/30", "infinity", "Necromancer"]; let config = { move_keys: key_option[0], copy_keys: false, copy_build: false, copy_mouse: false, movement_mode: movement_modes[0], mouse_mode: mouse_modes[0], afk: false, drone_repel: false, drone_repel_mode: repel_modes[0], }; //GUI logic (visual menu) function n2id(string) { return string.toLowerCase().replace(/ /g, "-"); } class El { constructor( name, type, el_color, width, height, opacity = "1", zindex = "100" ) { this.el = document.createElement(type); this.el.style.backgroundColor = el_color; this.el.style.width = width; this.el.style.height = height; this.el.style.opacity = opacity; this.el.style.zIndex = zindex; this.el.id = n2id(name); } setPosition(position, display, top, left, translate) { this.el.style.position = position; this.el.style.display = display; this.el.style.top = top; this.el.style.left = left; this.el.style.transform = "translate(" + translate + ")"; this.display = display; //store last display } margin(top, left, right, bottom) { this.el.style.marginTop = top; this.el.style.marginLeft = left; this.el.style.marginRight = right; this.el.style.marginBottom = bottom; } setText(text, txt_color, font, fontsize, stroke, align) { this.el.innerHTML = text; this.el.style.color = txt_color; this.el.style.fontFamily = font; this.el.style.fontSize = fontsize; this.el.style.textShadow = stroke; this.el.style.textAlign = align; } add(parent) { parent.appendChild(this.el); } remove() { if (this.el.parentElement) { this.el.parentElement.removeChild(this.el); console.log("Element removed successfully."); } else { console.warn("Attempted to remove element, but it's not in the DOM."); } } toggle(showOrHide) { switch (showOrHide) { case "hide": this.el.display = "none"; break; case "show": this.el.display = this.display; break; } } } class Setting { constructor(name, text, type, configsett, cycleArray = []) { this.sett = new El(name, "button", "Indigo", "100px", "60px", "0.75"); this.sett.setPosition("relative", "block"); this.sett.margin("20px", "10px", "10px", "20px"); this.sett.setText( text, "white", "Lucida Console, Courier New, monospace", "15px", "0 0 2px gray", "center" ); const element = this.sett.el; // Reference the DOM element element.onclick = () => { switch (type) { case "boolean": config[configsett] = !config[configsett]; element.style.backgroundColor = config[configsett] ? "Navy" : "Indigo"; break; case "cycle": { const currentIndex = cycleArray.indexOf(config[configsett]); const nextIndex = (currentIndex + 1) % cycleArray.length; config[configsett] = cycleArray[nextIndex]; element.innerHTML = `${text.split(":")[0]}: ${config[configsett]}`; } break; default: console.error("Invalid setting type:", type); break; } }; } add(parent) { this.sett.add(parent); } remove() { this.sett.remove(); } toggle(showOrHide) { this.sett.toggle(showOrHide); } } let gui_loaded = false; let hidden = false; function load_GUI() { //define everything if (!gui_loaded) { let sett_classes = []; let cont = new El("Mb Container", "div", "purple", "350px", "675x", "0.75"); cont.setPosition("absolute", "block", "50%", "100%", "-50%, -50%"); let credit = new El( "credit Element", "div", "transparent", "150px", "25px", "0.75" ); credit.setText( "Multibox by r!PsAw", "white", "Lucida Console, Courier New, monospace", "20px", "0 0 2px red", "center" ); credit.setPosition("relative", "block"); let mk_setting = new Setting( "Move Keys", `Move Keys: ${config.move_keys}`, "cycle", "move_keys", key_option ); sett_classes.push(mk_setting); let ck_setting = new Setting( "Copy Keys", "Copy Keys", "boolean", "copy_keys" ); sett_classes.push(ck_setting); let cb_setting = new Setting( "Copy Build", "Copy Build", "boolean", "copy_build" ); sett_classes.push(cb_setting); let cm_setting = new Setting( "Copy Mouse", "Copy Mouse", "boolean", "copy_mouse" ); sett_classes.push(cm_setting); let mvm_setting = new Setting( "Movement Mode", `Movement: ${config.movement_mode}`, "cycle", "movement_mode", movement_modes ); sett_classes.push(mvm_setting); let mm_setting = new Setting( "Mouse Mode", `Mouse Mode: ${config.mouse_mode}`, "cycle", "mouse_mode", mouse_modes ); sett_classes.push(mm_setting); let afk_setting = new Setting("Afk", "Afk", "boolean", "afk"); sett_classes.push(afk_setting); let dr_setting = new Setting( "Drone Repel", "Repel Drones", "boolean", "drone_repel" ); sett_classes.push(dr_setting); let dm_setting = new Setting( "Drone Repel Modes", `Repel Mode: ${config.drone_repel_mode}`, "cycle", "drone_repel_mode", repel_modes ); sett_classes.push(dm_setting); //load elements if unloaded cont.add(document.body); credit.add(cont.el); let l = sett_classes.length; for (let i = 0; i < l; i++) { sett_classes[i].add(cont.el); } gui_loaded = true; } } //mouse function click_at(x, y, delay1 = 150) { input.onTouchStart(-1, x, y); setTimeout(() => { input.onTouchEnd(-1, x, y); }, delay1); } function ghost_click_at(x, y, delay1 = 150) { input.onTouchStart(0, x, y); setTimeout(() => { input.onTouchEnd(0, x, y); }, delay1); } function mouse_move(x, y) { input.onTouchMove(-1, x, y); } //define keys const RAW_MAPPING = [ "KeyA", "KeyB", "KeyC", "KeyD", "KeyE", "KeyF", "KeyG", "KeyH", "KeyI", "KeyJ", "KeyK", "KeyL", "KeyM", "KeyN", "KeyO", "KeyP", "KeyQ", "KeyR", "KeyS", "KeyT", "KeyU", "KeyV", "KeyW", "KeyX", "KeyY", "KeyZ", "ArrowUp", "ArrowLeft", "ArrowDown", "ArrowRight", "Tab", "Enter", "NumpadEnter", "ShiftLeft", "ShiftRight", "Space", "Numpad0", "Numpad1", "Numpad2", "Numpad3", "Numpad4", "Numpad5", "Numpad6", "Numpad7", "Numpad8", "Numpad9", "Digit0", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9", "F2", "End", "Home", "Semicolon", "Comma", "NumpadComma", "Period", "Backslash", ] function key_down(keyString) { const index = RAW_MAPPING.indexOf(keyString); if (index === -1) { console.error(`Invalid key string: ${keyString}`); return; } const result = index + 1; // Add 1 to the index as per your requirement input.onKeyDown(result); } function key_up(keyString) { const index = RAW_MAPPING.indexOf(keyString); if (index === -1) { console.error(`Invalid key string: ${keyString}`); return; } const result = index + 1; // Add 1 to the index as per your requirement input.onKeyUp(result); } function key_press(keyString, delay = 100) { key_down(keyString); setTimeout(() => { key_up(keyString) }, delay); } //those are updating player.keys when the script executes them /* function script_key_down(keyString, player) { const index = RAW_MAPPING.indexOf(keyString); player.keys[index] = 1; //console.log(`index ${index} player.keys[index] ${player.keys[index]} keyString ${keyString}`); key_down(keyString); } function script_key_up(keyString, player) { const index = RAW_MAPPING.indexOf(keyString); player.keys[index] = 0; //console.log(`index ${index} player.keys[index] ${player.keys[index]} keyString ${keyString}`); key_up(keyString); } */ //credits to mi300 const ARENA_WIDTH = 26000; const ARENA_HEIGHT = 26000; let minimapArrow = [0, 0]; let square_pos = [0, 0] let leaderArrow = [0, 0]; let minimapPos = [0, 0]; let minimapDim = [0, 0]; let calls = 0; let points = []; function hook(target, callback) { function check() { window.requestAnimationFrame(check); if (window.arrows) { minimapArrow[0] = window.arrows[0][0]; minimapArrow[1] = window.arrows[0][0]; minimapPos[0] = window.arrows[2][0]; minimapPos[1] = window.arrows[2][1]; minimapDim[0] = window.arrows[3][0]; minimapDim[1] = window.arrows[3][1]; //console.warn("[r!PsAw] canceled!"); //console.log(minimapArrow); return; } const func = CanvasRenderingContext2D.prototype[target] if (func.toString().includes(target)) { CanvasRenderingContext2D.prototype[target] = new Proxy(func, { apply(method, thisArg, args) { callback(thisArg, args) return Reflect.apply(method, thisArg, args) } }); } } window.requestAnimationFrame(check) } hook('beginPath', function(thisArg, args) { calls = 1; points = []; }); hook('moveTo', function(thisArg, args) { if (calls == 1) { calls += 1; points.push(args) } else { calls = 0; } }); hook('lineTo', function(thisArg, args) { if (calls >= 2 && calls <= 6) { calls += 1; points.push(args) } else { calls = 0; } }); function getCentre(vertices) { let centre = [0, 0]; vertices.forEach(vertex => { centre[0] += vertex[0] centre[1] += vertex[1] }); centre[0] /= vertices.length; centre[1] /= vertices.length; return centre; } hook('fill', function(thisArg, args) { if (calls >= 4 && calls <= 6) { if (!window.M_X && thisArg.fillStyle === "#000000" && thisArg.globalAlpha > 0.9) { minimapArrow = getCentre(points); return; } } else { calls = 0; } }); hook('strokeRect', function(thisArg, args) { const t = thisArg.getTransform(); minimapPos = [t.e, t.f]; minimapDim = [t.a, t.d]; }); //detect if focused let is_main = document.hasFocus(); function setFocusState(isFocused) { is_main = isFocused; } window.addEventListener('focus', () => setFocusState(true)); window.addEventListener('blur', () => setFocusState(false)); //status(0) = is in game? status(1) = is connected? everything else returns null function status(type) { let s; switch (type) { case 0: s = extern.doesHaveTank() > 0; break case 1: s = !!window.lobby_ip; break } return s; } //create ingame Notifications function rgbToNumber(r, g, b) { return (r << 16) | (g << 8) | b; } const notification_rbgs = { require: [255, 165, 0], //orange warning: [255, 0, 0], //red normal: [0, 0, 128] //blue } let notifications = []; function new_notification(text, color, duration) { input.inGameNotification(text, color, duration); } function one_time_notification(text, color, duration){ if(notifications.includes(text)){ return; } if(!inGame){ notifications = []; }else{ new_notification(text, color, duration); notifications.push(text); } } //FOV finder let FOV = 0.55; let fov_factors = [0.699, 0.8, 0.85, 0.899]; let fov_tanks = { 0.699: ["Ranger"], 0.8: ["Assassin", "Stalker"], 0.85: ["Predator", "Streamliner", "Hunter"], 0.899: ["Sniper", "Overseer", "Overlord", "Necromancer", "Manager", "Trapper", "Gunner Trapper", "Overtrapper", "Mega Trapper", "Tri-Trapper", "Smasher", "Landmine", "Streamliner", "Auto Trapper", "Battleship", "Auto Smasher", "Spike", "Factory", "Skimmer", "Glider", "Rocketeer"] }; function find_fieldFactor(tank) { let fieldFactor = 1; let l = fov_factors.length; for (let i = 0; i < l; i++) { if (fov_tanks[fov_factors[i]].includes(tank)) { fieldFactor = fov_factors[i]; } } return fieldFactor; } function calculateFOV(Fv, l) { const numerator = 0.55 * Fv; const denominator = Math.pow(1.01, (l - 1) / 2); return (numerator / denominator); } const crx = CanvasRenderingContext2D.prototype; let diepFont = "20"; //I'm just assigning some value to it here, so it's not null or undefined let sf = { autoFire: false, autoSpin: false }; //this function is for both main and slave tab function update_sf(state, f_or_s) { switch (state) { case " ON": sf[f_or_s] = true; break case " OFF": sf[f_or_s] = false; break } } crx.fillText = new Proxy(crx.fillText, { apply: function(f, _this, args) { //detect Auto Spin & Auto Fire if (args[0] === "diep.io") { diepFont = _this.font.split("px")[0]; } if (args[0].includes("Auto Fire: ") && _this.font.split("px")[0] === diepFont) { update_sf(args[0].split(':')[1], "autoFire"); } if (args[0].includes("Auto Spin: ") && _this.font.split("px")[0] === diepFont) { update_sf(args[0].split(':')[1], "autoSpin"); } //detect data for FOV if (args[0].startsWith("Lvl ") && inGame) { let words = args[0].split(" "); let level = words[1]; let tank = words.slice(2).join(" ").trim(); let fieldFactor = find_fieldFactor(tank); FOV = calculateFOV(fieldFactor, level); you.fov = FOV; console.log(` %c[r!PsAw Multibox] FOV value was changed, look :0 tank: ${tank} level: ${level} fieldFactor: ${fieldFactor} FOV: ${you.fov} `, "color: purple"); } f.apply(_this, args); } }); //share & recieve information across tabs /* keys index explanation: 0: 0 = undefined, 1 = wasd, 2 = arrow keys value 0 for unpressed and 1 for pressed: 1: rest_keys[0] 2: rest_keys[1] 3: rest_keys[2] 4: rest_keys[3] 5: Shift (Triggered by ShiftLeft, ShiftRight or Right Mouse click 6: Space (Triggered by Space and Left Mouse Click) 7: Backslash (since sandbox arena is unusual, it breaks the world coords system, so it won't be used for now) auto Fire & Auto Spin (0 for off and 1 for on): 8: Auto Fire 9: Auto Spin This setup reduces number of transfered values from 64 to 10 Because the build is stored in a different array */ class Player { constructor() { this.pos_xy = new Uint16Array(2); //remake in world coords this.afk_xy = new Uint16Array(2); //remake in world coords this.mouse_xy = new Uint16Array(4); //last 2 should be world coords this.keys = new Uint8Array(10); this.build = new Uint8Array(33); this.windowSizes = new Uint16Array(2); this.minimapScale = new Uint16Array(4); this.fov = FOV; } } function update_move_keys(player){ let bool = 0; if(key_option.includes(config.move_keys)){ bool = key_option.indexOf(config.move_keys)+1; } player.keys[0] = bool; //console.log(player.keys[0]); } function update_build(player) { player.build.fill(0); let raw = extern.get_convar("game_stats_build"); let temp_arr = [...raw]; let l = temp_arr.length; for (let i = 0; i < l; i++) { player.build[i] = temp_arr[i]; } } /* OLD VERSION (with converter to 1/2/3/4/5/6/7/8) function update_build(player) { player.build.fill(0); let raw = extern.get_convar("game_stats_build"); let temp_arr = [...raw]; let l = temp_arr.length; for (let i = 0; i < l; i++) { let increase_index = parseFloat(temp_arr[i]); player.build[increase_index - 1]++; } } */ function update_pos(player) { player.pos_xy[0] = Math.floor(minimapArrow[0]); player.pos_xy[1] = Math.floor(minimapArrow[1]); //console.log(player.pos_xy); } function update_minimap_Scale(player) { player.minimapScale[0] = minimapPos[0]; player.minimapScale[1] = minimapPos[1]; player.minimapScale[2] = minimapDim[0]; player.minimapScale[3] = minimapDim[1]; } function update_window_sizes(player) { player.windowSizes[0] = window.innerWidth; player.windowSizes[1] = window.innerHeight; } function save_sf(player){ player.keys[8] = sf.autoFire?1:0; player.keys[9] = sf.autoSpin?1:0; //console.log(player.keys); } function save_info(player) { localStorage.setItem("Multibox Player", JSON.stringify(player)); } function get_info() { return JSON.parse(localStorage.getItem("Multibox Player")); } //define some values let wasd = ["KeyW", "KeyA", "KeyS", "KeyD"]; let arrows = ["ArrowUp", "ArrowLeft", "ArrowDown", "ArrowRight"]; let build_keys = [ "KeyU", "KeyM", "Numpad1", "Numpad2", "Numpad3", "Numpad4", "Numpad5", "Numpad6", "Numpad7", "Numpad8", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", ]; function move_keys() { switch (config.move_keys) { case "WASD": return wasd; break case "Arrows": return arrows; break } } function rest_keys() { //opposite to move_keys switch(config.move_keys){ case "WASD": return arrows; break case "Arrows": return wasd; break } } //copy clone values function copy_key_inputs(player) { //OLD /* for (let i = 0; i < RAW_MAPPING.length; i++) { const keyString = RAW_MAPPING[i]; if (!keyString) { console.error(`Invalid keyString at index ${i}`); continue; } switch (player.keys[i]) { case 0: if (!rest_keys().includes(keyString) && !build_keys.includes(keyString)) { //DO NOT copy wasd/arrow keys OR build keys key_up(keyString); } break; case 1: if (!rest_keys().includes(keyString) && !build_keys.includes(keyString)) { //DO NOT copy wasd/arrow keys OR build keys key_down(keyString); //console.log(keyString); } break; default: console.error(`Unexpected value for player.keys[${i}]: ${player.keys[i]}`); } } */ //NEW for(let i = 1; i < 8; i++){ copy_key_sub_func(i, player); } } function copy_key_sub_func(index, player){ if(index < 5 && config.movement_mode != "Copy"){ return; } let mk = move_keys(); let allowed_keys = [mk[0], mk[1], mk[2], mk[3], "ShiftLeft", "Space", "Backslash"]; let key = allowed_keys[index-1]; if(player.keys[index] === 0){ key_up(key); }else{ key_down(key); } } //scaling from window to window function scaleCoordinates(sourceX, sourceY, sourceWidth, sourceHeight, targetWidth, targetHeight) { // Scale factors for width and height const scaleX = targetWidth / sourceWidth; const scaleY = targetHeight / sourceHeight; // Scale the coordinates const scale = Math.min(scaleX, scaleY); const targetX = sourceX * scale; const targetY = sourceY * scale; return { x: targetX, y: targetY }; } //copy mouse coords function get_invert_mouse_coords(x, y, width, height) { let center = { x: width / 2, y: height / 2 }; let d = { x: x - center.x, y: y - center.y }; let inverted_coords = { x: center.x - d.x, y: center.y - d.y }; return inverted_coords; } function copy_mouse_inputs(player, clone) { console.log("copying inputs"); switch (config.mouse_mode) { case "Copy": { console.log("Copy"); let final = scaleCoordinates(clone.mouse_xy[0], clone.mouse_xy[1], clone.windowSizes[0], clone.windowSizes[1], player.windowSizes[0], player.windowSizes[1]); console.log(final); mouse_move(final.x, final.y); } break case "Reversed": { //haven't tested yet let modified = get_invert_mouse_coords(clone.mouse_xy[0], clone.mouse_xy[1], clone.windowSizes[0], clone.windowSizes[1]); let final = scaleCoordinates(modified.x, modified.y, clone.windowSizes[0], clone.windowSizes[1], player.windowSizes[0], player.windowSizes[1]); mouse_move(final.x, final.y); } break } } //update your values //const KEY_MAP = new Map(RAW_MAPPING.map((key, index) => [key, index])); window.addEventListener('keydown', function(e) { //OLD /* if (connected && inGame && is_main) { if (move_keys().includes(e.code) || build_keys.includes(e.code)) { return; //don't copy wasd/arrows or build keys } if (e.code === "KeyQ") { hidden = !hidden; toggle_GUI(hidden); } let index = KEY_MAP.get(e.code); if (index !== undefined) { you.keys[index] = 1; //console.log(`pressed ${e.code} status ${you.keys[index]} index ${index}`); } } */ //NEW if (connected && is_main) { if (e.code === "KeyQ") { hidden = !hidden; toggle_GUI(hidden); } if(inGame){ if(move_keys().includes(e.code)){ let index = move_keys().indexOf(e.code); you.keys[index+1] = 1; //console.log(you.keys); } if(rest_keys().includes(e.code)){ let rest_move = ["W, A, S, D", "Arrow Keys"]; if(rest_keys()[0] === "KeyW"){ new_notification(`Warning, you are using ${rest_move[0]}, use ${rest_move[1]} instead OR change your move keys to ${rest_move[0]}`, rgbToNumber(243, 185, 26), 5000); }else{ new_notification(`Warning, you are using ${rest_move[1]}, use ${rest_move[0]} instead OR change your move keys to ${rest_move[1]}`, rgbToNumber(243, 185, 26), 5000); } } if(e.code === "Space"){ you.keys[6] = 1; //console.log(you.keys); } if(e.code === "ShiftLeft" || e.code === "ShiftRight"){ you.keys[5] = 1; //console.log(you.keys); } if(e.code === "Backslash"){ you.keys[7] = 1; //console.log(you.keys); } } } }); window.addEventListener('keyup', function(e) { //OLD /* if (connected && inGame && is_main) { let index = KEY_MAP.get(e.code); if (index !== undefined) { you.keys[index] = 0; //console.log(`unpressed ${e.code} status ${you.keys[index]} index ${index}`); } } */ //NEW if (connected && inGame && is_main) { if(move_keys().includes(e.code)){ let index = move_keys().indexOf(e.code); you.keys[index+1] = 0; //console.log(you.keys); } if(e.code === "Space"){ you.keys[6] = 0; //console.log(you.keys); } if(e.code === "ShiftLeft" || e.code === "ShiftRight"){ you.keys[5] = 0; //console.log(you.keys); } if(e.code === "Backslash"){ you.keys[7] = 0; //console.log(you.keys); } } }); window.addEventListener('mousemove', function(e) { if (connected && inGame && is_main) { you.mouse_xy[0] = e.clientX; you.mouse_xy[1] = e.clientY; //console.log(you.mouse_xy); } }); window.addEventListener("mousedown", function(e) { if (connected && inGame && is_main) { if (e.button === 0){ you.keys[6] = 1; //console.log(you.keys); } if (e.button === 2) { you.keys[5] = 1; //console.log(you.keys); } } }); window.addEventListener("mouseup", function(e) { if (connected && inGame && is_main) { if (e.button === 0){ you.keys[6] = 0; //console.log(you.keys); } if (e.button === 2) { you.keys[5] = 0; //console.log(you.keys); } } }); //copy build function read_build(player) { let buildStr = ""; for (let i = 0; i < 33; i++) { if (player.build[i] === 0) { break } buildStr += player.build[i]; } return buildStr; } function copy_build(string) { extern.execute(`game_stats_build ${string}`); } //AFK logic let moving = false; let goal = { x: 0, y: 0 }; function set_goal(x, y) { goal.x = x; goal.y = y; } function move_to_goal(player) { if (config.afk) { if (player.pos_xy[0] > goal.x) { key_up(rest_keys()[3]); key_down(rest_keys()[1]); } else { key_up(rest_keys()[1]); key_down(rest_keys()[3]); } if (player.pos_xy[1] > goal.y) { key_up(rest_keys()[2]); key_down(rest_keys()[0]); } else { key_up(rest_keys()[0]); key_down(rest_keys()[2]); } moving = true; } else { if (moving) { for (let i = 0; i < rest_keys().length; i++) { key_up(rest_keys()[i]); } moving = false; } set_goal(player.pos_xy[0], player.pos_xy[1]); } } //Tank Clump (enabled when copy keys enabled) let debug = [ 0, 0, 0, 0 ]; function scale_minimap(PlayerInfo, CloneInfo) { //NOTE: This is only possible, because minimap is a square //player let pos1 = { x: PlayerInfo[0], y: PlayerInfo[1] }; let m_pos1 = { x: PlayerInfo[2], y: PlayerInfo[3] }; let m_dim1 = { w: PlayerInfo[4], h: PlayerInfo[5] }; console.log("PlayerInfo"); console.log(PlayerInfo); //clone let pos2 = { x: CloneInfo[0], y: CloneInfo[1] }; let m_pos2 = { x: CloneInfo[2], y: CloneInfo[3] }; let m_dim2 = { w: CloneInfo[4], h: CloneInfo[5] }; console.log("CloneInfo"); console.log(CloneInfo); //translate clone coords into player coords let distance_2_mpos = { x: pos2.x - m_pos2.x, y: pos2.y - m_pos2.y }; let calc_percentage = { x: (distance_2_mpos.x / m_dim2.w) * 100, y: (distance_2_mpos.y / m_dim2.h) * 100 }; //use % from clone and transfer to player let scaled_clone = { x: m_pos1.x + (m_dim1.w / 100 * calc_percentage.x), y: m_pos1.y + (m_dim1.h / 100 * calc_percentage.y) } debug[0] = window_2_canvas(pos1.x); debug[1] = window_2_canvas(pos1.y); debug[2] = window_2_canvas(scaled_clone.x); debug[3] = window_2_canvas(scaled_clone.y); return scaled_clone; } function clump(player, clone) { if (config.copy_keys && config.movement_mode === "Clump") { if(config.afk){ one_time_notification("Disabled Clump since you have afk on :)", rgbToNumber(243, 185, 26), 5000); if (moving) { for (let i = 0; i < move_keys().length; i++) { script_key_up(move_keys()[i], player); } moving = false; } return; } let scaled_clone = scale_minimap([ player.pos_xy[0], player.pos_xy[1], player.minimapScale[0], player.minimapScale[1], player.minimapScale[2], player.minimapScale[3] ], [ clone.pos_xy[0], clone.pos_xy[1], clone.minimapScale[0], clone.minimapScale[1], clone.minimapScale[2], clone.minimapScale[3] ]); console.log(` you ${player.pos_xy} clone ${scaled_clone.x} ${scaled_clone.y} 1st cond ${player.pos_xy[0] > scaled_clone.x} 2nd cond ${player.pos_xy[1] > scaled_clone.y} `); if (player.pos_xy[0] > scaled_clone.x) { key_up(rest_keys()[3]); key_down(rest_keys()[1]); } else { key_up(rest_keys()[1]); key_down(rest_keys()[3]); } if (player.pos_xy[1] > scaled_clone.y) { key_up(rest_keys()[2]); key_down(rest_keys()[0]); } else { key_up(rest_keys()[0]); key_down(rest_keys()[2]); } moving = true; } else { if (moving) { for (let i = 0; i < move_keys().length; i++) { key_up(move_keys()[i]); } moving = false; } set_goal(player.pos_xy[0], player.pos_xy[1]); } } //toggle GUI function toggle_GUI(state) { let cont = document.getElementById("mb-container"); if (state) { cont.style.display = "none"; } else { cont.style.display = "block"; } } //Drone Repel let timings = { //long 50/50 by default main: 50000, inside: 25000 } let reset_finished = false; function repel_loop() { if (inGame && config.drone_repel) { reset_finished = false; key_down("ShiftLeft"); setTimeout(() => { key_up("ShiftLeft"); }, timings.inside); } else { if (!reset_finished) { key_up("ShiftLeft"); reset_finished = true; } } } setInterval(repel_loop, timings.main); function update_timings() { switch (config.drone_repel_mode) { case "long 50/50": timings.main = 50000; timings.inside = 25000; break case "infinite 70/30": timings.main = 10000; timings.inside = 7000; break case "infinity": timings.main = 100000; timings.inside = 99999; break case "Necromancer": timings.main = 50000; timings.inside = 20000; break } } //replace move keys of every clone to your main move keys function new_move_keys(player, clone){ if(player.keys[0] != clone.keys[0]){ let btn = document.getElementById("move-keys"); let index = clone.keys[0]-1; config.move_keys = key_option[index]; btn.innerHTML = `Move Keys: ${key_option[index]}`; } } //this loop will handle your auto fire + auto spin, separately from init function handle_sf(){ if(connected && inGame && config.copy_keys){ if(!is_main){ if(you.keys[8] != him.keys[8]){ key_press("KeyE"); you.keys[8] = him.keys[8]; } if(you.keys[9] != him.keys[9]){ key_press("KeyC"); you.keys[9] = him.keys[9]; } } } } setInterval(handle_sf, 2500); //initialise (I luv this shit) function init() { window.requestAnimationFrame(init); inGame = status(0); connected = status(1); if (connected) { if (!you) { you = new Player(); console.log("%c[r!PsAw] Player found, reading info for multibox... ^w^", "color: green"); } load_GUI(); if (inGame) { update_move_keys(you); update_build(you); update_window_sizes(you); update_minimap_Scale(you); update_pos(you); move_to_goal(you); update_timings(); if (is_main) { save_sf(you); save_info(you); } else { him = get_info(); if (config.copy_keys) { copy_key_inputs(him); clump(you, him); } new_move_keys(you, him); config.copy_build ? copy_build(read_build(him)) : null; config.copy_mouse ? copy_mouse_inputs(you, him) : null; } }else{ update_sf(" OFF", "autoFire"); update_sf(" OFF", "autoSpin"); } } } window.requestAnimationFrame(init); //canvas debug setTimeout(() => { let gui = () => { if (!is_main) { ctx.beginPath(); ctx.moveTo(debug[0], debug[1]); ctx.lineTo(debug[2], debug[3]); ctx.strokeStyle = "black"; ctx.stroke(); } window.requestAnimationFrame(gui); }; gui(); setTimeout(() => { gui(); }, 5000); }, 1000);