Server-Side Example
Complete server-side code for an addon.
Database Setup
-- myaddon/sv_database.lua
MyAddon.DB = nil
hook.Add("MyAddon.Loaded", "MyAddon.Database", function()
if not MyAddon.Config.Database then return end
local cfg = MyAddon.Config.Database
MyAddon.DB = cLib.MYSQL.f.ConnectDatabase({
db_host = cfg.Host,
db_port = cfg.Port,
db_user = cfg.User,
db_password = cfg.Password,
db_name = cfg.Database
}, function(db)
print("[MyAddon] Database connected!")
MyAddon.CreateTables()
end, function(db, err)
print("[MyAddon] Database error:", err)
end)
end)
function MyAddon.CreateTables()
cLib.MYSQL.f.Query(MyAddon.DB, [[
CREATE TABLE IF NOT EXISTS myaddon_players (
id INT AUTO_INCREMENT PRIMARY KEY,
steamid VARCHAR(32) NOT NULL UNIQUE,
data TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_steamid (steamid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
]], {}, function()
print("[MyAddon] Tables ready!")
end)
endNetwork Setup
-- myaddon/sv_network.lua
cLib.Net.SetPrefix("MyAddon.")
cLib.Net.RegisterMultiple({
"OpenMenu",
"SyncData",
"SaveData",
"RequestData"
})
-- Send data to player on spawn
hook.Add("PlayerInitialSpawn", "MyAddon.Sync", function(ply)
timer.Simple(1, function()
if not IsValid(ply) then return end
MyAddon.LoadPlayerData(ply, function(data)
cLib.Net.Send("SyncData", data, ply)
end)
end)
end)
-- Handle save request
cLib.Net.Receive("SaveData", function(data, ply)
if not IsValid(ply) then return end
MyAddon.SavePlayerData(ply, data, function(success)
if success then
cLib.Net.Send("SyncData", {success = true, message = "Saved!"}, ply)
else
cLib.Net.Send("SyncData", {success = false, message = "Failed to save"}, ply)
end
end)
end)
-- Handle data request
cLib.Net.Receive("RequestData", function(data, ply)
if not IsValid(ply) then return end
MyAddon.LoadPlayerData(ply, function(playerData)
cLib.Net.Send("SyncData", playerData, ply)
end)
end)Server Functions
-- myaddon/sv_functions.lua
function MyAddon.LoadPlayerData(ply, callback)
local steamid = ply:SteamID64()
cLib.MYSQL.f.Query(MyAddon.DB,
"SELECT * FROM myaddon_players WHERE steamid = ?",
{steamid},
function(results)
if results and results[1] then
local data = util.JSONToTable(results[1].data or "{}") or {}
callback(data)
else
-- Create new player
MyAddon.CreatePlayer(ply, function()
callback({})
end)
end
end,
function(err)
cLib.Debug.Error("Failed to load player:", err)
callback({})
end
)
end
function MyAddon.SavePlayerData(ply, data, callback)
local steamid = ply:SteamID64()
local json = util.TableToJSON(data)
cLib.MYSQL.f.Query(MyAddon.DB,
"UPDATE myaddon_players SET data = ? WHERE steamid = ?",
{json, steamid},
function()
callback(true)
end,
function(err)
cLib.Debug.Error("Failed to save player:", err)
callback(false)
end
)
end
function MyAddon.CreatePlayer(ply, callback)
local steamid = ply:SteamID64()
cLib.MYSQL.f.Query(MyAddon.DB,
"INSERT INTO myaddon_players (steamid, data) VALUES (?, ?)",
{steamid, "{}"},
function()
callback()
end
)
end