// ==UserScript== // @name 2 BGD Advanced Request Controller (Updated) // @namespace http://tampermonkey.net/ // @match https://payment.ivacbd.com/* // @version 1.3 // @description Enhanced request controller with auto-retry, draggable UI, and minimize/maximize feature after abort on redirect (302) // @author Aniruddha // @grant none // ==/UserScript== (function () { 'use strict'; let activeControllers = []; // Abort all active requests function abortAllRequests() { activeControllers.forEach(controller => { if (controller && !controller.signal.aborted) { controller.abort(); console.log('Request aborted'); } }); activeControllers = []; showStatus('All requests aborted due to redirect'); } // Status display function showStatus(message) { const statusElement = document.getElementById('request-status') || createStatusElement(); statusElement.textContent = message; console.log(message); } function createStatusElement() { const statusElement = document.createElement('div'); statusElement.id = 'request-status'; statusElement.style.cssText = ` width: 100%; text-align: center; margin: 10px 0; padding: 8px; background: #f8f9fa; border-radius: 4px; font-size: 14px; `; buttonContainer.insertBefore(statusElement, buttonContainer.firstChild.nextSibling); return statusElement; } function darkenColor(color, percent) { const hex = color.replace('#', ''); const num = parseInt(hex, 16); const amt = Math.round(2.55 * percent); const R = Math.max((num >> 16) - amt, 0); const G = Math.max((num >> 8 & 0x00FF) - amt, 0); const B = Math.max((num & 0x0000FF) - amt, 0); return `#${(1 << 24 | R << 16 | G << 8 | B).toString(16).slice(1)}`; } // Modified fetch with redirect detection async function controlledFetch(url, options) { const controller = new AbortController(); activeControllers.push(controller); try { const response = await fetch(url, { ...options, signal: controller.signal, redirect: 'manual' }); if (response.type === 'opaqueredirect' || response.status === 302) { abortAllRequests(); return null; } if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const data = await response.json(); return data; } catch (error) { if (error.name !== 'AbortError') { console.error('Fetch error:', error); showStatus(`Error: ${error.message}`); } return null; } finally { activeControllers = activeControllers.filter(c => c !== controller); } } function createFetchButton(fetchFunction, buttonText, color) { const button = document.createElement('button'); button.textContent = buttonText; button.style.cssText = ` padding: 12px 24px; background: ${color}; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 600; margin: 5px; width: 200px; height: 50px; transition: all 0.3s ease; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden; `; button.addEventListener('mouseover', () => { button.style.background = darkenColor(color, 15); button.style.transform = 'translateY(-2px)'; button.style.boxShadow = '0 6px 12px rgba(0, 0, 0, 0.15)'; }); button.addEventListener('mouseout', () => { button.style.background = color; button.style.transform = 'translateY(0)'; button.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)'; }); button.addEventListener('mousedown', () => { button.style.transform = 'translateY(1px)'; button.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.1)'; }); button.addEventListener('click', function (e) { const ripple = document.createElement('span'); ripple.style.cssText = ` position: absolute; background: rgba(255, 255, 255, 0.4); border-radius: 50%; transform: scale(0); animation: ripple 600ms linear; pointer-events: none; `; const rect = this.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = e.clientX - rect.left - size / 2; const y = e.clientY - rect.top - size / 2; ripple.style.width = ripple.style.height = `${size}px`; ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; this.appendChild(ripple); setTimeout(() => ripple.remove(), 600); fetchFunction(); }); buttonContainer.appendChild(button); } const buttonContainer = document.createElement('div'); buttonContainer.style.cssText = ` position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 9999; display: flex; flex-wrap: wrap; justify-content: center; max-width: 90%; gap: 10px; padding: 15px; background: rgba(255, 255, 255, 0.95); border-radius: 12px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); backdrop-filter: blur(5px); border: 1px solid rgba(255, 255, 255, 0.2); animation: fadeInUp 0.5s ease-out; cursor: move; `; let isDragging = false, offsetX, offsetY; const panelTitle = document.createElement('div'); panelTitle.textContent = '2 BGD Request Controller'; panelTitle.style.cssText = ` width: 100%; text-align: center; font-weight: bold; font-size: 16px; margin-bottom: 10px; color: #333; text-shadow: 0 1px 2px rgba(0,0,0,0.1); cursor: move; user-select: none; `; panelTitle.addEventListener('mousedown', (e) => { isDragging = true; const rect = buttonContainer.getBoundingClientRect(); offsetX = e.clientX - rect.left; offsetY = e.clientY - rect.top; buttonContainer.style.transition = 'none'; document.body.style.userSelect = 'none'; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; buttonContainer.style.left = `${e.clientX - offsetX}px`; buttonContainer.style.top = `${e.clientY - offsetY}px`; buttonContainer.style.transform = 'none'; }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; buttonContainer.style.transition = 'all 0.3s ease'; document.body.style.userSelect = ''; } }); // Panel toggle button const toggleButton = document.createElement('button'); toggleButton.textContent = '-'; toggleButton.title = 'Minimize Panel'; toggleButton.style.cssText = ` position: absolute; top: 5px; right: 5px; width: 25px; height: 25px; font-weight: bold; background: #ccc; border: none; border-radius: 50%; cursor: pointer; z-index: 10000; `; let isMinimized = false; toggleButton.addEventListener('click', () => { isMinimized = !isMinimized; const children = Array.from(buttonContainer.children).filter(el => el !== panelTitle && el !== toggleButton); children.forEach(el => el.style.display = isMinimized ? 'none' : 'flex'); toggleButton.textContent = isMinimized ? '+' : '-'; }); buttonContainer.appendChild(toggleButton); buttonContainer.appendChild(panelTitle); const style = document.createElement('style'); style.textContent = ` @keyframes ripple { to { transform: scale(4); opacity: 0; } } @keyframes fadeInUp { from { opacity: 0; transform: translate(-50%, 20px); } to { opacity: 1; transform: translate(-50%, 0); } } `; document.head.appendChild(style); document.body.appendChild(buttonContainer); const buttonColors = { application: '#ef4444', personal: '#f59e0b', overview: '#8b5cf6', stop: '#dc2626' }; createFetchButton(abortAllRequests, 'STOP REQUESTS', buttonColors.stop); const fetchFunctions = [ { text: 'Application', func: () => { const csrf = window.csrf_token; showStatus('Submitting Application...'); controlledFetch("https://payment.ivacbd.com/application-info-submit", { headers: { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "content-type": "application/x-www-form-urlencoded", }, referrer: "https://payment.ivacbd.com/", body: `_token=${csrf}&highcom=1&webfile_id=BGDDV57F0C25&webfile_id_repeat=BGDDV57F0C25&ivac_id=17&visa_type=13&family_count=1&visit_purpose=MEDICAL+AND+MEDICAL+ATTENDANCE`, method: "POST", mode: "cors", credentials: "include" }).then(data => data && showStatus('Application submitted')); }, color: buttonColors.application }, { text: 'Personal', func: () => { const csrf = window.csrf_token; showStatus('Submitting Personal Info...'); controlledFetch("https://payment.ivacbd.com/personal-info-submit", { headers: { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "content-type": "application/x-www-form-urlencoded", }, referrer: "https://payment.ivacbd.com/personal-info", body: `_token=${csrf}&full_name=UJAL+BHAKTA&email_name=bd229bgst@gmail.com&pho_ne=01747429232&web_file_id=BGDDV57F0C25&family%5B1%5D%5Bname%5D=SANGITA+RANI&family%5B1%5D%5Bwebfile_no%5D=BGDDV57F2E25&family%5B1%5D%5Bagain_webfile_no%5D=BGDDV57F2E25`, method: "POST", mode: "cors", credentials: "include" }).then(data => data && showStatus('Personal info submitted')); }, color: buttonColors.personal }, { text: 'Overview', func: () => { const csrf = window.csrf_token; showStatus('Submitting Overview...'); controlledFetch("https://payment.ivacbd.com/overview-submit", { headers: { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "content-type": "application/x-www-form-urlencoded", }, referrer: "https://payment.ivacbd.com/overview", body: `_token=${csrf}`, method: "POST", mode: "cors", credentials: "include" }).then(data => data && showStatus('Overview submitted')); }, color: buttonColors.overview } ]; fetchFunctions.forEach(({ text, func, color }) => createFetchButton(func, text, color)); })();

Comments

Popular posts from this blog