O maior portal de MU Online do Brasil — desde 2003
Tutorial Intermediário Website

Como criar um sistema Vote4Coins (Gtop100, XtremeTop) no MU Online

Monte um sistema Vote4Coins completo para o seu servidor de MU Online, recompensando jogadores que votam em listas como Gtop100 e XtremeTop via callback (postback) seguro, com anti-fraude, cooldown e creditação automática de moedas.

BR Bruno · Atualizado em 10 jul 2025 · ⏱ 12 de leitura
Resposta rápida

Listas de votação como Gtop100 e XtremeTop são um dos motores de crescimento orgânico mais baratos que um servidor de MU Online pode ter. Quanto mais votos você acumula, mais alto aparece no ranking, e mais jogadores novos descobrem o servidor sem gastar um centavo em anúncios. O problema é que ning

Listas de votação como Gtop100 e XtremeTop são um dos motores de crescimento orgânico mais baratos que um servidor de MU Online pode ter. Quanto mais votos você acumula, mais alto aparece no ranking, e mais jogadores novos descobrem o servidor sem gastar um centavo em anúncios. O problema é que ninguém vota de graça por muito tempo — por isso existe o Vote4Coins: um sistema que troca votos por moedas do jogo. Neste tutorial de nível intermediário você vai construir esse sistema do zero, com foco no que realmente importa: creditar somente votos confirmados pela lista, através do callback (postback), e blindar tudo contra fraude.

O erro clássico de quem começa é creditar a recompensa no momento em que o jogador clica no botão "Votar". Isso é um convite à fraude: o jogador clica, ganha a moeda, fecha a aba sem completar o voto, e repete. O jeito certo é entender que existem dois momentos distintos — o redirecionamento (jogador vai para a lista) e o callback (a lista confirma para o seu servidor que o voto foi válido). A recompensa mora no segundo momento. Todos os nomes de campos, parâmetros e tabelas aqui são exemplos e variam por versão da distribuição e por lista; confira sempre a documentação atual de cada site e o schema do seu banco.

Pré-requisitos

  • Site em PHP 7.4+ (idealmente 8.x) com acesso ao banco de dados do site e do jogo.
  • Conta de administrador registrada em cada lista que você vai usar (Gtop100, XtremeTop, TopG, XtremeTop100, etc.).
  • Seu servidor já cadastrado nessas listas, com o Site ID / ID do servidor e a chave secreta (às vezes chamada de "postback key", "callback key" ou "incentive hash") em mãos.
  • Sistema de login no site que identifique a conta do jogo do jogador (para saber quem recebe a recompensa).
  • HTTPS ativo — muitas listas exigem URL de callback segura.
  • Noção de como creditar moeda no banco do jogo (WCoin, créditos VIP, pontos de eventos — varia por versão).

Como funciona o fluxo de votação com callback

Antes de codar, entenda o caminho completo de um voto premiado. São seis etapas, e cada uma tem um papel claro.

  1. O jogador logado clica em "Votar no Gtop100" no seu site.
  2. Seu backend registra um voto pendente e redireciona o jogador para a URL da lista, embutindo um identificador (geralmente o IP ou um pingUsername com o login do jogador).
  3. O jogador resolve o CAPTCHA e confirma o voto na lista.
  4. A lista valida o voto (IP único no período, CAPTCHA correto) e faz uma requisição HTTP ao seu callback informando que o voto foi bem-sucedido.
  5. Seu callback valida a origem e a chave secreta, encontra o jogador pelo identificador e credita a recompensa de forma idempotente.
  6. O jogador volta ao site e vê o saldo atualizado; o cooldown começa a contar.
EtapaQuem executaConfia para creditar?
Clique em "Votar"JogadorNão
RedirecionamentoSeu backendNão
Confirmação na listaJogador + listaNão (ainda)
Callback/postbackServidor da listaSim, após validar
CreditaçãoSeu backend

Modelando as tabelas de votos e recompensas

Crie no banco do site uma tabela para rastrear cada voto. Ela controla o cooldown e a idempotência do callback.

CREATE TABLE votes (
    id          BIGINT AUTO_INCREMENT PRIMARY KEY,
    account     VARCHAR(20) NOT NULL,        -- conta do jogo
    site        VARCHAR(30) NOT NULL,        -- 'gtop100', 'xtremetop', ...
    ip          VARCHAR(45) NOT NULL,
    status      ENUM('pending','confirmed') DEFAULT 'pending',
    reward      INT NOT NULL DEFAULT 0,
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,
    confirmed_at DATETIME NULL,
    INDEX idx_cooldown (account, site, created_at),
    INDEX idx_ip (ip, site, created_at)
);

Uma segunda tabela de configuração ajuda a manter as recompensas e cooldowns por lista sem mexer no código:

CREATE TABLE vote_sites (
    site        VARCHAR(30) PRIMARY KEY,
    display_name VARCHAR(60) NOT NULL,
    reward      INT NOT NULL,         -- ex.: 200 WCoin por voto
    cooldown_h  INT NOT NULL DEFAULT 12,
    secret_key  VARCHAR(120) NOT NULL,
    vote_url    VARCHAR(255) NOT NULL
);

Passo a passo: redirecionamento do voto

Quando o jogador clica em votar, você registra o pendente e o envia para a lista. O identificador enviado depende da lista: algumas usam o IP do jogador para casar o callback; outras aceitam um pingUsername com o login. Exemplo genérico:

<?php
session_start();
$account = $_SESSION['account'] ?? null;
if (!$account) { header('Location: /login'); exit; }

$site = $_GET['site'] ?? '';
$cfg  = buscarVoteSite($site);              // lê de vote_sites
if (!$cfg) { http_response_code(404); exit; }

// checar cooldown antes de deixar votar de novo
if (emCooldown($account, $site, $cfg['cooldown_h'])) {
    header('Location: /votar?erro=cooldown'); exit;
}

// registra voto pendente
registrarVotoPendente($account, $site, $_SERVER['REMOTE_ADDR'], $cfg['reward']);

// redireciona para a lista (URL e parâmetros VARIAM por lista)
$url = str_replace('{USER}', urlencode($account), $cfg['vote_url']);
header("Location: {$url}");

O vote_url para o Gtop100, por exemplo, costuma seguir o padrão de página do servidor com um parâmetro de incentivo (pingUsername). No XtremeTop, o casamento normalmente é por IP. Consulte a documentação de cada lista para os parâmetros exatos — eles mudam com o tempo.

Passo a passo: o callback (postback)

Este é o coração do sistema. A lista faz uma requisição ao seu callback quando o voto é válido. O formato varia bastante:

  • Gtop100 normalmente envia um POST com campos como Successful (1 = sucesso, 0 = falha), pingUsername (o identificador que você mandou), pingIP e um VoteID, além de uma verificação por chave.
  • XtremeTop100 costuma fazer um GET simples no seu callback passando o IP do votante, e você deve casar esse IP com o voto pendente mais recente.

O padrão de código, porém, é sempre o mesmo: valide, case, credite idempotente, responda.

<?php
// callback do Gtop100 (exemplo — campos variam)
$sucesso = $_POST['Successful'] ?? '0';
$user    = $_POST['pingUsername'] ?? '';
$ip      = $_POST['pingIP'] ?? $_SERVER['REMOTE_ADDR'];

// 1. validar origem: chave secreta e/ou IP do servidor da lista
if (!validarChaveSecreta('gtop100', $_POST)) {
    http_response_code(403); exit('invalid');
}

if ($sucesso === '1') {
    // 2. encontrar o voto pendente daquele jogador/lista
    $voto = buscarVotoPendente($user, 'gtop100');
    if ($voto) {
        creditarVoto($voto['id']);   // idempotente
    }
}
echo 'ok';   // muitas listas esperam uma resposta específica

Repare que o callback não confia no navegador do jogador — a requisição vem do servidor da lista. Mesmo assim, valide a chave secreta e, se possível, restrinja por faixa de IP da lista, porque um atacante pode tentar chamar seu callback diretamente para forjar votos.

Creditação idempotente da recompensa

A função de creditação deve garantir que o mesmo voto pendente não vire moeda duas vezes. Use a transição de status como trava:

<?php
function creditarVoto(int $voteId): void
{
    global $siteDb, $gameDb;

    // trava: só credita se ainda estiver 'pending'
    $upd = $siteDb->prepare(
        "UPDATE votes SET status='confirmed', confirmed_at=NOW()
         WHERE id=? AND status='pending'"
    );
    $upd->execute([$voteId]);
    if ($upd->rowCount() === 0) return;   // já creditado

    $v = /* buscar account e reward do voto */;

    // credita no banco do JOGO (tabela/coluna VARIAM por versão)
    $gameDb->prepare(
        "UPDATE MEMB_INFO SET WCoin = WCoin + ? WHERE memb___id = ?"
    )->execute([$v['reward'], $v['account']]);
}

Se o callback for reenviado (algumas listas repetem em caso de timeout), o WHERE status='pending' garante crédito único. A coluna WCoin na MEMB_INFO é o caso típico de Season 6; sua versão pode usar Cash, uma tabela de pontos própria ou um sistema de créditos VIP. Varia por versão — confirme antes.

Anti-fraude: cooldown, IP e chave secreta

Vote4Coins é um ímã de abuso. Reforce três barreiras:

  1. Cooldown por conta e lista: respeite o intervalo oficial da lista (12 ou 24 h). Bloqueie novo voto pendente antes desse prazo.
  2. Controle por IP: registre o IP e limite votos por IP no período, dificultando multi-contas do mesmo jogador.
  3. Validação do callback: chave secreta obrigatória e, quando possível, verificação do IP de origem do servidor da lista. Nunca aceite um callback só porque ele "parece" certo.
<?php
function emCooldown(string $acc, string $site, int $horas): bool {
    global $siteDb;
    $q = $siteDb->prepare(
        "SELECT 1 FROM votes
         WHERE account=? AND site=? AND status='confirmed'
           AND created_at > (NOW() - INTERVAL ? HOUR) LIMIT 1"
    );
    $q->execute([$acc, $site, $horas]);
    return (bool)$q->fetch();
}

Página de votação para o jogador

No painel, mostre cada lista com um botão "Votar" e o tempo restante de cooldown. Um exemplo de estrutura para renderizar dinamicamente:

const sites = [
  { site: "gtop100",   nome: "Gtop100",    reward: 200, cooldownRestante: 0 },
  { site: "xtremetop", nome: "XtremeTop100", reward: 150, cooldownRestante: 3600 },
];
// desabilite o botão enquanto cooldownRestante > 0 e exiba contador regressivo

Deixe claro para o jogador quanto ele ganha por voto e o intervalo — transparência reduz tickets de suporte. Se você está montando toda a estrutura do servidor, o Vote4Coins é apenas um dos módulos web; veja o guia geral de como criar um servidor de MU Online para entender onde ele se encaixa.

Erros comuns e soluções

SintomaCausa provávelSolução
Jogador votou mas não recebeuCallback não configurado ou URL errada na listaCadastre a URL de postback correta no painel da lista
Recompensa creditada sem votarCreditou no clique, não no callbackSó credite no callback confirmado (Successful=1)
Voto creditado em dobroFalta de idempotênciaUse UPDATE ... WHERE status='pending' como trava
Callback rejeitado (403)Chave secreta divergenteReconfirme a secret key no painel da lista e no vote_sites
Jogador vota várias vezes seguidasCooldown não aplicadoCheque cooldown por conta e IP antes do redirecionamento
Callback forjado por terceirosSem validação de origemValide chave secreta e restrinja IP de origem da lista

Segurança e boas práticas

  • Nunca exponha a secret key da lista no front-end ou no Git.
  • Trate o callback como entrada não confiável até validar chave e origem.
  • Registre logs de callbacks recebidos (payload + IP) para auditar fraudes.
  • Casar por pingUsername é mais confiável que casar por IP puro, quando a lista permite.
  • Se um jogador reclamar de voto não pago, cheque primeiro se a lista realmente enviou o callback — muitas vezes o CAPTCHA falhou do lado dele.
  • Limite a recompensa total diária por conta para conter abuso mesmo com múltiplas listas.

Checklist de lançamento

  • Servidor cadastrado em cada lista com Site ID e secret key salvos
  • Tabelas votes e vote_sites criadas
  • URL de callback configurada em cada lista, com HTTPS
  • Validação de chave secreta implementada em cada handler
  • Creditação idempotente testada (callback duplicado não paga duas vezes)
  • Cooldown por conta e por IP funcionando
  • Nome real da tabela/coluna de moeda do game DB confirmado para sua versão
  • Página de votação com contador de cooldown
  • Logs de callback habilitados para auditoria
  • Teste ponta a ponta com um voto real em cada lista

Com esse sistema você transforma cada jogador ativo em um divulgador diário do servidor, sobe nos rankings de forma orgânica e ainda dá uma recompensa justa em troca — tudo de forma automática, segura e à prova de quem tenta burlar o clique de votar.

Perguntas frequentes

O que é Vote4Coins no MU Online?

É um sistema que recompensa jogadores com moedas do jogo (WCoin, créditos ou pontos) sempre que eles votam no seu servidor em sites de ranking como Gtop100 e XtremeTop, aumentando sua posição nas listas e a divulgação.

Como o site de votação avisa que o voto foi válido?

Através de um callback (também chamado postback ou pingback): quando o voto é confirmado, a lista faz uma requisição HTTP para uma URL do seu site, informando o identificador do jogador. Só nesse momento a recompensa deve ser creditada.

Por que não devo creditar assim que o jogador clica em votar?

Porque o clique não garante voto válido. O jogador pode fechar a página, o CAPTCHA pode falhar ou ele pode votar de um IP já usado. Somente o callback confirmado pela lista garante que o voto contou.

Como impedir que um jogador vote várias vezes seguidas?

Combine o cooldown oficial da lista (geralmente 12 ou 24 horas) com um registro próprio de votos por conta e por IP, além de validar o callback pela chave secreta e pelo IP de origem da lista.

Posso usar mais de uma lista de votação ao mesmo tempo?

Sim, e é recomendado. Cada lista tem seu próprio callback e cooldown. Basta criar um handler por lista e uma tabela unificada de votos para controlar recompensas e evitar duplicidade.

BR
Editor de eventos, mapas e itens

Bruno é especialista em eventos, mapas, bosses e economia de itens do MU Online. Documenta cada detalhe com base em jogo real.

Continue lendo

Artigos relacionados