How to Configure Premium Account System on MU Online Server
Learn how to implement a Premium/VIP account system on your MU Online server using SQL Server, configuring benefits, duration, and web panel integration.
System Overview
A Premium account system lets you offer differentiated benefits to players — boosted experience rates, improved drop chances, access to exclusive events — all controlled directly through the SQL Server database and read by the GameServer at runtime.
This guide covers the full implementation: database structure, server configuration, web panel integration, and automated expiration.
Step 1 — Prepare the Database Structure
Connect to SQL Server Management Studio and select the MuOnline database.
1.1 — Add columns to the MEMB_INFO table:
USE MuOnline;
GO
ALTER TABLE MEMB_INFO
ADD premium_status TINYINT NOT NULL DEFAULT 0,
premium_tier TINYINT NOT NULL DEFAULT 0,
premium_expire DATETIME NULL,
premium_notes VARCHAR(100) NULL;
GO
premium_status: 0 = Normal, 1 = Premium activepremium_tier: 0 = no tier, 1 = Bronze, 2 = Silver, 3 = Goldpremium_expire: expiration date/time (NULL = no expiry)
1.2 — Create an activation log table:
CREATE TABLE MEMB_PREMIUM_LOG (
log_id INT IDENTITY(1,1) PRIMARY KEY,
memb_guid INT NOT NULL,
memb_name VARCHAR(10) NOT NULL,
tier TINYINT NOT NULL,
activated_by VARCHAR(50) NOT NULL,
activated_at DATETIME NOT NULL DEFAULT GETDATE(),
expire_at DATETIME NULL,
duration_days INT NOT NULL
);
GO
Step 2 — Create Management Stored Procedures
2.1 — Procedure to activate Premium:
CREATE PROCEDURE sp_ActivatePremium
@memb_name VARCHAR(10),
@tier TINYINT,
@duration_days INT,
@activated_by VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @memb_guid INT;
DECLARE @expire_date DATETIME;
SELECT @memb_guid = memb_guid
FROM MEMB_INFO
WHERE memb_name = @memb_name;
IF @memb_guid IS NULL
BEGIN
RAISERROR('Account not found: %s', 16, 1, @memb_name);
RETURN;
END
-- If account already has active Premium, extend from current expiry date
SET @expire_date = CASE
WHEN premium_status = 1 AND premium_expire > GETDATE()
THEN DATEADD(DAY, @duration_days, premium_expire)
ELSE
DATEADD(DAY, @duration_days, GETDATE())
END
FROM MEMB_INFO WHERE memb_guid = @memb_guid;
UPDATE MEMB_INFO
SET premium_status = 1,
premium_tier = @tier,
premium_expire = @expire_date
WHERE memb_guid = @memb_guid;
INSERT INTO MEMB_PREMIUM_LOG
(memb_guid, memb_name, tier, activated_by, expire_at, duration_days)
VALUES
(@memb_guid, @memb_name, @tier, @activated_by, @expire_date, @duration_days);
SELECT 'Premium activated successfully. Expires at: ' + CONVERT(VARCHAR, @expire_date, 120) AS result;
END;
GO
2.2 — Procedure to expire accounts automatically:
CREATE PROCEDURE sp_ExpirePremiumAccounts
AS
BEGIN
SET NOCOUNT ON;
UPDATE MEMB_INFO
SET premium_status = 0,
premium_tier = 0
WHERE premium_status = 1
AND premium_expire IS NOT NULL
AND premium_expire < GETDATE();
SELECT @@ROWCOUNT AS expired_accounts;
END;
GO
Step 3 — Configure SQL Server Agent Job for Automatic Expiration
- In SSMS, expand SQL Server Agent → right-click Jobs → New Job
- Name:
PremiumExpiration_Job - Under Steps → New Step:
- Step name:
Expire Accounts - Type:
Transact-SQL script (T-SQL) - Database:
MuOnline - Command:
``sql EXEC sp_ExpirePremiumAccounts; ``
- Under Schedules → New Schedule:
- Name:
Hourly - Frequency:
Daily, recurs every1 hour
- Click OK to save.
services.msc) that SQL Server Agent (MSSQLSERVER) has status Running and startup type Automatic.Step 4 — Configure Benefits in GameServer
Experience and drop benefits are controlled by configuration files and, in some versions, by database tables.
4.1 — Main rates file:
Edit GameServer/Data/Etc/Rates.ini (or GameServer/Data/Config/Rates.cfg depending on version):
[PremiumRates]
; Tier 1 - Bronze
Bronze_ExpRate = 150 ; 1.5x normal experience
Bronze_DropRate = 120 ; 1.2x drop chance
Bronze_ZenRate = 110 ; 1.1x zen
; Tier 2 - Silver
Silver_ExpRate = 200
Silver_DropRate = 150
Silver_ZenRate = 125
; Tier 3 - Gold
Gold_ExpRate = 300
Gold_DropRate = 200
Gold_ZenRate = 150
4.2 — On servers that read rates from the database:
-- Table T_PREMIUM_RATES (create if it does not exist)
CREATE TABLE T_PREMIUM_RATES (
tier TINYINT PRIMARY KEY,
tier_name VARCHAR(20),
exp_rate SMALLINT,
drop_rate SMALLINT,
zen_rate SMALLINT
);
INSERT INTO T_PREMIUM_RATES VALUES
(1, 'Bronze', 150, 120, 110),
(2, 'Silver', 200, 150, 125),
(3, 'Gold', 300, 200, 150);
/reloadconfig on some builds).Step 5 — Integrate with the Web Panel
If you use a PHP panel (AppServ, XAMPP) or ASP.NET webEngineNET, create the activation endpoint.
PHP example with MSSQL (PDO):
<?php
// admin/activate_premium.php
require_once '../includes/db.php'; // PDO connection to SQL Server
function activatePremium($membName, $tier, $durationDays, $activatedBy) {
global $pdo;
$stmt = $pdo->prepare("EXEC sp_ActivatePremium ?, ?, ?, ?");
$stmt->execute([$membName, $tier, $durationDays, $activatedBy]);
return $stmt->fetchColumn();
}
// Usage via admin form POST:
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['memb_name'])) {
$result = activatePremium(
$_POST['memb_name'],
(int)$_POST['tier'],
(int)$_POST['duration'],
$_SESSION['admin_user']
);
echo json_encode(['success' => true, 'message' => $result]);
}
?>
Status check on player profile:
SELECT
mi.memb_name,
mi.premium_status,
pt.tier_name,
mi.premium_expire,
DATEDIFF(DAY, GETDATE(), mi.premium_expire) AS days_remaining
FROM MEMB_INFO mi
LEFT JOIN T_PREMIUM_RATES pt ON pt.tier = mi.premium_tier
WHERE mi.memb_name = 'PlayerName';
Step 6 — Verify and Test
6.1 — Activate manually for testing:
EXEC sp_ActivatePremium 'TestAccount', 2, 30, 'Admin';
6.2 — Confirm in the database:
SELECT memb_name, premium_status, premium_tier, premium_expire
FROM MEMB_INFO
WHERE memb_name = 'TestAccount';
6.3 — Force-test expiration:
-- Force the test account to expire
UPDATE MEMB_INFO
SET premium_expire = DATEADD(MINUTE, -1, GETDATE())
WHERE memb_name = 'TestAccount';
-- Run the procedure manually
EXEC sp_ExpirePremiumAccounts;
-- Verify it returned to status 0
SELECT memb_name, premium_status FROM MEMB_INFO WHERE memb_name = 'TestAccount';
sql BACKUP DATABASE MuOnline TO DISK = 'C:\Backups\MuOnline_pre_premium.bak'; ``Common Troubleshooting
GameServer does not apply Premium rates even after the database is updated: Check whether your MuServer build supports dynamic rate reading. In older builds (pre-2010), rates are compiled into the executable. In those cases, use source patches or edit the values directly in the executable with a hex editor (consult the forum for your specific version).
sp_ActivatePremium returns a permissions error: The SQL user used by DataServer needs EXECUTE permission on these procedures:
GRANT EXECUTE ON sp_ActivatePremium TO [muserver_user];
GRANT EXECUTE ON sp_ExpirePremiumAccounts TO [muserver_user];
Player retains Premium status after expiration: The GameServer may have an active session cache. Force the player to reconnect or restart the GameServer to clear the account cache. Lower AccountCacheTime in DataServer/Data/DataServerInfo.ini to minimize this delay:
[DBConfig]
AccountCacheTime = 60 ; in seconds, default is usually 300
Perguntas frequentes
Which database table controls Premium status?
The main table is MEMB_INFO in the MuOnline database. You add custom columns such as premium_status (TINYINT) and premium_expire (DATETIME) to it, depending on your MuServer version.
How does the GameServer read Premium status in real time?
The GameServer queries the account table through DataServer on each login or session refresh. Cache settings live in DataServer/Data/DataServerInfo.ini — lower the AccountCacheTime value for faster updates.
Can I have multiple VIP tiers (Bronze, Silver, Gold)?
Yes. Use an INT column (e.g., premium_tier) with values 0=Normal, 1=Bronze, 2=Silver, 3=Gold and replicate the benefit logic for each tier in stored procedures or server-side code.
What happens when a Premium account expires?
Create a SQL Server Agent Job or a web panel routine that runs UPDATE MEMB_INFO SET premium_status=0 WHERE premium_expire < GETDATE() periodically, automatically reverting all benefits.