Gotta go fast - PPM Autographs

Go, go, go, go, go, go, go Gotta go fast Gotta go fast Gotta go faster, faster, faster, faster, faster! Sonic X

// ==UserScript==
// @name        Gotta go fast - PPM Autographs
// @namespace   Violentmonkey Scripts
// @author      Drinkwater
// @license     MIT
// @match       https://*.popmundo.com/World/Popmundo.aspx/Character/Items/*
// @grant       none
// @version     1.5
// @description Go, go, go, go, go, go, go Gotta go fast Gotta go fast Gotta go faster, faster, faster, faster, faster! Sonic X
// ==/UserScript==

(function () {
    'use strict';

    // Variáveis de controle
    let tempoTotalInicial = 0;
    let horarioPrimeiroDefter = null;
    let primeiroDefterId = 0;
    let indiceBlocoHumano = 0;
    let idsDefterFixos = [];
    let blocoProcessando = false;
    let indiceDefter = 0;
    let TEMPO_TOTAL = 360; // 6 minutos = 360 segundos
    let INDICE_REGISTRO = 0;

    // Obtém a quantidade de cadernos de autógrafos disponíveis no inventário
    function obterQuantidadeDefter() {
        const elementoDefter = jQuery('#checkedlist a:contains("Caderno de Autógrafos")');
        if (elementoDefter.length > 0) {
            const quantidadeDefter = elementoDefter.closest('td').find('em').text().trim();
            if (quantidadeDefter.startsWith('x')) {
                return parseInt(quantidadeDefter.substring(1));
            }
        }
        return 0;
    }

    // Adiciona mensagens na tabela de registros
    function adicionarRegistro(dado) {
        if (window.parent === window) {
            jQuery("#registros-autografo").append(`<tr class="${INDICE_REGISTRO % 2 == 0 ? "odd" : "even"}"><td>${dado}</td></tr>`);
            INDICE_REGISTRO++;
        }
    }

    // Filtra as pessoas on‑line que aceitam autógrafos
    async function obterPessoasColetaveis(iframe) {
        let documentoIframe = iframe.contentDocument || iframe.contentWindow.document;
        let primeiraTabelaPessoas = documentoIframe.querySelector('#tablepeople');

        // Marca apenas a checkbox de autógrafo
        let checkboxAutografo = documentoIframe.querySelector('#ctl00_cphLeftColumn_ctl00_chkAutograph');
        if (checkboxAutografo) {
            checkboxAutografo.checked = true;
        }

        // Desmarca outras checkboxes
        ['#ctl00_cphLeftColumn_ctl00_chkGame', '#ctl00_cphLeftColumn_ctl00_chkRelationships'].forEach(seletor => {
            let cb = documentoIframe.querySelector(seletor);
            if (cb && cb.checked) cb.checked = false;
        });

        // Aplica o filtro
        let botaoFiltro = documentoIframe.querySelector('#ctl00_cphLeftColumn_ctl00_btnFilter');
        if (botaoFiltro) {
            botaoFiltro.click();
        } else {
            throw new Error("Botão de filtro não encontrado.");
        }

        // Aguarda a atualização da tabela
        return new Promise(resolve => {
            let intervalo = setInterval(() => {
                let novoDoc = iframe.contentDocument || iframe.contentWindow.document;
                let novaTabelaPessoas = novoDoc.querySelector('#tablepeople');

                if (novaTabelaPessoas && novaTabelaPessoas !== primeiraTabelaPessoas) {
                    clearInterval(intervalo);
                    let pessoasFiltradas = [];

                    Array.from(novaTabelaPessoas.querySelectorAll('tbody tr')).forEach(linha => {
                        let linkPersonagem = linha.querySelector('a');
                        let textoStatus = linha.querySelectorAll('td')[1]?.textContent.trim().toLowerCase();

                        let estadosOcupados = ["em viagem", "em exploração", "exploração", "voando"];
                        let estaOcupado = estadosOcupados.some(e => textoStatus.includes(e));

                        if (!estaOcupado && linkPersonagem) {
                            pessoasFiltradas.push({
                                name: linkPersonagem.textContent,
                                id: linkPersonagem.href.split('/').pop(),
                                status: textoStatus
                            });
                        }
                    });

                    resolve(pessoasFiltradas);
                }
            }, 1000);
        });
    }

    // Cria um iframe invisível apontando para a lista de pessoas on‑line
    async function criarIframe() {
        let dominio = window.location.hostname;
        let url = `https://${dominio}/World/Popmundo.aspx/City/PeopleOnline/`;

        let iframe = document.createElement('iframe');
        iframe.src = url;
        iframe.style.display = 'none';
        document.body.appendChild(iframe);

        return new Promise((resolve, reject) => {
            iframe.onload = () => resolve(iframe);
            iframe.onerror = () => reject('Erro ao carregar o iframe');
        });
    }

    // Navega até o local do personagem selecionado
    async function irParaLocal(iframe, personagemId, personagemNome) {
        let dominio = iframe.contentWindow.location.host;
        iframe.src = `https://${dominio}/World/Popmundo.aspx/Character/${personagemId}`;
        await aguardarCarregamentoIframe(iframe);

        let doc = iframe.contentDocument || iframe.contentWindow.document;
        let linkLocal = doc.querySelector('#ctl00_cphRightColumn_ctl00_lnkInteract')?.href ||
                        doc.querySelector('#ctl00_cphRightColumn_ctl00_btnInteract')?.href;

        // Se não houver link direto, tenta extrair a partir da apresentação do personagem
        if (!linkLocal) {
            let pres = doc.querySelector('.characterPresentation');
            if (pres) {
                let links = pres.querySelectorAll('a');
                if (links.length) {
                    let ultimoLink = links[links.length - 1];
                    let localId = ultimoLink.getAttribute('href').split('/').pop();
                    linkLocal = `https://${dominio}/World/Popmundo.aspx/Locale/MoveToLocale/${localId}/${personagemId}`;
                }
            }
            if (!linkLocal) {
                adicionarRegistro(`${personagemNome} não está mais na cidade ou ocorreu um problema!`);
                return;
            }
        }

        let caminhoRelativo = linkLocal.split('/World/')[1];
        if (!caminhoRelativo) {
            adicionarRegistro('Algo deu errado, mas continuaremos!');
            return;
        }

        iframe.src = `https://${iframe.contentWindow.location.host}/World/${caminhoRelativo}`;
        adicionarRegistro(`<b>${personagemNome}</b> está indo para o local`);
        await aguardarCarregamentoIframe(iframe);
    }

    // Helper para aguardar carregamento do iframe
    function aguardarCarregamentoIframe(iframe) {
        return new Promise(resolve => { iframe.onload = () => resolve(); });
    }

    // Recupera os IDs dos cadernos de autógrafos do personagem
    async function obterIdsDefter(iframe, pessoa) {
        let doc = iframe.contentDocument || iframe.contentWindow.document;
        await new Promise(r => setTimeout(r, 2000)); // pequena espera para o DOM renderizar

        // Loga mensagens de erro, se existirem
        let msgErro = jQuery(doc).find('.error, .warning, .message').text().trim();
        if (msgErro) adicionarRegistro(`Debug – Mensagem de erro encontrada: ${msgErro}`);

        let select = jQuery(doc).find('#ctl00_cphTopColumn_ctl00_ddlUseItem');
        if (!select.length) {
            adicionarRegistro(`<b>${pessoa.name}</b> não está mais disponível ou não permite o uso de itens`);
            return [];
        }

        let ids = [];
        select.find('option').each(function () {
            let texto = jQuery(this).text().trim();
            let valor = jQuery(this).val();
            if (texto === 'Caderno de Autógrafos') {
                ids.push(valor);
                if (!primeiroDefterId) primeiroDefterId = valor;
            }
        });
        return ids;
    }

    // Usa um caderno de autógrafos específico
    async function coletarAssinatura(iframe, defterId, pessoa) {
        let doc = iframe.contentDocument || iframe.contentWindow.document;
        let select = doc.querySelector('#ctl00_cphTopColumn_ctl00_ddlUseItem');
        if (!select) return;

        select.value = defterId;
        let botaoEnviar = doc.querySelector('#ctl00_cphTopColumn_ctl00_btnUseItem');
        if (!botaoEnviar) {
            adicionarRegistro(`<b>${pessoa.name}</b> botão para usar item não encontrado`);
            return;
        }

        botaoEnviar.click();
        await aguardarCarregamentoIframe(iframe);

        // Aguarda proporcionalmente ao número de cadernos
        let total = obterQuantidadeDefter();
        if (total > 1) {
            await new Promise(r => setTimeout(r, Math.floor(TEMPO_TOTAL / total) * 1000));
        }
    }

    // Interface gráfica e laço principal
    jQuery(document).ready(function () {
        jQuery('#checkedlist').before('<div class="box" id="caixa-autografos"><h2>✨ Coletor de Cadernos de Autógrafos</h2></div>');
        jQuery('#caixa-autografos').append('<p>📝 Este recurso usará todos os seus cadernos de autógrafos no inventário para conseguir assinaturas de alguns nomes populares metidos!</p>');
        jQuery('#caixa-autografos').append('<p class="actionbuttons"><input type="button" name="btn-iniciar" value="🚀 Iniciar" id="autografo-iniciar" class="rmargin5"></p>');
        jQuery('#caixa-autografos').append('<table id="registros-autografo" class="data dataTable"></table>');
        jQuery('#registros-autografo').append('<tbody><tr><th>📋 Registros</th></tr></tbody>');

        jQuery('#autografo-iniciar').click(async function () {
            try {
                jQuery(this).prop('disabled', true).prop('value', '🔄 Coletando Assinaturas...');

                while (true) {
                    let qtdDefter = obterQuantidadeDefter();
                    if (!qtdDefter) {
                        adicionarRegistro('❌ Nenhum caderno de autógrafos encontrado. Tentando novamente...');
                        await new Promise(r => setTimeout(r, 5000));
                        continue;
                    }
                    adicionarRegistro(`📦 Número de cadernos encontrados: ${qtdDefter}`);

                    let iframe = await criarIframe();
                    let pessoasDisponiveis = await obterPessoasColetaveis(iframe);
                    let processadas = 0;

                    if (pessoasDisponiveis.length) {
                        for (const p of pessoasDisponiveis) {
                            if (processadas >= qtdDefter) break;

                            await new Promise(r => setTimeout(r, 3000));
                            await irParaLocal(iframe, p.id, p.name);
                            let ids = await obterIdsDefter(iframe, p);

                            if (ids.length) {
                                await new Promise(r => setTimeout(r, 3000));
                                adicionarRegistro(`✍️ Coletando assinatura de <b>${p.name}</b>. ID do caderno: ${ids[indiceDefter]}`);
                                await coletarAssinatura(iframe, ids[indiceDefter], p);
                                indiceDefter = (indiceDefter + 1) % ids.length;
                                processadas++;
                            }
                        }
                    } else {
                        adicionarRegistro('❌ Nenhuma pessoa disponível, tentando novamente em 30 segundos...');
                        await new Promise(r => setTimeout(r, 30000));
                    }

                    if (iframe) iframe.remove();
                }
            } catch (erro) {
                console.error('Erro:', erro);
                adicionarRegistro('❌ Ocorreu um erro durante a execução do script.');
                jQuery('#autografo-iniciar').prop('disabled', false).prop('value', '🚀 Iniciar');
            }
        });
    });
})();