Epix Auto Friend

Automatically adds all the Epix friends links from the gamescom discord server

目前为 2024-08-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Epix Auto Friend
  3. // @namespace Violentmonkey Scripts
  4. // @match https://discord.com/channels/574865170694799400/1259933715409145966*
  5. // @inject-into content
  6. // @grant GM_addStyle
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // @version 1.0
  10. // @author UpDownLeftDie
  11. // @license MIT
  12. // @description Automatically adds all the Epix friends links from the gamescom discord server
  13.  
  14. // ==/UserScript==
  15.  
  16. let EPIX_IDS = [];
  17. let DISCORD_TOKEN = '';
  18. let EPIX_FRIENDS = [];
  19.  
  20. function main() {
  21. EPIX_FRIENDS = GM_getValue('epixFriends') || [];
  22. EPIX_IDS = GM_getValue('epixIds') || [];
  23. DISCORD_TOKEN = localStorage.getItem("token")?.replaceAll('\"', '');
  24. console.log({EPIX_FRIENDS, EPIX_IDS, DISCORD_TOKEN: !!DISCORD_TOKEN});
  25.  
  26. const epixButton = document.createElement('button');
  27. epixButton.setAttribute('id', 'epixButton');
  28. epixButton.setAttribute('type', 'button');
  29. epixButton.innerHTML = 'Run Epix Friend Adder';
  30. document.querySelector('h1').appendChild(epixButton);
  31.  
  32. document.getElementById("epixButton").addEventListener("click", handleButton, false);
  33. }
  34.  
  35. async function handleButton(event) {
  36. await getEpixIds();
  37.  
  38. const epixButton = document.getElementById('epixButton');
  39. epixButton.setAttribute('disabled', true);
  40. epixButton.innerHTML = 'Running...';
  41.  
  42.  
  43. let messages = [];
  44. do {
  45. const minId = GM_getValue('discordMinId');
  46. console.log({minId});
  47. messages = await getDiscordMessages(minId);
  48. const codes = getEpixCodes(messages);
  49. console.log({messages, codes});
  50. if (codes.length <= 0 && messages.length > 0) {
  51. GM_setValue('discordMinId', messages[messages.length - 1][0].id);
  52. }
  53. for(let i in codes) {
  54. const promises = EPIX_IDS.map(epixId => connectRequest(epixId, codes[i].code));
  55. let responses = await Promise.all(promises);
  56. let json = await responses[0].json();
  57. const status = json?.data?.status.toUpperCase();
  58. updateFriends(status, codes[i]);
  59. }
  60. } while(messages.length >= 25);
  61.  
  62. epixButton.innerHTML = 'Done!';
  63. }
  64.  
  65. async function getEpixIds() {
  66. return new Promise((resolve, reject) => {
  67. const inputValue = EPIX_IDS?.length ? EPIX_IDS.join(',') : '';
  68. const dialog = document.createElement('dialog');
  69. dialog.setAttribute('open', true);
  70. dialog.setAttribute('id', 'epixIdsDialog')
  71. dialog.innerHTML = `
  72. <p>Enter your Epix user id(s) (<strong>NOT the same as your invite id!</strong>)</p>
  73. To get this go to your <a href="https://www.gamescom.global/en/epix" target="_blank">profile</a>:
  74. <ol>
  75. <li>open dev tools</li>
  76. <li>refresh the page</li>
  77. <li>look at network requests for "user?userId=XXXXXXX"</li>
  78. </ol>
  79. <form method="dialog">
  80. <input id="epixIds" placeholder="b5629b160f555ab4b08ef8e49568b7dd, a49f9b160f555vd4b08ef8e49568b7a2" value="${inputValue}" />
  81. <button id="epixIdAddButton">START</button>
  82. </form>
  83. `;
  84. document.body.appendChild(dialog);
  85. document.getElementById("epixIdAddButton").addEventListener("click", ()=> {
  86. const idStr = document.getElementById("epixIds").value;
  87. const ids = idStr.split(',').reduce((acc, curr) => {
  88. const id = curr.replace(/\W/gi, '');
  89. if (!id) return acc;
  90. acc.push(id);
  91. return acc;
  92. }, []);
  93. EPIX_IDS = ids;
  94. GM_setValue('epixIds', EPIX_IDS);
  95. dialog.parentNode.removeChild(dialog);
  96. resolve();
  97. }, false);
  98. });
  99. }
  100.  
  101. function getEpixCodes(discordMessages) {
  102. const codes = discordMessages.reduce((acc, curr) => {
  103. const message = curr[0]
  104. const match = message.content.match(/epix-connect=([\w\d]{7})/i);
  105. if (match?.[1] && !EPIX_FRIENDS.includes(match[1])) {
  106. acc.push({code: match[1], messageId: message.id});
  107. }
  108. return acc;
  109. }, [])
  110.  
  111. return codes;
  112. }
  113.  
  114.  
  115. function updateFriends(status, code) {
  116. if (status === "CONNECTION_SUCCESSFUL" || status === "ALREADY_MATCHED") {
  117. EPIX_FRIENDS.push(code.code);
  118. GM_setValue('epixFriends', EPIX_FRIENDS);
  119. GM_setValue('discordMinId', code.messageId);
  120. }
  121.  
  122. }
  123.  
  124.  
  125.  
  126. //--- Style our newly added elements using CSS.
  127. GM_addStyle (`
  128. #epixButton {
  129. margin-left: 10px;
  130. }
  131.  
  132. #epixIdsDialog {
  133. margin-top: 5rem;
  134. }
  135. #epixIdsDialog ol {
  136. list-style: auto;
  137. padding-left: 35px;
  138. margin-bottom: 10px;
  139. }
  140. #epixIdsDialog input {
  141. width: 100%;
  142. }
  143. #epixIdsDialog button {
  144. margin: 5px auto;
  145. display: block;
  146. font-size: large;
  147. background: greenyellow;
  148. padding: 2px 10px;
  149. }
  150. `);
  151.  
  152.  
  153. async function connectRequest(userId, profileId) {
  154. return fetch("https://wfppjum4x2.execute-api.eu-central-1.amazonaws.com/production/connection-request", {
  155. "referrer": "https://www.gamescom.global/",
  156. "referrerPolicy": "strict-origin-when-cross-origin",
  157. "body": `{"userId":"${userId}","profileId":"${profileId}"}`,
  158. "method": "POST",
  159. "mode": "cors",
  160. "credentials": "omit"
  161. });
  162. }
  163.  
  164.  
  165. async function getDiscordMessages(minId) {
  166. const params = queryString([
  167. ['limit', 25],
  168. ['channel_id', '1259933715409145966'],
  169. ['min_id', minId],
  170. ['sort_by', 'timestamp'],
  171. ['sort_order', 'asc'],
  172. ['has','link'],
  173. ]);
  174. const res = await fetch(`https://discord.com/api/v9/guilds/574865170694799400/messages/search?${params}`, {
  175. "headers": {
  176. "accept": "*/*",
  177. "authorization": DISCORD_TOKEN
  178. },
  179. "referrer": "https://discord.com/channels/574865170694799400/1259933715409145966",
  180. "referrerPolicy": "strict-origin-when-cross-origin",
  181. "method": "GET",
  182. "mode": "cors",
  183. "credentials": "include"
  184. });
  185. if (!res.ok) {
  186. console.error({ERROR: res.error});
  187. return;
  188. }
  189.  
  190. const data = await res.json();
  191. return data.messages;
  192. }
  193.  
  194.  
  195. const queryString = params => params.filter(p => p[1] !== undefined).map(p => p[0] + '=' + encodeURIComponent(p[1])).join('&');
  196.  
  197. (new MutationObserver(check)).observe(document, {childList: true, subtree: true});
  198. function check(changes, observer) {
  199. if(document.querySelector('h1')) {
  200. observer.disconnect();
  201. main();
  202. }
  203. }