Greasy Fork

StakeUsPlus

StakeUs plugin framework

目前为 2024-02-17 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.cloud/scripts/487489/1328597/StakeUsPlus.js

// ==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);

})();