Greasy Fork

Toradorable Skin Changer

A Toradorable skin changer supporting multiple animations and variable image display times, Minimizes chat lag by using a custom skin updating function, and Adds in auto/instant-respawn. To use, press "C" in game to cycle between different animations.

目前为 2016-11-15 提交的版本。查看 最新版本

// ==UserScript==
// @name         Toradorable Skin Changer
// @version      1.2.11
// @description A Toradorable skin changer supporting multiple animations and variable image display times, Minimizes chat lag by using a custom skin updating function, and Adds in auto/instant-respawn. To use, press "C" in game to cycle between different animations.

// @author       Toradorable
// @match        http://alis.io/*
// @require https://greasyfork.org/scripts/24844-toradorable-animation-for-toradorable-skin-changer/code/Toradorable%20Animation%20for%20Toradorable%20Skin%20Changer.js
// @require      https://greasyfork.org/scripts/24858-dancing-cat-animation-for-toradorable-skin-changer/code/Dancing%20Cat%20Animation%20for%20Toradorable%20Skin%20Changer.js
// @grant        none
// @namespace http://tampermonkey.net/
// ==/UserScript==

// To use, press "C" in game to cycle between different animations. Animation being used is displayed on the right sidebar.

// 1st press turns animation on, 2nd press turns it off and selects the next animation,
// 3rd press turns the animation on and so on.

// NOTE: Anything after two slashes ("//") or inbetween a "/*" and a "*/" are comments, they do nothing and can be safely removed

// This is my Toradorable skinchanger script with most hackery removed.
// If my full script were posted, Taiga would get ticked off from all the trolling and within 2-3 minutes I would be beaten to a pulp.

/* NOTE: To Add more animations, appended to the list below. 
 * The first element in the skin array is the display time in milliseconds. 1000 milliseconds = 1 second,
 * Second element is the url to display.
 * Format:
{   name: "Replace With Name Of Your Animation", // This will be displayed in the sidebar to the right of the screen
    skin: [
        HowLongToShowFirstImageInMilliseconds, "replace/with/url/for/1st.img",
        HowLongToShowSeccondImageInMilliseconds, "url/for/2nd.img",
        etcetera, "etcetera",
]}
 * Look in the skinList for examples.
 */

/*
 *  Skin Variables
 */

// Skin Lists
var defaultspeed=100;
var skinList = (typeof skinList === 'object') ? skinList : [];

/* Add Animation Example
skinList.push({name:"Toradorable",
	skin: [
// Display time
// in
// Milliseconds, "Url"
            500, "https://s22.postimg.org/jha3867up/image.png",
            500, "https://s22.postimg.org/jrhlrimgx/image.png",
            500, "https://s22.postimg.org/6xjjy691d/image.png",
            500, "https://s22.postimg.org/idpyw7n7l/Ra2.png",
            500, "https://s22.postimg.org/inxhfk1tt/exclam.png",
           2000, "https://s18.postimg.org/tl8xraeux/Taiga_square.png"
     ]}
);
*/
// indexes
var skinidx=0;
var currentskinidx=0;
var lagout_i=0;
// Activation Status
var skinChangerWanted = false;
var skinChanger = false;

var FakeSkinWanted=false;
var DoStealSkin=false;
var DoShareSkin=false;
// Auto Join Games when Dead
//var autoJoinGame = true;
window.autoJoinGame=true;
var refreshSkinTimeout;
var defaultspeed=100;
var lagout_speed=30;
var FakeSkinPredictable = false;

var LastXY=[0,0];
var testHasRestarted=0;
var FailCount=0;

var TargetsLastSkin;
var CurrentSkin;
var SharedSkin;

var EVERYONE={};

/*
 * Setup Custome Web Elements
 */

var overlays2=document.getElementById("overlays2");
var mipmapNode = document.getElementById("mipmapNode");
var chatboxInput=document.getElementById("input_box2");


var SkinTargetType = chatboxInput.cloneNode(true);
SkinTargetType.name="Skin Target Type:";
SkinTargetType.id="SkinTargetType";
SkinTargetType.value="Standby"; // Theft, Swap, Push
SkinTargetType.placeholder="Skin Target Type:";
SkinTargetType.style.cssText = document.defaultView.getComputedStyle(chatboxInput, "").cssText;
SkinTargetType.style.width="200px";
SkinTargetType.style.right="9px";
SkinTargetType.style.bottom="250px";
SkinTargetType.style.position="absolute";
overlays2.insertBefore(SkinTargetType, overlays2.lastChild);
//overlays2.insertBefore(StealSkinBox, overlays2.lastChild);

var SkinListBox = document.createElement("select"); //StealSkinBox.cloneNode(true);
SkinListBox.name="Selected Skin:";
SkinListBox.id="SelectedSkinElm";
SkinListBox.value=""; // Theft, Swap, Push
SkinListBox.placeholder="No Animation Selected";
SkinListBox.style.cssText = document.defaultView.getComputedStyle(chatboxInput, "").cssText;
SkinListBox.style.width="200px";
SkinListBox.style.right="9px";
SkinListBox.style.bottom="210px";
SkinListBox.style.position="absolute";

overlays2.insertBefore(SkinListBox, overlays2.lastChild);

for (var i = 0; i < skinList.length; i++) {
    var option = document.createElement("option");
    //option.style.cssText = document.defaultView.getComputedStyle(chatboxInput, "").cssText;
    option.value = i;
    option.text = skinList[i].name;
    SkinListBox.appendChild(option);
}
SkinListBox.onchange=function(event){ skinidx=event.target.value ; haveUsedSkin=false; };



/*
 * Setup Hotkeys
 * FIXME: hot key saving realy does not work... It seems like it works on one part, but new values do not discard old values, causeing conflicts.
 */
var hotKeyTable = document.getElementById("hotkey_table");
var hotkeyMappingREV={};
var tmphotkeyMapping=JSON.parse(getLocalStorage("hotkeyMapping"));
for (var prop in tmphotkeyMapping) {
	hotkeyMappingREV[tmphotkeyMapping[prop]]=prop;
}

function AddHotKey(hk) {
	var hkdefault = {
	    id: "hk_change_my_hotkey_id",
	    defaultHotkey: "",
	    key: null,
	    description: "Change My Description",
	    keyDown: null,
	    keyUp: null,
	    type: "NORMAL"
	};
	hk = Object.assign(hkdefault,hk);
	if (! hk.key || hk.key === null) hk.key = hotkeyMappingREV[hk.id];
	if (! hk.key || hk.key === null) hk.key = hk.defaultHotkey;
	var hk_element = hotKeyTable.lastChild.cloneNode(true);
	hk_element.children[0].dataset.hotkeyid = hk.id;
	hk_element.children[0].innerHTML=hk.key;
	hk_element.children[1].innerHTML=hk.description;
	hk_element.children[2].innerHTML="/";
	console.log("Adding Hotkey: " + hk);
	hotKeyTable.appendChild(hk_element);
	
	hotkeyConfig[hk.id]= {
	    defaultHotkey: hk.defaultHotkey,
	    name: hk.description,
	    keyDown: hk.keyDown,
	    type: hk.type
	};
	hotkeyMapping[hk.key] = hk.id;
	return hk_element;
}



function UpdateTargetBox() {
    
    if (skinChanger && DoShareSkin && DoStealSkin) {
        SkinTargetType.value="SwappingSkins";
    }
    else if (DoShareSkin && DoStealSkin) {
        SkinTargetType.value="SwappingSkins(NoAnimate)";
    }
    else if (skinChanger && DoShareSkin) {
        SkinTargetType.value="SharingSkin";
    }
    else if (DoShareSkin) {
        SkinTargetType.value="SharingSkin(NoAnimate)";
    }
    else if (DoStealSkin) {
        SkinTargetType.value="StealingSkin";
    }
    else if (skinChanger) {
        SkinTargetType.value="AnimatedSkin";
    }
    else {
        SkinTargetType.value="Standby";
    }
}

/*
var hk_AutoStealNearbySkin = AddHotKey({
id: "hk_AutoStealNearbySkin",
defaultHotkey: "M",
description: "Start/Stop Auto-Stealing Nearby Skin",
keyDown: function() {    }
});
*/
var hk_ReconnectToServer = AddHotKey({
id: "hk_ReconnectToServer",
defaultHotkey: "L",
description: "Reconnect to Server",
keyDown: function() {
    connect(myApp.getCurrentPartyCode());
    RefreshSkinIn(1200);
}
});
function NextSkin() {
    skinidx++;
    if(skinidx >= skinList.length) {skinidx = 0;}
    SkinListBox.selectedIndex =skinidx;
}
function PrevSkin() {
    skinidx--;
    if(skinidx < 0) {skinidx = skinList.length - 1;}
    SkinListBox.selectedIndex =skinidx;
}
var haveUsedSkin=false;
var hk_CycleSkinRotator = AddHotKey({
id: "hk_CycleSkinRotator",
defaultHotkey: "C",
description: "Cycle Skin Rotator",
keyDown: function() { 
    if (skinChangerWanted && !skinChanger) {
        RefreshSkin(0,true);
        //LagOnce();
    } else if(skinChangerWanted) {
        skinChangerWanted=false;
        skinChanger=false;
        if (haveUsedSkin) NextSkin();
    } else {
        skinChangerWanted=true;
        skinChanger=true;
        //if (haveUsedSkin) NextSkin();
        AutoChangeSkin();
    }
    UpdateTargetBox();
}
});
//myApp.refreshHotkeySettingPage();

//myApp.restoreSetting();

myApp.setUpHotKeyConfigPage();

/*********************
 * Generic Functions *
 *********************/


function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

function Print(msg) {
	console.log(msg);
}


/******************
 * Global Overrides
 ******************/
//Function override. Allow sending messages when dead
myApp["onDead"] = function() {
    isJoinedGame = false;
    $(".btn-spectate")["prop"]("disabled", false);
    $("#nick")["prop"]("disabled", false);
    $(".nav")["show"]();
    // Auto Respawn
    if (window.autoJoinGame) setNick(document.getElementById('nick').value);
    //conn["leaveRoom"](myApp["getRoom"]())
}


/*****************
** Custom Hot Keys
******************/

const keycodes={
    backspace:8,    tab:9,         enter:13,
    shift:16,       ctrl:17,       alt:18,
    pause_break:19, capslock:20,   escape:27,
    space:32,       pageup:33,     pagedown:34,
    end:35,         home:36,       leftarrow:37,
    uparrow:38,     rightarrow:39, downarrow:40,
    insert:45,      delete:46,
    0:48,   1:49,   2:50,   3:51,
    4:52,   5:53,   6:54,   7:55,
    8:56,   9:57,   a:65,   b:66,
    c:67,   d:68,   e:69,   f:70,
    g:71,   h:72,   i:73,   j:74,
    k:75,   l:76,   m:77,   n:78,
    o:79,   p:80,   q:81,   r:82,
    s:83,   t:84,   u:85,   v:86,
    w:87,   x:88,   y:89,   z:90
};

window.addEventListener('keydown', keydown);
function keydown(e) {
    var chatArea=$("#chatboxArea2");
    var chatIsFocused=$("#input_box2").is(':focus') || $("#LieAsElm").is(':focus') || $("#StealSkinElm").is(':focus');
   /*if(e.keyCode === keycodes.c && !(chatIsFocused)) {
        if (skinChangerWanted && !skinChanger) {
            RefreshSkin(0,true);
            //LagOnce();
        } else if(skinChangerWanted) {
            skinChangerWanted=false;
            skinChanger=false;
        } else {
            skinChangerWanted=true;
            skinChanger=true;
            skinidx++;
            if(skinidx >= skinList.length) {skinidx = 0;}
            AutoChangeSkin();
        }
    }
    else */ if(e.keyCode === 27) {
        skinChanger = false;
        DoStealSkin=false;
        amfakedead=false;
        DoShareSkin=false;
        //temporary workaround to StealSkin/FakeSkin/ HotKey "M" Problem 
        $("#overlays")["show"]();
    }
    /*else if(e.keyCode === keycodes.l && !(chatIsFocused)) {
        //naservers();
        connect(myApp.getCurrentPartyCode());
    }*/
    else if(e.keyCode === keycodes.q && !(chatIsFocused)) {
        Lagloop(50);
    }
    /*else if(e.keyCode === keycodes.m && !(chatIsFocused)) {
        skinChanger=false;
        if (FakeSkinWanted && !DoStealSkin) {
            RefreshSkin(0,true);
            //LagOnce();
        } else if(FakeSkinWanted) {
            FakeSkinWanted=false;
            DoStealSkin=false;
        } else {
            FakeSkinWanted=true;
            DoStealSkin=true;
            FakeSkin();
        }
    }*/
    /*else if (e.keyCode === keycodes.n && !chatIsFocused) {
        LieAs.value=GetNearestCell()[1];
        StealSkinBox.value=GetNearestSkinnedCell()[1];
    }*/
    /*else if((e.keyCode === keycodes.space || e.keyCode === keycodes.t) && !IsDoingFireork && !($("#chatboxArea2").is(":focus"))) {
        fireworkidx=0;
        Firework();
    }*/
}

// FIXME Im not sure what I was doing here
function HasRestarted() {
    if (testHasRestarted >=5) {
        testHasRestarted=0;
    } else {
        testHasRestarted++;
        return false;
    }
    var myCell;
    try {
        if(typeof getCell != 'function') throw "GetCell is NotAFunc";
        myCell=getCell();
        if(myCell === undefined) throw "GetCell Returned null";
        if(myCell[0] === undefined) throw "CellDataEmpty";
        if(myCell[0].x === undefined) throw "Cell has no X";
        FailCount=0;
    }
    catch(err) {
        console.log(err," ",FailCount);
        myCell=null;
        FailCount++;
    }
    finally {
        if (FailCount >= 5) return true;
        else if (FailCount !== 0) return false;
        myCell=myCell[0];
    }
    if (LastXY[0] != myCell.x || LastXY[1] != myCell.y) {
        LastXY=[myCell.x,myCell.y];
        return false;
    }
    var LB = getLB();
    if (LB.length != 9) return false;
    for (var i=0; i < 8; i++) { // Leaderboard 1-8 should be named RESTART
        if (LB[i].name != "RESTART") return false;
    }
    // Leaderboard 9 should be named ALIS.IO
    if (LB[8].name != "ALIS.IO") return false;
    return true;
}


/*************************
 * Skin Changing Functions
 *************************/

/*
 * Change Your Skin
 */
function ChangeSkinTo(skin=CurrentSkin,displaylocal=true) {
    document.getElementById('skinurl').value = skin;
    //setNick(document.getElementById('nick').value);
    socket.emit("playerUpdated", {
        "action": "update",
        "displayName": playerDetailsByIdentifier[nodeList[0][1] + nodeList[0][6]].displayName,
        "socketRoom": playerDetailsByIdentifier[nodeList[0][1] + nodeList[0][6]].socketRoom,
        "identifier": playerDetailsByIdentifier[nodeList[0][1] + nodeList[0][6]].identifier,
        "url": skin,
        "nick": playerDetailsByIdentifier[nodeList[0][1] + nodeList[0][6]].nick,
        "team": playerDetailsByIdentifier[nodeList[0][1] + nodeList[0][6]].team,
        "token": playerDetailsByIdentifier[nodeList[0][1] + nodeList[0][6]].token
    });
    nodeList[0][5]=skin;
    if (displaylocal) {
        playerDetailsByIdentifier[nodeList[0][1] + nodeList[0][6]].url=skin;
    }
    CurrentSkin=skin;
}


// Refresh Skin unctions

function RefreshSkinCancel() {
    if (refreshSkinTimeout) {
        clearTimeout(refreshSkinTimeout);
    }
}
function RefreshSkinIn(timeout,FailCount,StartStopped) {
   // RefreshSkinCancel();
    if (FailCount) {
        refreshSkinTimeout = setTimeout( function(){ RefreshSkin(FailCount,StartStopped); }, timeout );
    }
    else {
        refreshSkinTimeout = setTimeout( RefreshSkin, timeout );
    }
}


function RefreshSkin(FailCount=0,StartStopped=false) {
	Print("Refreshing Skin");
    var hasRestarted=HasRestarted();
    if((!isJoinedGame) || hasRestarted ) {
        //skinChanger=false;
        if (hasRestarted) {
            //naservers();
            console.log("Leaderboard indicates a restart occured. Reconnecting to server.");
            connect(myApp.getCurrentPartyCode());
            // If the above stops working, try respawn();
            //respawn();
        }
        console.log("We are dead. Our final score was",getHighestScore()/100,". Respawning.");
        RefreshSkinCancel();
        refreshSkinTimeout=setTimeout(function(){setNick(document.getElementById('nick').value); RefreshSkin(FailCount+1);}, 1200*(FailCount+1) );
        return;
    }
    /*if(FakeSkinWanted) {
     //   skinChanger=false;
        if(StartStopped) { 
        	DoStealSkin=true;
        	FakeSkin();
        }
     //   FakeSkin();
    }*/
    if(skinChangerWanted) {
        //DoStealSkin=false;
        if(StartStopped && !FakeSkinWanted) {
            skinChanger=true;
            ChangeSkinTo();
        }
        AutoChangeSkin(FailCount);
    } 
    else if (StartStopped) {
        var curskin=skinList[skinidx].skin;
        if(currentskinidx >= curskin.length) {currentskinidx = 0;}
        var skinSpeed=curskin[currentskinidx];
        ChangeSkinTo(curskin[currentskinidx+1]);
    }
    UpdateTargetBox();
}

function AutoChangeSkin(FailCount=0){
    if(skinChanger) {
        if(skinidx >= skinList.length) {skinidx = 0;}
        haveUsedSkin=true;
        var curskin=skinList[skinidx].skin;
        if(currentskinidx >= curskin.length) {currentskinidx = 0;}
        var skinSpeed=curskin[currentskinidx];
        //if(!FakeSkinWanted) {
        	ChangeSkinTo(curskin[currentskinidx+1]);
        //}
        /*if (DoShareSkin) {
        	ShareSkin(curskin[currentskinidx+1]);
        }*/
        currentskinidx+=2;
        if(currentskinidx >= curskin.length) {currentskinidx = 0;}
        RefreshSkinIn(skinSpeed);
    }
}


// Skin updates are sent whenever...
// action: "join", The Player pushes play
// action: "join", setNick is called
// action: "update", A different player joins the game (to let them download the skin)
addJS_Node(isNumeric);



// Method for overloading global functions directly (functions in objects dont need this)
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';
    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}