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