Greasy Fork

Greasy Fork is available in English.

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

当前为 2025-06-13 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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');
            }
        });
    });
})();