Como Configurar Rate Limits e Ajustes de Taxa por Horário no MU
Aprenda a configurar rate limits dinâmicos e ajustes automáticos de EXP, drop e taxas por horário no seu servidor MU Online.
Rate limits e ajustes de taxa por horário são técnicas avançadas que permitem ao administrador do servidor MU Online criar picos de atividade planejados, recompensar jogadores nos horários de pico e equilibrar a economia do servidor de forma automática. Este guia cobre a implementação completa usando SQL Server (2008–2019) e o sistema de configuração do GameServer Season 6.
Conceito: Como o MU Online Processa Taxas
O MuServer lê as taxas base de dois lugares principais:
- GameServer/GameServer.ini — define os multiplicadores globais fixos de EXP, Drop e Jewel no momento de inicialização.
- Banco de dados (MuOnline) — algumas tabelas como
T_EventConfig,T_RateControl(em builds customizados) ouT_ServerInfopodem sobrescrever esses valores em runtime sem reiniciar o servidor.
A estratégia deste tutorial é manter o .ini com valores base conservadores e usar SQL Server Agent Jobs (ou Windows Task Scheduler) para injetar multiplicadores dinâmicos na tabela de configuração do banco, que o GameServer lê periodicamente.
Passo 1: Estrutura Base no GameServer.ini
Localize o arquivo principal de configuração:
GameServer/GameServer.ini
Defina os valores base que serão usados como referência mínima (fora do horário de bônus):
[GameServerInfo]
ExpRate=30
DropRate=30
MoneyDropRate=30
JewelDropRate=30
MasterExpRate=15
Passo 2: Criar a Tabela de Controle de Taxas no Banco
Conecte ao SQL Server Management Studio (SSMS) e execute no banco MuOnline:
USE MuOnline;
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE name = 'T_RateSchedule' AND type = 'U')
BEGIN
CREATE TABLE T_RateSchedule (
ScheduleID INT IDENTITY(1,1) PRIMARY KEY,
HoraInicio TINYINT NOT NULL, -- 0-23
HoraFim TINYINT NOT NULL, -- 0-23 (exclusivo)
DiaSemana TINYINT NOT NULL, -- 0=Todos, 1=Dom, 2=Seg... 7=Sab
MultExpRate DECIMAL(5,2) NOT NULL DEFAULT 1.00,
MultDropRate DECIMAL(5,2) NOT NULL DEFAULT 1.00,
MultJewelRate DECIMAL(5,2) NOT NULL DEFAULT 1.00,
MultMasterExp DECIMAL(5,2) NOT NULL DEFAULT 1.00,
Descricao VARCHAR(100) NULL,
Ativo BIT NOT NULL DEFAULT 1
);
END
GO
Insira os horários de bônus desejados:
-- Bônus de fim de semana (Sáb e Dom, dia inteiro) - EXP e Drop dobrados
INSERT INTO T_RateSchedule (HoraInicio, HoraFim, DiaSemana, MultExpRate, MultDropRate, MultJewelRate, MultMasterExp, Descricao)
VALUES (0, 23, 1, 2.00, 1.50, 1.50, 2.00, 'Bônus Domingo Completo');
INSERT INTO T_RateSchedule (HoraInicio, HoraFim, DiaSemana, MultExpRate, MultDropRate, MultJewelRate, MultMasterExp, Descricao)
VALUES (0, 23, 7, 2.00, 1.50, 1.50, 2.00, 'Bônus Sábado Completo');
-- Horário de pico (todos os dias, 20h-23h) - +50% EXP
INSERT INTO T_RateSchedule (HoraInicio, HoraFim, DiaSemana, MultExpRate, MultDropRate, MultJewelRate, MultMasterExp, Descricao)
VALUES (20, 23, 0, 1.50, 1.00, 1.00, 1.50, 'Happy Hour Noturno');
-- Madrugada (todos os dias, 00h-08h) - taxas reduzidas
INSERT INTO T_RateSchedule (HoraInicio, HoraFim, DiaSemana, MultExpRate, MultDropRate, MultJewelRate, MultMasterExp, Descricao)
VALUES (0, 8, 0, 0.80, 0.80, 0.80, 0.80, 'Taxa Madrugada Reduzida');
GO
Passo 3: Criar a Tabela de Estado Atual de Taxas
Esta tabela é lida pelo GameServer (ou por um web panel) para exibir as taxas vigentes:
USE MuOnline;
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE name = 'T_RateAtual' AND type = 'U')
BEGIN
CREATE TABLE T_RateAtual (
ID INT PRIMARY KEY DEFAULT 1,
ExpRateAtual INT NOT NULL DEFAULT 30,
DropRateAtual INT NOT NULL DEFAULT 30,
JewelRateAtual INT NOT NULL DEFAULT 30,
MasterExpAtual INT NOT NULL DEFAULT 15,
UltimaAtualizacao DATETIME NOT NULL DEFAULT GETDATE(),
FonteAplicada VARCHAR(100) NULL
);
-- Registro único (linha de estado global)
INSERT INTO T_RateAtual (ID, ExpRateAtual, DropRateAtual, JewelRateAtual, MasterExpAtual)
VALUES (1, 30, 30, 30, 15);
END
GO
Passo 4: Stored Procedure de Aplicação de Taxa
USE MuOnline;
GO
CREATE OR ALTER PROCEDURE sp_AplicarTaxaHoraria
AS
BEGIN
SET NOCOUNT ON;
DECLARE @HoraAtual TINYINT = DATEPART(HOUR, GETDATE());
DECLARE @DiaAtual TINYINT = DATEPART(WEEKDAY, GETDATE()); -- 1=Dom, 7=Sab
-- Taxas base (lidas do .ini via constantes aqui)
DECLARE @BaseExp INT = 30;
DECLARE @BaseDrop INT = 30;
DECLARE @BaseJewel INT = 30;
DECLARE @BaseMaster INT = 15;
-- Multiplicadores calculados (maior prioridade = regra mais específica)
DECLARE @MultExp DECIMAL(5,2) = 1.00;
DECLARE @MultDrop DECIMAL(5,2) = 1.00;
DECLARE @MultJewel DECIMAL(5,2) = 1.00;
DECLARE @MultMaster DECIMAL(5,2) = 1.00;
DECLARE @Fonte VARCHAR(100) = 'Padrão';
-- Seleciona a regra mais específica ativa para o momento atual
-- DiaSemana=0 é curinga; regras específicas por dia têm prioridade
SELECT TOP 1
@MultExp = MultExpRate,
@MultDrop = MultDropRate,
@MultJewel = MultJewelRate,
@MultMaster = MultMasterExp,
@Fonte = Descricao
FROM T_RateSchedule
WHERE Ativo = 1
AND @HoraAtual >= HoraInicio
AND @HoraAtual <= HoraFim
AND (DiaSemana = @DiaAtual OR DiaSemana = 0)
ORDER BY
CASE WHEN DiaSemana = @DiaAtual THEN 0 ELSE 1 END ASC, -- Específico primeiro
HoraFim - HoraInicio ASC; -- Menor janela = mais específico
-- Atualiza T_RateAtual com os valores calculados
UPDATE T_RateAtual
SET
ExpRateAtual = CAST(@BaseExp * @MultExp AS INT),
DropRateAtual = CAST(@BaseDrop * @MultDrop AS INT),
JewelRateAtual = CAST(@BaseJewel * @MultJewel AS INT),
MasterExpAtual = CAST(@BaseMaster * @MultMaster AS INT),
UltimaAtualizacao = GETDATE(),
FonteAplicada = @Fonte
WHERE ID = 1;
END;
GO
Teste a procedure manualmente:
EXEC sp_AplicarTaxaHoraria;
SELECT * FROM T_RateAtual;
Passo 5: Agendar Execução Automática via SQL Server Agent
No SSMS, navegue até: SQL Server Agent → Jobs → New Job
Ou execute via T-SQL:
USE msdb;
GO
EXEC sp_add_job
@job_name = N'MU_AtualizarTaxasHorarias';
EXEC sp_add_jobstep
@job_name = N'MU_AtualizarTaxasHorarias',
@step_name = N'Executar sp_AplicarTaxaHoraria',
@command = N'EXEC MuOnline.dbo.sp_AplicarTaxaHoraria',
@database_name = N'MuOnline';
-- Executa a cada 15 minutos
EXEC sp_add_schedule
@schedule_name = N'A_Cada_15min',
@freq_type = 4, -- Diário
@freq_interval = 1,
@freq_subday_type = 4, -- Minutos
@freq_subday_interval = 15;
EXEC sp_attach_schedule
@job_name = N'MU_AtualizarTaxasHorarias',
@schedule_name = N'A_Cada_15min';
EXEC sp_add_jobserver
@job_name = N'MU_AtualizarTaxasHorarias';
GO
atualizar_taxas.bat em C:\MuServer\Scripts\ com o conteúdo: sqlcmd -S .\SQLEXPRESS -d MuOnline -E -Q "EXEC dbo.sp_AplicarTaxaHoraria" e agende no Agendador de Tarefas do Windows para rodar a cada 15 minutos.Passo 6: Integrar com o GameServer (Rate Limit Real-Time)
Para que o GameServer aplique as taxas do banco sem reiniciar, alguns builds S6 suportam comandos GM via socket. Use o comando de console do GameServer:
/setexp [valor]
/setdrop [valor]
Automatize via um script batch que lê o T_RateAtual e envia os comandos:
@echo off
REM C:\MuServer\Scripts\sync_rates.bat
FOR /F "tokens=1" %%A IN ('sqlcmd -S .\MSSQLSERVER -d MuOnline -E -h-1 -Q "SET NOCOUNT ON; SELECT ExpRateAtual FROM T_RateAtual WHERE ID=1"') DO SET EXP=%%A
FOR /F "tokens=1" %%A IN ('sqlcmd -S .\MSSQLSERVER -d MuOnline -E -h-1 -Q "SET NOCOUNT ON; SELECT DropRateAtual FROM T_RateAtual WHERE ID=1"') DO SET DROP=%%A
echo Taxa EXP atual: %EXP%
echo Taxa DROP atual: %DROP%
REM Enviar para console do GameServer via named pipe ou ferramenta admin
REM (implementação varia por build - consulte a documentação do seu MuServer)
Passo 7: Rate Limiting de Conexões (ConnectServer)
Além das taxas de EXP/Drop, limite o número de conexões simultâneas no arquivo:
ConnectServer/ConnectServer.ini
[ServerInfo]
MaxConnections=500
MaxConnectionsPerIP=3
ConnectionTimeout=30
LoginRateLimit=5
; LoginRateLimit = máximo de tentativas de login por IP em 60 segundos
Para rate limiting de pacotes suspeitos, edite:
GameServer/GameServer.ini
[AntiHack]
PacketFloodLimit=100
; Máximo de pacotes por segundo por conexão antes de desconectar
PacketFloodAction=1
; 0=Log apenas, 1=Kick, 2=Ban temporário
BanDuration=30
; Duração do ban temporário em minutos
Verificação e Troubleshooting
Verificar taxa atual aplicada:
SELECT
ExpRateAtual,
DropRateAtual,
JewelRateAtual,
MasterExpAtual,
UltimaAtualizacao,
FonteAplicada
FROM MuOnline.dbo.T_RateAtual
WHERE ID = 1;
Verificar histórico de execuções do Job:
SELECT
j.name AS JobName,
h.run_date,
h.run_time,
h.run_status, -- 1=Sucesso, 0=Falha
h.message
FROM msdb.dbo.sysjobhistory h
JOIN msdb.dbo.sysjobs j ON h.job_id = j.job_id
WHERE j.name = 'MU_AtualizarTaxasHorarias'
ORDER BY h.run_date DESC, h.run_time DESC;
T_RateSchedule antes de alterar regras de horário. Uma configuração incorreta pode aplicar taxas zeradas (MultExpRate=0), impedindo a progressão de todos os jogadores no servidor.Resetar para taxas padrão emergencialmente:
UPDATE MuOnline.dbo.T_RateAtual
SET ExpRateAtual=30, DropRateAtual=30, JewelRateAtual=30, MasterExpAtual=15,
FonteAplicada='Reset Manual de Emergência', UltimaAtualizacao=GETDATE()
WHERE ID=1;
Perguntas frequentes
Posso aplicar taxas diferentes para VIP e não-VIP no mesmo horário?
Sim. Utilize a tabela T_UserProperty ou T_AccountCharacter para filtrar por conta VIP. Crie uma stored procedure que verifica o campo VipLevel antes de aplicar o multiplicador, ex: IF @VipLevel >= 1 SET @ExpMult = @ExpMult * 1.5.
O SQL Agent está desabilitado no meu SQL Server Express, como agendar?
O SQL Server Express não possui SQL Agent. Utilize o Agendador de Tarefas do Windows (Task Scheduler) para executar um script .bat que chama SQLCMD, ex: sqlcmd -S localhost -d MuOnline -Q \"EXEC sp_AplicarTaxaHoraria\" -E a cada 30 minutos.
Como evitar conflito entre o rate limit do GameServer.ini e as taxas do banco?
As taxas do GameServer.ini são multiplicadores base. As stored procedures do banco aplicam um segundo multiplicador em cima. Mantenha o .ini com ExpRate=1 e gerencie tudo pelo banco para evitar dupla multiplicação acidental.
É possível configurar taxas por mapa específico além do horário?
Sim. A tabela T_MapConfig (em alguns builds de S6) ou a lógica customizada na stored procedure pode checar o MapNumber e aplicar taxas diferentes. Combine com DATEPART(HOUR, GETDATE()) para taxas por mapa E horário simultaneamente.