Discord Status Animator (Manual edit/Non-UI)

Automatically changes your Discord status

当前为 2021-06-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Discord Status Animator (Manual edit/Non-UI)
  3. // @namespace https://github.com/Hakorr/discord-status-animator
  4. // @run-at document-start
  5. // @version 1.4
  6. // @description Automatically changes your Discord status
  7. // @author HKR
  8. // @match https://discord.com/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. //Welcome! Don't be scared by the code, I was too lazy to do an UI for this.
  14. //All you have to edit is the statusanimation function's code (Around the line 40)
  15. var name = "Status Animator";
  16. var version = "V1.4";
  17. var run = true;
  18.  
  19. //A Cookie will be made with this name, feel free to edit it
  20. //DO NOT SHARE THIS COOKIE WITH ANYONE AS IT'S YOUR DISCORD TOKEN
  21. var cookie_name = "StatusToken";
  22. var delete_cookie_after_a_week = true;
  23. //Your status will be changed to these after you close the Discord tab
  24. var default_status_text = "";
  25. var default_status_emoji = "";
  26. var default_status_state = "online";
  27. //Animation blocks////////////////
  28. /* Timeouts are in milliseconds!
  29. - await delay(ms);
  30. - await blank();
  31. - await status(emoji,text,state);
  32. -> states = invisible, dnd, idle, online
  33. - await typewriter("text",timeout,reversed);
  34. - await glitch("text",times,timeout);
  35. - await glitchtype("text",timeout,glitch_rate,reversed);
  36. - await sentence("text",timeout);
  37. - await blink("text",timeout,times);
  38. - await count("prefix",count_to,"suffix",timeout,reversed);
  39. */async function statusanimation() {
  40. ////////////////////////////////////
  41. //This is your animation code///////
  42.  
  43. await status("👐","This","online");
  44. await delay(500);
  45.  
  46. await status("👀","Is","dnd");
  47. await delay(500);
  48.  
  49. await status("😶","a test...","idle");
  50. await delay(500);
  51.  
  52. await status("","","online");
  53. await delay(500);
  54.  
  55. await typewriter("It's just a test!",100);
  56. await typewriter("It's just a test!",100,true);
  57. await delay(500);
  58.  
  59. await glitch("I am just testing this!",25,100);
  60.  
  61. await glitchtype("I am just testing this!",50,5);
  62. await glitchtype("I am just testing this!",50,5,true);
  63. await delay(1000);
  64.  
  65. await sentence("This is a test!",500);
  66. await delay(500);
  67.  
  68. await blink("Just testing...",1000,5);
  69. await delay(5000);
  70. await count("I've tested this ",10," times!",500,false);
  71. await count("(",10," Seconds) Until detonation",100,true);
  72. await status("💥","Boom!!!","dnd");
  73. await delay(100);
  74. await status("💥","Boom!!!","idle");
  75. await delay(100);
  76. await status("💥","Boom!!!","dnd");
  77. await delay(100);
  78. await status("💥","Boom!!!","idle");
  79. await delay(100);
  80. await status("💥","Boom!!!","dnd");
  81. await blank();
  82. await delay(5000);
  83. /////////////////////////////
  84. //This loops the animation
  85. if (run) statusanimation(); }
  86. //Do not edit after this line (If you don't know what you're doing)
  87. ///////////////////////////////////////////////////////////////////
  88.  
  89. //Output XX/XX/XX @ XX:XX:XX
  90. function getDateTime() {
  91. var currentdate = new Date();
  92. if(currentdate.getMinutes() > 9) var fixed_minutes = currentdate.getMinutes();
  93. else var fixed_minutes = "0" + currentdate.getMinutes();
  94. if(currentdate.getSeconds() > 9) var fixed_seconds = currentdate.getSeconds();
  95. else var fixed_seconds = "0" + currentdate.getSeconds();
  96.  
  97. var datetime = currentdate.getDate() + "/" + (currentdate.getMonth()+1) + "/" + currentdate.getFullYear() + " @ " + currentdate.getHours() + ":" + fixed_minutes + ":" + fixed_seconds;
  98.  
  99. return datetime;
  100. }
  101. //Output: XX:XX:XX
  102. function getExactTime() {
  103. var currentdate = new Date();
  104. if(currentdate.getMinutes() > 9) var fixed_minutes = currentdate.getMinutes();
  105. else var fixed_minutes = "0" + currentdate.getMinutes();
  106. if(currentdate.getSeconds() > 9) var fixed_seconds = currentdate.getSeconds();
  107. else var fixed_seconds = "0" + currentdate.getSeconds();
  108.  
  109. var datetime = currentdate.getHours() + ":" + fixed_minutes + ":" + fixed_seconds;
  110.  
  111. return datetime;
  112. }
  113. //Output: X:XX
  114. function getTime() {
  115. var currentdate = new Date();
  116. if(currentdate.getMinutes() > 9) var fixed_minutes = currentdate.getMinutes();
  117. else var fixed_minutes = "0" + currentdate.getMinutes();
  118.  
  119. var datetime = currentdate.getHours() + ":" + fixed_minutes;
  120.  
  121. return datetime;
  122. }
  123. //Simple delay function for animation
  124. function delay(t) {
  125. return new Promise(function(resolve) {
  126. setTimeout(resolve, t)
  127. });
  128. }
  129. //Typewriter effect
  130. async function typewriter(text,timeout,reversed) {
  131. //Repeat for each letter
  132. for(var i = 1; i <= text.length; i++) {
  133. //Cut the text
  134. if(!reversed) var substring_text = text.substring(0,i);
  135. else var substring_text = text.substring(0,text.length - i);
  136. //Set the status to the cutted text
  137. await status("",substring_text);
  138. //Wait a selected amount of time until writing the next letter
  139. await delay(timeout);
  140. }
  141. return;
  142. }
  143.  
  144. //Glitch effect
  145. async function glitch(text,times,timeout) {
  146. //Repeat for each letter
  147. for(var i = 1; i < times; i++) {
  148. //Shuffle the text
  149. var glitch_text = shuffle(text)
  150. //Set the status to the cutted text
  151. await status("",glitch_text);
  152. //Wait a selected amount of time until writing the next letter
  153. await delay(timeout);
  154. }
  155. return;
  156. }
  157. //Glitchtype effect
  158. async function glitchtype(text,timeout,glitch_rate,reversed) {
  159. //Repeat for each letter
  160. for(var i = 1; i <= text.length; i++) {
  161. //Cut the text
  162. if(!reversed) var substring_text = text.substring(0,i);
  163. else var substring_text = text.substring(0,text.length - i);
  164. //Glitch rest of the text
  165. if(!reversed) var glitch_text = shuffle(text.substring(i));
  166. else var glitch_text = shuffle(text.substring(text.length - i));
  167. //Set the status to the cutted text + glitched text
  168. await status("",substring_text + glitch_text);
  169. //Wait a selected amount of time until writing the next letter
  170. await delay(timeout);
  171. for(var a = 0; a < glitch_rate; a++) {
  172. //Glitch rest of the text
  173. if(!reversed) var glitch_text = shuffle(text.substring(i));
  174. else var glitch_text = shuffle(text.substring(text.length - i));
  175. //Set the status to the cutted text + glitched text
  176. await status("",substring_text + glitch_text);
  177. //Wait a selected amount of time until writing the next glitched characterset at the end of the string
  178. await delay(timeout/2);
  179. }
  180. }
  181. return;
  182. }
  183. async function sentence(text,timeout) {
  184. //Split sentence into words
  185. var words = text.split(" ");
  186. //Repeat for each word
  187. for(var i = 0; i < words.length; i++) {
  188. //Set status to array's word
  189. await status("",words[i]);
  190. //Wait a selected amount of time until writing the next letter
  191. await delay(timeout);
  192. }
  193. return;
  194. }
  195. async function blink(text,timeout,times) {
  196. for(var i = 0; i < times; i++) {
  197. await status("",text);
  198. await delay(timeout);
  199. await blank();
  200. await delay(timeout);
  201. }
  202. return;
  203. }
  204. async function blank() {
  205. await status("","");
  206. return;
  207. }
  208. async function count(prefix,count_to,suffix,timeout,reversed) {
  209. for(var i = 0; i < count_to; i++) {
  210. if(!reversed) {
  211. var recalculated_count = i + 1;
  212. var final_string = prefix + recalculated_count + suffix;
  213. }
  214. else {
  215. var recalculated_count = count_to - i;
  216. var final_string = prefix + recalculated_count + suffix;
  217. }
  218. await status("",final_string);
  219. await delay(timeout);
  220. }
  221. return;
  222. }
  223. //codespeedy.com/shuffle-characters-of-a-string-in-javascript/
  224. function getRandomInt(n) {
  225. return Math.floor(Math.random() * n);
  226. }
  227. //codespeedy.com/shuffle-characters-of-a-string-in-javascript/
  228. function shuffle(s) {
  229. var arr = s.split(''); // Convert String to array
  230. var n = arr.length; // Length of the array
  231.  
  232. for(var i=0 ; i<n-1 ; ++i) {
  233. var j = getRandomInt(n); // Get random of [0, n-1]
  234.  
  235. var temp = arr[i]; // Swap arr[i] and arr[j]
  236. arr[i] = arr[j];
  237. arr[j] = temp;
  238. }
  239.  
  240. s = arr.join(''); // Convert Array to string
  241. return s; // Return shuffled string
  242. }
  243. //Function to read the saved cookie
  244. window.getCookie = function(name) {
  245. var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
  246. if (match) return match[2];
  247. }
  248. //Set the Discord Token as a Cookie for future use of the script
  249. //If there is no Token cookie
  250. if(document.cookie.indexOf(cookie_name + "=") == -1) {
  251. //Ask user if they want to refresh the page to get the token
  252. if(confirm("\"" + cookie_name + "\" cookie not found. Refreshing Discord to get it.\n\n- " + name + " " + version)) {
  253. //Load the page again and create a new element which will have the token in its localStorage
  254. location.reload();
  255. var i = document.createElement('iframe');
  256. document.body.appendChild(i);
  257. //Get Token from localStorage
  258. var token = i.contentWindow.localStorage.token
  259. token = token.slice(1, -1);
  260. //Delete cookie after a week or not
  261. if(delete_cookie_after_a_week)
  262. document.cookie = cookie_name + "=" + token + "; secure=true; max-age=604800; path=/";
  263. else
  264. document.cookie = cookie_name + "=" + token + "; secure=true; path=/";
  265.  
  266. } else throw new Error("[Not an actually uncaught] User stopped the Status Animator. \n\nNo cookie was found and user decided not to continue.");
  267. }
  268. var status_text = "";
  269. var status_emoji = "";
  270. var status_state = "";
  271. //Function that changes the status variables (Saves up a bit space)
  272. async function status(emoji,text,state) {
  273. if(run) {
  274. status_text = text;
  275. status_emoji = emoji;
  276. status_state = state;
  277. await setstatus();
  278. return;
  279. }
  280. }
  281. //Get Discord Token from saved Cookie
  282. var token = getCookie(cookie_name);
  283.  
  284. //HTTP Request's URL address
  285. var url = "https://discord.com/api/v9/users/@me/settings";
  286. //Function that handles the HTTP request for the status change
  287. async function setstatus() {
  288.  
  289. var request = new XMLHttpRequest();
  290. request.open("PATCH", url);
  291. request.setRequestHeader("Accept", "*/*" );
  292. request.setRequestHeader("Content-Type", "application/json");
  293. request.setRequestHeader("Authorization", token);
  294. request.send(JSON.stringify({"custom_status":{"text":status_text,"emoji_name":status_emoji}}));
  295.  
  296. //If the request failed
  297. request.onreadystatechange = () => {
  298. if (request.status != 200) {
  299. run = false;
  300. throw new Error("[Not an actually uncaught] Failed to update status. \n\nThe HTTP request failed. Most likely because the authorization token is incorrect.");
  301. }
  302. };
  303. if(status_state == "invisible" || status_state == "dnd" || status_state == "idle" || status_state == "online") {
  304. var request2 = new XMLHttpRequest();
  305. request2.open("PATCH", url);
  306. request2.setRequestHeader("Accept", "*/*" );
  307. request2.setRequestHeader("Content-Type", "application/json");
  308. request2.setRequestHeader("Authorization", token);
  309. request2.send(JSON.stringify({"status":status_state}));
  310. //If the request failed
  311. request2.onreadystatechange = () => {
  312. if (request2.status != 200) {
  313. run = false;
  314. throw new Error("[Not an actually uncaught] Failed to update status. \n\nThe HTTP request failed. Most likely because the authorization token is incorrect.");
  315. }
  316. };
  317. }
  318. return;
  319. }
  320. //Start the animation for the first time
  321. if (run) statusanimation();
  322. //Edit (Clear by default) status before exiting
  323. window.onbeforeunload = function () {
  324. run = false;
  325. status_text = default_status_text;
  326. status_emoji = default_status_emoji;
  327. if(status_state == "invisible" || status_state == "dnd" || status_state == "idle" || status_state == "online")
  328. status_state = default_status_state;
  329. setstatus();
  330. return "";
  331. };
  332. })();