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.
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.
- O jogador logado clica em "Votar no Gtop100" no seu site.
- Seu backend registra um voto pendente e redireciona o jogador para a URL da lista, embutindo um identificador (geralmente o IP ou um
pingUsernamecom o login do jogador). - O jogador resolve o CAPTCHA e confirma o voto na lista.
- 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.
- Seu callback valida a origem e a chave secreta, encontra o jogador pelo identificador e credita a recompensa de forma idempotente.
- O jogador volta ao site e vê o saldo atualizado; o cooldown começa a contar.
| Etapa | Quem executa | Confia para creditar? |
|---|---|---|
| Clique em "Votar" | Jogador | Não |
| Redirecionamento | Seu backend | Não |
| Confirmação na lista | Jogador + lista | Não (ainda) |
| Callback/postback | Servidor da lista | Sim, após validar |
| Creditação | Seu 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),pingIPe umVoteID, 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:
- Cooldown por conta e lista: respeite o intervalo oficial da lista (12 ou 24 h). Bloqueie novo voto pendente antes desse prazo.
- Controle por IP: registre o IP e limite votos por IP no período, dificultando multi-contas do mesmo jogador.
- 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
| Sintoma | Causa provável | Solução |
|---|---|---|
| Jogador votou mas não recebeu | Callback não configurado ou URL errada na lista | Cadastre a URL de postback correta no painel da lista |
| Recompensa creditada sem votar | Creditou no clique, não no callback | Só credite no callback confirmado (Successful=1) |
| Voto creditado em dobro | Falta de idempotência | Use UPDATE ... WHERE status='pending' como trava |
| Callback rejeitado (403) | Chave secreta divergente | Reconfirme a secret key no painel da lista e no vote_sites |
| Jogador vota várias vezes seguidas | Cooldown não aplicado | Cheque cooldown por conta e IP antes do redirecionamento |
| Callback forjado por terceiros | Sem validação de origem | Valide 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
votesevote_sitescriadas - 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.