Discord Status Animator (Manual edit/Non-UI)

Automatically changes your Discord status

目前为 2021-06-15 提交的版本。查看 最新版本

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

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址