您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在勇者福利社參加抽抽樂時,可以直接免費兌換抽獎卷而不用看廣告!
// ==UserScript== // @name 巴哈姆特勇者福利社-跳過廣告&兌換流程自動化 // @namespace ani20168 // @version 2.3.1 // @description 在勇者福利社參加抽抽樂時,可以直接免費兌換抽獎卷而不用看廣告! // @author ani20168 // @homepage https://home.gamer.com.tw/profile/index.php?&owner=a20280210 // @match https://fuli.gamer.com.tw/* // @icon https://www.google.com/s2/favicons?sz=64&domain=gamer.com.tw // @grant GM_xmlhttpRequest // @require https://openuserjs.org/src/libs/sizzle/GM_config.js // ==/UserScript== (function() { 'use strict'; var observer; var enableAutoProcessOnBuyDPage = false; var enableAutoSkip = false; // GM_config選單 var GM_configStruct = { 'id': 'UserScriptConfig', 'title': '抽抽樂腳本設定', 'fields': { 'enableAutoProcessOnBuyDPage': { 'label': '自動送出收件資料', 'type': 'checkbox', 'default': false, 'title': '啟用後,在填寫收件人頁面會自動送出收件資料,開啟這項功能前請先確保收件人資訊完整,而且頁面上的"請幫我記住收件人資料"的確認框為打勾的狀態。' }, 'enableAutoSkip': { 'label': '自動跳過廣告', 'type': 'checkbox', 'default': false, 'title': '啟用後,只要頁面是在抽抽樂的商品頁面,而且此商品目前可以透過看廣告的方式兌換抽獎機會,則會自動執行廣告跳過流程。' } }, 'css': ` #UserScriptConfig { font-family: 'Arial', sans-serif; background-color: #fff; color: #333; width: 300px; padding: 15px; margin: 0 auto; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } #UserScriptConfig .config_var { margin-bottom: 10px; } #UserScriptConfig .field_label { margin-bottom: 5px; display: block; font-weight: bold; } #UserScriptConfig input[type='checkbox'] { margin-right: 10px; transform: scale(1.2); } #UserScriptConfig .section_header_holder { margin-bottom: 15px; } #UserScriptConfig .config_header { font-size: 18px; margin-bottom: 15px; text-align: center; } #UserScriptConfig .saveclose_buttons { text-align: center; padding: 8px 16px; margin:20px 40px 5px; border: 2px solid transparent; border-radius: 10px; transition: border-color 0.15s ease-in-out; } #UserScriptConfig .saveclose_buttons:hover { border-color: #90ee90; } #UserScriptConfig .reset, #UserScriptConfig .reset a { color: #999; text-decoration: none; padding: 8px 16px; display: block; margin: 10px auto 0; font-size: 12px; text-align: center; } #UserScriptConfig .reset:hover, #UserScriptConfig .reset a:hover { color: #666; } #UserScriptConfig .config_var { display: flex; align-items: center; justify-content: space-between; } `, 'frameStyle': ` bottom: auto; border: 2px solid #6F6F6F; display: none; height: 290px; left: 50%; margin: 0; max-height: 100%; max-width: 100%; opacity: 0; overflow: auto; padding: 0; position: fixed; right: auto; top: 50%; width: 330px; z-index: 9999; border-radius: 8px; box-shadow: 10px 10px 20px rgba(0,0,0,0.4); ` , 'events': { 'open': function() { console.log("配置界面已開啟"); }, 'save': function() { console.log("設定已保存"); enableAutoProcessOnBuyDPage = GM_config.get('enableAutoProcessOnBuyDPage'); enableAutoSkip = GM_config.get('enableAutoSkip'); alert("保存完成!"); }, 'close': function() { console.log("配置界面已關閉"); }, 'init': () => { console.log("UI初始化"); //獲取使用者設定 enableAutoProcessOnBuyDPage = GM_config.get('enableAutoProcessOnBuyDPage'); enableAutoSkip = GM_config.get('enableAutoSkip'); } } }; // 初始化GM_config GM_config.init(GM_configStruct); //處理驗證流程 function handleCaptchaVerification() { var captchaFound = false; // 用於標記是否找到驗證器 // 嘗試執行Google reCAPTCHA var googleRecaptcha = document.getElementById('recaptcha'); if (googleRecaptcha && typeof grecaptcha !== 'undefined' && grecaptcha.execute) { grecaptcha.execute(); captchaFound = true; // 標記找到Google reCAPTCHA } // 嘗試執行Cloudflare Turnstile if (typeof turnstile !== 'undefined' && document.querySelector('.cf-turnstile')) { turnstile.render('.cf-turnstile'); captchaFound = true; // 標記找到Cloudflare Turnstile } // 如果沒有找到任何驗證器,則提交表單 if (!captchaFound) { jQuery('#buyD').submit(); } } // 檢查目前頁面是否為 message_done 頁面 if (window.location.href.includes('https://fuli.gamer.com.tw/message_done.php')) { // 在 message_done 頁面上執行的操作 var button = document.querySelector('button'); if (button) { button.click(); } } // 等待頁面加載完畢 window.addEventListener('load', function() { // 找到TOP-my元素 var guiTopMyElement = document.querySelector('.TOP-my ul'); // 創建GUI按鈕的列表項 var guiButtonLi = document.createElement('li'); guiButtonLi.className = 'mobilehide'; // 創建GUI按鈕的連結元素 var guiButtonLink = document.createElement('a'); guiButtonLink.href = 'javascript:void(0)'; guiButtonLink.onclick = function() { GM_config.open(); }; // 為GUI按鈕添加圖標 var guiButtonIcon = document.createElement('img'); guiButtonIcon.src = 'https://i.imgur.com/uj2yF4e.png'; guiButtonLink.appendChild(guiButtonIcon); // 將連結元素加入到列表項中,然後將列表項加入到TOP-my區塊 guiButtonLi.appendChild(guiButtonLink); guiTopMyElement.insertBefore(guiButtonLi, guiTopMyElement.firstChild); // 將GUI按鈕添加到最左側 // 檢查目前頁面是否為 buyD 頁面 if (enableAutoProcessOnBuyDPage && window.location.href.includes('https://fuli.gamer.com.tw/buyD.php')) { document.getElementById('agree-confirm').checked = true; handleCaptchaVerification(); return; } //如果沒有兌換欄位 var btnList = document.getElementById('buyBtnContent'); if (!btnList) return; //看一下需不需要先回答問題,如果需要,回答問題並重整 var questionButton = btnList.querySelector('a[onclick^="showQuestion(1);"]'); if (questionButton) { getCsrfToken().then(token => { sendAnswerQuestionRequest(token); setTimeout(function() { location.reload(); }, 2000); }).catch(error => { console.error('獲取 CSRF token 時發生錯誤:', error); }); return; } //如果沒有看廣告兌換按鈕就return var adButton = btnList.querySelector('a[onclick^="window.FuliAd.checkAd"]'); if (!adButton) return; var newButton = document.createElement('a'); newButton.className = 'btn-base c-accent-o'; newButton.textContent = '跳過廣告'; newButton.href = '#'; newButton.style.marginLeft = '10px'; newButton.addEventListener('click', function(event) { event.preventDefault(); executeAdSkippingProcess(); }); btnList.appendChild(newButton); // 如果啟用自動跳過廣告,則自動點擊新按鈕 if (enableAutoSkip) { newButton.click(); } }); function executeAdSkippingProcess() { watchAdCheck(); getCsrfToken().then(token => { setTimeout(function() { sendPostRequest(token); }, 2000); }).catch(error => { console.error('獲取 CSRF token 時發生錯誤:', error); }); } // 獲取CSRF token function getCsrfToken() { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: "https://fuli.gamer.com.tw/ajax/getCSRFToken.php?_=1702883537159", onload: function(response) { var token = response.responseText.trim(); if (token) { resolve(token); } else { reject('Token not found in response'); } }, onerror: function(error) { reject('Error during request: ' + error.message); } }); }); } function sendAnswerQuestionRequest(csrfToken) { // 獲取網頁中的問題和答案 let templateContent = document.getElementById('question-popup').innerHTML; let tempDiv = document.createElement('div'); tempDiv.innerHTML = templateContent; let questions = tempDiv.querySelectorAll('.fuli-option[data-question]'); let questionNumbers = new Set(); questions.forEach(question => { questionNumbers.add(question.getAttribute('data-question')); }); let answers = []; questionNumbers.forEach(questionNumber => { let firstOption = tempDiv.querySelector(`.fuli-option[data-question="${questionNumber}"]`); answers.push(firstOption.getAttribute('data-answer')); }); // 獲取sn var urlParams = new URLSearchParams(window.location.search); var snValue = urlParams.get('sn'); // 準備payload var formData = new FormData(); formData.append('sn', snValue); formData.append('token', csrfToken); answers.forEach(answer => formData.append('answer[]', answer)); // 這一段只是在看payload而已... var object = {}; formData.forEach((value, key) => { if(!Reflect.has(object, key)){ object[key] = value; return; } if(!Array.isArray(object[key])){ object[key] = [object[key]]; } object[key].push(value); }); var payloadData = JSON.stringify(object); // 發送post GM_xmlhttpRequest({ method: "POST", url: "https://fuli.gamer.com.tw/ajax/answer_question.php", data: formData, onload: function(response) { console.log('Payload sent:', payloadData); console.log('回答問題post的回應:', response.responseText); } }); } // 發送已看完廣告的post請求 function sendPostRequest(csrfToken) { var urlParams = new URLSearchParams(window.location.search); var snValue = urlParams.get('sn'); var adButton = document.querySelector('a[onclick^="window.FuliAd.checkAd"]'); console.log('sn:',encodeURIComponent(snValue)) if (!snValue) { console.log('無法獲取sn參數'); return; } GM_xmlhttpRequest({ method: "POST", url: "https://fuli.gamer.com.tw/ajax/finish_ad.php", headers: { "Content-Type": "application/x-www-form-urlencoded" }, data: "token=" + encodeURIComponent(csrfToken) + "&area=item&sn=" + encodeURIComponent(snValue), onload: function(response) { console.log('post回應:', response.responseText); adButton.click(); } }); } // 發送get檢查是否已經看過廣告 function watchAdCheck() { var urlParams = new URLSearchParams(window.location.search); var snValue = urlParams.get('sn'); var adButton = document.querySelector('a[onclick^="window.FuliAd.checkAd"]'); if (!snValue) { console.log('無法獲取sn參數'); return; } GM_xmlhttpRequest({ method: "GET", url: "https://fuli.gamer.com.tw/ajax/check_ad.php?area=item&sn=" + encodeURIComponent(snValue), onload: function(response) { try { var responseData = JSON.parse(response.responseText); if (responseData.data && responseData.data.finished === 1) { alert('你已經看過/跳過廣告了!'); adButton.click(); return; }else{ clickAdButton(); } } catch (e) { console.error('解析回應時發生錯誤:', e); } } }); } // 自動點擊"看廣告免費兌換"按鈕 function clickAdButton() { var adButton = document.querySelector('a[onclick^="window.FuliAd.checkAd"]'); if (adButton) { adButton.click(); startObservingDialog(); } } // 監視對話框 function startObservingDialog() { var observerOptions = { childList: true, subtree: true }; observer = new MutationObserver(function(mutations, obs) { var dialog = document.querySelector('.dialogify__content'); if (dialog) { var confirmButton = dialog.querySelector('.btn-box .btn-insert.btn-primary'); if (confirmButton) { confirmButton.disabled = true; confirmButton.style.backgroundColor = '#e5e5e5'; } setTimeout(function() { handleDialogButtons(dialog); obs.disconnect(); }, 500); } }); observer.observe(document.body, observerOptions); } // 處理確認窗口的按鈕 function handleDialogButtons(dialog) { var cancelButton = dialog.querySelector('.btn-box .btn-insert:not(.btn-primary)'); var confirmButton = dialog.querySelector('.btn-box .btn-insert.btn-primary'); if (cancelButton) { setTimeout(function() { cancelButton.click(); if (confirmButton) { confirmButton.disabled = false; confirmButton.style.backgroundColor = ''; } }, 1000); } } })();