-- Per-character data path resolution.
--
-- Previously the analyser modules keyed files under "/characterdata/" by the
-- session creature ID (player:getId()), which is a fresh number every login.
-- That scattered preferences across one stale folder per session and meant
-- UI settings never persisted. We now key by the character's DB GUID, which
-- the server pushes via extended opcode 90 right after login. The GUID is
-- stable across renames, sessions, and server restarts.
--
-- While we wait for opcode 90 to arrive (or on an older server build that
-- doesn't send it), fall back to the sanitized character name so writes
-- still land somewhere deterministic rather than crashing.

local CHARACTERDATA_OPCODE = 90
local characterGuid = nil

ProtocolGame.registerExtendedOpcode(CHARACTERDATA_OPCODE, function(_, _, buffer)
    if buffer and buffer ~= '' then
        characterGuid = buffer
    end
end)

-- Deliberately do NOT clear characterGuid on onGameEnd. The analyser modules
-- save their state on onGameEnd too; if we cleared the guid first, their
-- saves would fall back to the name path. Next login overwrites it via
-- opcode 90 anyway, so letting it linger between sessions is harmless.

local function sanitize(s)
    return (s or 'unknown'):gsub('[^%w%-]', '_')
end

-- Returns "/characterdata/<key>" or "/characterdata/<key>/<filename>".
-- <key> is the DB GUID when available, otherwise the sanitized character name.
function getCharacterDataPath(player, filename)
    if not player then return nil end

    local key
    if characterGuid and characterGuid ~= '' then
        key = characterGuid
    else
        key = sanitize(player:getName())
    end

    local base = '/characterdata/' .. key
    if filename then
        return base .. '/' .. filename
    end
    return base
end
