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/status-animator
  4. // @run-at document-start
  5. // @version 1.2
  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.2";
  17. var run = true;
  18.  
  19. //A Cookie will be made with this name, feel free to edit it
  20. var cookie_name = "StatusToken";
  21. var delete_cookie_after_a_week = true;
  22. //Your status will be changed to these after you close the Discord tab
  23. var default_status_text = "";
  24. var default_status_emoji = "";
  25. var default_status_state = "online";
  26. //Animation blocks////////////////
  27. /*
  28. - await status(emoji,text,state);
  29. -> states = invisible, dnd, idle, online
  30. - await typewriter("text",timeout);
  31. - await glitch("text",times,timeout);
  32. - await glitchtype("text",timeout,glitch_rate);
  33. - await delay(ms);
  34. */async function statusanimation() {
  35. ////////////////////////////////////
  36. await status("👐","This","online");
  37. await delay(500);
  38. await status("👀","Is","dnd");
  39. await delay(500);
  40. await status("😶","A","idle");
  41. await delay(500);
  42. await status("✨","Test","invisible");
  43. await delay(500);
  44. await status("","","online");
  45. await typewriter("It's just a test!",100);
  46. await delay(500);
  47. await glitch("I am just testing this!",25,100);
  48. await delay(500);
  49.  
  50. await glitchtype("I am just testing this!",100,3);
  51. await delay(2000);
  52. await status("","");
  53. await delay(2000);
  54. /////////////////////////////
  55. //Loop the animation
  56. if (run) statusanimation(); }
  57. //Do not edit after this line (If you don't know what you're doing)
  58. ///////////////////////////////////////////////////////////////////
  59. //Simple delay function for animation
  60. function delay(t) {
  61. return new Promise(function(resolve) {
  62. setTimeout(resolve, t)
  63. });
  64. }
  65. //Typewriter effect
  66. async function typewriter(text,timeout) {
  67. //Repeat for each letter
  68. for(var i = 1; i <= text.length; i++) {
  69.  
  70. //Cut the text
  71. var substring_text = text.substring(0,i);
  72. //Set the status to the cutted text
  73. await status("",substring_text);
  74. //Wait a selected amount of time until writing the next letter
  75. await delay(timeout);
  76. }
  77. return;
  78. }
  79. //Glitch effect
  80. async function glitch(text,times,timeout) {
  81. //Repeat for each letter
  82. for(var i = 1; i < times; i++) {
  83.  
  84. //Shuffle the text
  85. var glitch_text = shuffle(text)
  86. //Set the status to the cutted text
  87. await status("",glitch_text);
  88. //Wait a selected amount of time until writing the next letter
  89. await delay(timeout);
  90. }
  91. return;
  92. }
  93. //Glitchtype effect
  94. async function glitchtype(text,timeout, glitch_rate) {
  95. //Repeat for each letter
  96. for(var i = 1; i <= text.length; i++) {
  97. //Cut the text
  98. var substring_text = text.substring(0,i);
  99. //Glitch rest of the text
  100. var glitch_text = shuffle(text.substring(i));
  101. //Set the status to the cutted text + glitched text
  102. await status("",substring_text + glitch_text);
  103. //Wait a selected amount of time until writing the next letter
  104. await delay(timeout);
  105. for(var a = 0; a < glitch_rate; a++) {
  106. //Glitch rest of the text
  107. glitch_text = shuffle(text.substring(i));
  108. //Set the status to the cutted text + glitched text
  109. await status("",substring_text + glitch_text);
  110. //Wait a selected amount of time until writing the next glitched characterset at the end of the string
  111. await delay(100);
  112. }
  113. }
  114. return;
  115. }
  116. //codespeedy.com/shuffle-characters-of-a-string-in-javascript/
  117. function getRandomInt(n) {
  118. return Math.floor(Math.random() * n);
  119. }
  120. //codespeedy.com/shuffle-characters-of-a-string-in-javascript/
  121. function shuffle(s) {
  122. var arr = s.split(''); // Convert String to array
  123. var n = arr.length; // Length of the array
  124.  
  125. for(var i=0 ; i<n-1 ; ++i) {
  126. var j = getRandomInt(n); // Get random of [0, n-1]
  127.  
  128. var temp = arr[i]; // Swap arr[i] and arr[j]
  129. arr[i] = arr[j];
  130. arr[j] = temp;
  131. }
  132.  
  133. s = arr.join(''); // Convert Array to string
  134. return s; // Return shuffled string
  135. }
  136. //Function to read the saved cookie
  137. window.getCookie = function(name) {
  138. var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
  139. if (match) return match[2];
  140. }
  141. //Set the Discord Token as a Cookie for future use of the script
  142. //If there is no Token cookie
  143. if(document.cookie.indexOf(cookie_name + "=") == -1) {
  144. //Ask user if they want to refresh the page to get the token
  145. if(confirm("\"" + cookie_name + "\" cookie not found. Refreshing Discord to get it.\n\n- " + name + " " + version)) {
  146. //Load the page again and create a new element which will have the token in its localStorage
  147. location.reload();
  148. var i = document.createElement('iframe');
  149. document.body.appendChild(i);
  150. //Get Token from localStorage
  151. var token = i.contentWindow.localStorage.token
  152. token = token.slice(1, -1);
  153. //Delete cookie after a week or not
  154. if(delete_cookie_after_a_week)
  155. document.cookie = cookie_name + "=" + token + "; secure=true; max-age=604800; path=/";
  156. else
  157. document.cookie = cookie_name + "=" + token + "; secure=true; path=/";
  158.  
  159. } else throw new Error("[Not an actually uncaught] User stopped the Status Animator. \n\nNo cookie was found and user decided not to continue.");
  160. }
  161. var status_text = "";
  162. var status_emoji = "";
  163. var status_state = "";
  164. //Function that changes the status variables (Saves up a bit space)
  165. async function status(emoji,text,state) {
  166. if(run) {
  167. status_text = text;
  168. status_emoji = emoji;
  169. status_state = state;
  170. await setstatus();
  171. return;
  172. }
  173. }
  174. //Get Discord Token from saved Cookie
  175. var token = getCookie(cookie_name);
  176.  
  177. //HTTP Request's URL address
  178. var url = "https://discord.com/api/v9/users/@me/settings";
  179. //Function that handles the HTTP request for the status change
  180. async function setstatus() {
  181.  
  182. var request = new XMLHttpRequest();
  183. request.open("PATCH", url);
  184. request.setRequestHeader("Accept", "*/*" );
  185. request.setRequestHeader("Content-Type", "application/json");
  186. request.setRequestHeader("Authorization", token);
  187. request.send(JSON.stringify({"custom_status":{"text":status_text,"emoji_name":status_emoji}}));
  188.  
  189. //If the request failed
  190. request.onreadystatechange = () => {
  191. if (request.status != 200) {
  192. run = false;
  193. throw new Error("[Not an actually uncaught] Failed to update status. \n\nThe HTTP request failed. Most likely because the authorization token is incorrect.");
  194. }
  195. };
  196. if(status_state == "invisible" || status_state == "dnd" || status_state == "idle" || status_state == "online") {
  197. var request2 = new XMLHttpRequest();
  198. request2.open("PATCH", url);
  199. request2.setRequestHeader("Accept", "*/*" );
  200. request2.setRequestHeader("Content-Type", "application/json");
  201. request2.setRequestHeader("Authorization", token);
  202. request2.send(JSON.stringify({"status":status_state}));
  203. //If the request failed
  204. request2.onreadystatechange = () => {
  205. if (request2.status != 200) {
  206. run = false;
  207. throw new Error("[Not an actually uncaught] Failed to update status. \n\nThe HTTP request failed. Most likely because the authorization token is incorrect.");
  208. }
  209. };
  210. }
  211. return;
  212. }
  213. //Start the animation for the first time
  214. if (run) statusanimation();
  215. //Edit (Clear by default) status before exiting
  216. window.onbeforeunload = function () {
  217. run = false;
  218. status_text = default_status_text;
  219. status_emoji = default_status_emoji;
  220. if(status_state == "invisible" || status_state == "dnd" || status_state == "idle" || status_state == "online")
  221. status_state = default_status_state;
  222. setstatus();
  223. return "";
  224. };
  225. })();