Como colocar VIP e bônus de criação de conta no servidor de MU Online
Implemente um sistema de VIP no servidor de MU Online — tabelas SQL, GameServer.ini, bônus de boas-vindas, EXP aumentado para VIPs, e integração com o site.
O sistema de VIP dá a jogadores que apoiam o servidor bônus de jogo — EXP e Drop aumentados, itens de boas-vindas, acesso a mapas exclusivos, etc. A implementação envolve o banco de dados SQL e o GameServer.ini.
O sistema de VIP dá a jogadores que apoiam o servidor bônus de jogo — EXP e Drop aumentados, itens de boas-vindas, acesso a mapas exclusivos, etc. A implementação envolve o banco de dados SQL e o GameServer.ini.
Como o sistema de VIP funciona no MuServer
1. Jogador ativa VIP (via site ou GM command)
│
2. Uma linha é inserida/atualizada na tabela MEMB_VIP
com data de início e de expiração
│
3. Na próxima sessão do jogador, o GameServer
verifica se o VIP está ativo e aplica os bônus
│
4. Bônus de EXP e Drop são aplicados automaticamente
(configurados no GameServer.ini)
Passo 1 — Estrutura da tabela de VIP no banco
Algumas distribuições já incluem a tabela de VIP. Se não tiver, crie:
USE MuOnline;
GO
-- Tabela de controle de VIP
CREATE TABLE MEMB_VIP (
memb___id VARCHAR(10) NOT NULL, -- login da conta (FK para MEMB_INFO)
vip_type TINYINT NOT NULL DEFAULT 1, -- tipo de VIP: 1=Bronze, 2=Prata, 3=Ouro
start_date DATETIME NOT NULL DEFAULT GETDATE(),
end_date DATETIME NOT NULL, -- data de expiração
activated TINYINT NOT NULL DEFAULT 1, -- 1=ativo, 0=expirado
CONSTRAINT PK_MEMB_VIP PRIMARY KEY (memb___id)
);
GO
-- Índice para consultas rápidas por data
CREATE INDEX IX_VIP_EndDate ON MEMB_VIP (end_date);
GO
Alternativa — coluna na MEMB_INFO
Algumas distribuições adicionam colunas diretamente na MEMB_INFO:
ALTER TABLE MEMB_INFO ADD vip_type TINYINT DEFAULT 0;
ALTER TABLE MEMB_INFO ADD vip_end DATETIME NULL;
GO
Passo 2 — Ativar VIP para uma conta
-- Dar VIP por 30 dias
MERGE MEMB_VIP AS target
USING (VALUES ('nomeConta', 1, GETDATE(), DATEADD(DAY, 30, GETDATE())))
AS source (memb___id, vip_type, start_date, end_date)
ON target.memb___id = source.memb___id
WHEN MATCHED THEN
UPDATE SET
end_date = DATEADD(DAY, 30, CASE WHEN target.end_date > GETDATE()
THEN target.end_date -- estende se ainda ativo
ELSE GETDATE() END),
vip_type = source.vip_type,
activated = 1
WHEN NOT MATCHED THEN
INSERT (memb___id, vip_type, start_date, end_date)
VALUES (source.memb___id, source.vip_type, source.start_date, source.end_date);
GO
Versão simplificada (INSERT ou UPDATE separados)
-- Verificar se já tem VIP
IF EXISTS (SELECT 1 FROM MEMB_VIP WHERE memb___id = 'nomeConta')
BEGIN
-- Estender VIP existente
UPDATE MEMB_VIP
SET end_date = DATEADD(DAY, 30,
CASE WHEN end_date > GETDATE() THEN end_date ELSE GETDATE() END),
activated = 1
WHERE memb___id = 'nomeConta';
END
ELSE
BEGIN
-- Novo VIP
INSERT INTO MEMB_VIP (memb___id, vip_type, start_date, end_date)
VALUES ('nomeConta', 1, GETDATE(), DATEADD(DAY, 30, GETDATE()));
END
GO
Passo 3 — Configurar bônus VIP no GameServer.ini
; ===== SISTEMA VIP =====
[VIP_SYSTEM]
Enable = 1 ; habilitar sistema de VIP
; VIP Tipo 1 (Bronze)
VIP1_ExpRate = 2 ; 2x de bônus de EXP (multiplicado pelo ExpRate base)
VIP1_DropRate = 2 ; 2x de bônus de Drop
VIP1_ZenRate = 2 ; 2x de zen dropado
; VIP Tipo 2 (Prata)
VIP2_ExpRate = 3
VIP2_DropRate = 3
VIP2_ZenRate = 3
; VIP Tipo 3 (Ouro)
VIP3_ExpRate = 5
VIP3_DropRate = 5
VIP3_ZenRate = 5
; Tempo de verificação de VIP (em segundos)
VipCheckInterval = 60 ; verifica a cada 60 segundos se o VIP expirou
; Notificação ao expirar
VipExpiryNotify = 1 ; enviar mensagem ao jogador quando VIP expirar
VIP_EXP_RATE, outras VipExpBonus, outras nem têm essa seção e usam um sistema diferente. Leia o GameServer.ini da sua distribuição para ver quais parâmetros de VIP estão disponíveis.Passo 4 — Bônus de boas-vindas ao criar conta
O "welcome bonus" (bônus ao criar conta) geralmente é implementado no sistema de registro do site, não no GameServer. O site insere um item inicial no inventário do personagem ou dá zen ao criar o primeiro personagem:
<?php
// No script de criação de conta (PHP), após criar o personagem:
function darBonasVindas($pdoSqlServer, $nomePersonagem) {
// Dar zen inicial (via SQL Server PDO)
$stmt = $pdoSqlServer->prepare(
"UPDATE Character SET Money = 5000000 WHERE Name = ?"
);
$stmt->execute([$nomePersonagem]);
// Log do bônus
error_log("Bônus de boas-vindas dado para: $nomePersonagem");
}
Bônus via SQL (inserção direta)
-- Dar zen ao primeiro personagem criado de uma conta
UPDATE Character
SET Money = 5000000
WHERE AccountID = 'nomeConta'
AND Name IN (
SELECT TOP 1 Name
FROM Character
WHERE AccountID = 'nomeConta'
ORDER BY CreateDate ASC
);
Bônus de itens via SQL (requer conhecimento do formato binário)
O inventário no MuServer é armazenado como dados binários — adicionar itens diretamente via SQL é complexo e depende do formato da distribuição. Na maioria dos casos, use um GM command para dar o item ao jogador, ou um painel administrativo do site.
-- Alguns sistemas de site têm tabela de pending items:
-- O GameServer lê esta tabela na próxima sessão e dá o item ao jogador
INSERT INTO PendingItems (AccountID, ItemGroup, ItemID, ItemLevel, Options)
VALUES ('nomeConta', 0, 5, 10, 0x00); -- formato varia por distribuição
Passo 5 — Verificar e gerenciar VIPs via SQL
Listar VIPs ativos
SELECT v.memb___id, v.vip_type,
DATEDIFF(DAY, GETDATE(), v.end_date) AS DiasRestantes
FROM MEMB_VIP v
WHERE v.end_date > GETDATE() AND v.activated = 1
ORDER BY v.end_date ASC;
Limpar VIPs expirados
UPDATE MEMB_VIP
SET activated = 0
WHERE end_date < GETDATE() AND activated = 1;
Ver histórico de VIP de uma conta
SELECT memb___id, vip_type, start_date, end_date,
CASE WHEN end_date > GETDATE() THEN 'ATIVO' ELSE 'EXPIRADO' END AS Status
FROM MEMB_VIP
WHERE memb___id = 'nomeConta'
ORDER BY start_date DESC;
Remover VIP de uma conta
UPDATE MEMB_VIP
SET activated = 0, end_date = GETDATE()
WHERE memb___id = 'nomeConta';
Passo 6 — Integração com o site (PHP)
O sistema de site precisa dar VIP automaticamente após confirmação de doação/pagamento:
<?php
// dar-vip.php — chamado após confirmação de pagamento
function ativarVIP(PDO $dbMu, string $conta, int $dias, int $tipo): bool {
// Verificar se a conta existe
$check = $dbMu->prepare("SELECT COUNT(*) FROM MEMB_INFO WHERE memb___id = ?");
$check->execute([$conta]);
if ($check->fetchColumn() == 0) {
return false; // conta não existe
}
// Verificar VIP existente
$existing = $dbMu->prepare("SELECT end_date FROM MEMB_VIP WHERE memb___id = ?");
$existing->execute([$conta]);
$row = $existing->fetch();
if ($row) {
// Estender VIP
$baseDate = ($row['end_date'] > date('Y-m-d H:i:s')) ? $row['end_date'] : date('Y-m-d H:i:s');
$newEnd = date('Y-m-d H:i:s', strtotime("+{$dias} days", strtotime($baseDate)));
$upd = $dbMu->prepare(
"UPDATE MEMB_VIP SET end_date = ?, vip_type = ?, activated = 1 WHERE memb___id = ?"
);
$upd->execute([$newEnd, $tipo, $conta]);
} else {
// Novo VIP
$end = date('Y-m-d H:i:s', strtotime("+{$dias} days"));
$ins = $dbMu->prepare(
"INSERT INTO MEMB_VIP (memb___id, vip_type, start_date, end_date) VALUES (?, ?, NOW(), ?)"
);
$ins->execute([$conta, $tipo, $end]);
}
return true;
}
Tipos de benefícios VIP que podem ser implementados
| Benefício | Implementação |
|---|---|
| EXP aumentado | VIP1_ExpRate no GameServer.ini |
| Drop aumentado | VIP1_DropRate no GameServer.ini |
| Zen extra | VIP1_ZenRate no GameServer.ini |
| Acesso a áreas exclusivas | Checar VIP no mapa específico no GameServer |
| Nicknames coloridos | Prefixo de cor no nome (depende da distribuição) |
| Slots extras de personagem | Coluna CharacterSlot na MEMB_INFO |
| Command exclusivo | Verificar ctl_code ou vip_type no handler do comando |
| Armazenamento expandido | Munic warehouse slots — requer modificação do servidor |
Tabela de exemplos de configuração por nível de VIP
| Nível | Preço sugerido | EXP bônus | Drop bônus | Duração |
|---|---|---|---|---|
| Bronze (1) | R$ 10 | +50% | +25% | 30 dias |
| Prata (2) | R$ 25 | +100% | +50% | 30 dias |
| Ouro (3) | R$ 50 | +200% | +100% | 30 dias |
Stored Procedure para automação
-- SP para ativar VIP (chamada pelo site ou trigger de pagamento)
CREATE PROCEDURE sp_AtivarVIP
@conta VARCHAR(10),
@tipo TINYINT = 1,
@dias INT = 30
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM MEMB_INFO WHERE memb___id = @conta)
BEGIN
RAISERROR('Conta não encontrada', 16, 1);
RETURN;
END;
IF EXISTS (SELECT 1 FROM MEMB_VIP WHERE memb___id = @conta)
BEGIN
UPDATE MEMB_VIP
SET end_date = DATEADD(DAY, @dias,
CASE WHEN end_date > GETDATE() THEN end_date ELSE GETDATE() END),
vip_type = @tipo,
activated = 1
WHERE memb___id = @conta;
END
ELSE
BEGIN
INSERT INTO MEMB_VIP (memb___id, vip_type, start_date, end_date)
VALUES (@conta, @tipo, GETDATE(), DATEADD(DAY, @dias, GETDATE()));
END;
END;
GO
-- Como usar:
EXEC sp_AtivarVIP 'nomeDaConta', 2, 30;
-- Ativa VIP tipo 2 (Prata) por 30 dias para 'nomeDaConta'
Perguntas frequentes
Preciso de código especial para VIP no MuServer?
Não — a maioria das distribuições já tem suporte a VIP embutido. O que você precisa configurar é a tabela de VIP no banco, a coluna na MEMB_INFO e os bônus no GameServer.ini.
VIP no MuServer afeta o drop e o EXP?
Sim — você configura multiplicadores de EXP e Drop separados para jogadores VIP no GameServer.ini. Quando o jogador tem status VIP ativo, o servidor aplica os bônus automaticamente.
Como integrar o VIP com um sistema de pagamento?
Isso depende do sistema de site do servidor. A integração geral envolve: receber confirmação de pagamento → inserir/atualizar a linha na tabela de VIP → o GameServer verifica a validade na próxima sessão.
Posso ter vários níveis de VIP?
Sim — você pode criar até 3 ou mais níveis (VIP Bronze/Prata/Ouro) com bônus diferentes, usando uma coluna de nível na tabela de VIP.