eluna-scripts-ornfelt/lua/lua-battlepass/lua_scripts/battlepass/02_BP_Database.lua
2026-02-24 16:53:17 +01:00

307 lines
8.2 KiB
Lua

--[[
Battle Pass System - Database Module
BP_Database.lua
Database operations for the Battle Pass system.
Handles loading, saving, and updating player data.
]]
-- Namespace
BattlePass = BattlePass or {}
BattlePass.DB = BattlePass.DB or {}
-- Creates an empty player data structure
local function CreateEmptyPlayerData()
return {
guid = 0,
current_level = 0,
current_exp = 0,
total_exp = 0,
claimed_levels = "",
last_daily_login = nil,
dirty = false
}
end
-- Read Operations
-- Loads player data from the database
function BattlePass.DB.LoadPlayerProgress(guid)
local query = CharDBQuery(string.format([[
SELECT current_level, current_exp, total_exp, claimed_levels, last_daily_login
FROM character_battlepass
WHERE guid = %d
]], guid))
if not query then
return nil
end
local data = CreateEmptyPlayerData()
data.guid = guid
data.current_level = query:GetUInt32(0)
data.current_exp = query:GetUInt32(1)
data.total_exp = query:GetUInt32(2)
data.claimed_levels = query:GetString(3) or ""
data.last_daily_login = query:GetString(4)
data.dirty = false
BattlePass.Debug("Loaded player data for GUID " .. guid ..
" (Level: " .. data.current_level ..
", XP: " .. data.current_exp .. ")")
return data
end
-- Creates a new player entry
function BattlePass.DB.CreatePlayerEntry(guid)
CharDBExecute(string.format([[
INSERT INTO character_battlepass (guid, current_level, current_exp, total_exp, claimed_levels)
VALUES (%d, 0, 0, 0, '')
ON DUPLICATE KEY UPDATE guid = guid
]], guid))
local data = CreateEmptyPlayerData()
data.guid = guid
data.dirty = false
BattlePass.Debug("Created new player entry for GUID " .. guid)
return data
end
-- Retrieves or creates player data
function BattlePass.DB.GetOrCreatePlayerData(player)
local guid = player:GetGUIDLow()
-- Check cache first
if BattlePass.PlayerCache[guid] then
return BattlePass.PlayerCache[guid]
end
-- Load from DB
local data = BattlePass.DB.LoadPlayerProgress(guid)
-- Create if doesn't exist
if not data then
data = BattlePass.DB.CreatePlayerEntry(guid)
end
-- Cache the data
BattlePass.PlayerCache[guid] = data
return data
end
-- Write Operations
-- Saves player data to the database
function BattlePass.DB.SavePlayerProgress(guid, data)
if not data then
BattlePass.Error("Cannot save nil data for GUID " .. guid)
return
end
local claimedLevels = data.claimed_levels or ""
CharDBExecute(string.format([[
UPDATE character_battlepass
SET current_level = %d,
current_exp = %d,
total_exp = %d,
claimed_levels = '%s'
WHERE guid = %d
]], data.current_level, data.current_exp, data.total_exp, claimedLevels, guid))
data.dirty = false
BattlePass.Debug("Saved player data for GUID " .. guid)
end
-- Saves player data if modified
function BattlePass.DB.SaveIfDirty(player)
local guid = player:GetGUIDLow()
local data = BattlePass.PlayerCache[guid]
if data and data.dirty then
BattlePass.DB.SavePlayerProgress(guid, data)
end
end
-- Saves all cached data (for shutdown)
function BattlePass.DB.SaveAllCached()
local count = 0
for guid, data in pairs(BattlePass.PlayerCache) do
if data.dirty then
BattlePass.DB.SavePlayerProgress(guid, data)
count = count + 1
end
end
if count > 0 then
BattlePass.Info("Saved " .. count .. " dirty player records")
end
end
-- Update Operations
-- Marks a level as claimed
function BattlePass.DB.MarkLevelClaimed(guid, level)
local data = BattlePass.PlayerCache[guid]
if not data then
BattlePass.Error("No cached data for GUID " .. guid)
return
end
if BattlePass.IsInCSV(data.claimed_levels, level) then
BattlePass.Debug("Level " .. level .. " already claimed for GUID " .. guid)
return
end
data.claimed_levels = BattlePass.AddToCSV(data.claimed_levels, level)
data.dirty = true
BattlePass.Debug("Marked level " .. level .. " as claimed for GUID " .. guid)
-- Save to database immediately
BattlePass.DB.SavePlayerProgress(guid, data)
end
-- Removes a level from the claimed list (admin command)
function BattlePass.DB.UnmarkLevelClaimed(guid, level)
local data = BattlePass.PlayerCache[guid]
if not data then
BattlePass.Error("No cached data for GUID " .. guid)
return false
end
if not BattlePass.IsInCSV(data.claimed_levels, level) then
BattlePass.Debug("Level " .. level .. " not claimed for GUID " .. guid)
return false
end
data.claimed_levels = BattlePass.RemoveFromCSV(data.claimed_levels, level)
data.dirty = true
BattlePass.Debug("Unmarked level " .. level .. " for GUID " .. guid)
-- Save to database immediately
BattlePass.DB.SavePlayerProgress(guid, data)
return true
end
-- Checks if a level has been claimed
function BattlePass.DB.IsLevelClaimed(guid, level)
local data = BattlePass.PlayerCache[guid]
if not data then
return false
end
return BattlePass.IsInCSV(data.claimed_levels, level)
end
-- Updates the last daily login date
function BattlePass.DB.UpdateDailyLogin(guid)
CharDBExecute(string.format([[
UPDATE character_battlepass
SET last_daily_login = CURDATE()
WHERE guid = %d
]], guid))
local data = BattlePass.PlayerCache[guid]
if data then
data.last_daily_login = os.date("%Y-%m-%d")
end
BattlePass.Debug("Updated daily login for GUID " .. guid)
end
-- Checks if daily login bonus is available
function BattlePass.DB.IsDailyLoginAvailable(guid)
local data = BattlePass.PlayerCache[guid]
if not data then
return true
end
if not data.last_daily_login or data.last_daily_login == "" then
return true
end
local today = os.date("%Y-%m-%d")
return data.last_daily_login ~= today
end
-- Administrative Operations
-- Resets player data
function BattlePass.DB.ResetPlayer(guid)
CharDBExecute(string.format([[
UPDATE character_battlepass
SET current_level = 0,
current_exp = 0,
total_exp = 0,
claimed_levels = '',
last_daily_login = NULL
WHERE guid = %d
]], guid))
local data = BattlePass.PlayerCache[guid]
if data then
data.current_level = 0
data.current_exp = 0
data.total_exp = 0
data.claimed_levels = ""
data.last_daily_login = nil
data.dirty = false
end
BattlePass.Info("Reset Battle Pass data for GUID " .. guid)
end
-- Sets player level (admin)
function BattlePass.DB.SetPlayerLevel(guid, level)
local maxLevel = BattlePass.GetConfigNumber("max_level", 100)
level = math.max(0, math.min(level, maxLevel))
CharDBExecute(string.format([[
UPDATE character_battlepass
SET current_level = %d,
current_exp = 0
WHERE guid = %d
]], level, guid))
local data = BattlePass.PlayerCache[guid]
if data then
data.current_level = level
data.current_exp = 0
data.dirty = false
end
BattlePass.Info("Set Battle Pass level to " .. level .. " for GUID " .. guid)
end
-- Adds XP to a player (admin, without triggering automatic level-ups)
function BattlePass.DB.AddPlayerExp(guid, amount)
local data = BattlePass.PlayerCache[guid]
if not data then
BattlePass.Error("No cached data for GUID " .. guid)
return
end
data.current_exp = data.current_exp + amount
data.total_exp = data.total_exp + amount
data.dirty = true
BattlePass.Debug("Added " .. amount .. " XP to GUID " .. guid ..
" (Total: " .. data.current_exp .. ")")
end
-- Cache Cleanup
-- Removes player data from cache
function BattlePass.DB.ClearFromCache(guid)
BattlePass.PlayerCache[guid] = nil
BattlePass.Debug("Cleared cache for GUID " .. guid)
end
-- Clears all cache (for reload)
function BattlePass.DB.ClearAllCache()
BattlePass.DB.SaveAllCached()
BattlePass.PlayerCache = {}
BattlePass.Info("Cleared all player cache")
end