StakeUsPlus

StakeUs plugin framework

目前為 2024-02-17 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/487489/1328597/StakeUsPlus.js

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         StakeUsPlus
// @namespace    a
// @version      2.0
// @description  StakeUs plugin framework
// @author       diehard2k0
// @match        *://stake.us/*
// @grant        none
// @require      http://code.jquery.com/jquery-3.4.1.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/anchorme/2.1.2/anchorme.min.js
// ==/UserScript==

(function() {
    'use strict';

    const VERSION = "1.0";

    if(window.StakeUsPlus) {
        // already loaded
        return;
    }

    const LOCAL_STORAGE_KEY_DEBUG = "StakeUsPlus:debug";
    const INFO = {};

    const CONFIG_TYPES_LABEL = ["label"];
    const CONFIG_TYPES_BOOLEAN = ["boolean", "bool", "checkbox"];
    const CONFIG_TYPES_INTEGER = ["integer", "int"];
    const CONFIG_TYPES_FLOAT = ["number", "num", "float"];
    const CONFIG_TYPES_STRING = ["string", "text"];
    const CONFIG_TYPES_SELECT = ["select"];
    const CONFIG_TYPES_COLOR = ["color"];

    function logFancy(s, color="#00f7ff") {
        console.log("%cStakeUsPlus: %c"+s, `color: ${color}; font-weight: bold; font-size: 12pt;`, "color: black; font-weight: normal; font-size: 10pt;");
    }

    class StakeUsPlusPlugin {

        constructor(id, opts) {
            if(typeof id !== "string") {
                throw new TypeError("StakeUsPlusPlugin constructor takes the following arguments: (id:string, opts?:object)");
            }
            this.id = id;
            this.opts = opts || {};
            this.config = null;
        }

        getConfig(name) {
            if(!this.config) {
                StakeUsPlus.loadPluginConfigs(this.id);
            }
            if(this.config) {
                return this.config[name];
            }
        }
    }

    const internal = {
        init() {
            const self = this;

            $("#svelte").append(`
            <style>
            .ipp-chat-command-help {
              padding: 0.5em 0;
            }
            .ipp-chat-command-help:first-child {
              padding-top: 0;
            }
            .ipp-chat-command-help:last-child {
              padding-bottom: 0;
            }
            dialog.ipp-dialog {
              background-color: white;
              border: 1px solid rgba(0, 0, 0, 0.2);
              width: 500px;
              max-width: 800px;
              border-radius: 5px;
              display: flex;
              flex-direction: column;
              justify-content: flex-start;
            }
            dialog.ipp-dialog > div {
              width: 100%;
            }
            dialog.ipp-dialog > .ipp-dialog-header > h4 {
              margin-bottom: 0;
            }
            dialog.ipp-dialog > .ipp-dialog-header {
              border-bottom: 1px solid rgba(0, 0, 0, 0.2);
              padding-bottom: 0.25em;
            }
            dialog.ipp-dialog > .ipp-dialog-actions {
              padding-top: 0.25em;
              padding-bottom: 0.25em;
            }
            dialog.ipp-dialog > .ipp-dialog-actions {
              border-top: 1px solid rgba(0, 0, 0, 0.2);
              padding-top: 0.25em;
              text-align: right;
            }
            dialog.ipp-dialog > .ipp-dialog-actions > button {
              margin: 4px;
            }
            </style>
            `);

            // hook into websocket messages
            const hookIntoOnMessage = () => {
                try {
                    const original_onmessage = window.websocket.connected_socket.onmessage;
                    if(typeof original_onmessage === "function") {
                        window.websocket.connected_socket.onmessage = function(event) {
                            original_onmessage.apply(window.websocket.connected_socket, arguments);
                            self.onMessageReceived(event.data);
                        }
                        return true;
                    }
                    else {
                        return false;
                    }
                }
                catch(err) {
                    console.error("Had trouble hooking into websocket...");
                    return false;
                }
            };
            $(function() {
                if(!hookIntoOnMessage()) {
                    // try once more
                    setTimeout(hookIntoOnMessage, 40);
                }
            });

            // create plugin menu item and panel
            var pluginHTML = `
                <button data-test="plugins" data-testid="plugins" class="button variant-action size-sm align-left svelte-1pcg5q8" data-analytics="global-navbar-plugins-button" style="border-radius: 0 var(--border-radius-0-25) var(--border-radius-0-25) 0;">
                    <span class="content-or-loader svelte-kgkwgo">
                       <span> Plugins </span>
                    </span>
                 </button>
                `
            const lastMenuItem = $("#svelte > div.wrap.svelte-sizi7f > div.main-content.svelte-sizi7f > div.navigation.svelte-1ekwux9 > div > div > div > div.stack.x-flex-start.y-center.gap-smaller.padding-none.direction-horizontal.padding-left-auto.padding-top-auto.padding-bottom-auto.padding-right-auto.svelte-1mgzzos > div");
            logFancy("Adding Menu");
            lastMenuItem.after(pluginHTML);
            const overlay = document.createElement('div');
            overlay.setAttribute('id', 'pluginsOverlay');
            overlay.style.position = 'fixed';
            overlay.style.top = '0';
            overlay.style.left = '0';
            overlay.style.width = '100%';
            overlay.style.height = '100%';
            overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
            overlay.style.zIndex = '9999';
            overlay.style.display = 'none'; // Initially hide the overlay

            document.body.appendChild(overlay);

            // Adding a modal to show plugins and their settings
            const modalHTML = `
                <div class="modal fade" id="pluginsModal" tabindex="-1" aria-labelledby="pluginsModalLabel" aria-hidden="true">
                    <div class="modal-dialog modal-dialog-centered">
                        <div class="modal-content" style="border: 2px solid #000;">
                            <div class="modal-header">
                                <h5 class="modal-title" id="pluginsModalLabel">Plugins</h5>
                                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                            </div>
                            <div class="modal-body" id="pluginsModalBody"></div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                            </div>
                        </div>
                    </div>
                </div>
            `;

            // Append the modal HTML to the specified element
            overlay.insertAdjacentHTML('beforeend', modalHTML);

            // Click event handler for the Plugins button
            $('[data-testid="plugins"]').on('click', function() {
                $('#pluginsOverlay').show(); // Show the overlay
                $('#pluginsModal').modal('show'); // Show the modal
            });

            // Close event handler for the modal
            $('#pluginsModal').on('hidden.bs.modal', function() {
                $('#pluginsOverlay').hide(); // Hide the overlay when the modal is closed
            });

            logFancy(`(v${self.version}) initialized.`);
        },

        showPluginsModal() {
            const pluginsModalBody = $('#pluginsModalBody');
            pluginsModalBody.empty();

            // Iterate through each plugin and add its details to the modal body
            window.StakeUsPlus.forEachPlugin(plugin => {
                let name = "An StakeUs+ Plugin!";
                let description = "";
                let author = "Unknown";
                let settings = "";
                if(INFO.hasOwnProperty(plugin.id)) {
                    const pluginInfo = INFO[plugin.id];
                    name = pluginInfo.name || name;
                    description = pluginInfo.description || description;
                    author = pluginInfo.author || author;
                }

                const pluginSettings = plugin.config;
                if(pluginSettings) {
                    settings = "<ul>";
                    for(const key in pluginSettings) {
                        if(pluginSettings.hasOwnProperty(key)) {
                            settings += `<li><strong>${key}:</strong> ${pluginSettings[key]}</li>`;
                        }
                    }
                    settings += "</ul>";
                }

                const pluginHTML = `
                    <div class="card">
                        <div class="card-header">
                            <h5 class="card-title">${name}</h5>
                        </div>
                        <div class="card-body">
                            <p class="card-text">${description}</p>
                            <p class="card-text"><strong>Author:</strong> ${author}</p>
                            <p class="card-text"><strong>Settings:</strong></p>
                            ${settings}
                        </div>
                    </div>
                `;
                pluginsModalBody.append(pluginHTML);
            });

            // Show the modal
            $('#pluginsModal').modal('show');
        },

        onMessageReceived(data) {
            console.log("Received data from websocket: " + data);
        }
    };

    window.StakeUsPlus = {
        version: VERSION,

        // Define the showPluginsModal function directly within the StakeUsPlus object
        showPluginsModal() {
            internal.showPluginsModal();
        },

        loadPluginConfigs(id) {
            logFancy(`Fetching config for plugin '${id}'...`);
            // Simulate fetching plugin configuration from some external source
            // Here you would typically load plugin settings from localStorage or a server
            // For simplicity, we'll just set some dummy settings
            const dummyConfig = {
                setting1: true,
                setting2: "some value",
                setting3: 42
            };

            setTimeout(() => {
                logFancy(`Config loaded for plugin '${id}':`, "#ff00ff");
                console.log(dummyConfig);
                window.StakeUsPlus[id].config = dummyConfig;
            }, 1000);
        },

        forEachPlugin(callback) {
            for(const pluginId in window.StakeUsPlus) {
                if(window.StakeUsPlus.hasOwnProperty(pluginId) && window.StakeUsPlus[pluginId] instanceof StakeUsPlusPlugin) {
                    callback(window.StakeUsPlus[pluginId]);
                }
            }
        }
    };


    // Add to window and init
    window.StakeUsPlusPlugin = StakeUsPlusPlugin;
    //    window.StakeUsPlus = new StakeUsPlus();

    setTimeout(function() {
        internal.init.call(window.StakeUsPlus);
    }, 5000);
    //internal.init.call(window.StakeUsPlus);

})();