Bulk Join Raids

UI for selecting and joining raids by difficulty with a draggable button

当前为 2025-05-28 提交的版本,查看 最新版本

// ==UserScript==
// @name         Bulk Join Raids
// @version      1.1
// @license MIT
// @namespace    https://gf.qytechs.cn/users/1159361
// @description  UI for selecting and joining raids by difficulty with a draggable button
// @author       Zaregoto_Gaming
// @match        https://play.dragonsofthevoid.com/*
// @exclude      https://play.dragonsofthevoid.com/#/login
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const raidMap = {
        "r.lesser-tree-ent": "Lesser Tree Ent",
        "r.superior-watcher": "Superior Watcher",
        "r.elven-rangers": "Elven Rangers",
        "r.greater-ent": "Greater Ent",
        "r.sand-wyrm": "Sand Wyrm",
        "r.corrupted-golem": "Corrupted Golem",
        "r.naga-risaldar": "Naga Risaldar",
        "r.galeohog": "Galeohog",
        "r.naga-karamati": "Naga Karamati",
        "r.jagar-the-red": "Jagar the Red",
        "r.rotting-fen-lure": "Rotting Fen Lure",
        "r.sentry-ghoul": "Sentry Ghoul",
        "r.fallen-naga-subedar": "Fallen Naga Subedar",
        "r.bone-dragon": "Bone Dragon"
    };

    const difficulties = ["easy", "hard", "legendary"];

    function loadSettings() {
        return JSON.parse(localStorage.getItem('autojoinRaidSettings')) || {};
    }

    function saveSettings(settings) {
        localStorage.setItem('autojoinRaidSettings', JSON.stringify(settings));
    }

    function loadButtonPosition() {
        return JSON.parse(localStorage.getItem('autojoinButtonPosition')) || { top: '40px', left: '10px' };
    }

    function saveButtonPosition(position) {
        localStorage.setItem('autojoinButtonPosition', JSON.stringify(position));
    }

    function makeDraggable(element) {
        let offsetX, offsetY, isDragging = false;

        element.addEventListener('mousedown', (e) => {
            isDragging = true;
            offsetX = e.clientX - element.getBoundingClientRect().left;
            offsetY = e.clientY - element.getBoundingClientRect().top;
            element.style.cursor = 'grabbing';
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            let newX = e.clientX - offsetX;
            let newY = e.clientY - offsetY;

            newX = Math.max(0, Math.min(window.innerWidth - element.offsetWidth, newX));
            newY = Math.max(0, Math.min(window.innerHeight - element.offsetHeight, newY));

            element.style.top = `${newY}px`;
            element.style.left = `${newX}px`;
            element.style.right = 'auto';
        });

        document.addEventListener('mouseup', () => {
            if (!isDragging) return;
            isDragging = false;
            element.style.cursor = 'grab';
            saveButtonPosition({ top: element.style.top, left: element.style.left });
        });
    }

    function createUI(button) {
        const settings = loadSettings();
        const ui = document.createElement("div");
        ui.id = "autojoin-ui";
        ui.style.position = "fixed";
        ui.style.background = "#fff";
        ui.style.padding = "10px";
        ui.style.border = "1px solid black";
        ui.style.borderRadius = "8px";
        ui.style.boxShadow = "0 2px 6px rgba(0,0,0,0.2)";
        ui.style.zIndex = "1000";
        ui.style.maxHeight = "400px";
        ui.style.overflowY = "auto";

        const buttonRect = button.getBoundingClientRect();
        ui.style.top = `${Math.min(window.innerHeight - 410, buttonRect.bottom + window.scrollY)}px`;
        ui.style.left = `${Math.min(window.innerWidth - 300, buttonRect.left + window.scrollX)}px`;

        const title = document.createElement("div");
        title.innerHTML = `<strong>Bulk Join Settings</strong>`;
        ui.appendChild(title);

        const runButton = document.createElement("button");
        runButton.textContent = "Join Selected Raids";
        runButton.style.margin = "8px 0 12px 0";
        runButton.onclick = joinSelectedRaids;
        ui.appendChild(runButton);

        Object.entries(raidMap).forEach(([id, name]) => {
            const nameLabel = document.createElement("div");
            nameLabel.textContent = name;
            nameLabel.style.fontWeight = "bold";
            ui.appendChild(nameLabel);

            difficulties.forEach(diff => {
                const checkbox = document.createElement("input");
                checkbox.type = "checkbox";
                checkbox.checked = settings[id]?.includes(diff) || false;
                checkbox.onchange = () => {
                    if (!settings[id]) settings[id] = [];
                    if (checkbox.checked) {
                        if (!settings[id].includes(diff)) settings[id].push(diff);
                    } else {
                        settings[id] = settings[id].filter(d => d !== diff);
                    }
                    saveSettings(settings);
                };
                ui.appendChild(checkbox);
                ui.appendChild(document.createTextNode(" " + diff.charAt(0).toUpperCase() + diff.slice(1)));
                ui.appendChild(document.createElement("br"));
            });
            ui.appendChild(document.createElement("hr"));
        });

        document.body.appendChild(ui);
    }

    function addToggleButton() {
        const button = document.createElement("button");
        button.textContent = "⚔️ Bulk Join";
        button.style.position = "fixed";
        button.style.zIndex = "1001";
        button.style.cursor = "grab";

        const pos = loadButtonPosition();
        button.style.top = pos.top;
        button.style.left = pos.left;

        button.onclick = () => {
            const existingUI = document.getElementById("autojoin-ui");
            if (existingUI) {
                existingUI.remove();
            } else {
                createUI(button);
            }
        };

        document.body.appendChild(button);
        makeDraggable(button);
    }

    async function joinSelectedRaids() {
        const token = localStorage.token;
        const settings = loadSettings();

        const publicRaids = await getpublicraids(token);
        const activeRaids = await getactiveraids(token);

        const toJoin = publicRaids.filter(raid => {
            if (raid.health < 1000) return false;
            if (activeRaids.some(r => r.id === raid.id)) return false;
            return settings[raid.raidXmlId]?.includes(raid.difficulty);
        });

        let count = 0;
        for (let raid of toJoin) {
            await joinraid(raid.joinkey, token);
            count++;
        }
        alert("Joined " + count + " raids");
    }

    async function getpublicraids(token) {
        const res = await fetch("https://api.dragonsofthevoid.com/api/raid/public", {
            headers: { authorization: token }
        });
        return res.json();
    }

    async function getactiveraids(token) {
        const res = await fetch("https://api.dragonsofthevoid.com/api/raid/active", {
            headers: { authorization: token }
        });
        return res.json();
    }

    async function joinraid(joinkey, token) {
        const res = await fetch("https://api.dragonsofthevoid.com/api/raid/join/" + joinkey, {
            headers: { authorization: token }
        });
        return res.json();
    }

    window.addEventListener("load", () => {
        addToggleButton();
    });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址