RateLimit Bypass

Send custom requests when emote buttons are clicked

当前为 2024-04-30 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name RateLimit Bypass
  3. // @namespace RishiSunak
  4. // @version 0.2
  5. // @description Send custom requests when emote buttons are clicked
  6. // @author You
  7. // @match https://kick.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. function getCookie(name) {
  15. const cookies = document.cookie.split('; ');
  16. for (const cookie of cookies) {
  17. const [cookieName, cookieValue] = cookie.split('=');
  18. if (cookieName === name) {
  19. return cookieValue;
  20. }
  21. }
  22. return null;
  23. }
  24.  
  25. const authToken = getCookie('XSRF-TOKEN');
  26. const xsrfToken = decodeURIComponent(authToken);
  27.  
  28. function sendRequest(chatId, emoteNumber, xsrfToken) {
  29. const headers = {
  30. 'Accept': 'application/json, text/plain, */*',
  31. 'Authorization': authToken,
  32. 'X-Xsrf-Token': xsrfToken,
  33. 'Origin': 'https://kick.com',
  34. 'Referer': 'https://kick.com/nickwhite',
  35. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
  36. 'Content-Type': 'application/json'
  37. };
  38.  
  39. const url = 'https://kick.com/api/v2/messages/send/' + chatId;
  40. const jsonData = JSON.stringify({
  41. 'content': `[emote:${emoteNumber}:RishiBypass]`,
  42. 'type': 'message'
  43. });
  44.  
  45. fetch(url, {
  46. method: 'POST',
  47. headers: headers,
  48. credentials: 'include',
  49. body: jsonData
  50. }).then(response => {
  51. if (!response.ok) {
  52. throw new Error('Failed to send request');
  53. }
  54. console.log('Request sent successfully');
  55. }).catch(error => {
  56. console.error('Error sending request:', error);
  57. });
  58. }
  59.  
  60. function attachEventListeners(chatId) {
  61. const emoteItems = document.querySelectorAll('img[src*="/emotes/"]');
  62. emoteItems.forEach(emote => {
  63. const clone = emote.cloneNode(true);
  64. emote.parentNode.replaceChild(clone, emote);
  65. });
  66.  
  67. const newEmoteItems = document.querySelectorAll('img[src*="/emotes/"]');
  68. newEmoteItems.forEach(emote => {
  69. emote.addEventListener('click', function(event) {
  70. event.preventDefault();
  71. event.stopPropagation();
  72. console.log('Clicked IMG element:', event.target);
  73. console.log('SRC:', event.target.src);
  74. const emoteNumber = event.target.src.match(/\/emotes\/(\d+)\/fullsize/)[1];
  75. console.log('Emote Number:', emoteNumber);
  76. sendRequest(chatId, emoteNumber, xsrfToken);
  77. attachEventListeners(chatId);
  78. });
  79. });
  80. }
  81.  
  82. setTimeout(function() {
  83. fetch('https://kick.com/api/v2/channels/' + window.location.pathname.split('/').pop(), {
  84. method: 'GET',
  85. credentials: 'include'
  86. }).then(response => {
  87. if (!response.ok) {
  88. throw new Error('Failed to fetch chat ID');
  89. }
  90. return response.json();
  91. }).then(data => {
  92. const chatId = data.chatroom && data.chatroom.id ? data.chatroom.id : null;
  93. if (!chatId) {
  94. throw new Error('Chat ID not found in response');
  95. }
  96. console.log('Chat ID:', chatId);
  97.  
  98. attachEventListeners(chatId);
  99. }).catch(error => {
  100. console.error('Error:', error);
  101. });
  102. }, 3000);
  103.  
  104.  
  105. function hideRateLimitMessage() {
  106. const toastHolder = document.querySelector('.toast-holder');
  107. if (toastHolder) {
  108. toastHolder.style.display = 'none';
  109. }
  110. }
  111.  
  112. function attachHideRateLimitListeners() {
  113. const observerTarget = document.querySelector('body');
  114. const observer = new MutationObserver(mutationsList => {
  115. mutationsList.forEach(mutation => {
  116. if (mutation.addedNodes.length > 0) {
  117. mutation.addedNodes.forEach(addedNode => {
  118. if (addedNode.nodeType === 1) {
  119. if (addedNode.classList && addedNode.classList.contains('toast-holder')) {
  120. hideRateLimitMessage();
  121. }
  122. }
  123. });
  124. }
  125. });
  126. });
  127.  
  128. const observerConfig = { childList: true, subtree: true };
  129. observer.observe(observerTarget, observerConfig);
  130. }
  131.  
  132.  
  133. hideRateLimitMessage();
  134. attachHideRateLimitListeners();
  135. })();