How to Integrate Website and Game on Your MU Online Server
Learn how to connect your MU Online game server to a web panel, sharing the same database and enabling account management, rankings, and web features.
Understanding the Integration Architecture
Connecting a website to a MU Online game server is not a matter of installing a plugin — it is an architectural decision that links two separate systems through a shared database. The game server (GameServer, ConnectServer, JoinServer, DataServer) writes and reads player data from Microsoft SQL Server. Your web panel reads from and writes to that same database to provide account registration, character rankings, item shops, vote systems, and administrative tools.
Before touching any configuration file, you need a clear picture of what each component does:
- SQL Server — the single source of truth shared by both the game and the website.
- Game server processes — ConnectServer, GameServer, JoinServer, DataServer. They must never be exposed directly to the web.
- Web server — Apache or Nginx serving PHP, ASP.NET, or Node.js pages. It communicates only with SQL Server, never directly with game server processes.
- Firewall — controls which ports are reachable from the internet. SQL Server should never be open to the public internet.
> [!WARNING] > Never expose your SQL Server port (1433) to the public internet. All web-to-database traffic must travel over a private network interface or localhost. A misconfigured firewall is one of the most common causes of server compromises.
Preparing the SQL Server for Web Access
Your game databases likely already exist (MuOnline, MEMB_INFO, MuEventChips, and others depending on your season). The first step is creating a dedicated SQL Server login for the web application.
Open SQL Server Management Studio (SSMS) and run the following script. Replace the placeholder values with your own:
-- Create a login at the server level
CREATE LOGIN [mu_webuser] WITH PASSWORD = 'StrongPassword!42',
DEFAULT_DATABASE = [MuOnline],
CHECK_EXPIRATION = OFF,
CHECK_POLICY = ON;
-- Map the login to each relevant database
USE [MuOnline];
CREATE USER [mu_webuser] FOR LOGIN [mu_webuser];
-- Grant only what the site needs
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA::dbo TO [mu_webuser];
USE [MEMB_INFO];
CREATE USER [mu_webuser] FOR LOGIN [mu_webuser];
GRANT SELECT, INSERT, UPDATE ON SCHEMA::dbo TO [mu_webuser];
Key tables your web panel will interact with most frequently:
MEMB_INFO → account credentials and status
MEMB_STAT → online status, last login timestamps
Character → character name, class, level, resets
T_CashShop_Item → web shop / cash item records
MuEventChips → Goblin Points or similar vote reward tables
Connection string format (PHP PDO example):
Host → 127.0.0.1 or private LAN IP (never 0.0.0.0)
Port → 1433
Driver → ODBC Driver 17 for SQL Server
DB → MuOnline (set per query with USE or fully qualify table names)
> [!TIP] > Enable SQL Server Mixed Authentication mode (SQL Server and Windows Authentication) if it is not already active. You can verify this in SSMS under Server Properties → Security. Restart the SQL Server service after changing the authentication mode.
Configuring the Web Server
Apache with PHP (Windows)
If your game server runs on Windows (which is typical for Season 6 through Season 15 setups), you are likely running Apache via XAMPP or a standalone installation. Key configuration points:
- Bind Apache to a specific IP address, not
0.0.0.0, if you want to restrict access to a management interface. - Place your web panel files outside the game server directories — for example
C:\WebPanel\htdocs\rather than inside the MuServer folder tree. - Enable the
php_sqlsrvandphp_pdo_sqlsrvextensions inphp.ini. These are Microsoft's official PHP drivers for SQL Server and offer better performance and compatibility than the generic ODBC extension.
; php.ini additions
extension = php_sqlsrv.dll
extension = php_pdo_sqlsrv.dll
; Recommended security settings
expose_php = Off
display_errors = Off
log_errors = On
error_log = C:\WebPanel\logs\php_errors.log
session.cookie_httponly = 1
session.use_strict_mode = 1
Nginx as a Reverse Proxy (Linux panels)
If you run a Linux-based web panel (such as a PHP-FPM setup or a Node.js application) and want Nginx to sit in front:
server {
listen 80;
server_name panel.yourdomain.com;
# Redirect all HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name panel.yourdomain.com;
ssl_certificate /etc/ssl/certs/your_cert.pem;
ssl_certificate_key /etc/ssl/private/your_key.pem;
location / {
proxy_pass http://127.0.0.1:3000; # → Node or PHP-FPM upstream
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Linking Account Registration to the Game
Account creation on the website must write data in exactly the format the game server expects. The most critical table is MEMB_INFO. A minimal registration insert looks like this:
-- Example: registering a new account
-- Password hashing must match your server core's expected format
INSERT INTO MEMB_INFO (
memb___id, -- → account name (max 10 chars, alphanumeric)
memb__pwd, -- → hashed password (MD5 or server-specific hash)
memb_name, -- → display name
sno__numb, -- → social/ID number field (set to '0000000000' if unused)
bloc_code, -- → 0 = active, 1 = blocked
mail_addr, -- → email address
mail_chek, -- → email verified flag (0 or 1)
appl_days, -- → account creation date
modi_days, -- → last modification date
out__days, -- → last logout date
true_days -- → subscription/validity date
)
VALUES (
@accountName,
UPPER(CONVERT(VARCHAR(32), HASHBYTES('MD5', @password), 2)),
@displayName,
'0000000000',
0,
@email,
0,
GETDATE(),
GETDATE(),
GETDATE(),
'2099-12-31'
);
MEMB_INFO table in SSMS before writing any registration code. Some cores use a custom XOR or SHA1 hash instead of plain MD5.Building Character Rankings and Statistics Pages
Rankings are one of the most visited pages on any MU Online web panel. The recommended approach is to pre-compute ranking data into a dedicated table rather than running heavy joins on every page load.
Create a summary table:
CREATE TABLE dbo.WebRankingCache (
RankPosition INT NOT NULL,
CharName VARCHAR(10) NOT NULL,
CharClass SMALLINT NOT NULL,
CharLevel SMALLINT NOT NULL,
ResetCount INT NOT NULL DEFAULT 0,
GuildName VARCHAR(8) NULL,
LastUpdated DATETIME NOT NULL DEFAULT GETDATE(),
CONSTRAINT PK_WebRankingCache PRIMARY KEY (RankPosition)
);
-- Stored procedure to refresh rankings
-- Schedule this with SQL Server Agent every 5 minutes
CREATE PROCEDURE dbo.sp_RefreshWebRankings
AS
BEGIN
TRUNCATE TABLE dbo.WebRankingCache;
INSERT INTO dbo.WebRankingCache (RankPosition, CharName, CharClass, CharLevel, ResetCount, GuildName)
SELECT
ROW_NUMBER() OVER (ORDER BY C.cLevel DESC, C.LevelUpPoint DESC) AS RankPosition,
C.Name AS CharName,
C.Class AS CharClass,
C.cLevel AS CharLevel,
ISNULL(CR.ResetCount, 0) AS ResetCount,
G.G_Name AS GuildName
FROM dbo.Character C
LEFT JOIN dbo.CharacterResets CR ON CR.Name = C.Name -- → adjust table/column to your core
LEFT JOIN dbo.GuildMember GM ON GM.Name = C.Name
LEFT JOIN dbo.Guild G ON G.G_Name = GM.G_Name
WHERE C.CtlCode = 0 -- → exclude GM characters from public ranking
ORDER BY RankPosition;
END;
Security Hardening Checklist
Before your web panel is reachable from the internet, verify the following:
- SQL Server port 1433 is blocked at the firewall for all external IPs.
- The web database user has no DDL permissions (no CREATE, DROP, ALTER).
- All user-supplied input is parameterized — never concatenated into SQL strings.
- HTTPS is enforced; HTTP requests redirect to HTTPS.
- Session tokens are regenerated after login and invalidated on logout.
- Admin pages are protected by IP whitelist or two-factor authentication at the application layer.
- Error messages shown to users do not reveal database structure, table names, or stack traces.
Keeping the game server and web server on a private LAN with only the web server's port 443 exposed to the internet is the most effective single measure you can take to protect your infrastructure.
Perguntas frequentes
Can the website and game server run on the same machine?
Yes. Running both on the same machine is the simplest starting point. You point your web server (Apache or Nginx) to localhost and connect to the same SQL Server instance used by the game. For production environments with many players, separating the web server from the game server reduces resource contention and improves stability.
What database user permissions does the website need?
The web application should use a dedicated SQL Server login with only SELECT, INSERT, UPDATE, and DELETE permissions on the specific MU databases (MuOnline, MEMB_INFO, etc.). Never use the sa account or any account with sysadmin rights for the web panel connection string.
How do I keep account registration secure?
Use HTTPS on your web panel, hash passwords with a method compatible with how your server core stores them (usually MD5 or a custom hash), apply rate limiting on the registration endpoint, and validate all inputs server-side to prevent SQL injection. CAPTCHA on the registration form is strongly recommended.
Why do rankings on my site not update in real time?
MU Online servers update character statistics at save intervals (typically every few minutes or on logout). Your website reads directly from the database, so rankings will always reflect the last saved state. You can schedule a SQL Agent job or a cron-driven script to pre-compute ranking tables at regular intervals to reduce query load and improve page speed.