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

Como criar um sistema de indicação (referral) no MU Online

Implemente um sistema de indicação no site do seu servidor de MU Online, com links únicos, recompensas em Cash e proteção contra fraudes de auto-indicação.

GA Gabriel · Atualizado em 14 set 2025 · ⏱ 17 min de leitura
Resposta rápida

Um sistema de indicação — ou referral — transforma seus próprios jogadores no melhor canal de aquisição do servidor. A lógica é simples e poderosa: cada jogador recebe um link único; quando um amigo se cadastra por esse link e realmente começa a jogar, ambos ganham uma recompensa. O resultado é um c

Um sistema de indicação — ou referral — transforma seus próprios jogadores no melhor canal de aquisição do servidor. A lógica é simples e poderosa: cada jogador recebe um link único; quando um amigo se cadastra por esse link e realmente começa a jogar, ambos ganham uma recompensa. O resultado é um crescimento orgânico e barato, movido por quem já confia no servidor. Mas há um abismo entre a ideia e uma implementação que não seja imediatamente explorada por quem quer farmar recompensas com contas falsas. Este tutorial mostra como construir um sistema de referral no site do seu servidor de MU Online que seja ao mesmo tempo atraente para o jogador honesto e resistente à fraude, com links rastreáveis, liberação condicionada a engajamento real e crédito automático de Cash. Usaremos PHP e SQL Server como exemplo por serem o padrão da maioria dos servidores privados, mas a lógica se aplica a qualquer stack. Nomes de tabelas e colunas variam por versão e emulador, então trate cada query como esqueleto a adaptar.

Pré-requisitos

O sistema de indicação vive no site, então você precisa de um site funcional integrado ao banco do servidor. Se ainda não integrou site e jogo, comece pelo guia de como criar servidor de MU Online antes de seguir.

  • Site do servidor rodando em PHP 7.4+ com acesso ao banco de dados.
  • SQL Server com a tabela de contas do MU (frequentemente MEMB_INFO) acessível.
  • Sistema de contas/login já funcionando no site.
  • Uma coluna ou tabela onde o Cash (moeda do cash shop) do jogador é armazenado — o nome varia por versão (ex.: CashShopData, WCoinC, Credits).
  • Conhecimento básico de PHP, SQL e sessões de login.

Como o fluxo de indicação funciona

Antes do código, fixe o fluxo. Cada etapa existe para fechar uma brecha de fraude:

  1. O jogador logado acessa a página "Indique um amigo" e vê seu código de indicação único e o link pronto para copiar.
  2. Um novo visitante clica no link; o código fica gravado na sessão/cookie dele.
  3. Ao se cadastrar, a nova conta é vinculada ao indicador, com status pendente.
  4. O sistema monitora o progresso do indicado. Quando ele atinge uma meta real (ex.: nível 150 ou 3 dias jogados), o status vira liberado.
  5. Só então as recompensas são creditadas para os dois lados, e o vínculo é marcado como pago para nunca pagar duas vezes.

O ponto crítico é o passo 4: recompensa liberada no cadastro é convite à fraude. Recompensa liberada por engajamento real filtra 90% dos abusos.

Passo 1 — Estrutura de dados

Crie uma tabela dedicada para os referrals. Ela mantém o histórico auditável e separa a lógica de indicação das tabelas do jogo:

CREATE TABLE Referrals (
    Id            INT IDENTITY(1,1) PRIMARY KEY,
    ReferrerAcc   VARCHAR(20) NOT NULL,   -- conta que indicou
    ReferredAcc   VARCHAR(20) NOT NULL,   -- conta indicada
    ReferredIP    VARCHAR(45) NULL,
    Status        VARCHAR(10) NOT NULL DEFAULT 'pendente', -- pendente/liberado/pago
    CreatedAt     DATETIME NOT NULL DEFAULT GETDATE(),
    RewardedAt    DATETIME NULL,
    CONSTRAINT UQ_Referred UNIQUE (ReferredAcc) -- cada conta só é indicada uma vez
);

Gere o código de indicação a partir do próprio nome da conta (com um hash curto) ou armazene um código aleatório por conta. Para simplicidade, muitos servidores usam o próprio nome de usuário como código.

Passo 2 — Capturar o código na chegada

Quando alguém acessa o site com ?ref=CODIGO, grave esse código antes que ele se perca. Um cookie de longa duração cobre visitantes que não se cadastram na mesma sessão:

<?php
// incluir no topo do index.php do site
if (isset($_GET['ref']) && !isset($_COOKIE['ref_code'])) {
    $ref = preg_replace('/[^a-zA-Z0-9_]/', '', $_GET['ref']);
    if ($ref !== '') {
        // 30 dias de janela de atribuição
        setcookie('ref_code', $ref, time() + 60*60*24*30, '/');
    }
}

Note a sanitização: aceitamos apenas caracteres válidos de conta, o que já elimina tentativas de injeção pela URL.

Passo 3 — Vincular no cadastro

No processamento do cadastro, depois de criar a conta com sucesso, registre o vínculo — mas somente após as checagens antifraude:

<?php
function registrarReferral(PDO $db, string $novaConta, string $novoIP): void {
    if (empty($_COOKIE['ref_code'])) return;

    $ref = preg_replace('/[^a-zA-Z0-9_]/', '', $_COOKIE['ref_code']);
    if ($ref === '' || strcasecmp($ref, $novaConta) === 0) return; // auto-indicação

    // O indicador precisa existir de fato
    $stmt = $db->prepare("SELECT memb___id FROM MEMB_INFO WHERE memb___id = ?");
    $stmt->execute([$ref]);
    if (!$stmt->fetch()) return;

    // Bloqueia mesmo IP entre indicador e indicado
    $ipInd = $db->prepare("
        SELECT r.ReferredIP FROM Referrals r
        WHERE r.ReferrerAcc = ? AND r.ReferredIP = ?");
    $ipInd->execute([$ref, $novoIP]);
    if ($ipInd->fetch()) return; // já indicou alguém deste mesmo IP

    $ins = $db->prepare("
        INSERT INTO Referrals (ReferrerAcc, ReferredAcc, ReferredIP)
        VALUES (?, ?, ?)");
    $ins->execute([$ref, $novaConta, $novoIP]);
}

Passo 4 — Liberar a recompensa por engajamento

Este é o coração antifraude. Um script agendado (cron ou Agendador de Tarefas do Windows) roda periodicamente, verifica quais indicados atingiram a meta e libera as recompensas. A meta de exemplo é nível 150 em algum personagem da conta — ajuste o nome da tabela Character e a coluna de nível à sua versão:

<?php
// cron/liberar_referrals.php — rodar a cada 10 min
require 'db.php';

$pendentes = $db->query("
    SELECT Id, ReferrerAcc, ReferredAcc
    FROM Referrals WHERE Status = 'pendente'")->fetchAll(PDO::FETCH_ASSOC);

foreach ($pendentes as $r) {
    // O indicado alcançou a meta?
    $chk = $db->prepare("
        SELECT TOP 1 cLevel FROM Character
        WHERE AccountID = ? AND cLevel >= 150");
    $chk->execute([$r['ReferredAcc']]);

    if ($chk->fetch()) {
        creditarCash($db, $r['ReferrerAcc'], 200); // indicador
        creditarCash($db, $r['ReferredAcc'], 100);  // indicado
        $up = $db->prepare("
            UPDATE Referrals SET Status = 'pago', RewardedAt = GETDATE()
            WHERE Id = ?");
        $up->execute([$r['Id']]);
    }
}

function creditarCash(PDO $db, string $conta, int $valor): void {
    // Nome da coluna/tabela de Cash VARIA por versão
    $up = $db->prepare("
        UPDATE MEMB_INFO SET Credits = Credits + ? WHERE memb___id = ?");
    $up->execute([$valor, $conta]);
}

Repare que a recompensa só é creditada uma vez, porque o status vira pago na mesma transação lógica.

Passo 5 — Página do jogador

Dê ao jogador logado uma página que mostra o link e o histórico. É o que gera compartilhamento:

<?php
$conta = $_SESSION['username'];
$link  = "https://seusite.com/?ref=" . urlencode($conta);

$stats = $db->prepare("
    SELECT
      SUM(CASE WHEN Status = 'pago' THEN 1 ELSE 0 END) AS pagos,
      COUNT(*) AS total
    FROM Referrals WHERE ReferrerAcc = ?");
$stats->execute([$conta]);
$row = $stats->fetch(PDO::FETCH_ASSOC);
?>
<h2>Indique e ganhe</h2>
<input type="text" value="<?= htmlspecialchars($link) ?>" readonly onclick="this.select()">
<p>Amigos que já jogaram: <?= (int)$row['pagos'] ?> de <?= (int)$row['total'] ?> indicados</p>

Camadas de proteção antifraude

Nenhuma checagem isolada resolve. Combine várias e o custo de fraudar supera a recompensa:

CamadaO que verificaLimite
Meta de engajamentoNível/tempo mínimo do indicadoFiltra contas descartáveis
Bloqueio de auto-indicaçãoNome de conta igualImpede o caso mais óbvio
Comparação de IPMesmo IP entre as contasIP dinâmico e VPN driblam
HWID/hardwareMesma máquina (quando disponível)Depende de suporte do cliente
E-mail únicoMesmo e-mail nas duas contasSó se e-mail for obrigatório
Limite por indicadorMáximo de indicações por diaReduz farm em massa

Erros comuns e soluções

SintomaCausa provávelSolução
Recompensa dada em massa a contas fantasmaLiberação no cadastroCondicione à meta de engajamento no cron
Mesmo jogador ganha várias vezes pelo mesmo indicadoFalta de status "pago"Use a constraint única e marque como pago ao creditar
Cash não é creditadoNome da coluna erradoConfira o schema; a coluna de Cash varia por versão
Código ?ref= some antes do cadastroSem cookie de atribuiçãoGrave o código em cookie de 30 dias
Auto-indicação passaSó compara nomeCombine IP, HWID e e-mail além do nome
Cron não roda no WindowsSem tarefa agendadaCrie tarefa no Agendador para chamar o PHP via CLI

Boas práticas

Use sempre prepared statements — o exemplo acima nunca concatena entrada do usuário em SQL. Registre logs de cada liberação de recompensa para auditar disputas. Defina recompensas modestas o suficiente para não quebrar a economia do servidor, mas atraentes o bastante para motivar o compartilhamento; Cash é preferível a itens porque é trivial de creditar e reverter. E comunique as regras claramente na página de indicação: metas, prazos e o que caracteriza fraude passível de banimento.

Checklist de lançamento

  • Tabela Referrals criada com constraint de indicado único
  • Captura do código ?ref= via cookie de 30 dias
  • Vínculo criado no cadastro somente após checagens antifraude
  • Bloqueio de auto-indicação por nome, IP e e-mail
  • Cron/tarefa liberando recompensas por meta de engajamento
  • Crédito de Cash testado com o schema real do servidor
  • Página do jogador com link e histórico funcionando
  • Todas as queries usando prepared statements
  • Regras publicadas e recompensas balanceadas com a economia
  • Logs de liberação ativos para auditoria

Perguntas frequentes

Quando devo liberar a recompensa da indicação?

Nunca no cadastro. Libere só quando o indicado atingir uma meta real de engajamento, como um nível mínimo ou um tempo mínimo jogado, para evitar contas falsas criadas apenas pela recompensa.

Como impedir que a pessoa se auto-indique?

Compare IP, hardware/HWID quando disponível e e-mail entre indicador e indicado, e bloqueie recompensas quando coincidirem. Nenhuma checagem isolada é perfeita; combine várias.

Onde guardo o código de indicação?

Em uma coluna na tabela de contas ou em uma tabela própria de referrals. O ideal é uma tabela dedicada que registra indicador, indicado, status e data, mantendo o histórico auditável.

Posso dar recompensa em itens em vez de Cash?

Sim, mas Cash (moeda do cash shop) é mais simples e seguro de creditar via site. Entregar itens exige manipular o inventário no banco, o que é mais arriscado e varia muito por versão.

O sistema de referral funciona em qualquer versão de MU?

A lógica do site é independente da versão. O que muda é o nome das tabelas de conta e a forma de creditar Cash, que variam por emulador; adapte as queries ao seu schema.

GA
Editor de guias e builds

Gabriel cobre gameplay, builds de classes, PvP e progressão. Testa cada estratégia em servidor antes de publicar.

Continue lendo

Artigos relacionados