This wiki has been permanently archived. As such, editing and registration have been closed.

User:Lumpy HTF/AutoTurn.js

From CollabVM Wiki, the horrible, autism-inducing, trash filled wiki, featuring people who can't speak English
Revision as of 19:26, 20 May 2022 by import>Lumpy HTF (Lumpy HTF moved page User:Lumpy HTF/test.js to User:Lumpy HTF/AutoTurn.js: to see the url format for loading scripts in)
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// ==UserScript==
// @name         Auto-Turn
// @namespace    http://computernewb.com/
// @version      1.2.0
// @description  A auto turn script with a efficent auto turn method, graphical dropdown, easy-to-use interface, GUI with metro theme support, auto start options, you name it. While your typical auto turn script would just be a plain dev console script, this userscript version is loaded with features, and the ones I mentioned aren't the only ones. See for yourself by checking the about page in the script today.
// @author       Swordlink1
// @match        https://computernewb.com/collab-vm/*
// @match        http://computernewb.com/collab-vm/*
// @match        localhost
// @icon         https://www.google.com/s2/favicons?sz=64&domain=computernewb.com
// @grant        none
// ==/UserScript==

(function() {
    'use strict'; // WELCOME TO THE RTM RELEASE! This userscript will be receiving more features in future updates. Stay tuned! The updates are in this script's changelog.
    // defining some variables
    var bgcolor = $(".navbar").css("background-color"); // detect cvm red and black theme
    var crab = false; // variable for cvm red and black theme detection (crab is cvm red and black theme)
    var bt4 = false; // variable for cvm bootstrap 4 theme detection
    var bt5 = false; // variable for cvm bootstrap 5 theme detection
    var betatheme = false; // variable for cvm beta theme detection
    var devrelease = true; // tells if its a dev release
    var btns = document.getElementById("btns") || document.getElementById("vote-stats").nextSibling;
    var adminbtns = document.getElementById("admin-btns");
    var turnbtn = document.getElementById("turn-btn"); // the setinterval continously defined this variable and i didnt like that so i moved this up here
    var scriptver = "1.2.0"; // look at the top of the window variables
    // pre-dropdown theme support helper (needed for theme detection variables and certain themes)
    try { // using ifs instead of else ifs just in case both crab and some other thing is applied
        if (bgcolor == "rgb(106, 16, 16)") { // cvm red and black theme detection
            crab = true;
        }
        if ($.fn.tooltip.Constructor.VERSION == '4.1.3') {
            bt4 = true;
        }
        if ($.fn.tooltip.Constructor.VERSION == "5.0.2") {
            bt5 = true;
        }
    } catch (e) {
        if (turnbtn.classList.contains("ui")) { // detection for future update
            betatheme = true;
        }
    }
    // start of dropdown preparers (DO NOT REMOVE THIS CODE. This is essential for proper theme compatibility.)
    if (bt4) { // bootstrap 4 theme dropdown preparing code
        var autoturnoptions = document.createElement("div"); // the base of the dropdown
        autoturnoptions.id = "auto-turn-options";
        autoturnoptions.classList.add("dropdown");
        autoturnoptions.style.display = "inline-block";
        btns.insertBefore(autoturnoptions, adminbtns);
        var dropdownhelper = document.createElement("button"); // the button that makes the dropdown toggable
        dropdownhelper.classList.add("btn", "btn-default", "dropdown-toggle");
        dropdownhelper.type = "button";
        dropdownhelper.id = "autoturn-dropdownbtn";
        dropdownhelper.setAttribute("data-toggle", "dropdown");
        dropdownhelper.setAttribute("aria-haspopup", "true");
        dropdownhelper.setAttribute("aria-expanded", "false");
        dropdownhelper.innerHTML = "Auto-Turn";
        autoturnoptions.appendChild(dropdownhelper);
        var dropdownlist = document.createElement("div"); // the actual dropdown itself with all the options
        dropdownlist.id = "autoturn-dropdown-list"; // user123 removed the ids, damn, anyways if some mod wants to add stuff into this dropdown then there you go (although i might as well just add the addoption function into "window" which i have done)
        dropdownlist.classList.add("dropdown-menu");
        dropdownlist.setAttribute("aria-labelledby", "autoturn-dropdownbtn");
        autoturnoptions.appendChild(dropdownlist);
    } else if (bt5) {
        autoturnoptions = document.createElement("div"); // the base of the dropdown
        autoturnoptions.id = "auto-turn-options";
        autoturnoptions.classList.add("dropdown");
        autoturnoptions.style.display = "inline-block";
        btns.insertBefore(autoturnoptions, adminbtns);
        dropdownhelper = document.createElement("button"); // the button that makes the dropdown toggable
        dropdownhelper.classList.add("btn", "btn-light", "dropdown-toggle");
        dropdownhelper.type = "button";
        dropdownhelper.id = "autoturn-dropdownbtn";
        dropdownhelper.setAttribute("data-bs-toggle", "dropdown");
        dropdownhelper.setAttribute("aria-expanded", "false");
        dropdownhelper.innerHTML = "Auto-Turn";
        autoturnoptions.appendChild(dropdownhelper);
        dropdownlist = document.createElement("div"); // the actual dropdown itself with all the options
        dropdownlist.id = "autoturn-dropdown-list"; // user123 removed the ids, damn, anyways if some mod wants to add stuff into this dropdown then there you go (although i might as well just add the addoption function into "window" which i have done)
        dropdownlist.classList.add("dropdown-menu");
        dropdownlist.setAttribute("aria-labelledby", "autoturn-dropdownbtn");
        autoturnoptions.appendChild(dropdownlist);
    } else { // original bootstrap 3
        autoturnoptions = document.createElement("div"); // the base of the dropdown
        autoturnoptions.id = "auto-turn-options";
        autoturnoptions.classList.add("btn-group");
        btns.insertBefore(autoturnoptions, adminbtns);
        dropdownhelper = document.createElement("button"); // the button that makes the dropdown toggable
        dropdownhelper.classList.add("btn", "btn-default", "dropdown-toggle");
        dropdownhelper.setAttribute("data-toggle", "dropdown");
        dropdownhelper.setAttribute("aria-haspopup", "true");
        dropdownhelper.setAttribute("aria-expanded", "false");
        dropdownhelper.innerHTML = "Auto-Turn <span class='caret'></span>";
        autoturnoptions.appendChild(dropdownhelper);
        dropdownlist = document.createElement("ul"); // the actual dropdown itself with all the options
        dropdownlist.id = "autoturn-dropdown-list"; // user123 removed the ids, damn, anyways if some mod wants to add stuff into this dropdown then there you go (although i might as well just add the addoption function into "window" which i have done)
        dropdownlist.classList.add("dropdown-menu");
        dropdownlist.style.position = "absolute"; // the only thing thats affected in dark mode is the position of the dropdown so there's not need to make a detection variable and all of that
        autoturnoptions.appendChild(dropdownlist);
    }
    // end of dropdown prepapers (now for some post-dropdown startup code + post-dropdown theme support)
    if (localStorage.getItem('autoturn-autostart') == "true") { // for autostart options
        window.autoturnenabled = true; // the reason why this uses window variable is because in the first version, you had to start auto-turn in the dev console and the only way to change the variable was to make it globally accessible using window variables. it is still kept today because why not? ;)
        turnbtn.click();
    } else {
        window.autoturnenabled = false; // same comment as the insanely long comment 2 lines above
    }
    if (crab) { // for cvm red and black theme graphical dropdown compatibility
        dropdownlist.style.backgroundColor = "#111";
    }
    // adding and preparing modals (modals are like that change username popup)
    var helpmodalbody =
        `
        <div style="text-align: center;">
            <h2>Options Help</h2>
            <hr>
            <h3>Auto-Turn Options</h3>
            <h4>Enable Auto-Turn</h4>
            <p>Automatically starts taking turns everytime your turn ends.</p>
            <h4>Disable Auto-Turn</h3>
            <p>Stops the function described above.</p>
            <h3>Auto-Start Options</h3>
            <h4>Start on page load</h4>
            <p>Automatically enable Auto-Turn each time you start/restart a new session on CollabVM.</p>
            <h4>Start on user input only</h3>
            <p>Does not automatically enable Auto-Turn on every new CollabVM session.</p>
            <h3>Misc. Options</h3>
            <h4>About Script and FAQ</h4>
            <p>Shows a about page and a FAQ at the bottom of it.</p>
            <h4>Changelog</h4>
            <p>Shows a changelog of all the versions since 0.1.</p>
            <h4>Options Help</h4>
            <p>Shows this help page.</p>
        </div>
        `;
    var aboutscriptbody = // more info here
        `
        <div style="text-align: center;">
            <h2>Auto-Turn v${scriptver} by swordlink1 and User123</h2>
            <hr>
            <h3>Script Info</h3>
            <p>Did you only use Fylrobot for !turnspam, just to see that all of Fylrobot (including !turnspam) doesn't work for some reason now? Do you want a Auto-Turn script that you can actually manage well? Do you want a Auto-Turn script that isn't hard to use? Do you want a Auto-Turn script that has a lot of features?</p>
            <p>Well, you're at the right place then! This Auto-Turn script is actively maintained, guaranteeing new features and bug fixes often, comes with a graphical dropdown without-a-hassle, is very easy to use, and is getting new features almost everyday!</p>
            <p>Are you a experienced JS developer that wants to mod this script? No problem! This code has a lot of comments, making sure you know exactly where each function is! It's also easy to manage the graphical dropdown and modals (modals are like the options help and about script page!).</p>
            <h3>Script Features</h3>
            <p>Here are all the features of the script! :D</p>
            <ul style="text-align: left;">
                <li>Efficently takes turn when your turn has ended, unlike other auto-turn scripts that wait 18 seconds to take a turn again instead, which could be interefered by cooldowns.</li>
                <li>Provides a graphical controls designed to be very easy-to-use and understandable.</li>
                <li>Uses Bootstrap modals (like the page you're seeing right now!) instead of plain JS alert boxes.</li>
                <li>Provides a about page with all the scripts info, plus a help page for understanding each option's function.</li>
                <li>Provides auto-start options so you don't have to enable auto-turn manually each time if you want it on all the time.</li>
                <li>Code is commented so you can understand the code.</li>
                <li>The graphical dropdown supports the CVM Red and Black theme userstyle.</li>
                <li>Supports all metro themes + the Bootstrap 4 theme.</li>
                <li>Comes with a changelog to know the new features and bug fixes of each update.</li>
                <li>Comes with a FAQ to answer all your questions.</li>
                <li>And there's more to come...</li>
            </ul>
            <h3>Use Cases</h3>
            <ol style="text-align: left;">
                <li>Let's say you're alone on a VM. Since you're alone, why keep taking a turn everytime? It's not like people are going to come anytime soon, it looks like. This is one of the situations that this script is useful for./li>
                <li>Let's say that a forkie is well, forking the VM. You can stop him faster, but how? Since this script automatically takes a turn for you.</li>
                <li>Or let's just say you're tired of manually click turn everytime. This script would obviously be the best script for that situation.</li>
                <li>And there's more use cases that will come in the future.</li>
            </ol>
            <h3>F.A.Q</h3>
            <p>Okay, these questions were probably never asked, so this is more of a Q&A. You might have some of these questions though, so if you do, then search in this Q&A.</p>
            <h4><b>Q:</b> Where can I meet you on CollabVM?</h4>
            <p><b>A:</b> I'm guest59511. You'll see me most of the on the Install Any OS VMs, whether it be the new OSes or old OSes one (VM7 and VM8).</p>
            <h4><b>Q:</b> Where can I contact you on the Computernewb Wiki?</h4>
            <p><b>A:</b> I'm Swordlink1. Just make a new topic on my talk page and I'll likely notice it the next day.</p>
            <h4><b>Q:</b> Can I contact you to suggest new features or to send bug reports?</h4>
            <p><b>A:</b> Yes! You indeed can. In fact, please do!</p>
            <h4><b>Q:</b> What if I want this userscript to be compatible with a custom userstyle I made?</h4>
            <p><b>A:</b> Contact me on either platform, give me the userstyle, and I'll make it compatible.</p>
            <h4><b>Q:</b> What will happen when CollabVM 3.0 is released?</h4>
            <p><b>A:</b> If 3.0's website classes stays the same, then there will be no problem. Otherwise depending on the changes, the 3.0 website compatibility could take from just half a hour to days.</p>
            <h4><b>Q:</b> Are you going to make any other CVM userscripts soon?</h4>
            <p><b>A:</b> Yes! I'm planning to make a bot creator script, a mute script, and a script that notifies you when somebody pings/mentions you in the chat!</p>
            <p>Enjoy!</p>
        </div>
        `;
    var changelogbody = // can somebody finish this changelog for me please
    /*
    when doing minor version updates, be like:
    v0.6.0
    * adds something
    * adds something else
    * adds another thing (v0.6.9)
    */
        `
        <div style="text-align: center;">
            <h2>Auto-Turn Versions Changelog</h2>
            <hr>
            <h3>Changelog</h3>
            <p>Here is the changelog for all public release & dev versions.</p>
            <h4>v0.9.0</h4>
            <ul style="text-align: left;">
                <li>Uses alerts instead of modals when in Bootstrap 5. (modals are the thing powering this page rn (also applies to options help and about script)).</li>
                <li>Adds more versions to the changelog all the way down to v0.7.</li>
                <li>Adds a feature to automatically disable Auto-Turn when AFK for 3 minutes.</li>
                <li>Fixes a bug that doesn't enable Auto-Turn until you manually take a turn.</li>
                <li>Adds a settings page.</li>
            </ul>
            <h4>v1.1.0</h4>
            <ul style="text-align: left;">
                <li>Adds Bootstrap 5 theme support.</li>
                <li>Fixes a bug with Bootstrap 4 Theme support.</li>
                <li>Fix a bug with the options help page not showing. (v1.1.1)</li>
                <li>Update the changelog. (v1.1.2)</li>
            </ul>
            <h4>v1.0.0 RTM!</h4>
            <ul style="text-align: left">
                <li>Adds Bootstrap 4 theme support. (and some bootstrap 5 and beta theme variables (that have working detection) for v1.1.0 (BT5) and v1.3.0 (Beta))</li>
                <li>Add back removed theme compatibility. I didn't remove it, User123 did. (v1.0.1)</li>
                <li>Adds a global window variable to detect if Auto-Turn is installed.</li>
                <li>Adds a changelog page.</li>
            </ul>
            <h4>v0.9.0</h4>
            <ul style="text-align: left;">
                <li>Adds about menu.</li>
                <li>Adds CVM Red and Black Theme support.</li>
                <li>Adds support for UserVM.</li>
                <li>Improves the code. (v0.9.1)</li>
                <li>Adds Darkest Metro Theme support. (v0.9.3)</li>
                <li>Adds metro theme support. (v0.9.4)</li>
                <li>Adds a modern method to center the text in modals, and moves list in modals to the left. (v0.9.5)</li>
                <li>Adds mutant observers as a more efficent way to check for turn end. If your browser doesn't support mutant obeservers, it will automatically fall back to the old method. (v0.9.6)</li>
                <li>Adds a global window variable to detect if Auto-Turn is installed.</li>
                <li>Adds a changelog page.</li>
            </ul>
            <small>can somebody finish this for me please? (all the way down to v0.1)</small>
        </div>
        `;
    /*
    speaking of updates, v1.1.0 will introduce a feature that automatically disables auto-turn on afk (although you can enable/disable it) and bootstrap 5 theme supoprt.
    */
    addmodal("About Script (scroll down if you can't fully see the whole page)", aboutscriptbody, "OK", "autoturn-aboutscript");
    addmodal("Options Help (scroll down if you can't fully see the whole page)", helpmodalbody, "Done", "autoturn-optionhelp");
    addmodal("Changelog (scroll down if you can't fully see the whole page)", changelogbody, "Close", "autoturn-changelog");
    // auto-turn options
    addoption("Enable Auto-Turn", function() {window.autoturnenabled = true; turnbtn.click();}); // commented here so it's more visible what the autoturn variable is
    addoption("Disable Auto-Turn", function() {window.autoturnenabled = false});
    addseparator();
    // autostart options
    addoption("Start on page load", enableautostart); // automatically starts auto-turn
    addoption("Start on user input only", disableautostart); // starts only when told to
    addseparator();
    // misc. options for future updates
    if (bt5) { // the reason why modals arent supported in bootstrap 5 is because cvm's bootstrap 5 theme is too broken to display modals (even change username wont work on chrome incognito no extensions!)
        addoption("CVM's Bootstrap 5 Theme");
        addoption("is too broken to display");
        addoption("modals, which these options");
        addoption("rely on. Sorry about that!");
    } else {
        addoption("About Script and FAQ", showaboutscript);
        addoption("Changelog", showchangelog);
        addoption("Options Help", showoptionshelp);
    }
    // defining "window" (global) variables
    window.autoturninstalled = true; // see if auto turn is installed (for other scripts)
    window.autoturnscriptver = scriptver; // so some other script can access it idk
    window.autoturnaddoption = addoption; // see the comment on line 39
    window.autoturnaddseperator = addseparator;
    window.autoturnaddmodal = addmodal;
    // functions (did i write too many comments?)
    function enableautostart() { // enables auto-start (does not toggle it)
        localStorage.setItem('autoturn-autostart', 'true');
    }

    function disableautostart() { // last one, but disables it instead
        localStorage.setItem('autoturn-autostart', 'false');
    }

    function showaboutscript() { // also exactly what it says
        $("#autoturn-aboutscript").modal();
    }

    function showoptionshelp() { // exactly what it says
        $("#autoturn-optionhelp").modal();
        // GM_notification("A new widget is available at the frobber.", "New widget!"); // what it was even for (by user123)
        /* (by swordlink1)
        1. it's "was it", not "it was".
        2. it was just a test ok
        */
    }

    function showchangelog() { // also exactly what it says
        $("#autoturn-changelog").modal();
    }

    function addmodal(title, body, btntext, modalid) { // developer convience, and only has support for one generic close button (if you want extra buttons with extra functionality, then modify this function to your likings)
        var modaltoadd = document.createElement("div");
        modaltoadd.classList.add("modal", "fade");
        modaltoadd.id = "" + modalid;
        modaltoadd.setAttribute("tabindex", "-1");
        modaltoadd.setAttribute("aria-labelledby", modalid + "Label");
        if (bt4) {
            modaltoadd.setAttribute("aria-hidden", "true");
            modaltoadd.setAttribute("role", "dialog");
            modaltoadd.innerHTML =
            `
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="${modalid}Label">${title}</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    </div>
                    <div class="modal-body">
                        ${body}
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">${btntext}</button>
                </div>
            </div>
            `;
        } else if (bt5) {
            modaltoadd.setAttribute("aria-hidden", "true");
            modaltoadd.innerHTML =
            `
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="${modalid}Label">${title}</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                </div>
            </div>
            `;
        } else {
            modaltoadd.setAttribute("role", "dialog");
            modaltoadd.innerHTML =
            `
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                        <h4 class="modal-title" id="${modalid}Label">${title}</h4>
                    </div>
                    <div class="modal-body">
                        ${body}
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">${btntext}</button>
                </div>
            </div>
            `;
        }
        document.body.appendChild(modaltoadd);
    }

    function addoption(optionname, doonclick) { // same comment as above, except that it adds a interactable dropdown option instead
        var optiontoadd = document.createElement("li"), link = document.createElement("a");
        link.href = "javascript:void(0)";
        link.onclick = doonclick;
        link.style.cursor = "pointer";
        link.innerHTML = optionname;
        link.classList.add("dropdown-item");
        if (bt4) {
            dropdownlist.appendChild(link);
        } else {
            optiontoadd.appendChild(link);
            dropdownlist.appendChild(optiontoadd);
        }
    }

    function addseparator() { // same comment as above, except that it adds a separator instead that separates/divides the options
        if (bt4) {
            var separatortoadd = document.createElement("div");
        } else {
            var separatortoadd = document.createElement("li");
        }
        separatortoadd.classList.add("divider", "dropdown-divider");
        separatortoadd.setAttribute("role", "separator");
        if (crab == true) {
            if (bt4) {
                separatortoadd.style.borderTop = "1px solid #222";
            } else {
                separatortoadd.style.backgroundColor = "#222";
            }
        }
        dropdownlist.appendChild(separatortoadd);
    }

	// if browser supports MutationObserver, then use a better way to detect turn end
	if(window.MutationObserver) {
		var observer = new MutationObserver(function(mutations) {
			mutations.forEach(function() {
				if (window.autoturnenabled && turnbtn.style.display != "none") {
					turnbtn.click();
				}
			});
		});
		observer.observe(turnbtn, {attributes: true, attributeFilter: ['style']});
	} else {
    	setInterval(function() {
    		if (window.autoturnenabled && turnbtn.style.display != "none") {
				// checking for autoturnenabled first so it don't check the turnbtn display when unneeded
            	turnbtn.click();
        	}
    	}, 0);
	}
})();