XITAO KKKKKKKKKKKK
  • JavaScript 97.5%
  • CSS 1.3%
  • HTML 1.2%
Find a file
thomasnrs 0765adb843 Atributo por classe = stat principal (VIT opcional) + override por membro
Regra do usuario: warrior=STR, ranger=DEX, wizard/priest=INT, direto.
VIT so quando a pessoa escolher.

- PRIORIDADE_CLASSE agora poe o stat principal em [0] e VIT por ultimo
  em todas (proximoAtributo sempre pega o [0], entao tudo vai pro
  principal). Antes warrior/ranger/etc levavam VIT.
- Corrige o normalizarConfig do overlay que RE-ENCHIA prioridadeStats
  com vitality mesmo vazio (era o que forcava VIT no main de qualquer
  classe — raiz do bug do ranger). Vazio = auto por classe.
- Aba Squad: dropdown de atributo por membro ("Auto (classe)" + os 4),
  igual ao foco de gear; grava em prioridadePorClasse. Pra quem quiser
  buildar diferente (ex: VIT num membro).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 10:09:05 -03:00
docs Sniper de mercado: auto-comprar pechinchas (lendário no piso) 2026-08-30 01:19:40 -03:00
icons Extensão GoH Tracer: captura de tráfego, inspector e runner de automação 2026-08-28 23:32:49 -03:00
src Atributo por classe = stat principal (VIT opcional) + override por membro 2026-08-30 10:09:05 -03:00
test Sniper de mercado: auto-comprar pechinchas (lendário no piso) 2026-08-30 01:19:40 -03:00
.gitattributes Extensão GoH Tracer: captura de tráfego, inspector e runner de automação 2026-08-28 23:32:49 -03:00
.gitignore Runner resiliente ao F5: religa sozinho e captura o id do jogador 2026-08-29 00:06:10 -03:00
manifest.json Squad + farm ~7x: cadência do tick, atributo/equip por membro 2026-08-29 20:28:03 -03:00
README.md Rebrand para Revolution, ícones SVG, persistência em localStorage, panes redimensionáveis 2026-08-29 01:37:27 -03:00

Revolution

Extensão Chrome (Manifest V3) que só liga em https://gameofheroes.com/game e grava um trace completo do tráfego do jogo — fetch, XMLHttpRequest, WebSocket, EventSource (SSE) e sendBeacon — com corpos de requisição/resposta, headers e tempos.

O objetivo desta fase 1 é catalogar os padrões da API do jogo antes de escrever qualquer automação.

Instalar

  1. chrome://extensions → ligar Modo do desenvolvedor
  2. Carregar sem compactação → selecionar esta pasta
  3. Abrir https://gameofheroes.com/game (recarregar a aba se já estiver aberta — o hook entra em document_start)

Requer Chrome/Edge 111+ (usa world: "MAIN" em content script).

Usar

Inspector flutuante (dentro do jogo): um botão arrastável (logo Revolution) no canto da tela abre um console de pacotes sobreposto ao jogo, em tempo real. Ele é ciente do Game of Heroes — em vez de listar URLs, ele lê a resposta e resume em linguagem de jogo:

20:45:21  POST  ⚔️ tick de combate    200  1089ms
          +15 xp · +9 ouro · 3 kills · fase 3/10 · HP 130/230
20:45:21  POST  ⚔️ baús               200  1237ms
          Chests collected. · 30 ouro · 🎁 0/5
20:46:26  POST  🔑 renovar lease      200   149ms
          ttl 600s
  • Trilha de categorias à esquerda: Combate, Sessão, Personagem, Missões, Loja, Chat, WebSocket, Mapa, Social, Conteúdo, Auth, Config, Assets — com contagem ao vivo.
  • Chip de rate limit no cabeçalho, que fica âmbar quando o balde passa de 75% gasto.
  • Detalhe com abas Resumo / Request / Response / Headers.
  • ↻ reenviar — refaz a chamada exatamente como capturada, usando o fetch nativo e o contexto de auth vivo da aba. O replay aparece marcado na lista e não é recapturado.
  • bloquear — impede o jogo de fazer aquela chamada. O fetch rejeita como falha de rede real (igual ao bloqueio do DevTools). As regras persistem em localStorage (namespace revolution:).
  • ⧉ fetch / curl / json — copia a chamada pronta pra reproduzir fora.

A UI vive num Shadow DOM, então o CSS do jogo não a afeta e ela não afeta o do jogo.

Popup (ícone da extensão): liga/desliga a gravação, mostra contadores, exporta o trace cru e limpa a base.

Painel de análise: F12 → aba Revolution. Quatro abas:

Aba O que mostra
Requisições Lista tipo Network, com detalhe de headers/corpos e botão copiar como fetch
WebSocket Todos os frames enviados/recebidos (WS e SSE), com payload formatado
Padrões Endpoints normalizados (/hero/8821/hero/:id) com schema inferido, status, latência e detecção de polling
Resumo Visão geral: hosts, erros, cabeçalhos de auth e candidatos a automação

Exportações

  • Trace JSON / NDJSON — eventos crus, para reprocessar
  • HAR 1.2 — abre no DevTools, Charles, Insomnia, Postman
  • Padrões (JSON) — catálogo de endpoints + schemas, pronto pra alimentar código
  • Catálogo de API (Markdown) — documentação legível dos endpoints descobertos

O que ele extrai sozinho

  • Endpoint normalizado: IDs numéricos, UUIDs, hashes e tokens viram :id, :uuid, :hash, :token
  • Schema achatado do JSON: hero.gear[].name : string (100%) ex=Espada
  • Polling: endpoints chamados ≥4× com intervalo regular (mostra o período mediano)
  • Auth: quais headers carregam credencial (authorization, x-csrf-token, x-api-key…)
  • Tipo de mensagem WS: lê type/op/event/cmd/action e entende prefixo socket.io (42["evento",…])

O que já descobrimos do jogo

Resumo: REST (Laravel + Sanctum) para tudo, inclusive combate, que é resolvido no servidor e devolvido como um "cinema" (replay determinístico com seed). WebSocket (Laravel Reverb, protocolo Pusher) apenas para broadcast de chat e PvP.

Arquitetura

manifest.json
src/
  inject/hook.js       MAIN world, document_start — intercepta as APIs de rede
  content/bridge.js    ISOLATED world — agrupa em lotes e manda pro service worker
  background/sw.js     persiste no IndexedDB, poda, serve consultas
  lib/db.js            IndexedDB (events + sessions)
  lib/analyze.js       correlação req/res, normalização, inferência de schema, HAR
  overlay/overlay.js   inspector flutuante "Revolution" dentro do jogo (Shadow DOM)
  devtools/            painel de análise
  popup/               controle rápido

Cada carregamento da página vira uma sessão própria, dá pra filtrar/exportar por sessão.

Configuração

Em chrome.storage.local.config (padrões em sw.js):

Chave Padrão Efeito
enabled true liga/desliga a captura
captureBodies true grava corpos de req/res
captureWs true grava frames de WebSocket/SSE
maxBodyBytes 262144 corta corpos maiores que isso
maxEvents 50000 teto do banco; poda os mais antigos
redactKeys password, senha, secret… campos mascarados antes de gravar
ignoreUrlPatterns analytics URLs ignoradas

Cuidados de implementação

  • Todo hook delega para a implementação original e é envelopado em try/catch — se o tracer falhar, o jogo continua.
  • Respostas text/event-stream, mídia e binários não têm o corpo lido (evita travar streams).
  • Corpos são cortados em maxBodyBytes e campos sensíveis são mascarados antes de tocar o disco.

Runner de automação (fase 2)

O runner (src/auto/) roda no MAIN world, reusa o lease vivo da aba e automatiza a sua conta no ritmo que o servidor já aceita do cliente oficial. Liga pela aba 🤖 Automação do inspector flutuante.

O que ele faz, num laço contínuo:

  • Tick de combate na variante que avança (x-goh-cinema-prefetch, corpo {"speed":1,"paused":false}), reagendando pelo cinema.duration_ms do próprio servidor
  • Resgata missões completas (completed && !claimed), tratando 422 como já-resgatada
  • Coleta baús antes de estourar o teto de 5 (senão perde recompensa)
  • Distribui stat_points ao subir de nível (PATCH /character/:id/stats), por prioridade de atributo — opt-in
  • Abre baús do inventário (POST /inventory/open-chest) — opt-in
  • Mantém a sessão viva renovando o lease a cada 120s

Trilhos de segurança (não negociáveis, no código):

  • Uma sessão só: nunca faz lease/acquire (isso criaria um segundo holder). Só reusa o que a aba tem.
  • Corpo do tick fixo: o transporte recusa qualquer tick com corpo diferente do cliente real.
  • Allowlist de rotas: só dispara o que está marcado permitidaRunner em rotas.js.
  • Nunca para sozinho (padrão nuncaParar: true): falha de servidor (500, timeout, 401/403, 429, orçamento) vira recua-e-continua, não desistência. Só você para: botão PARAR TUDO, window.gohParar(), ou window.__GOH_AUTO_KILL__ = true. O 429 sempre espera a janela virar (nunca martela). Travas de morte (parar no wipe, HP mínimo) existem mas vêm desligadas — morrer só revive no tick seguinte.
  • Governor de rate limit que conta os dois baldes (global 360 + sub-balde) e respeita a margem.

Módulos

src/auto/
  rotas.js       rota -> { familia, balde, idempotente, permitidaRunner }  (allowlist)
  estado.js      store passivo do estado do jogo (alimentado pelas respostas)
  orcamento.js   governor dos dois níveis de rate limit
  agenda.js      o scheduler (o laço) e as tarefas
  runner.js      entrada: harvester de credenciais + transporte (fetch nativo)

Detalhes de arquitetura e protocolo de mensagens em docs/runner.md.

Banco de provas

test/ tem um mock local fiel ao contrato real:

cd test && npm install
npm start        # sobe o mock na 3333
npm test         # smoke: 111 checagens do contrato
npm run test:e2e # roda o runner de verdade contra o mock

O e2e liga o runner contra o mock e verifica que ele farma sozinho — credita ticks, distribui pontos, abre baús, resgata missões — respeitando o rate limit.

Aviso

Ferramenta que opera a sua própria conta. Automatizar ações provavelmente fere os termos de uso do jogo, e a conta é sua responsabilidade — vale ler os termos antes de ligar o runner. O runner opera uma sessão só e não contorna pagamento, privilégio nem controle de sessão.