// ==UserScript==
// @name Discord Status Animator (Manual edit/Non-UI)
// @namespace https://github.com/Hakorr/status-animator
// @run-at document-start
// @version 1.4
// @description Automatically changes your Discord status
// @author HKR
// @match https://discord.com/*
// @grant none
// ==/UserScript==
(function() {
//Welcome! Don't be scared by the code, I was too lazy to do an UI for this.
//All you have to edit is the statusanimation function's code (Around the line 40)
var name = "Status Animator";
var version = "V1.4";
var run = true;
//A Cookie will be made with this name, feel free to edit it
//DO NOT SHARE THIS COOKIE WITH ANYONE AS IT'S YOUR DISCORD TOKEN
var cookie_name = "StatusToken";
var delete_cookie_after_a_week = true;
//Your status will be changed to these after you close the Discord tab
var default_status_text = "";
var default_status_emoji = "";
var default_status_state = "online";
//Animation blocks////////////////
/* Timeouts are in milliseconds!
- await delay(ms);
- await blank();
- await status(emoji,text,state);
-> states = invisible, dnd, idle, online
- await typewriter("text",timeout,reversed);
- await glitch("text",times,timeout);
- await glitchtype("text",timeout,glitch_rate,reversed);
- await sentence("text",timeout);
- await blink("text",timeout,times);
- await count("prefix",count_to,"suffix",timeout,reversed);
*/async function statusanimation() {
////////////////////////////////////
//This is your animation code///////
await status("👐","This","online");
await delay(500);
await status("👀","Is","dnd");
await delay(500);
await status("😶","a test...","idle");
await delay(500);
await status("","","online");
await delay(500);
await typewriter("It's just a test!",100);
await typewriter("It's just a test!",100,true);
await delay(500);
await glitch("I am just testing this!",25,100);
await glitchtype("I am just testing this!",50,5);
await glitchtype("I am just testing this!",50,5,true);
await delay(1000);
await sentence("This is a test!",500);
await delay(500);
await blink("Just testing...",1000,5);
await delay(5000);
await count("I've tested this ",10," times!",500,false);
await count("(",10," Seconds) Until detonation",100,true);
await status("💥","Boom!!!","dnd");
await delay(100);
await status("💥","Boom!!!","idle");
await delay(100);
await status("💥","Boom!!!","dnd");
await delay(100);
await status("💥","Boom!!!","idle");
await delay(100);
await status("💥","Boom!!!","dnd");
await blank();
await delay(5000);
/////////////////////////////
//This loops the animation
if (run) statusanimation(); }
//Do not edit after this line (If you don't know what you're doing)
///////////////////////////////////////////////////////////////////
//Output XX/XX/XX @ XX:XX:XX
function getDateTime() {
var currentdate = new Date();
if(currentdate.getMinutes() > 9) var fixed_minutes = currentdate.getMinutes();
else var fixed_minutes = "0" + currentdate.getMinutes();
if(currentdate.getSeconds() > 9) var fixed_seconds = currentdate.getSeconds();
else var fixed_seconds = "0" + currentdate.getSeconds();
var datetime = currentdate.getDate() + "/" + (currentdate.getMonth()+1) + "/" + currentdate.getFullYear() + " @ " + currentdate.getHours() + ":" + fixed_minutes + ":" + fixed_seconds;
return datetime;
}
//Output: XX:XX:XX
function getExactTime() {
var currentdate = new Date();
if(currentdate.getMinutes() > 9) var fixed_minutes = currentdate.getMinutes();
else var fixed_minutes = "0" + currentdate.getMinutes();
if(currentdate.getSeconds() > 9) var fixed_seconds = currentdate.getSeconds();
else var fixed_seconds = "0" + currentdate.getSeconds();
var datetime = currentdate.getHours() + ":" + fixed_minutes + ":" + fixed_seconds;
return datetime;
}
//Output: X:XX
function getTime() {
var currentdate = new Date();
if(currentdate.getMinutes() > 9) var fixed_minutes = currentdate.getMinutes();
else var fixed_minutes = "0" + currentdate.getMinutes();
var datetime = currentdate.getHours() + ":" + fixed_minutes;
return datetime;
}
//Simple delay function for animation
function delay(t) {
return new Promise(function(resolve) {
setTimeout(resolve, t)
});
}
//Typewriter effect
async function typewriter(text,timeout,reversed) {
//Repeat for each letter
for(var i = 1; i <= text.length; i++) {
//Cut the text
if(!reversed) var substring_text = text.substring(0,i);
else var substring_text = text.substring(0,text.length - i);
//Set the status to the cutted text
await status("",substring_text);
//Wait a selected amount of time until writing the next letter
await delay(timeout);
}
return;
}
//Glitch effect
async function glitch(text,times,timeout) {
//Repeat for each letter
for(var i = 1; i < times; i++) {
//Shuffle the text
var glitch_text = shuffle(text)
//Set the status to the cutted text
await status("",glitch_text);
//Wait a selected amount of time until writing the next letter
await delay(timeout);
}
return;
}
//Glitchtype effect
async function glitchtype(text,timeout,glitch_rate,reversed) {
//Repeat for each letter
for(var i = 1; i <= text.length; i++) {
//Cut the text
if(!reversed) var substring_text = text.substring(0,i);
else var substring_text = text.substring(0,text.length - i);
//Glitch rest of the text
if(!reversed) var glitch_text = shuffle(text.substring(i));
else var glitch_text = shuffle(text.substring(text.length - i));
//Set the status to the cutted text + glitched text
await status("",substring_text + glitch_text);
//Wait a selected amount of time until writing the next letter
await delay(timeout);
for(var a = 0; a < glitch_rate; a++) {
//Glitch rest of the text
if(!reversed) var glitch_text = shuffle(text.substring(i));
else var glitch_text = shuffle(text.substring(text.length - i));
//Set the status to the cutted text + glitched text
await status("",substring_text + glitch_text);
//Wait a selected amount of time until writing the next glitched characterset at the end of the string
await delay(timeout/2);
}
}
return;
}
async function sentence(text,timeout) {
//Split sentence into words
var words = text.split(" ");
//Repeat for each word
for(var i = 0; i < words.length; i++) {
//Set status to array's word
await status("",words[i]);
//Wait a selected amount of time until writing the next letter
await delay(timeout);
}
return;
}
async function blink(text,timeout,times) {
for(var i = 0; i < times; i++) {
await status("",text);
await delay(timeout);
await blank();
await delay(timeout);
}
return;
}
async function blank() {
await status("","");
return;
}
async function count(prefix,count_to,suffix,timeout,reversed) {
for(var i = 0; i < count_to; i++) {
if(!reversed) {
var recalculated_count = i + 1;
var final_string = prefix + recalculated_count + suffix;
}
else {
var recalculated_count = count_to - i;
var final_string = prefix + recalculated_count + suffix;
}
await status("",final_string);
await delay(timeout);
}
return;
}
//codespeedy.com/shuffle-characters-of-a-string-in-javascript/
function getRandomInt(n) {
return Math.floor(Math.random() * n);
}
//codespeedy.com/shuffle-characters-of-a-string-in-javascript/
function shuffle(s) {
var arr = s.split(''); // Convert String to array
var n = arr.length; // Length of the array
for(var i=0 ; i<n-1 ; ++i) {
var j = getRandomInt(n); // Get random of [0, n-1]
var temp = arr[i]; // Swap arr[i] and arr[j]
arr[i] = arr[j];
arr[j] = temp;
}
s = arr.join(''); // Convert Array to string
return s; // Return shuffled string
}
//Function to read the saved cookie
window.getCookie = function(name) {
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) return match[2];
}
//Set the Discord Token as a Cookie for future use of the script
//If there is no Token cookie
if(document.cookie.indexOf(cookie_name + "=") == -1) {
//Ask user if they want to refresh the page to get the token
if(confirm("\"" + cookie_name + "\" cookie not found. Refreshing Discord to get it.\n\n- " + name + " " + version)) {
//Load the page again and create a new element which will have the token in its localStorage
location.reload();
var i = document.createElement('iframe');
document.body.appendChild(i);
//Get Token from localStorage
var token = i.contentWindow.localStorage.token
token = token.slice(1, -1);
//Delete cookie after a week or not
if(delete_cookie_after_a_week)
document.cookie = cookie_name + "=" + token + "; secure=true; max-age=604800; path=/";
else
document.cookie = cookie_name + "=" + token + "; secure=true; path=/";
} else throw new Error("[Not an actually uncaught] User stopped the Status Animator. \n\nNo cookie was found and user decided not to continue.");
}
var status_text = "";
var status_emoji = "";
var status_state = "";
//Function that changes the status variables (Saves up a bit space)
async function status(emoji,text,state) {
if(run) {
status_text = text;
status_emoji = emoji;
status_state = state;
await setstatus();
return;
}
}
//Get Discord Token from saved Cookie
var token = getCookie(cookie_name);
//HTTP Request's URL address
var url = "https://discord.com/api/v9/users/@me/settings";
//Function that handles the HTTP request for the status change
async function setstatus() {
var request = new XMLHttpRequest();
request.open("PATCH", url);
request.setRequestHeader("Accept", "*/*" );
request.setRequestHeader("Content-Type", "application/json");
request.setRequestHeader("Authorization", token);
request.send(JSON.stringify({"custom_status":{"text":status_text,"emoji_name":status_emoji}}));
//If the request failed
request.onreadystatechange = () => {
if (request.status != 200) {
run = false;
throw new Error("[Not an actually uncaught] Failed to update status. \n\nThe HTTP request failed. Most likely because the authorization token is incorrect.");
}
};
if(status_state == "invisible" || status_state == "dnd" || status_state == "idle" || status_state == "online") {
var request2 = new XMLHttpRequest();
request2.open("PATCH", url);
request2.setRequestHeader("Accept", "*/*" );
request2.setRequestHeader("Content-Type", "application/json");
request2.setRequestHeader("Authorization", token);
request2.send(JSON.stringify({"status":status_state}));
//If the request failed
request2.onreadystatechange = () => {
if (request2.status != 200) {
run = false;
throw new Error("[Not an actually uncaught] Failed to update status. \n\nThe HTTP request failed. Most likely because the authorization token is incorrect.");
}
};
}
return;
}
//Start the animation for the first time
if (run) statusanimation();
//Edit (Clear by default) status before exiting
window.onbeforeunload = function () {
run = false;
status_text = default_status_text;
status_emoji = default_status_emoji;
if(status_state == "invisible" || status_state == "dnd" || status_state == "idle" || status_state == "online")
status_state = default_status_state;
setstatus();
return "";
};
})();