Introduction
mysqloo est le module de référence pour interagir avec MySQL depuis du Lua GMod. Async, performant, supporté par DarkRP, ULib, beaucoup d'addons. Si tu fais autre chose qu'un serveur sandbox, tu vas en avoir besoin.
Prérequis
- Un serveur GMod chez VeryCloud
- Une BDD MySQL/MariaDB accessible (via Plesk VeryCloud, autre VPS, ou service managé)
- Accès Files dans Wisp
Étape 1 : Choisir la version de mysqloo
mysqloo a plusieurs builds selon la plateforme. Le projet officiel est sur GitHub.
- Source : https://github.com/FredyH/MySQLOO
- Releases : https://github.com/FredyH/MySQLOO/releases
Sur un serveur Wisp VeryCloud (Linux x64), tu veux le fichier gmsv_mysqloo_linux64.dll (oui, l'extension reste .dll même sous Linux, c'est la convention GMod).
Étape 2 : Uploader le binaire
Dans Wisp → Files :
- Va dans
/garrysmod/lua/bin/ - Si le dossier n'existe pas, crée-le
- Upload
gmsv_mysqloo_linux64.dll
Restart le serveur.
Étape 3 : Vérifier le chargement
Au boot, en console :
require("mysqloo")
Si aucune erreur n'apparaît, c'est chargé. Sinon, vérifie l'architecture (32 vs 64 bits) et le bon nom de fichier.
💡 Si tu tournes en 32 bits (rare en 2026), c'est
gmsv_mysqloo_linux.dll(sans le 64).
Étape 4 : Préparer la BDD côté MySQL
Crée la BDD et l'utilisateur dédié (depuis phpMyAdmin / Plesk / CLI) :
CREATE DATABASE gmod_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'gmod_user'@'IP_DU_SERVEUR_GMOD' IDENTIFIED BY 'mdp_solide_16_chars_min';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, ALTER, DROP
ON gmod_db.*
TO 'gmod_user'@'IP_DU_SERVEUR_GMOD';
FLUSH PRIVILEGES;
⚠️ Ne mets JAMAIS
%pour l'host. Précise l'IP du serveur GMod (récupérable dans Wisp → Network). Si tu héberges la BDD chez VeryCloud aussi, c'est ton IP de service.
Étape 5 : Premier script Lua avec mysqloo
Crée /garrysmod/lua/autorun/server/db_init.lua :
require("mysqloo")
local DB_HOST = "ton.mysql.host"
local DB_USER = "gmod_user"
local DB_PASS = "mdp_solide_16_chars_min"
local DB_NAME = "gmod_db"
local DB_PORT = 3306
DB = mysqloo.connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT)
function DB:onConnected()
print("[DB] Connexion MySQL OK")
end
function DB:onConnectionFailed(err)
print("[DB] Connexion echec : " .. err)
end
DB:connect()
Restart le serveur. Tu dois voir [DB] Connexion MySQL OK en console.
Étape 6 : Première query
local q = DB:query("CREATE TABLE IF NOT EXISTS players (\
steamid VARCHAR(20) PRIMARY KEY,\
name VARCHAR(64),\
money INT DEFAULT 500,\
last_login DATETIME\
)")
function q:onSuccess()
print("[DB] Table players cree")
end
function q:onError(err)
print("[DB] Erreur creation table : " .. err)
end
q:start()
Toutes les queries mysqloo sont async : tu déclares les callbacks onSuccess et onError, puis :start().
Étape 7 : Pattern pour les opérations courantes
SELECT :
local function GetPlayerMoney(ply, cb)
local q = DB:query(string.format(
"SELECT money FROM players WHERE steamid = %s",
DB:escape(ply:SteamID()) -- prevention SQLi
))
function q:onSuccess(data)
cb(tonumber(data[1] and data[1].money) or 0)
end
function q:onError(err)
print("[DB] GetPlayerMoney error : " .. err)
cb(0)
end
q:start()
end
INSERT / UPDATE avec prepared statement :
local stmt = DB:prepare("UPDATE players SET money = ? WHERE steamid = ?")
stmt:setNumber(1, 1000)
stmt:setString(2, ply:SteamID())
function stmt:onSuccess()
print("[DB] Update OK")
end
function stmt:onError(err)
print("[DB] Update error : " .. err)
end
stmt:start()
Toujours préférer les prepared statements : performance + protection SQL injection.
Étape 8 : Reconnexion auto
mysqloo gère mal les déconnexions silencieuses (timeout MySQL après inactivité). Pattern de reconnexion :
function DB:onConnectionFailed(err)
print("[DB] Connexion perdue, retry dans 5s...")
timer.Simple(5, function()
DB:connect()
end)
end
Ou mieux : ping périodique pour garder la connexion alive :
timer.Create("DB_Ping", 60, 0, function()
local q = DB:query("SELECT 1")
function q:onError(err)
print("[DB] Ping failed, reconnexion...")
DB:connect()
end
q:start()
end)
Étape 9 : Intégration avec DarkRP
DarkRP utilise MySQLite par-dessus mysqloo (ou SQLite). Configure dans /garrysmod/addons/darkrpmodification/lua/darkrp_config/mysql.lua (voir tuto DarkRP).
Les autres addons DarkRP-compatibles utiliseront automatiquement ta connexion DB.
Étape 10 : Sécurité
Quelques règles de base :
- Compte MySQL dédié (un par application/serveur)
- IP source restreinte (jamais
%) - Mot de passe long, jamais commit en clair sur Git
- TLS pour MySQL si la connexion sort du datacenter (paramètre
ssl=truedans le driver) - Backup régulier de la BDD (mysqldump cron + offsite)
Dépannage
Module not found: mysqloo
- Fichier mal placé (doit être dans
/garrysmod/lua/bin/) - Mauvaise archi (linux64 vs win64 vs linux32)
Access denied for user
- Mot de passe incorrect
- IP source pas dans les
GRANT - Vérifier avec :
SELECT user, host FROM mysql.user;
Can't connect to MySQL server
- Port 3306 firewallé côté BDD
- IP du serveur GMod a changé (re-grant)
Queries lentes / serveur freeze
- Tu n'utilises pas mysqloo en async (vérifie
:start()et les callbacks) - BDD trop loin géographiquement (latence)
Commandes utiles
-- Tester la connexion en live
lua_run print(DB:status() == mysqloo.DATABASE_CONNECTED)
-- Lister les tables
lua_run local q = DB:query("SHOW TABLES") q.onSuccess = function(self, data) PrintTable(data) end q:start()
-- Echapper une string utilisateur
DB:escape(text)
Conclusion
mysqloo = pierre angulaire de tout serveur GMod sérieux : économie persistante, stats joueurs, bans, logs. Setup en 30 min avec une BDD préparée à côté. Toujours en async, toujours avec prepared statements pour les inputs utilisateur. Une fois en place, tous tes addons (DarkRP, ULib MySQL, custom) en bénéficient.
Pour aller plus loin : pool de connexions multiples pour la perf, MySQLite (abstraction SQLite/MySQL), monitoring de la latence DB côté gamemode.


















