[Discord] Status Animator (Manual edit/Non-UI)

Automatically changes your Discord status

  1. // ==UserScript==
  2. // @name [Discord] Status Animator (Manual edit/Non-UI)
  3. // @namespace HKR
  4. // @version 2.0
  5. // @description Automatically changes your Discord status
  6. // @author HKR
  7. // @match https://discord.com/discovery
  8. // @match https://discord.com/discovery/*
  9. // @match https://discord.com/store
  10. // @match https://discord.com/store/*
  11. // @match https://discord.com/channels
  12. // @match https://discord.com/channels/*
  13. // @match https://discord.com/app
  14. // @supportURL https://github.com/Hakorr/Userscripts/issues
  15. // @run-at document-start
  16. // ==/UserScript==
  17.  
  18. (() => {
  19. /////////////////////////////////////
  20. /* Animation blocks /////////////////
  21. (Timeouts are in milliseconds)
  22. (You can type "random" on the emoji slot to randomize it)
  23.  
  24. - await wait(ms);
  25. - await blank();
  26. - await state("state");
  27. -> states = invisible, dnd, idle, online
  28. - await emoji("emoji");
  29. - await text("text");
  30. - await status(emoji,text,state);
  31. -> states = invisible, dnd, idle, online
  32. - await typewriter("emoji","text",timeout,reversed);
  33. - await glitch("emoji","text",times,timeout);
  34. - await glitchtype("emoji","text",timeout,glitch_rate,reversed);
  35. - await sentence("emoji","text",timeout);
  36. - await blink("emoji","text",timeout,times);
  37. - await count("emoji","prefix",count_to,"suffix",timeout,reversed);
  38. - if(await skip(1,"unique")) return;
  39. -> The unique string can be anything. If you use two skips, remember to make each one different.
  40. - await activity("positive_emoji","positive_text","positive_state","negative_emoji","negative_text","negative_state");
  41. - await scroll("emoji","text",timeout,center_amount,reversed);
  42. -> Center amount means how many times it will move the full text sideways*/
  43.  
  44. ////////////////////////////////////
  45. //Animation loop////////////////////
  46.  
  47. // Do not leave the function empty, you'll freeze your page!
  48. // Remember to add delays, otherwise your page will freeze!
  49.  
  50. async function loop() {
  51. ////////////////////////////////////
  52. ////////////////////////////////////
  53. //Your animation code starts here///
  54. await blink("🥳","I'm using Discord Status Animator!", 3000, 1);
  55. if(await skip(10, "u")) return;
  56. await text("Get it here! Github.com/Hakorr");
  57. await wait(5000);
  58.  
  59. //Your animation code ends here/////
  60. ////////////////////////////////////
  61. ////////////////////////////////////
  62. }
  63.  
  64. ////////////////////////////////////
  65. //Settings//////////////////////////
  66.  
  67. // Create no variable, apply the token manually
  68. const MANUAL_DISCORD_TOKEN = "";
  69. // Your status will be changed to these after you exit Discord
  70. const DEFAULT_STATUS_TEXT = "";
  71. const DEFAULT_STATUS_EMOJI = "";
  72. const DEFAULT_STATUS_STATE = "online";
  73.  
  74. // DO NOT ENTER ZONE - DO NOT PROCEED IF YOU DON'T KNOW WHAT TO DO //
  75. /*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
  76. /////////////////////////////////////////////////////////////////////
  77. // DO NOT ENTER ZONE - DO NOT PROCEED IF YOU DON'T KNOW WHAT TO DO //
  78.  
  79. ///////////////////////////////////////////////////
  80. //Effect variables/////////////////////////////////
  81.  
  82. function randomEmoji() {
  83. const emojis = [
  84. '😄','😃','😀','😊','😉','😍','😘','😚','😗','😙','😜','😝','😛','😳','😁','😔','😌','😒','😞','😣','😢','😂','😭','😪','😥','😰','😅','😓','😩','😫','😨','😱','😠','😡','😤','😖','😆','😋','😷','😎','😴','😵','😲','😟','😦','😧','😈','👿','😮','😬','😐','😕','😯','😶','😇','😏','😑','👲','👳','👮','👷','💂','👶','👦','👧','👨','👩','👴','👵','👱','👼','👸','😺','😸','😻','😽','😼','🙀','😿','😹','😾','👹','👺','🙈','🙉','🙊','💀','👽','💩','🔥','✨','🌟','💫','💥','💢','💦','💧','💤','💨','👂','👀','👃','👅','👄','👍','👎','👌','👊','✊','✌','👋','✋','👐','👆','👇','👉','👈','🙌','🙏','☝','👏','💪','🚶','🏃','💃','👫','👪','👬','👭','💏','💑','👯','🙆','🙅','💁','🙋','💆','💇','💅','👰','🙎','🙍','🙇','🎩','👑','👒','👟','👞','👡','👠','👢','👕','👔','👚','👗','🎽','👖','👘','👙','💼','👜','👝','👛','👓','🎀','🌂','💄','💛','💙','💜','💚','❤','💔','💗','💓','💕','💖','💞','💘','💌','💋','💍','💎','👤','👥','💬','👣','💭','🐶','🐺','🐱','🐭','🐹','🐰','🐸','🐯','🐨','🐻','🐷','🐽','🐮','🐗','🐵','🐒','🐴','🐑','🐘','🐼','🐧','🐦','🐤','🐥','🐣','🐔','🐍','🐢','🐛','🐝','🐜','🐞','🐌','🐙','🐚','🐠','🐟','🐬','🐳','🐋','🐄','🐏','🐀','🐃','🐅','🐇','🐉','🐎','🐐','🐓','🐕','🐖','🐁','🐂','🐲','🐡','🐊','🐫','🐪','🐆','🐈','🐩','🐾','💐','🌸','🌷','🍀','🌹','🌻','🌺','🍁','🍃','🍂','🌿','🌾','🍄','🌵','🌴','🌲','🌳','🌰','🌱','🌼','🌐','🌞','🌝','🌚','🌑','🌒','🌓','🌔','🌕','🌖','🌗','🌘','🌜','🌛','🌙','🌍','🌎','🌏','🌋','🌌','🌠','⭐','☀','⛅','☁','⚡','☔','❄','⛄','🌀','🌁','🌈','🌊','🎍','💝','🎎','🎒','🎓','🎏','🎆','🎇','🎐','🎑','🎃','👻','🎅','🎄','🎁','🎋','🎉','🎊','🎈','🎌','🔮','🎥','📷','📹','📼','💿','📀','💽','💾','💻','📱','☎','📞','📟','📠','📡','📺','📻','🔊','🔉','🔈','🔇','🔔','🔕','📢','📣','⏳','⌛','⏰','⌚','🔓','🔒','🔏','🔐','🔑','🔎','💡','🔦','🔆','🔅','🔌','🔋','🔍','🛁','🛀','🚿','🚽','🔧','🔩','🔨','🚪','🚬','💣','🔫','🔪','💊','💉','💰','💴','💵','💷','💶','💳','💸','📲','📧','📥','📤','✉','📩','📨','📯','📫','📪','📬','📭','📮','📦','📝','📄','📃','📑','📊','📈','📉','📜','📋','📅','📆','📇','📁','📂','✂','📌','📎','✒','✏','📏','📐','📕','📗','📘','📙','📓','📔','📒','📚','📖','🔖','📛','🔬','🔭','📰','🎨','🎬','🎤','🎧','🎼','🎵','🎶','🎹','🎻','🎺','🎷','🎸','👾','🎮','🃏','🎴','🀄','🎲','🎯','🏈','🏀','⚽','⚾','🎾','🎱','🏉','🎳','⛳','🚵','🚴','🏁','🏇','🏆','🎿','🏂','🏊','🏄','🎣','☕','🍵','🍶','🍼','🍺','🍻','🍸','🍹','🍷','🍴','🍕','🍔','🍟','🍗','🍖','🍝','🍛','🍤','🍱','🍣','🍥','🍙','🍘','🍚','🍜','🍲','🍢','🍡','🍳','🍞','🍩','🍮','🍦','🍨','🍧','🎂','🍰','🍪','🍫','🍬','🍭','🍯','🍎','🍏','🍊','🍋','🍒','🍇','🍉','🍓','🍑','🍈','🍌','🍐','🍍','🍠','🍆','🍅','🌽','🏠','🏡','🏫','🏢','🏣','🏥','🏦','🏪','🏩','🏨','💒','⛪','🏬','🏤','🌇','🌆','🏯','🏰','⛺','🏭','🗼','🗾','🗻','🌄','🌅','🌃','🗽','🌉','🎠','🎡','⛲','🎢','🚢','⛵','🚤','🚣','⚓','🚀','✈','💺','🚁','🚂','🚊','🚉','🚞','🚆','🚄','🚅','🚈','🚇','🚝','🚋','🚃','🚎','🚌','🚍','🚙','🚘','🚗','🚕','🚖','🚛','🚚','🚨','🚓','🚔','🚒','🚑','🚐','🚲','🚡','🚟','🚠','🚜','💈','🚏','🎫','🚦','🚥','⚠','🚧','🔰','⛽','🏮','🎰','♨','🗿','🎪','🎭','📍','🚩','⬆','⬇','⬅','➡','🔠','🔡','🔤','↗','↖','↘','↙','↔','↕','🔄','◀','▶','🔼','🔽','↩','↪','ℹ','⏪','⏩','⏫','⏬','⤵','⤴','🆗','🔀','🔁','🔂','🆕','🆙','🆒','🆓','🆖','📶','🎦','🈁','🈯','🈳','🈵','🈴','🈲','🉐','🈹','🈺','🈶','🈚','🚻','🚹','🚺','🚼','🚾','🚰','🚮','🅿','♿','🚭','🈷','🈸','🈂','Ⓜ','🛂','🛄','🛅','🛃','🉑','㊙','㊗','🆑','🆘','🆔','🚫','🔞','📵','🚯','🚱','🚳','🚷','🚸','⛔','✳','❇','❎','✅','✴','💟','🆚','📳','📴','🅰','🅱','🆎','🅾','💠','➿','♻','♈','♉','♊','♋','♌','♍','♎','♏','♐','♑','♒','♓','⛎','🔯','🏧','💹','💲','💱','©','®','™','〽','〰','🔝','🔚','🔙','🔛','🔜','❌','⭕','❗','❓','❕','❔','🔃','🕛','🕧','🕐','🕜','🕑','🕝','🕒','🕞','🕓','🕟','🕔','🕠','🕕','🕖','🕗','🕘','🕙','🕚','🕡','🕢','🕣','🕤','🕥','🕦','✖','➕','➖','➗','♠','♥','♣','♦','💮','💯','✔','☑','🔘','🔗','➰','🔱','🔲','🔳','◼','◻','◾','◽','▪','▫','🔺','⬜','⬛','⚫','⚪','🔴','🔵','🔻','🔶','🔷','🔸','🔹'
  85. ];
  86. return emojis[Math.floor(Math.random() * emojis.length)];
  87. }
  88.  
  89. const getTime = mode => {
  90. const currentdate = new Date();
  91. let fixedMinutes = "";
  92. let fixedSeconds = "";
  93.  
  94. if(currentdate.getMinutes() > 9)
  95. fixedMinutes = currentdate.getMinutes();
  96. else
  97. fixedMinutes = "0" + currentdate.getMinutes();
  98.  
  99. if(currentdate.getSeconds() > 9)
  100. fixedSeconds = currentdate.getSeconds();
  101. else
  102. fixedSeconds = "0" + currentdate.getSeconds();
  103.  
  104. switch(mode) {
  105. case "full": // XX/XX/XX @ XX:XX:XX
  106. return `${currentdate.getDate()}/${currentdate.getMonth() + 1}/${currentdate.getFullYear()} @ ${currentdate.getHours()}:${fixedMinutes}:${fixedSeconds}`;
  107. case "exact": // XX:XX:XX
  108. return currentdate.getHours() + ":" + fixedMinutes + ":" + fixedSeconds;
  109. default: // XX:XX
  110. return currentdate.getHours() + ":" + fixedMinutes;
  111. }
  112. };
  113. const randomNumber = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
  114. ///////////////////////////////////////////////////
  115. //Effects//////////////////////////////////////////
  116.  
  117. const wait = t => new Promise(resolve => setTimeout(resolve, t)); // simple delay function for the animation
  118.  
  119. let USER_ON_PAGE = true;
  120. window.onfocus = () => USER_ON_PAGE = true;
  121. window.onblur = () => USER_ON_PAGE = false;
  122.  
  123. // Activity effect
  124. async function activity(positive_emoji, positive_text, positive_state, negative_emoji, negative_text, negative_state) {
  125. await status(
  126. (
  127. positive_emoji == "random"
  128. ? randomEmoji()
  129. : USER_ON_PAGE
  130. ? positive_emoji
  131. : negative_emoji
  132. ),
  133. USER_ON_PAGE ? positive_text : negative_text,
  134. USER_ON_PAGE ? positive_state : negative_state
  135. );
  136.  
  137. return;
  138. }
  139. // Scroll effect
  140. async function scroll(emoji, text, timeout, center_amount, reversed) {
  141. let space = " 󠀡"; // contains a space flag and a hidden special character at the end (may appear funky on some devices)
  142. // Scroll in
  143. for(let i = 1; i <= text.length; i++) {
  144. let cutted_text = reversed
  145. ? space.repeat(text.length - i + center_amount) + text.substring(i, 0)
  146. : text.substring(text.length - i);
  147. if(emoji != "random")
  148. await status(emoji, cutted_text);
  149. else
  150. await status(randomEmoji(), cutted_text);
  151. if(i != text.length)
  152. await wait(timeout);
  153. }
  154. // Scroll full text sideways for a bit
  155. for(let i = 1; i <= center_amount; i++) {
  156. let move_text = reversed
  157. ? space.repeat(center_amount - i) + text
  158. : space.repeat(i) + text;
  159. if(emoji != "random")
  160. await status(emoji, move_text);
  161. else
  162. await status(randomEmoji(), move_text);
  163. await wait(timeout);
  164. }
  165. // Scroll out
  166. for(let i = 1; i <= text.length; i++) {
  167. let cutted_text = reversed
  168. ? text.substring(i)
  169. : space.repeat(i + center_amount) + text.substring(text.length - i, 0);
  170. if(emoji != "random")
  171. await status(emoji, cutted_text);
  172. else
  173. await status(randomEmoji(), cutted_text);
  174. await wait(timeout);
  175. }
  176. return;
  177. }
  178. // Typewriter effect
  179. async function typewriter(emoji, text, timeout, reversed) {
  180. // Repeat for each letter
  181. for(let i = 1; i <= text.length; i++) {
  182. // Cut the text
  183. let substring_text = reversed
  184. ? text.substring(0, text.length - i)
  185. : text.substring(0, i);
  186. // Set the status to the cutted text
  187. if(emoji != "random")
  188. await status(emoji, substring_text);
  189. else
  190. await status(randomEmoji(), substring_text);
  191. // Wait a selected amount of time until writing the next letter
  192. await wait(timeout);
  193. }
  194. return;
  195. }
  196. // Glitch effect
  197. async function glitch(emoji, text, times, timeout) {
  198. // Repeat for each letter
  199. for(let i = 1; i < times; i++) {
  200. // Shuffle the text
  201. let glitch_text = shuffle(text);
  202. // Set the status to the cutted text
  203. if(emoji != "random")
  204. await status(emoji, glitch_text);
  205. else
  206. await status(randomEmoji(), glitch_text);
  207. // Wait a selected amount of time until writing the next letter
  208. await wait(timeout);
  209. }
  210. return;
  211. }
  212. // Glitchtype effect
  213. async function glitchtype(emoji, text, timeout, glitch_rate, reversed) {
  214. // Repeat for each letter
  215. for(let i = 1; i <= text.length; i++) {
  216. // Cut the text
  217. let substring_text = reversed
  218. ? text.substring(0, text.length - i)
  219. : text.substring(0, i);
  220.  
  221. // Glitch rest of the text
  222. let glitch_text = reversed
  223. ? shuffle(text.substring(text.length - i))
  224. : shuffle(text.substring(i));
  225. //S et the status to the cutted text + glitched text
  226. if(emoji != "random")
  227. await status(emoji, substring_text + glitch_text);
  228. else
  229. await status(randomEmoji(), substring_text + glitch_text);
  230. // Wait a selected amount of time until writing the next letter
  231. await wait(timeout);
  232. for(let a = 0; a < glitch_rate; a++) {
  233. // Glitch rest of the text
  234. let glitch_text = reversed
  235. ? shuffle(text.substring(text.length - i))
  236. : shuffle(text.substring(i));
  237.  
  238. // Set the status to the cutted text + glitched text
  239. await status(emoji, substring_text + glitch_text);
  240. // Wait a selected amount of time until writing the next glitched characterset at the end of the string
  241. await wait(timeout / 2);
  242. }
  243. }
  244. return;
  245. }
  246. // Sentence effect
  247. async function sentence(emoji, text, timeout) {
  248. // Split sentence into words
  249. const words = text.split(" ");
  250. // Repeat for each word
  251. for(let i = 0; i < words.length; i++) {
  252. // Set status to array's word
  253. if(emoji != "random")
  254. await status(emoji, words[i]);
  255. else
  256. await status(randomEmoji(), words[i]);
  257. // Wait a selected amount of time until writing the next letter
  258. await wait(timeout);
  259. }
  260. return;
  261. }
  262. // Blink effect
  263. async function blink(emoji, text, timeout, times) {
  264. for(let i = 0; i < times; i++) {
  265. if(emoji != "random")
  266. await status(emoji, text);
  267. else
  268. await status(randomEmoji(), text);
  269.  
  270. await wait(timeout);
  271.  
  272. await blank();
  273.  
  274. await wait(timeout);
  275. }
  276. return;
  277. }
  278. // Clear status effect
  279. async function blank() {
  280. await status("",""); // could just send blank status as {"custom_status":null}, but that behaves weirdly
  281. return;
  282. }
  283. const store = (function() {
  284. const map = {};
  285. return {
  286. set: function ( name, value ) {
  287. map[ name ] = value;
  288. },
  289. get: function ( name ) {
  290. return map[ name ];
  291. }
  292. };
  293. })();
  294. // Skip the end of the animation effect
  295. async function skip(amount, uniquetext) {
  296. const uniqueID = amount + "_" + uniquetext;
  297. const set = store.set;
  298. const get = store.get;
  299.  
  300. let currentamount = get(uniqueID);
  301. // Variable exists already
  302. if(currentamount >= 0) {
  303. // If to continue
  304. if(currentamount == amount) {
  305. // Reset the variable
  306. set(uniqueID,0);
  307. // Update the currentamount variable
  308. currentamount = get(uniqueID);
  309.  
  310. return false;
  311. }
  312. // Skip
  313. else {
  314. // Add one to the variable
  315. set(uniqueID,get(uniqueID) + 1);
  316. // Update the currentamount variable
  317. currentamount = get(uniqueID);
  318.  
  319. return true;
  320. }
  321. // No variable made already
  322. } else {
  323. // Make the variable
  324. set(uniqueID, 0);
  325. // Add one to it
  326. set(uniqueID, get(uniqueID) + 1);
  327. // Update the currentamount variable
  328. currentamount = get(uniqueID);
  329. return true;
  330. }
  331. }
  332. // Count effect
  333. async function count(emoji, prefix, count_to, suffix, timeout, reversed) {
  334. for(let i = 0; i < count_to; i++) {
  335. let recalculated_count = reversed
  336. ? count_to - i
  337. : i + 1;
  338.  
  339. let final_string = prefix + recalculated_count + suffix;
  340.  
  341. if(emoji != "random")
  342. await status(emoji, final_string);
  343. else
  344. await status(randomEmoji(), final_string);
  345. await wait(timeout);
  346. }
  347.  
  348. return;
  349. }
  350. ///////////////////////////////////////////////////
  351. //Main functions///////////////////////////////////
  352.  
  353. const DISCORD_TOKEN = MANUAL_DISCORD_TOKEN.length > 0
  354. ? MANUAL_DISCORD_TOKEN
  355. : localStorage.token.slice(1, -1);
  356.  
  357. const DISCORD_ENDPOINT = "https://discord.com/api/v9/users/@me/settings"; // Discord API user settings URL
  358. let ANIMATION_RUN = true;
  359.  
  360. let status_text = "";
  361. let status_emoji = "";
  362. let status_state = "";
  363.  
  364. // Source -> codespeedy.com/shuffle-characters-of-a-string-in-javascript/
  365. function shuffle(s) {
  366. const getRandomInt = n => Math.floor(Math.random() * n);
  367. var arr = s.split(''); // Convert String to array
  368. var n = arr.length; // Length of the array
  369. for(var i = 0; i < n-1; ++i) {
  370. var j = getRandomInt(n); // Get random of [0, n-1]
  371. var temp = arr[i]; // Swap arr[i] and arr[j]
  372. arr[i] = arr[j];
  373. arr[j] = temp;
  374. }
  375. s = arr.join(''); // Convert Array to string
  376. return s; // Return shuffled string
  377. }
  378.  
  379. //Function that changes the status variables (Saves up a bit space)
  380. async function status(emoji, text, state) {
  381. if(ANIMATION_RUN) {
  382. status_text = text;
  383. status_emoji = emoji;
  384. status_state = state;
  385. await setStatus();
  386. return;
  387. }
  388. }
  389.  
  390. async function sendStatusRequest(bodyJSON) {
  391. const stringifiedBody = JSON.stringify(bodyJSON);
  392.  
  393. if(typeof DISCORD_TOKEN != "string") {
  394. console.log("Invalid Discord token... Aborting!");
  395. ANIMATION_RUN = false;
  396. return false;
  397. }
  398.  
  399. await fetch(DISCORD_ENDPOINT, {
  400. method: 'PATCH',
  401. headers: {
  402. 'Content-Type': 'application/json',
  403. 'Authorization': DISCORD_TOKEN
  404. },
  405. body: stringifiedBody
  406. })
  407. .catch(() => {
  408. console.log("Failed to update status! Maybe your token is incorrect?");
  409. });
  410. return true;
  411. }
  412.  
  413. // Function that handles the HTTP request for the status change
  414. async function setStatus() {
  415. await sendStatusRequest({
  416. "custom_status" : {
  417. "text" : status_text,
  418. "emoji_name" : status_emoji
  419. }
  420. });
  421.  
  422. if(["invisible", "dnd", "idle", "online"].includes(status_state)) {
  423. await sendStatusRequest({
  424. "status" : status_state
  425. });
  426. }
  427.  
  428. return true;
  429. }
  430. async function state(text) {
  431. if(ANIMATION_RUN) {
  432. if(["invisible", "dnd", "idle", "online"].includes(status_state)) {
  433. status_state = text;
  434. await sendStatusRequest({
  435. "status" : status_state
  436. });
  437. }
  438.  
  439. return true;
  440. }
  441. }
  442. async function emoji(emoji) {
  443. if(ANIMATION_RUN) {
  444. status_emoji = emoji;
  445. await sendStatusRequest({
  446. "custom_status" : {
  447. "emoji_name" : status_emoji
  448. }
  449. });
  450. return true;
  451. }
  452. }
  453. async function text(text) {
  454. if(ANIMATION_RUN) {
  455. status_text = text;
  456.  
  457. await sendStatusRequest({
  458. "custom_status" : {
  459. "text" : status_text
  460. }
  461. });
  462.  
  463. return true;
  464. }
  465. }
  466.  
  467. (async () => {
  468. while(ANIMATION_RUN) {
  469. await loop();
  470. }
  471. })();
  472.  
  473. // set default status before exiting
  474. window.onbeforeunload = function () {
  475. ANIMATION_RUN = false;
  476. status_text = DEFAULT_STATUS_TEXT;
  477. status_emoji = DEFAULT_STATUS_EMOJI;
  478. if(["invisible", "dnd", "idle", "online"].includes(status_state))
  479. status_state = DEFAULT_STATUS_STATE;
  480. setStatus();
  481. return true;
  482. };
  483. })();

QingJ © 2025

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