Twitch Plays Pokemon - Command Filtering & Spamming Tool

Adds tools to your chatbox for spamming chat and filtering out commands from chat.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        Twitch Plays Pokemon - Command Filtering & Spamming Tool
// @namespace   butt
// @description Adds tools to your chatbox for spamming chat and filtering out commands from chat.
// @include     http://www.twitch.tv/twitchplayspokemon
// @include     http://beta.twitch.tv/twitchplayspokemon
// @include     http://www.twitch.tv/twitchplayspokemon/chat?popout=&secret=safe
// @include     http://beta.twitch.tv/twitchplayspokemon/chat?popout=&secret=safe
// @version     1.12
// @grant       none
// ==/UserScript==

function tppmain() {
var $ = window.$;

function setUpTheShit(){
    var spamhandle;
    var counterHandle;
    
    var autoSpam = true;
    var slowMode = true;
    var autoInterval = 30; //starting interval between spams
    var fastInterval = 6; //Guess at minimum interval that won't get you b&
    //var randomInterval = 30; //a random value up to this will be added to each timer
    var lastSpamTime = 0;
    var lastLastSpamTime = 0;
    var timeConfirmedSlow = timeSecs();
    var tryTime = 100; //seconds to wait before testing whether the room's slow again
    var timeBuffer = 2; //seconds to add to intervals, to avoid sending too fast

    var stretchLetters = "aeioufjlmnrswy"; //Letters that can be randomly stretched
    var maxStretch = 12; //maximum extra letters to add
    
    var tooFastRegex = /This room is in slow mode and you are sending messages too quickly\. You will be able to talk again in (\d+) seconds\./;
    var genericTooFastRegex = /Your message was not sent because you are sending messages too quickly\./;
    var identicalRegex = /Your message was not sent because it is identical to the previous one you sent, less than (\d+) seconds ago\./;
    var slowModeRegex = /This room is now in slow mode\. You may send messages every (\d+) seconds/;
    var r9kRegex = /This room is in r9k mode and the message you attempted to send is not unique\.\sSee http:\/\/bit\.ly\/bGtBDf for more details\./;
    var bannedRegex = /You are banned from talking in twitchplayspokemon for (\d+) more seconds./;
    var inputRegex = /^((up|down|left|right|a|b|start|select|anarchy|democracy|wait|l|r|(\d+,\d+)|(!bet.+)?)(\+)?)+$/i;
    
    // Add buttons and shit
    $(".chat-interface").append('<div id="muh-controls" style="position:absolute;top:115px;padding:5px;"><label style="display:inline" for="dubs">Filter Inputs </label><input type="checkbox" id="dubs" checked><label style="display:inline" for="randomize"> Randomize Spam </label><input type="checkbox" id="randomize" checked><div><label for="spam-radio" style="display:inline">Spam: </label> <input type="radio" id="spam-radio" name="spam-radio" value="manual" title="Set spam intervals manually.">Manual  <input type="radio" name="spam-radio" value="auto" title="Auto mode parses the chat to determine optimal intervals automatically.">Auto  <input type="radio" name="spam-radio" value="none" checked title="Disable spamming.">  None </div><div><label for="spam-text" style="display:inline">Text </label><input type="text" id="spam-text" value="guys we need to beat misty"></div><div><label for="spam-interval" style="display:inline">Interval(secs) </label><input type="text" id="spam-interval" value="32" style="width:50px"><span id="spam-counter"></span><span id="spam-notice" style="color:green"> You spammed!</span></div></div>');
    $(".chat-interface").css("bottom", "80px");

    // FILTERING
    var showAll = false;
    $("#dubs").click( function() {
        showAll = !showAll;
    } );

    function randomChecked() {
        return ( $("#randomize:checked").size() > 0 ); 
    }
    
    amShit = function (str) {
        return str.match(inputRegex);
    };
    var addMessage = App.Room.prototype.addMessage;
    
    window.adminMsgs = new Array();
    App.Room.prototype.addMessage = function (anus) {
        if (showAll || !amShit($.trim(anus.message.toLowerCase()))) {
            addMessage.call(this, anus);
        } 
        if(anus.style === "admin") {
            window.adminMsgs.push(anus);
            //console.log(anus.message);
            handleAdminMsg(anus);
        }
    };
    
    handleAdminMsg = function(msg) {
        var tooFastBy, slowModeTime, identicalTime;

        //Only read admin messages in auto-spam mode
        if(!autoSpam) return;

        //Catch if we posted too fast
        if( (tooFastBy = tooFastRegex.exec(msg.message)) !== null ) {
            tooFastBy = parseInt(tooFastBy[1]);
            //Post again after time
            spamIn(tooFastBy);
            tooFastTime = lastSpamTime - lastLastSpamTime;
            enterSlowMode(tooFastTime + tooFastBy);
            console.log("Too fast by " + tooFastBy);
        }
        else if(msg.message.match(genericTooFastRegex)) {
            setAutoInterval(autoInterval * 2);
            console.log("Generically too fast!");
        }
        else if(msg.message.match(r9kRegex)) {
            if( randomChecked() ) {
                spamIn(1);
            }
            console.log("r9k-blocked");
        }
        else if( (identicalTime = identicalRegex.exec(msg.message)) !== null) {
            //Does this mean we're in slow mode? Let's assume yes.
            identicalTime = parseInt(identicalTime[1]);
            tooFastTime = lastSpamTime - lastLastSpamTime;
            canSpamIn = identicalTime - tooFastTime;
            spamIn(canSpamIn);
            if( !randomChecked() ) {
                enterSlowMode(identicalTime); //If input not randomized, gotta slow down
            }
            console.log("Identical message! Time:"+identicalTime+". Only waited: "+tooFastTime+". Resend in " + canSpamIn); //30-0-30??
        }
        else if( (slowModeTime = slowModeRegex.exec(msg.message)) !== null) {
            slowModeTime = parseInt(slowModeTime[1]);
            //Update auto-timer
            enterSlowMode(slowModeTime);
            console.log("Entered slow mode!");
        }
        else if( (bannedTime = bannedRegex.exec(msg.message)) !== null) {
            bannedTime = parseInt(bannedTime[1]);
            //Try not spamming so fast
            if(autoInterval == fastInterval) {
                fastInterval += 3;
                console.log("Increasing fast interval to "+fastInterval);
            }
            spamIn(bannedTime);
            enterSlowMode(30);
            console.log("b& for " + bannedTime);
        }
        else {
            console.log(msg.message);
        }
    }
    
    enterSlowMode = function(time) {
        if(time > fastInterval){
            slowMode = true;
            setAutoInterval(time);
        }
        else {
            setAutoInterval(fastInterval);
        }
        timeConfirmedSlow = timeSecs();
    }

    function setAutoInterval(time) {
        time = Math.floor(time);
        autoInterval = time;
        if(autoSpam){
            $("input#spam-interval").val(time + timeBuffer);
        }
    }

    //Returns new spam interval in seconds
    decideInterval = function() {
        var timeSinceConfirmedSlow = (timeSecs() - timeConfirmedSlow);
        if(slowMode && timeSinceConfirmedSlow > tryTime) {
            console.log("Checking if still slow...");
            slowMode = false;
            setAutoInterval(fastInterval);
        }

        //Randomize interval
        //if(autoInterval == fastInterval) {
            //addToInterval = Math.floor( Math.random() * randomInterval );
            //return autoInterval + addToInterval;
        //}
        return autoInterval;
    }
        
    
    // SPAMMING
    $("#spam-notice").hide();
    
    function spam(){
        var textbox = $(".chat-interface .textarea-contain textarea");
        var old_shit = textbox.val();
        var text = $("#spam-text").val().toString(); 
        if( !amShit(text) && $("#randomize:checked").size() > 0) {
            text = randomize(text);
        }
        textbox.val(text); 
        
        textbox.focus().blur();
        $(".send-chat-button button")[0].click();
        lastLastSpamTime = lastSpamTime;
        lastSpamTime = timeSecs();
        
        $("#spam-notice").show();
        $("#spam-notice").fadeOut(3000);
        textbox.val(old_shit);
        
        var interval =  autoSpam ? decideInterval() : parseInt($("#spam-interval").val());
        spamIn(interval);
    }

    //randomly elongates vowels in string
    function randomize(str) {
        var indices = new Array();
        for(i=0; i < str.length; i++) {
            ch = str[i].toLowerCase();
            if (stretchLetters.indexOf(ch) != -1) {
                indices.push(i);
            }
        }
        if(indices.length == 0) return str;
        
        var indA = indices[Math.floor( Math.random() * indices.length )];
        var indB = indices[Math.floor( Math.random() * indices.length )];
        if(indB < indA) {temp = indA; indA = indB; indB = temp;} //B is the higher index
        var duplicateABy = Math.floor( Math.random() * (maxStretch) + 1);
        var extraStringA = str[indA].repeat(duplicateABy);
        var duplicateBBy = Math.floor( Math.random() * (maxStretch) + 1);
        var extraStringB = str[indB].repeat(duplicateBBy);
        if(indB == indA) extraStringB = "";
        return str.slice(0,indA) + extraStringA + str.slice(indA, indB) + extraStringB + str.slice(indB);
    }

    
    //sets timer to spam, in seconds
    function spamIn(interval) {
        if(autoSpam) interval += timeBuffer;
        interval = Math.floor(interval);
        clearTimeout(spamhandle);
        spamhandle = setTimeout(spam, interval * 1000);
        counter($("#spam-counter"), interval);
    }
    
    //Returns "manual", "auto", or "none" based on radio buttons
    function getSpamMode() {
        return $("input:radio[name=spam-radio]:checked").val();
    }
    
    $("input:radio[name=spam-radio]").change(function(){
        var timeSince = timeSecs() - lastSpamTime;

        if(getSpamMode() === "manual") {
            autoSpam = false;
            $("input#spam-interval").removeAttr("disabled");
            clearTimeout(spamhandle);
            var interval = parseInt($("#spam-interval").val());
            if(timeSince < interval) {
                spamIn(interval - timeSince);
            }
            else spam();
        }
        else if(getSpamMode() === "auto") {
            autoSpam = true;
            $("input#spam-interval").attr("disabled", "true");
            clearTimeout(spamhandle);
            setAutoInterval(autoInterval);
            if(timeSince < autoInterval) {
                spamIn(autoInterval - timeSince);
            }
            else spam();
        }
        else if(getSpamMode() === "none") {
            autoSpam = false;
            $("input#spam-interval").removeAttr("disabled");
            clearTimeout(spamhandle);
            clearTimeout(counterHandle);
            $("#spam-counter").hide();
        }
    });
    
    //sets counter, in seconds
    function counter($el, n) {
        $("#spam-counter").show();
        clearTimeout(counterHandle);
        (function loop() {
            $el.html(n);
            if (n--) {
                counterHandle = setTimeout(loop, 1000);
            }
        })();
    }

    function timeSecs() {
        var deito = new Date();
        return deito.getTime() / 1000;
    }
    
    //Need this for chrome
    String.prototype.repeat = function( num ) {
    	return new Array( num + 1 ).join( this );
	}
    
    $(window).resize();
}

function loopydoo (){
    if ( typeof($) == "function" && document.readyState == 'complete' && $("div.chat-interface").size() > 0 ) {
        setUpTheShit();
    }
    else {
        setTimeout(loopydoo, 500);
    }
}

loopydoo();

}

//Inject dat shit nigga aaawwww yiss
var script = document.createElement('script');
script.textContent = '(' + tppmain.toString() + ')();';
document.body.appendChild(script);