Hordes.io Extra Overlay - By AriusII

An extra overlay for Hordes.io, where you can add your own custom overlays(menus) and more.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Hordes.io Extra Overlay - By AriusII
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  An extra overlay for Hordes.io, where you can add your own custom overlays(menus) and more.
// @author       AriusII - ╲⎝⧹ AriusII⧸⎠╱#4556  & Thanks xFuRiOuS#9356 for the help.
// @match        https://hordes.io/play
// @icon         https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://hordes.io&size=32
// @grant        none
// @namespace    https://greasyfork.org/users/898675
// @license      MIT
// @run-at       document-start
// ==/UserScript==

class HomeMenu {
    constructor() {
        this.name = "HomeMenu"
        this.windowname = "home"
    }

    Init_SubMenu() {
        this.SubMenu_Home()
    }

    Init_MainFrame() {
        this.name
        this.MenuFrame_Home()
    }

    Init_Window(origin) {
        this.WindowSettings(origin)
    }

    /**
     * It inserts a div with the id "SubMenuHome" and the class "choice" into the div with the id "SubMenu".
     */
    SubMenu_Home() {
        document.getElementById("SubMenu").insertAdjacentHTML('beforeend',
            `<div id=${this.name} class="choice">Home</div>`)
    }

    /**
     * It inserts HTML into a div with the ID "MenuFrame".
     */
    MenuFrame_Home() {
        document.getElementById("MenuFrame").insertAdjacentHTML('beforeend',
            `<div class="slot svelte-yjs4p5">
				<div class="card">
					<div class="svelte-cbx1m">
						<div>
							<h1 class="textprimary">Hordes.io <span class="textsub"> Extra Overlay</span></h1>
							<div class="textwhite"><img class="svgicon" src="/assets/ui/icons/gem.svg?v=5699699"> Created by AriusII</div>
							<div class="textwhite"><img class="svgicon" src="/assets/ui/icons/check.svg?v=5699699"> <span class="old svelte-cbx1m">Yes Ads</span> <span class="textsub">NO</span> Ads</div>
							<div class="textwhite"><img class="svgicon" src="/assets/ui/icons/check.svg?v=5699699"> Auto AFK</div>
							<div class="textwhite"><img class="svgicon" src="/assets/ui/icons/check.svg?v=5699699"> Auto Loot</div>
							<div class="textwhite"><img class="svgicon" src="/assets/ui/icons/check.svg?v=5699699"> Bot</div>
							<div class="textwhite"><img class="svgicon" src="/assets/ui/icons/check.svg?v=5699699"> Auto Selling</div>
							<div class="textgrey">+ more to come (TBA)</div>
						</div>
					</div><small class="textgrey">Readme</small>
					<p class="textgrey">Welcome to my Extra Overlay.</p>
				</div>
			</div>`)
    }

    Options() {
        const Settings = {
            "HomeMenu": {
                "Ads": false
            }
        }
        return Settings
    }

    WindowSettings(origin) {
        window[this.windowname] = this.Options()
        let world = origin.match(/([_a-zA-Z0-9]*?)\.entities\.array\.length;/)[1]
        let coder = origin.match(/\,([_a-zA-Z0-9]*?)=\{clientPlayerInput:\{/)[1]
        let ws = origin.match(/\(([_a-zA-Z0-9]*?)=new WebSocket/)[1]
        let send = origin.match(/([_a-zA-Z0-9]*?)=[_a-zA-Z0-9]*?=>\{void 0!==[_a-zA-Z0-9]*?&&1===[_a-zA-Z0-9]*?&&[_a-zA-Z0-9]*?\.send\(.*?\)\}/)[1]
        origin = origin.replace('this.player=t', `Object.assign(window. ${this.windowname}, {world: ${world}, me:t, coder: ${coder}, ws: ${ws}, send: ${send} }), this.player=t`)
        return window.origin = origin
    }
}

class Core {
    constructor(add) {
        this.ShowUI = false
        this.AddonsList = add
    }

    /**
     * It fetches the game's HTML, replaces the script tag with a script tag that will run the game's code,
     * and then writes the HTML to the document.
     * 
     * The reason I'm doing this is because I want to add a button to the game's UI. I'm doing this by
     * adding a button to the HTML, and then using the game's code to make it do something.
     * 
     */
    Init() {
        document.write()
        fetch('https://hordes.io/play').then(d => d.text()).then(async html => {
            const element = html.match(/<script.*?client\.js.*?><\/script>/)[0]
            const url = element.match(/src="(.*?)"/)[1]
            html = html.replace(element, `<script>let _t=origin;delete origin;eval(_t)</script>`)
            let origin = await fetch(url).then(d => d.text())
            await Promise.resolve(this.LoadAddons_Window(origin))

            setInterval(() => {
                if (document.getElementById("uiBtn") == null) {
                    this.UISettingsButtonInBar()
                }
            }, 1000)

            document.open().write(html)
            document.close()
        })
    }

    /**
     * It creates a UI for the user to interact with.
     */
    CreateUI() {
        if (!this.ShowUI) {
            document.querySelector(".l-ui.layout > .container:first-child").insertAdjacentHTML('beforeend',
                `<div class="container svelte-ntyx09 MainBody">
                    <div class="window panel-black svelte-yjs4p5 MainSubMenu">
                        <div class="titleframe svelte-yjs4p5 MainFrameTitle">
                            <img src="https://www.svgrepo.com/show/284868/unsecured-shield-hacker.svg" class="titleicon svgicon svelte-yjs4p5">
                            <div class="textprimary title svelte-yjs4p5">
                                <div name="title">Extra Overlay Settings - By AriusII</div>
                            </div>
                            <img src="/assets/ui/icons/cross.svg?v=5699699" class="btn black svgicon CloseMain">
                        </div>
                        <div class="slot svelte-yjs4p5">
                            <div id="MainDiv" class="divide svelte-ntyx09">
                                <div id="SubMenu">
                                
                                </div>

                                <div id="MenuFrame" class="menu panel-black scrollbar svelte-ntyx09">

                                </div>
                            </div>
                        </div>
                    </div>
                </div>`)
            this.LoadAddons_SubMenu()
            new HomeMenu().MenuFrame_Home()

            this.LoadAddons_Frame()

            document.querySelector('.CloseMain').addEventListener('click', e => this.CreateUI());
        } else {
            document.querySelector(".MainBody").remove()
        }
        this.ShowUI ^= 1
    }

    /**
     * It creates a button in the top bar of the page, and when clicked, it calls the CreateUI() function.
     * @returns true.
     */
    UISettingsButtonInBar() {
        document.querySelector(".svelte-1wol45y").insertAdjacentHTML('beforeend',
            `<div id="uiBtn" class="btn border black"><img class="svgicon" src="https://www.svgrepo.com/show/284868/unsecured-shield-hacker.svg"></div>`)
        document.querySelector("#uiBtn").addEventListener('click', e => this.CreateUI())
        return true
    }


    /**
     * It loops through the AddonsList array and calls the Init() function of each addon
     */
    LoadAddons_SubMenu() {
        this.AddonsList.forEach(addon => {
            return addon.Init_SubMenu()
        })
    }

    /**
     * It adds an event listener to each addon's submenu, and when clicked, it clears the menu frame and
     * inserts the addon's frame.
     */
    LoadAddons_Frame() {
        this.AddonsList.forEach(addon => {
            let SubMenu = document.getElementById(addon.name)
            SubMenu.addEventListener('click', e => {
                document.getElementById("MenuFrame").innerHTML = "";
                if (addon.Init_MainFrame() != undefined) {
                    document.getElementById('MenuFrame').insertAdjacentHTML('beforeend', addon.Init_MainFrame())
                }
            })
        })
    }

    /**
     * It's supposed to loop through an array of objects, and call a function in each object
     * @param origin - The origin of the window.
     */
    LoadAddons_Window(origin) {
        this.AddonsList.forEach(addon => {
            return Promise.resolve(addon.Init_Window(origin))
        })
    }
}

(function() {
    'use strict'
    const addons = [
        new HomeMenu(),
    ]
    new Core(addons).Init()
}())