Brazil's biggest MU Online portal — since 2003
Tutorial Intermediate Tutoriais

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.

VI ViciadosMU Team · Updated on 3 jul 2026 · ⏱ 12 min read

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.

Nota: This tutorial was tested on MuServer Season 6 Episode 3 with SQL Server 2008 R2, 2012, and 2019. The logic is equivalent for Season 9 and Season 13 with minor table name adjustments.

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 active
  • premium_tier: 0 = no tier, 1 = Bronze, 2 = Silver, 3 = Gold
  • premium_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
Dica: Keep the activation log in a separate table. It is essential for auditing and resolving player disputes about Premium time not being credited.

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

  1. In SSMS, expand SQL Server Agent → right-click JobsNew Job
  2. Name: PremiumExpiration_Job
  3. Under StepsNew Step:
  • Step name: Expire Accounts
  • Type: Transact-SQL script (T-SQL)
  • Database: MuOnline
  • Command:

``sql EXEC sp_ExpirePremiumAccounts; ``

  1. Under SchedulesNew Schedule:
  • Name: Hourly
  • Frequency: Daily, recurs every 1 hour
  1. Click OK to save.
Atenção: The SQL Server Agent must be running as a service. Check in Services (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);
Dica: After changing rates via the database, restart the GameServer or run the configuration reload command from the server console (/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';
Atenção: Always test using a dedicated test account, never on active player accounts. Back up the database before any ALTER TABLE in production: ``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.

VI

ViciadosMU Team

Equipe editorial do ViciadosMU — portal de MU Online no ar desde 2003.

Keep reading

Related articles