Pedir orçamento
Segurança absoluta e infraestrutura de alta performance para MuOnline
aceitando novos projetosBRT --:--:--

// kezor.dev: desenvolvimento de sistemas para servidores de MuOnline

Do código zero ao servidor definitivo

A infraestrutura que o seu projeto de MuOnline merece.

Soluções de ponta a ponta: sites premium, launchers com auto-update em tempo real, sistemas anti-cheat avançados e estabilidade garantida para o seu lançamento.

99,98%uptime médio
140+servidores entregues
0dupes após auditoria
+128 linhas · build ok
● GameServer online
mu-server · kezor
ResetSystem.cppProtocol.cppconfig.ini
TERMINALOUTPUTPROBLEMS 0
⎇ mainC++Ln 1, Col 1UTF-8 · CRLF
01. ls ~/servicos

Cada camada do servidor, escrita por quem entende o código.

~/servicos7 pastas
~/servicos/gameserver/

Sistemas no GameServer

Onde o jogo acontece. Escrevo e corrijo os sistemas que rodam no servidor: comandos, eventos, drops, combate e regras customizadas, com validação em cada ação do jogador.

C++ProtocoloEventosComandos
VipSystem.cppC++
bool CVipSystem::ApplyBonus(LPOBJ lpObj, int64_t& exp)
{
    const auto vip = m_Accounts.Find(lpObj->AccountID);
    if (!vip || vip->Expired(time(nullptr)))
        return false;

    exp += exp * vip->ExpBonus / 100;
    return true;
}
~/servicos/client/

Cliente e main.exe

Tudo que o jogador vê. Interfaces novas, janelas, itens, asas e efeitos visuais exigem código no cliente, sincronizado com o servidor.

C++HooksDLLItem.bmd
Hooks.cppC++
// exemplo: desvio de chamadas para a interface nova
void InitHooks()
{
    SetCompleteHook(0xE8, ADDR_DRAW_INTERFACE, &DrawInterfaceEx);
    SetCompleteHook(0xE9, ADDR_ITEM_TOOLTIP,  &ItemTooltipEx);
    SetByte(ADDR_MAX_LEVEL_CHECK, 0xEB);   // remove limite antigo
}
~/servicos/launcher/

Launcher com auto-update

A porta de entrada. Baixa só o que mudou, confere a integridade de cada arquivo e libera o jogo com a proteção já carregada.

C# .NETSHA-256Patch diferencialCDN
PatchService.csC#
var pending = remote.Files
    .Where(f => !File.Exists(Path.Combine(root, f.Path))
             || Hash.Sha256(Path.Combine(root, f.Path)) != f.Hash)
    .OrderBy(f => f.Priority)      // main.exe e DLLs primeiro
    .ToList();

await downloader.RunAsync(pending, progress, ct);
~/servicos/antihack/

Anti-hack e segurança

Proteção em user-mode e kernel contra injeção de memória, speed hack e manipulação de pacotes, com banimento por HWID e trilha de evidências.

C++KernelHWIDHeurística
Guard.cppC++
bool CGuard::ScanModules()
{
    for (const auto& mod : EnumerateModules(GetCurrentProcess()))
    {
        if (!m_Whitelist.contains(Hash(mod.path)))
            return Report(Detect::InjectedModule, mod.path);
    }
    return true;
}
~/servicos/web/

Site e painéis

A vitrine e o caixa do servidor. Site rápido, User CP e Admin CP completos, pagamentos com crédito automático e rankings lidos direto do banco.

PHPNode.jsPIXUser CPAdmin CP
pix.webhook.tsTS
app.post("/webhooks/pix", verifySignature, async (req, res) => {
  await db.transaction(async (trx) => {
    const pedido = await trx("Pedidos")
      .where({ txid: req.body.txid, status: "pendente" })
      .forUpdate().first();
    if (!pedido) return;              // já processado
    await trx("CashShopData").where({ AccountID: pedido.conta })
      .increment("WCoinC", pedido.moedas);
    await trx("Pedidos").where({ id: pedido.id }).update({ status: "pago" });
  });
  res.sendStatus(200);
});
~/servicos/database/

Banco SQL Server

Os bancos MuOnline e Me_MuOnline guardam anos de progresso. Índices certos deixam ranking e reset instantâneos, e backup testado separa um susto de um desastre.

T-SQLÍndicesJobsBackup
KZ_Ranking.sqlSQL
CREATE OR ALTER PROCEDURE dbo.KZ_RankingResets @Top INT = 100
AS
    SELECT TOP (@Top) Name, cLevel, ResetCount, Class
    FROM dbo.Character
    WHERE CtlCode = 0
    ORDER BY ResetCount DESC, cLevel DESC;
GO
CREATE INDEX IX_Rank ON dbo.Character (ResetCount DESC, cLevel DESC)
    INCLUDE (Class) WHERE CtlCode = 0;
~/servicos/infra/

VPS, rede e DDoS

Servidor dimensionado para o público esperado, portas mínimas expostas, proteção contra DDoS e monitoramento com alerta antes do jogador perceber.

Windows ServerFirewallAnti-DDoSMonitoramento
firewall.confCONF
# exemplo de regras: só o necessário exposto
allow tcp 44405        # ConnectServer
allow tcp 55901-55905  # GameServers
allow tcp 443          # site
deny  tcp 1433         # SQL Server nunca público
limit conn 8 per ip    # anti-flood de conexões
~/servicos/gameserver/README.md
# README.md

Sistemas no GameServer

Onde o jogo acontece. Escrevo e corrijo os sistemas que rodam no servidor: comandos, eventos, drops, combate e regras customizadas, com validação em cada ação do jogador.

C++ProtocoloEventosComandos
  • Reset, VIP, quests, invasões e sistemas sob medida
  • Correção de dupes, crashes e vazamento de memória
  • Anti-flood de pacotes e validação de cada ação
VipSystem.cppC++
bool CVipSystem::ApplyBonus(LPOBJ lpObj, int64_t& exp)
{
    const auto vip = m_Accounts.Find(lpObj->AccountID);
    if (!vip || vip->Expired(time(nullptr)))
        return false;

    exp += exp * vip->ExpBonus / 100;
    return true;
}
02. kezor systems --list

Sistemas que eu desenvolvo para MuOnline.

Cada sistema é escrito nas camadas que ele precisa: regra no GameServer, gravação no SQL Server, interface no cliente e painel no site. É isso que impede dupe e gambiarra.

kz/reset-systemv3.2

Reset e Master Reset com custo progressivo e pontos por classe.

  • Custo em zen que cresce por reset
  • Pontos definidos por classe
  • Limite diário configurável
servidorsqlweb
$ kezor add reset-system
kz/invasion-eventsv2.4

Invasões e eventos programados por dia e horário, sem reiniciar o servidor.

  • Agenda em arquivo de configuração
  • Prêmios por evento
  • Aviso global e no Discord
servidor
$ kezor add invasion-events
kz/castle-siegev1.8

Cerco automatizado com fases, registro de guilds e prêmios ao dono do castelo.

  • Fases e registro automáticos
  • Impostos e prêmios configuráveis
  • Log completo de cada cerco
servidorsqlweb
$ kezor add castle-siege
kz/custom-itemsv4.0

Itens, asas e sets novos com opções e efeitos, cliente e servidor sincronizados.

  • Novas entradas no Item.bmd
  • Opções excelentes e sockets
  • Efeitos e tooltip no cliente
clienteservidor
$ kezor add custom-items
kz/cash-shopv2.9

Loja in-game com WCoin, pacotes e VIP com expiração automática.

  • Pacotes e promoções
  • VIP com bônus de exp e drop
  • Crédito instantâneo via PIX
clienteservidorsqlweb
$ kezor add cash-shop
kz/quest-enginev1.5

Missões em cadeia, NPCs customizados e janelas de diálogo no cliente.

  • Quests em cadeia
  • NPCs de troca e teleporte
  • Progresso salvo por personagem
clienteservidorsql
$ kezor add quest-engine
kz/offlevelv2.1

Personagem continua upando desconectado, com regras por mapa e por VIP.

  • Coleta automática configurável
  • Regras por mapa
  • Sem ocupar conexão real
servidor
$ kezor add offlevel
kz/class-balancev1.3

Fórmulas de dano e defesa por classe, separadas para PvP e PvE.

  • Tabelas por classe
  • Simulação antes de aplicar
  • Ajuste sem recompilar
servidor
$ kezor add class-balance
kz/audit-logsv3.0

Trilha de trade, drop raro e comando de GM, com busca por serial no Admin CP.

  • Rastreio de item por serial
  • Alerta de anomalia de drop
  • Busca rápida no painel
servidorsqlweb
$ kezor add audit-logs
kz/rankings-apiv2.2

Rankings de reset, guild, PvP e eventos servidos por API com cache.

  • Procedures com índice próprio
  • Cache com expiração
  • Endpoints para site e bot
sqlweb
$ kezor add rankings-api
kz/discord-botv1.6

Avisos de evento, status do servidor e alertas privados para a equipe de GM.

  • Avisos automáticos
  • Ranking por comando
  • Alertas de segurança
sqlweb
$ kezor add discord-bot
kz/anti-floodv2.7

Filtro de pacotes e conexões que derruba flood antes de chegar ao GameServer.

  • Limite de pacotes por segundo
  • Limite de conexões por IP
  • Bloqueio temporário automático
servidor
$ kezor add anti-flood
03. git log --grep="dupe"

Como um dupe de trade é encontrado e fechado.

Exemplo do método que uso em servidores com item duplicado: provar pelo log, entender pelo pacote e corrigir na origem.

01/03

Provar pelo log

O mesmo serial de Jewel of Bless aparece em dois personagens no mesmo segundo. Não é bug visual, é cópia real de item.

02/03

Entender pelo pacote

Na captura, o cliente manda a confirmação da troca duas vezes em 3 ms, e o servidor processa as duas sem travar a operação.

03/03

Corrigir na origem

A troca passa a ser atômica: os dois personagens ficam travados, os inventários são revalidados e a gravação acontece uma única vez.

01. Provar pelo log

O mesmo serial de Jewel of Bless aparece em dois personagens no mesmo segundo. Não é bug visual, é cópia real de item.

item.log
21:14:07 [TRADE] Akira -> Lyra Jewel of Bless serial=0x0004A1F321:14:07 [TRADE] Lyra -> Akira 10.000.000 zen21:14:07 [SAVE] Akira inventory ok21:14:07 [SAVE] Lyra inventory ok21:14:08 [ITEM] Akira possui Jewel of Bless serial=0x0004A1F321:14:08 [ITEM] Lyra possui Jewel of Bless serial=0x0004A1F321:14:09 [WARN] serial duplicado detectado (2 donos)
■ mesmo serial em dois inventáriosOs dois lados gravaram o inventário antes de a troca terminar.

02. Entender pelo pacote

Na captura, o cliente manda a confirmação da troca duas vezes em 3 ms, e o servidor processa as duas sem travar a operação.

packet.hex
offset 00 01 02 03 04 0500000000 C1 06 3C 01 00 00 |..<...|00000006 C1 06 3C 01 00 00 |..<...| t=0.000ms cliente -> servidor confirmar trocat=0.003ms cliente -> servidor confirmar troca repetido
■ tipo do pacote (C1)■ tamanho em bytes■ código de confirmação de troca (ilustrativo)

03. Corrigir na origem

A troca passa a ser atômica: os dois personagens ficam travados, os inventários são revalidados e a gravação acontece uma única vez.

TradeSystem.cpp
@@ -212,7 +212,12 @@ void CTrade::Confirm(LPOBJ a, LPOBJ b) if (!a->TradeOk || !b->TradeOk) return;+ std::scoped_lock lock(a->TradeMutex, b->TradeMutex);+ if (a->TradeState != TRADE_OPEN || b->TradeState != TRADE_OPEN)+ return; // confirmação repetida+ if (!Revalidate(a, b))+ return Cancel(a, b);- SaveInventory(a);- SaveInventory(b); Exchange(a, b);+ gDataServer.SaveTradeAtomic(a, b); // uma transação Close(a, b);
+6 -2 · testado com 10.000 trocas simultâneas sem duplicação
DataServer/logs/item_2026-10-14.log
item.logpacket.hexTradeSystem.cpp
21:14:07 [TRADE] Akira -> Lyra Jewel of Bless serial=0x0004A1F321:14:07 [TRADE] Lyra -> Akira 10.000.000 zen21:14:07 [SAVE] Akira inventory ok21:14:07 [SAVE] Lyra inventory ok21:14:08 [ITEM] Akira possui Jewel of Bless serial=0x0004A1F321:14:08 [ITEM] Lyra possui Jewel of Bless serial=0x0004A1F321:14:09 [WARN] serial duplicado detectado (2 donos)
■ mesmo serial em dois inventáriosOs dois lados gravaram o inventário antes de a troca terminar.
offset 00 01 02 03 04 0500000000 C1 06 3C 01 00 00 |..<...|00000006 C1 06 3C 01 00 00 |..<...| t=0.000ms cliente -> servidor confirmar trocat=0.003ms cliente -> servidor confirmar troca repetido
■ tipo do pacote (C1)■ tamanho em bytes■ código de confirmação de troca (ilustrativo)
@@ -212,7 +212,12 @@ void CTrade::Confirm(LPOBJ a, LPOBJ b) if (!a->TradeOk || !b->TradeOk) return;+ std::scoped_lock lock(a->TradeMutex, b->TradeMutex);+ if (a->TradeState != TRADE_OPEN || b->TradeState != TRADE_OPEN)+ return; // confirmação repetida+ if (!Revalidate(a, b))+ return Cancel(a, b);- SaveInventory(a);- SaveInventory(b); Exchange(a, b);+ gDataServer.SaveTradeAtomic(a, b); // uma transação Close(a, b);
+6 -2 · testado com 10.000 trocas simultâneas sem duplicação
04. cat compatibilidade.md

Da 0.97d à Season 20+, cada geração quebra de um jeito.

Arquivos antigos e novos têm problemas diferentes. Antes de escrever uma linha, identifico em qual geração o seu servidor está.

GERAÇÃOONDE COSTUMA QUEBRARO QUE EU FAÇORISCO SEM REVISÃO
Clássicas0.97d a Season 2Protocolo simples e fácil de manipular. Main.exe sem estrutura para interface nova. Arquivos base com dupes conhecidos.Validação extra no servidor para compensar o cliente, hooks para janelas modernas e auditoria dos dupes clássicos.alto
IntermediáriasSeason 3 a Season 6Arquivos de origem duvidosa com backdoor. Master Level e eventos pesando no GameServer. Muitas versões quebradas circulando.Varredura de backdoor no core e nas DLLs, otimização de memória e dos loops de evento, identidade própria em site e launcher.alto
ModernasSeason 8 a Season 12Cliente pesado, mais tabelas no banco e mais pontos de dupe. Balanceamento de classes mais delicado.Patch diferencial para atualizações grandes, procedures e índices revisados por tabela, simulação de dano antes de cada ajuste.médio
AtuaisSeason 13 a Season 20+Emuladores complexos e pouco documentados. Exigência alta de hardware e rede. Jogador compara com o oficial.Diagnóstico profundo do emulador, infraestrutura dimensionada com teste de carga real e acabamento de nível oficial.médio
05. git log --graph

Do diagnóstico ao Go-Live, um commit por fase.

Cada fase termina com uma entrega que você valida antes da próxima começar. Os testes rodam numa branch separada e só entram em produção quando passam.

a3f91c2v0.1main

feat(escopo): Arquitetura e planejamento

Diagnóstico técnico do projeto, escolha da season e dos arquivos base, dimensionamento da VPS e da proteção contra DDoS.

+escopo.md+214
+infra/vps.md+86
+cronograma.md+40
7be04d9v0.5main

feat(core): Desenvolvimento e blindagem

Sistemas no GameServer, site integrado ao banco, launcher e camadas de segurança no cliente e no servidor.

+GameServer/Systems/*+3.4k
+Launcher/*+1.2k
+Web/*+5.8k
c15e7a0test/stress

test(stress): Testes de estresse e homologação

Carga com clientes simulados, ataque ativo ao anti-hack, auditoria do site e dos pagamentos e teste de restauração de backup.

+tests/load.ps1+312
+relatorio-seguranca.md+128
~TradeSystem.cpp+6 -2
e902bb4v1.0.0main

release(go-live): Lançamento e suporte contínuo

Plantão em tempo real na inauguração, monitoramento de processos, banco e rede, e suporte dedicado depois do Go-Live.

+monitoramento/alertas.yml+64
+runbook-golive.md+152
06. README.md#faq

Perguntas que todo dono de servidor faz.

Você trabalha em cima dos meus arquivos atuais?

Sim. Começo com uma auditoria do emulador, do cliente e do banco que você já tem e digo o que dá para aproveitar e o que precisa ser reescrito. Migrar não significa jogar fora o que funciona.

Dá para migrar de season sem perder as contas?

Dá. Mapeio as tabelas entre a estrutura antiga e a nova, converto personagens, itens e WCoin com scripts T-SQL e valido tudo numa cópia do banco antes de tocar na produção.

O anti-hack funciona em qualquer season?

A proteção é adaptada ao main.exe de cada versão. Clientes antigos exigem mais validação do lado do servidor, porque o protocolo é mais simples. Clientes novos permitem verificações mais profundas no próprio cliente.

Recebo o código-fonte do que for desenvolvido?

Sistemas, site e painéis feitos sob medida são entregues com código-fonte, histórico no Git e documentação. O núcleo do anti-hack é licenciado, para que a proteção não vaze e continue funcionando.

Como funciona o crédito automático de moedas?

O site gera a cobrança PIX, o provedor avisa por webhook assinado e o sistema credita as moedas numa transação única. Se o aviso chegar duas vezes, o crédito não duplica.

E se o servidor cair na inauguração?

No Go-Live eu monitoro processos, banco e rede em tempo real. Os processos têm reinício automático e o plano de contingência é definido ainda no planejamento.

08. kezor orcamento --novo

Solicite seu orçamento.

O valor depende da season, do nível de proteção e do quanto site e launcher serão personalizados. Marque o que precisa e a mensagem sai pronta para enviar.

Módulos--modulos
Previsão de lançamento--prazo