JVC Cloudflare Bypass

Bypass les captchas avec Cloudflare sur JVC

  1. // ==UserScript==
  2. // @name JVC Cloudflare Bypass
  3. // @namespace https://jeuxvideo.com/
  4. // @version 1.11
  5. // @description Bypass les captchas avec Cloudflare sur JVC
  6. // @author HulkDu92
  7. // @match *://*.jeuxvideo.com/*
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_addStyle
  10. // @connect cloudflare.com
  11. // @connect cloudflare.manfredi.io
  12. // @run-at document-end
  13. // @license MIT
  14. // @icon https://image.noelshack.com/fichiers/2025/06/5/1738891409-68747470733a2f2f74616d6e762e696d6769782e6e65742f63665f6279706173735f6c6f676f2e706e67.png
  15. // ==/UserScript==
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. const WARP_STATUS_KEY = "jvcWarpStatus";
  21. const CLOUDFLARE_TRACE_URL = "https://cloudflare.com/cdn-cgi/trace";
  22. const WARP_BUTTON_URL = "https://1.1.1.1/fr-FR/";
  23. const CLOUDFLARE_HUMAN_URL = "https://cloudflare.manfredi.io/test/";
  24.  
  25. // Injecte les styles des deux boutons
  26. function injectStyles() {
  27. GM_addStyle(`
  28. .btn-warp {
  29. border: 0.0625rem solid var(--jv-text-secondary);
  30. background: var(--jv-text-secondary);
  31. color: #fff;
  32. font-weight: 500;
  33. padding: 0;
  34. font-size: 0.8125rem;
  35. height: 1.75rem;
  36. min-width: 6.375rem;
  37. line-height: 1.6875rem;
  38. cursor: pointer;
  39. }
  40. .btn-warp:hover {
  41. background: var(--jv-text-secondary-hover, var(--jv-text-secondary));
  42. }
  43.  
  44. .btn-robot {
  45. border: 0.0625rem solid var(--jv-text-secondary);
  46. background: transparent;
  47. color: var(--jv-text-secondary);
  48. font-weight: 500;
  49. padding: 0;
  50. font-size: 0.8125rem;
  51. height: 1.75rem;
  52. min-width: 5.775rem;
  53. line-height: 1.6875rem;
  54. cursor: pointer;
  55. transition: all 0.2s ease;
  56. white-space: nowrap;
  57. }
  58.  
  59. .btn-robot svg {
  60. width: 1.1rem;
  61. height: 1.1rem;
  62. stroke: white;
  63. padding-bottom: 2px;
  64. }
  65.  
  66. .btn-robot:hover {
  67. border-color: var(--jv-text-secondary-hover, var(--jv-text-secondary));
  68. color: var(--jv-text-secondary-hover, var(--jv-text-secondary));
  69. }
  70. `);
  71. }
  72.  
  73. /**
  74. * Vérifie si Warp est activé et stocke le résultat dans sessionStorage.
  75. * Affiche le bouton si Warp est désactivé.
  76. */
  77. function checkWarpStatus() {
  78. const storedStatus = sessionStorage.getItem(WARP_STATUS_KEY);
  79. if (storedStatus !== null) {
  80. if (storedStatus === "false") showButtons();
  81. return;
  82. }
  83.  
  84. GM_xmlhttpRequest({
  85. method: "GET",
  86. url: CLOUDFLARE_TRACE_URL,
  87. onload: response => {
  88. const warpActive = response.responseText.includes("warp=on");
  89. sessionStorage.setItem(WARP_STATUS_KEY, warpActive.toString());
  90. if (!warpActive) showButtons();
  91. }
  92. });
  93. }
  94.  
  95. /**
  96. * Crée et affiche les deux boutons (Warp et Humanité).
  97. */
  98. function showButtons() {
  99. injectStyles();
  100. const warpButton = createWarpButton();
  101. const humanityButton = createHumanityButton();
  102.  
  103. // Trouve les conteneurs pour chaque bouton, par exemple dans des zones différentes
  104. const targetElementWarp = document.querySelector('.header__globalUser'); // pour le bouton Warp
  105. const targetElementHumanity = document.querySelector('.bloc-pre-right'); // pour le bouton Humanity
  106.  
  107. // Si l'élément cible pour Warp est trouvé, insère le bouton Warp dedans
  108. if (targetElementWarp) {
  109. targetElementWarp.insertBefore(warpButton, targetElementWarp.firstChild);
  110. } else {
  111. // Sinon, affiche le bouton en position fixe
  112. console.warn("Element cible pour Warp non trouvé, affichage en position fixed.");
  113. Object.assign(warpButton.style, {
  114. position: "fixed",
  115. bottom: "20px",
  116. right: "20px",
  117. zIndex: "9999"
  118. });
  119. document.body.appendChild(warpButton);
  120. }
  121.  
  122. // Si l'élément cible pour Humanity est trouvé, insère le bouton Humanity dedans
  123. if (targetElementHumanity) {
  124. targetElementHumanity.insertBefore(humanityButton, targetElementHumanity.firstChild);
  125. } else {
  126. // Sinon, affiche le bouton en position fixe aussi pour Humanity
  127. console.warn("Element cible pour Humanity non trouvé, affichage en position fixed.");
  128. Object.assign(humanityButton.style, {
  129. position: "fixed",
  130. bottom: "20px",
  131. right: "100px", // Tu peux ajuster cette valeur pour le positionner à côté du premier bouton
  132. zIndex: "9999"
  133. });
  134. document.body.appendChild(humanityButton);
  135. }
  136.  
  137. }
  138.  
  139. /**
  140. * Crée le bouton pour activer Warp.
  141. * @returns {HTMLElement} Le bouton créé.
  142. */
  143. function createWarpButton() {
  144. const button = document.createElement("button");
  145. button.type = "button";
  146. button.className = "btn btn-warp";
  147. button.title = "Bloquer Captcha 🛇";
  148. button.textContent = "Bloquer Captcha";
  149.  
  150. button.onclick = openCloudflareApp;
  151. return button;
  152. }
  153.  
  154. /**
  155. * Ouvre un lien vers 1.1.1.1 pour son installation
  156. */
  157. function openCloudflareApp() {
  158. sessionStorage.removeItem(WARP_STATUS_KEY);
  159. alert(
  160. "Le blocage complet des Captchas est possible grâce à l'application officielle de Cloudflare: 1.1.1.1\n\n" +
  161. "Cette application agit comme un pass VIP pour Cloudflare et empêche tous les captchas sur JVC.\n\n" +
  162. "Il est recommandé de l'activer uniquement pour JVC.\n\n" +
  163. "C'est une solution radicale (en espérant qu'elle soit temporaire :hap:) pour éviter les captchas abusifs."
  164. );
  165. window.open(WARP_BUTTON_URL, "_blank");
  166. }
  167.  
  168. /**
  169. * Crée le bouton pour vérifier l'humanité.
  170. * @returns {HTMLElement} Le bouton créé.
  171. */
  172. function createHumanityButton() {
  173. const button = document.createElement("button");
  174. button.type = "button";
  175. button.className = "btn btn-robot";
  176. button.innerHTML = `
  177. <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24">
  178. <g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
  179. <rect width="20" height="14" x="2" y="9" rx="4"/>
  180. <circle cx="12" cy="3" r="2"/>
  181. <path d="M12 5v4m-3 8v-2m6 0v2"/>
  182. </g>
  183. </svg>
  184. <span>Humain</span>
  185. `;
  186.  
  187. button.onclick = fetchPercentage;
  188. return button;
  189. }
  190.  
  191. /**
  192. * Récupère et affiche le pourcentage d'humanité.
  193. */
  194. function fetchPercentage() {
  195. GM_xmlhttpRequest({
  196. method: "GET",
  197. url: CLOUDFLARE_HUMAN_URL,
  198. onload: function(response) {
  199. const percentage = extractPercentage(response.responseText);
  200. if (percentage !== null) {
  201. showPopup(percentage);
  202. } else {
  203. alert("Erreur : Pourcentage non trouvé.");
  204. }
  205. },
  206. onerror: function() {
  207. alert("Erreur de récupération des données.");
  208. }
  209. });
  210. }
  211.  
  212. function extractPercentage(htmlString) {
  213. let parser = new DOMParser();
  214. let doc = parser.parseFromString(htmlString, "text/html");
  215.  
  216. let percentElement = Array.from(doc.querySelectorAll('*'))
  217. .find(el => el.textContent.includes('%') && el.textContent.includes('human'));
  218.  
  219. if (!percentElement) return null;
  220.  
  221. let match = percentElement.textContent.match(/(\d+)%/);
  222. return match ? parseInt(match[1], 10) : null;
  223. }
  224.  
  225. function showPopup(percentage) {
  226. let popup = document.createElement('div');
  227. popup.id = 'human-check-popup';
  228. popup.innerHTML = `
  229. <div class="popup-content">
  230. <span class="popup-close">&times;</span>
  231. <p>Vous êtes ${percentage}% humain.</p>
  232. <div class="progress-bar-container">
  233. <div class="progress-bar" style="width: ${percentage}%;"></div>
  234. </div>
  235. </div>
  236. `;
  237. document.body.appendChild(popup);
  238.  
  239. popup.querySelector('.popup-close').addEventListener('click', function() {
  240. popup.remove();
  241. });
  242.  
  243. GM_addStyle(`
  244. #human-check-popup {
  245. position: fixed;
  246. top: 50%;
  247. left: 50%;
  248. transform: translate(-50%, -50%);
  249. background: #181A1B;
  250. padding: 20px;
  251. box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  252. border-radius: 10px;
  253. z-index: 10000;
  254. width: 300px;
  255. text-align: center;
  256. color: #F0EEEC;
  257. }
  258.  
  259. .popup-content {
  260. position: relative;
  261. }
  262.  
  263. .popup-close {
  264. position: absolute;
  265. top: 5px;
  266. right: 10px;
  267. font-size: 20px;
  268. cursor: pointer;
  269. }
  270.  
  271. .progress-bar-container {
  272. width: 100%;
  273. height: 20px;
  274. background: #43413D;
  275. border-radius: 10px;
  276. margin-top: 10px;
  277. overflow: hidden;
  278. }
  279.  
  280. .progress-bar {
  281. height: 100%;
  282. background: #006600;
  283. transition: width 0.5s;
  284. }
  285. `);
  286.  
  287. }
  288.  
  289. checkWarpStatus();
  290. })();