Aladar

Aladar aka allies radar showing your allies on minimap.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name       Aladar
// @name:ru    Аладар
// @author     ClintFlames
// @version    1.0.0-alpha
// @namespace  https://violentmonkey.github.io
// @license    MIT

// @description       Aladar aka allies radar showing your allies on minimap.
// @description:ru    Aladar или же радар союзников - показывает ваших союзников на миникарте.
// @icon 
// @homepageURL https://github.com/ClintFlames/aladar
// @supportURL  https://github.com/ClintFlames/aladar/issues

// @match       https://diep.io/
// @run-at      document-start
// @inject-into page
// @noframes

// @require https://greatest.deepsurf.us/scripts/433681-diepapi/code/diepAPI.js?version=1129359

// @grant GM.getValue
// @grant GM.setValue
// @grant GM.addValueChangeListener
// @grant GM.registerMenuCommand
// @grant GM.unregisterMenuCommand

// @grant GM.notification
// ==/UserScript==

// buildnum (base 36) 5k



/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ({

/***/ "./src/Config.ts":
/*!***********************!*\
  !*** ./src/Config.ts ***!
  \***********************/
/***/ (function(__unused_webpack_module, exports) {


var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _Config_lastServer, _Config_showPlayer, _Config_autoConnect;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Config = void 0;
const getValue = async (name, defaultValue) => {
    const v = await GM.getValue(name);
    if (typeof v != typeof defaultValue)
        return defaultValue;
    return v;
};
class Config {
    get lastServer() { return __classPrivateFieldGet(this, _Config_lastServer, "f"); }
    set lastServer(v) { GM.setValue("lastServer", v); __classPrivateFieldSet(this, _Config_lastServer, v, "f"); }
    get showPlayer() { return __classPrivateFieldGet(this, _Config_showPlayer, "f"); }
    set showPlayer(v) { GM.setValue("showPlayer", v); __classPrivateFieldSet(this, _Config_showPlayer, v, "f"); }
    get autoConnect() { return __classPrivateFieldGet(this, _Config_autoConnect, "f"); }
    set autoConnect(v) { GM.setValue("autoConnect", v); __classPrivateFieldSet(this, _Config_autoConnect, v, "f"); }
    constructor() {
        _Config_lastServer.set(this, "");
        _Config_showPlayer.set(this, true);
        _Config_autoConnect.set(this, true);
    }
    async init(callback) {
        this.lastServer = await getValue("lastServer", "");
        this.showPlayer = await getValue("showPlayer", true);
        this.autoConnect = await getValue("autoConnect", true);
        GM.addValueChangeListener("lastServer", (_, oldValue, newValue) => {
            if (typeof newValue == "string")
                return;
            if (typeof oldValue == "string")
                return this.lastServer = oldValue;
            this.lastServer = "";
        });
        GM.addValueChangeListener("showPlayer", (_, oldValue, newValue) => {
            if (typeof newValue == "boolean")
                return;
            if (typeof oldValue == "boolean")
                return this.showPlayer = oldValue;
            this.showPlayer = true;
        });
        GM.addValueChangeListener("autoConnect", (_, oldValue, newValue) => {
            if (typeof newValue == "boolean")
                return;
            if (typeof oldValue == "boolean")
                return this.autoConnect = oldValue;
            this.autoConnect = true;
        });
        callback(this);
    }
}
exports.Config = Config;
_Config_lastServer = new WeakMap(), _Config_showPlayer = new WeakMap(), _Config_autoConnect = new WeakMap();


/***/ }),

/***/ "./src/aladarClient.ts":
/*!*****************************!*\
  !*** ./src/aladarClient.ts ***!
  \*****************************/
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.connect = void 0;
let _config;
let _playerList = [];
const { player: _player, game, minimap, arena } = window.unsafeWindow.diepAPI.apis;
const { Vector } = window.unsafeWindow.diepAPI.core;
let isOnline = false;
const clamp = (x, min, max) => Math.min(Math.max(x, min), max);
const scaleNumber = (x, origin, target) => (x - origin[0]) * (target[1] - target[0]) / (origin[1] - origin[0]) + target[0];
const connect = (config, data) => {
    if (isOnline)
        return alert("Already online");
    isOnline = true;
    const [url, joinCode] = data.split("::");
    if (!url)
        return alert("URL can't be empty.");
    if (!joinCode)
        return alert("You must specify joinCode.");
    const ws = (() => {
        try {
            return new WebSocket(url);
        }
        catch (e) {
            if (e instanceof Error) {
                if (e.message.endsWith("is invalid."))
                    return alert("URL is invalid.");
                console.log("ERROR: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n");
                console.log(e.message);
                isOnline = false;
            }
        }
    })();
    if (!(ws instanceof WebSocket))
        return;
    ws.binaryType = "arraybuffer";
    config.lastServer = data;
    const playerList = [];
    _playerList = playerList;
    _config = config;
    ws.onerror = e => {
        console.log("ERROR: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
        console.log(e);
        isOnline = false;
    };
    ws.onclose = e => {
        isOnline = false;
        switch (e.code) {
            case 4001:
                alert("joinCode is wrong.");
                break;
            case 4002:
                alert("Server player limit is reached.");
                break;
            case 4003:
                (0, exports.connect)(config, data);
                break;
        }
    };
    ws.onopen = () => {
        console.log("OPENED");
        ws.send(joinCode);
    };
    ws.onmessage = m => {
        const data = new Uint8Array(m.data);
        switch (data[0]) {
            case 0: {
                for (let i = 1; i < data.length; i += 4) {
                    playerList.push({
                        id: data[i],
                        color: data.slice(i + 1, i + 4).reduce((o, v) => o + v.toString(16).padStart(2, "0"), "#"),
                        pos: { x: NaN, y: NaN }
                    });
                }
                break;
            }
            case 1: {
                if (_player.isDead)
                    return ws.send("");
                const pos = [
                    Math.floor(clamp(scaleNumber(_player.position.x, [arena.size * -0.5, arena.size * 0.5], [0, 255]), 0, 255)),
                    Math.floor(clamp(scaleNumber(_player.position.y, [arena.size * -0.5, arena.size * 0.5], [0, 255]), 0, 255))
                ];
                if (pos[0] > 255 || pos[1] > 255)
                    return ws.send("");
                ws.send(new Uint8Array(pos));
                break;
            }
            case 2: {
                const closeListLength = data[1];
                if (closeListLength) {
                    for (let i = 0; i < closeListLength; i++) {
                        const id = data[2 + i];
                        playerList.splice(playerList.findIndex(p => p.id == id), 1);
                    }
                }
                for (const player of playerList)
                    player.pos = { x: NaN, y: NaN };
                for (let i = 2 + closeListLength; i < data.length; i += 3) {
                    const player = playerList.find(p => p.id == data[i]);
                    if (!player)
                        continue;
                    player.pos = {
                        x: data[i + 1],
                        y: data[i + 2]
                    };
                }
                break;
            }
        }
    };
};
exports.connect = connect;
game.once("ready", () => {
    let ctx;
    const interval = setInterval(() => {
        if (!_config)
            return;
        const canvas = document.getElementById("canvas");
        if (!canvas)
            return;
        const _ctx = canvas.getContext("2d");
        if (!_ctx)
            return;
        ctx = _ctx;
        clearInterval(interval);
        game.on("frame", () => {
            ctx.globalAlpha = 1;
            for (const { color, pos } of _playerList) {
                if (!_config.showPlayer && color == _playerList[0].color)
                    continue;
                if (isNaN(pos.x))
                    continue;
                const { x, y } = Vector.add(minimap.minimapPos, Vector.multiply(minimap.minimapDim, {
                    x: scaleNumber(pos.x, [0, 255], [0, 1]),
                    y: scaleNumber(pos.y, [0, 255], [0, 1])
                }));
                ctx.fillStyle = color;
                ctx.beginPath();
                ctx.arc(x, y, 3 * window.unsafeWindow.devicePixelRatio, 0, 2 * Math.PI);
                ctx.fill();
                ctx.strokeStyle = "#333339";
                ctx.stroke();
            }
        });
    }, 100);
});


/***/ }),

/***/ "./src/menu.ts":
/*!*********************!*\
  !*** ./src/menu.ts ***!
  \*********************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.startMenu = void 0;
const aladarClient_1 = __webpack_require__(/*! ./aladarClient */ "./src/aladarClient.ts");
const startMenu = (config) => {
    const changeValue = (buttonId, valueName) => (() => {
        const button = buttonList[buttonId];
        const status = button.status == "on" ? false : true;
        button.status = status ? "on" : "off";
        config[valueName] = status;
        reloadMenu();
    });
    const buttonList = [
        {
            name: "Connect to new server",
            callback: () => {
                const data = prompt("URL::JOINCODE", "");
                if (!data)
                    return alert("Empty data provided.");
                (0, aladarClient_1.connect)(config, data);
            }
        },
        {
            name: "Connect to last server",
            callback: () => {
                const lastServer = config.lastServer;
                if (!lastServer)
                    return alert("There is no last server.");
                (0, aladarClient_1.connect)(config, lastServer);
            }
        },
        {
            name: "Auto-connect to last server: ",
            status: config.autoConnect ? "on" : "off",
            callback: changeValue(2, "autoConnect")
        },
        {
            name: "Show you on minimap: ",
            status: config.showPlayer ? "on" : "off",
            callback: changeValue(3, "showPlayer")
        },
        {
            name: "Guide/Гайд",
            callback: () => { var _a; (_a = window.open("https://github.com/ClintFlames/aladar/blob/main/Guide.md", "_blank")) === null || _a === void 0 ? void 0 : _a.focus(); }
        }
    ];
    const loadMenu = () => {
        for (const button of buttonList) {
            if (!button.status) {
                GM.registerMenuCommand(button.name, button.callback);
                continue;
            }
            button.currentName = button.name + button.status;
            GM.registerMenuCommand(button.currentName, button.callback);
        }
    };
    const reloadMenu = () => {
        for (const button of buttonList) {
            if (!button.currentName) {
                GM.unregisterMenuCommand(button.name);
                continue;
            }
            GM.unregisterMenuCommand(button.currentName);
            button.currentName = "";
        }
        loadMenu();
    };
    loadMenu();
    GM.notification({
        title: "Aladar",
        text: "Loading complete"
    });
};
exports.startMenu = startMenu;


/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
var exports = __webpack_exports__;
/*!**********************!*\
  !*** ./src/index.ts ***!
  \**********************/

Object.defineProperty(exports, "__esModule", ({ value: true }));
const Config_1 = __webpack_require__(/*! ./Config */ "./src/Config.ts");
const aladarClient_1 = __webpack_require__(/*! ./aladarClient */ "./src/aladarClient.ts");
const menu_1 = __webpack_require__(/*! ./menu */ "./src/menu.ts");
const _window = window.unsafeWindow;
const config = new Config_1.Config();
config.init(() => {
    if (config.autoConnect && config.lastServer)
        (0, aladarClient_1.connect)(config, config.lastServer);
    (0, menu_1.startMenu)(config);
});
// const { Vector, CanvasKit } = _window.diepAPI.core;
// const { player, game, minimap, arena } = _window.diepAPI.apis;
// const { backgroundOverlay } = _window.diepAPI.tools;

})();

/******/ })()
;