// ==UserScript== // @name Bulk Offer & Accept Helper // @namespace http://tampermonkey.net/ // @version 2.5 // @description Oferta itens por nome/quantidade/preço e aceita ofertas/presentes/compras em massa por nome e preço máximo. // @author Mark & Análise/Modificação // @match *://*.popmundo.com/World/Popmundo.aspx/Character/OfferItem/* // @match *://*.popmundo.com/World/Popmundo.aspx/Character/ItemsOffered // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @run-at document-idle // @downloadURL none // ==/UserScript== (function() { 'use strict'; // ================================================================================= // --- ROTEADOR PRINCIPAL --- // ================================================================================= function initializeScript() { const currentUrl = window.location.href; if (currentUrl.includes('/Character/OfferItem/')) { console.log("Bulk Helper: Página de OFERTAR item detectada."); setupOfferPage(); } else if (currentUrl.includes('/Character/ItemsOffered')) { console.log("Bulk Helper: Página de ACEITAR ofertas detectada."); setupAcceptPage(); } } // ================================================================================= // --- FUNCIONALIDADE 1: OFERTAR ITENS EM MASSA (CÓDIGO COMPLETO) --- // ================================================================================= function setupOfferPage() { const ITEM_DROPDOWN_SELECTOR = '#ctl00_cphLeftColumn_ctl00_ddlItem'; const OFFER_BUTTON_SELECTOR = '#ctl00_cphLeftColumn_ctl00_btnGive'; const PRICE_INPUT_SELECTOR = '#ctl00_cphLeftColumn_ctl00_txtPriceTag'; const BASE_DELAY_MS = 2000; const POST_PRICE_SET_DELAY_MS = 100; const STORAGE_KEY_ITEMS_OFFER = 'popmundo_offerItem_items_swqp'; const STORAGE_KEY_RUNNING_OFFER = 'popmundo_offerItem_running_swqp'; const STORAGE_KEY_PRICE_OFFER = 'popmundo_offerItem_targetPrice'; let itemDropdown = document.querySelector(ITEM_DROPDOWN_SELECTOR); if (!itemDropdown) { console.warn("Bulk Offer Helper: Dropdown de itens não encontrado."); return; } function createOfferUI() { if (document.getElementById('bulkOfferUIScript')) return; const scriptUIArea = document.createElement('div'); scriptUIArea.id = 'bulkOfferUIScript'; scriptUIArea.style.border = '1px solid #ccc'; scriptUIArea.style.padding = '15px'; scriptUIArea.style.margin = '20px 0 15px 0'; scriptUIArea.style.backgroundColor = '#f9f9f9'; scriptUIArea.innerHTML = `

Bulk Offer Helper




Status: Pronto.
`; itemDropdown.parentNode.insertBefore(scriptUIArea, itemDropdown); document.getElementById('startOfferByNameQtyPriceBtnScript').addEventListener('click', startOfferByNameQuantityPrice); document.getElementById('stopBulkOfferBtnScript').addEventListener('click', stopOffer); GM_addStyle(` #itemNameInputScript, #itemQuantityInputScript, #itemPriceInputScript { border: 1px solid #ccc; border-radius: 3px; box-sizing: border-box; } #startOfferByNameQtyPriceBtnScript:disabled, #stopBulkOfferBtnScript:disabled { cursor: not-allowed; opacity: 0.6; } `); } async function startOfferByNameQuantityPrice() { const itemNameInput = document.getElementById('itemNameInputScript'); const quantityInput = document.getElementById('itemQuantityInputScript'); const priceInput = document.getElementById('itemPriceInputScript'); const statusDiv = document.getElementById('bulkOfferStatusScript'); const inputText = itemNameInput.value.trim(); const requestedQuantity = parseInt(quantityInput.value, 10); const requestedPrice = parseInt(priceInput.value, 10); if (!inputText) { statusDiv.textContent = "Erro: Digite o início do nome do item."; return; } if (isNaN(requestedQuantity) || requestedQuantity < 1) { statusDiv.textContent = "Erro: Quantidade inválida."; return; } if (isNaN(requestedPrice) || requestedPrice < 0) { statusDiv.textContent = "Erro: Preço inválido."; return; } const allItemsFound = Array.from(document.querySelector(ITEM_DROPDOWN_SELECTOR).options) .filter(option => option.value && option.value !== "-1" && option.textContent.trim().toLowerCase().startsWith(inputText.toLowerCase())) .map(option => ({ value: option.value, text: option.textContent.trim() })); if (allItemsFound.length === 0) { statusDiv.textContent = `Status: Nenhum item encontrado começando com "${inputText}".`; return; } const itemsToOfferThisRun = allItemsFound.slice(0, requestedQuantity); statusDiv.textContent = `Encontrado(s) ${allItemsFound.length}. Ofertando ${itemsToOfferThisRun.length} por ${requestedPrice} M$...`; await GM_setValue(STORAGE_KEY_PRICE_OFFER, requestedPrice); await GM_setValue(STORAGE_KEY_ITEMS_OFFER, JSON.stringify(itemsToOfferThisRun)); await GM_setValue(STORAGE_KEY_RUNNING_OFFER, true); disableOfferButtons(true); await processNextOffer(); } async function stopOffer() { await GM_deleteValue(STORAGE_KEY_ITEMS_OFFER); await GM_deleteValue(STORAGE_KEY_RUNNING_OFFER); await GM_deleteValue(STORAGE_KEY_PRICE_OFFER); const statusDiv = document.getElementById('bulkOfferStatusScript'); if (statusDiv) statusDiv.textContent = "Status: Oferta interrompida pelo usuário."; disableOfferButtons(false); } function disableOfferButtons(disabled) { document.getElementById('startOfferByNameQtyPriceBtnScript').disabled = disabled; document.getElementById('stopBulkOfferBtnScript').disabled = !disabled; document.getElementById('itemNameInputScript').disabled = disabled; document.getElementById('itemQuantityInputScript').disabled = disabled; document.getElementById('itemPriceInputScript').disabled = disabled; } async function processNextOffer() { const isRunning = await GM_getValue(STORAGE_KEY_RUNNING_OFFER, false); if (!isRunning) { disableOfferButtons(false); return; } let itemsToOffer = JSON.parse(await GM_getValue(STORAGE_KEY_ITEMS_OFFER, '[]')); const statusDiv = document.getElementById('bulkOfferStatusScript'); if (itemsToOffer.length === 0) { statusDiv.textContent = "Status: Todas as ofertas foram concluídas!"; await stopOffer(); return; } const itemDropdown = document.querySelector(ITEM_DROPDOWN_SELECTOR); const offerButton = document.querySelector(OFFER_BUTTON_SELECTOR); const pagePriceInput = document.querySelector(PRICE_INPUT_SELECTOR); if (!itemDropdown || !offerButton) { statusDiv.textContent = "Erro Crítico: Elementos da página desapareceram."; await stopOffer(); return; } const itemToOffer = itemsToOffer.shift(); const targetPrice = await GM_getValue(STORAGE_KEY_PRICE_OFFER, 0); if (pagePriceInput) pagePriceInput.value = String(targetPrice); await new Promise(resolve => setTimeout(resolve, POST_PRICE_SET_DELAY_MS)); const initialTotalCount = JSON.parse(await GM_getValue(STORAGE_KEY_ITEMS_OFFER, '[]')).length + itemsToOffer.length + 1; statusDiv.textContent = `Ofertando ${initialTotalCount - itemsToOffer.length}/${initialTotalCount}: '${itemToOffer.text}'...`; itemDropdown.value = itemToOffer.value; if (itemDropdown.value !== itemToOffer.value) { statusDiv.textContent = `Erro: Falha ao selecionar '${itemToOffer.text}'. Pulando...`; await GM_setValue(STORAGE_KEY_ITEMS_OFFER, JSON.stringify(itemsToOffer)); setTimeout(processNextOffer, BASE_DELAY_MS / 2); return; } await GM_setValue(STORAGE_KEY_ITEMS_OFFER, JSON.stringify(itemsToOffer)); await new Promise(resolve => setTimeout(resolve, BASE_DELAY_MS)); if (!await GM_getValue(STORAGE_KEY_RUNNING_OFFER, false)) { disableOfferButtons(false); return; } offerButton.click(); } async function checkOfferStateOnLoad() { createOfferUI(); const isRunning = await GM_getValue(STORAGE_KEY_RUNNING_OFFER, false); if (isRunning) { disableOfferButtons(true); document.getElementById('bulkOfferStatusScript').textContent = "Status: Recarregado, continuando oferta..."; await new Promise(resolve => setTimeout(resolve, 500)); await processNextOffer(); } else { disableOfferButtons(false); } } checkOfferStateOnLoad(); } // ================================================================================= // --- FUNCIONALIDADE 2: ACEITAR OFERTAS EM MASSA (CÓDIGO CORRIGIDO v2.5) --- // ================================================================================= function setupAcceptPage() { const BASE_DELAY_MS = 2000; const STORAGE_KEY_RUNNING_ACCEPT = 'popmundo_acceptItem_running'; const STORAGE_KEY_MAX_PRICE_ACCEPT = 'popmundo_acceptItem_maxPrice'; const STORAGE_KEY_ITEM_NAME_ACCEPT = 'popmundo_acceptItem_itemName'; function createAcceptUI() { if (document.getElementById('bulkAcceptUIScript')) return; const offersHeader = Array.from(document.querySelectorAll('.box h2')) .find(h2 => h2.textContent.includes('Itens sendo ofertados a você')); if (!offersHeader) { console.log("Bulk Accept Helper: Seção 'Itens sendo ofertados a você' não encontrada."); return; } const container = offersHeader.parentElement; const scriptUIArea = document.createElement('div'); scriptUIArea.id = 'bulkAcceptUIScript'; scriptUIArea.style.border = '1px solid #ccc'; scriptUIArea.style.padding = '15px'; scriptUIArea.style.margin = '10px 0'; scriptUIArea.style.backgroundColor = '#f9f9f9'; scriptUIArea.innerHTML = `

Bulk Accept Helper



Status: Pronto.
`; container.insertBefore(scriptUIArea, offersHeader.nextSibling); document.getElementById('startAcceptBtnScript').addEventListener('click', startBulkAccept); document.getElementById('stopAcceptBtnScript').addEventListener('click', stopBulkAccept); GM_addStyle(` #maxPriceInputScript, #itemNameInputAcceptScript { border: 1px solid #ccc; border-radius: 3px; box-sizing: border-box; } #startAcceptBtnScript:disabled, #stopAcceptBtnScript:disabled { cursor: not-allowed; opacity: 0.6; } `); } async function startBulkAccept() { const priceInput = document.getElementById('maxPriceInputScript'); const nameInput = document.getElementById('itemNameInputAcceptScript'); const statusDiv = document.getElementById('bulkAcceptStatusScript'); const maxPrice = parseInt(priceInput.value, 10); const targetName = nameInput.value.trim().toLowerCase(); if (isNaN(maxPrice) || maxPrice < 0) { statusDiv.textContent = "Erro: Preço máximo inválido."; priceInput.focus(); return; } statusDiv.textContent = `Iniciando... Buscando ofertas para "${targetName || 'qualquer item'}" com preço até ${maxPrice} M$.`; await GM_setValue(STORAGE_KEY_MAX_PRICE_ACCEPT, maxPrice); await GM_setValue(STORAGE_KEY_ITEM_NAME_ACCEPT, targetName); await GM_setValue(STORAGE_KEY_RUNNING_ACCEPT, true); disableAcceptButtons(true); await processNextAccept(); } async function stopBulkAccept() { await GM_deleteValue(STORAGE_KEY_RUNNING_ACCEPT); await GM_deleteValue(STORAGE_KEY_MAX_PRICE_ACCEPT); await GM_deleteValue(STORAGE_KEY_ITEM_NAME_ACCEPT); const statusDiv = document.getElementById('bulkAcceptStatusScript'); if (statusDiv) statusDiv.textContent = "Status: Processo interrompido pelo usuário."; disableAcceptButtons(false); } function disableAcceptButtons(disabled) { document.getElementById('startAcceptBtnScript').disabled = disabled; document.getElementById('stopAcceptBtnScript').disabled = !disabled; document.getElementById('maxPriceInputScript').disabled = disabled; document.getElementById('itemNameInputAcceptScript').disabled = disabled; } async function processNextAccept() { if (!await GM_getValue(STORAGE_KEY_RUNNING_ACCEPT, false)) { disableAcceptButtons(false); return; } const maxPrice = await GM_getValue(STORAGE_KEY_MAX_PRICE_ACCEPT, -1); const targetName = await GM_getValue(STORAGE_KEY_ITEM_NAME_ACCEPT, ''); const statusDiv = document.getElementById('bulkAcceptStatusScript'); const offersHeader = Array.from(document.querySelectorAll('.box h2')).find(h2 => h2.textContent.includes('Itens sendo ofertados a você')); if (!offersHeader) { statusDiv.textContent = "Status: Seção de ofertas não encontrada. Concluindo."; await stopBulkAccept(); return; } const offerContainer = offersHeader.parentElement; const allActionButtons = offerContainer.querySelectorAll('input[type="submit"][name*="btnAccept"]'); if (allActionButtons.length === 0) { statusDiv.textContent = "Status: Nenhuma oferta encontrada para processar. Concluindo."; await stopBulkAccept(); return; } let foundItemToAccept = false; for (const button of allActionButtons) { const row = button.closest('tr'); if (!row) continue; const itemName = row.querySelector('td')?.textContent.trim() || ''; if (!itemName) continue; let itemPrice = 0; let priceText = "Presente"; const regexPriceResult = row.textContent.match(/(\d+)\s*M\$/); // <- CORREÇÃO 1: Nome diferente if (regexPriceResult && regexPriceResult[1]) { itemPrice = parseInt(regexPriceResult[1], 10); priceText = `${itemPrice} M$`; } console.log(`Verificando: Nome='${itemName}', Preço=${itemPrice} M$. Alvo: Nome='${targetName}', Preço <= ${maxPrice} M$.`); const isNameOk = (targetName === '' || itemName.toLowerCase().includes(targetName)); const isPriceOk = (itemPrice <= maxPrice); // <- CORREÇÃO 2: Novo nome da variável if (isNameOk && isPriceOk) { statusDiv.textContent = `Aceitando '${itemName}' (${priceText})...`; foundItemToAccept = true; await new Promise(resolve => setTimeout(resolve, BASE_DELAY_MS)); if (!await GM_getValue(STORAGE_KEY_RUNNING_ACCEPT, false)) { console.log("Processo interrompido durante o delay final."); disableAcceptButtons(false); return; } console.log(`Clicando no botão: "${button.value}"`); button.click(); break; } } if (!foundItemToAccept) { statusDiv.textContent = "Status: Nenhuma outra oferta corresponde aos critérios. Concluído!"; await stopBulkAccept(); } } async function checkAcceptStateOnLoad() { createAcceptUI(); if (await GM_getValue(STORAGE_KEY_RUNNING_ACCEPT, false)) { disableAcceptButtons(true); document.getElementById('bulkAcceptStatusScript').textContent = "Status: Recarregado, buscando próxima oferta para aceitar..."; await new Promise(resolve => setTimeout(resolve, 500)); await processNextAccept(); } else { disableAcceptButtons(false); } } checkAcceptStateOnLoad(); } // Inicia o script initializeScript(); })();