qb-doorlock icon indicating copy to clipboard operation
qb-doorlock copied to clipboard

[BUG] - Linux wont save correctly on some hosting platforms.

Open Save5Bucks opened this issue 6 months ago • 1 comments

I have been going down a 2 week rabbit hole. On my windows test server the /newdoor saves fine. When trying on our main server which is linux it kept saving at "}" only

This is very envorinment specific i would imagine but this was how we got it to work on our linux server.

RegisterNetEvent('qb-doorlock:server:saveNewDoor', function(data, doubleDoor)
    local src = source
    if not QBCore.Functions.HasPermission(src, Config.CommandPermission) and not IsPlayerAceAllowed(src, 'command') then
        if Config.Warnings then
            showWarning(Lang:t("general.warn_no_permission_newdoor", {
                player = GetPlayerName(src),
                license = QBCore.Functions.GetIdentifier(src, 'license'),
                source = src
            }))
        end
        return
    end

    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    local configData = {}
    local jobs, jobGrade, gangs, gangGrade, cids, items, doorType, identifier

    if data.job then
        jobGrade = tonumber(data.jobGrade) or 0
        configData.authorizedJobs = { [data.job] = jobGrade }
        jobs = "['" .. data.job .. "'] = " .. jobGrade
    end
    if data.gang then
        gangGrade = tonumber(data.gangGrade) or 0
        configData.authorizedGangs = { [data.gang] = gangGrade }
        gangs = "['" .. data.gang .. "'] = " .. gangGrade
    end
    if data.cid then
        configData.authorizedCitizenIDs = { [data.cid] = true }
        cids = "['" .. data.cid .. "'] = true"
    end
    if data.item then
        configData.items = { [data.item] = 1 }
        items = "['" .. data.item .. "'] = 1"
    end

    configData.locked = data.locked
    configData.pickable = data.pickable
    configData.cantUnlock = data.cantunlock
    configData.hideLabel = data.hidelabel
    configData.distance = data.distance
    configData.doorType = data.doortype
    configData.doorRate = 1.0
    configData.doorLabel = data.doorlabel
    configData.fixText = false

    doorType = "'" .. data.doortype .. "'"
    identifier = data.configfile .. '-' .. data.dooridentifier

    if doubleDoor then
        configData.doors = {
            { objName = data.model[1], objYaw = data.heading[1], objCoords = data.coords[1] },
            { objName = data.model[2], objYaw = data.heading[2], objCoords = data.coords[2] }
        }
    else
        configData.objName = data.model
        configData.objYaw = data.heading
        configData.objCoords = data.coords
    end

    -- Build output block
    local label = "\n\n-- " .. data.dooridentifier .. " created by " .. Player.PlayerData.name
    local block = "Config.DoorList['" .. identifier .. "'] = {"

    for k, v in pairs(configData) do
        if k == 'authorizedJobs' or k == 'authorizedGangs' or k == 'authorizedCitizenIDs' or k == 'items' then
            local auth = jobs
            if k == 'authorizedGangs' then auth = gangs
            elseif k == 'authorizedCitizenIDs' then auth = cids
            elseif k == 'items' then auth = items end
            block = block .. ("\n    %s = { %s },"):format(k, auth)
        elseif k == 'doors' then
            local doors = {}
            for i = 1, 2 do
                local coords = configData.doors[i].objCoords
                local coordsStr = string.format("vec3(%f, %f, %f)", coords.x or coords[1], coords.y or coords[2], coords.z or coords[3])
                doors[i] = ("{objName = %s, objYaw = %s, objCoords = %s}"):format(
                    tostring(configData.doors[i].objName),
                    tostring(configData.doors[i].objYaw),
                    coordsStr
                )
            end
            block = block .. ("\n    doors = {\n        %s,\n        %s\n    },"):format(doors[1], doors[2])
        elseif k == 'doorType' then
            block = block .. ("\n    doorType = %s,"):format(doorType)
        elseif k == 'doorLabel' then
            block = block .. ("\n    doorLabel = '%s',"):format(v)
        elseif k == 'objCoords' then
            block = block .. ("\n    objCoords = vec3(%f, %f, %f),"):format(v.x or v[1], v.y or v[2], v.z or v[3])
        else
            block = block .. ("\n    %s = %s,"):format(k, tostring(v))
        end
    end

    block = block .. "\n}"

    -- Build filename
    local fileName = "configs/" .. (data.configfile and data.configfile:gsub(".lua", "") or "config") .. ".lua"
    local resource = GetCurrentResourceName()

    -- Load + append + save
    local existing = LoadResourceFile(resource, fileName)
    if not existing or existing == "" then
        existing = "Config = Config or {}\nConfig.DoorList = Config.DoorList or {}\n"
    end

    local finalContent = existing .. label .. "\n" .. block .. "\n"
    SaveResourceFile(resource, fileName, finalContent, #finalContent)

    -- Runtime + Notify
    Config.DoorList[identifier] = configData
    TriggerClientEvent('qb-doorlock:client:newDoorAdded', -1, configData, identifier, src)
    TriggerClientEvent('QBCore:Notify', src, "Door configuration saved successfully!", "success")
end)

Save5Bucks avatar May 25 '25 17:05 Save5Bucks

Only if the QB-Devs were useful. Thanks for your help!!!

CypherMorgan avatar Jun 14 '25 19:06 CypherMorgan