AWS DEVELOPMENT / DOCUMENTATION

Your server. Our expertise.

Everything you need to install, configure and build.

94 guides • 11 resources • Always here to help
Documentation/framework.lua
About resource versions

These guides include the original resource names. Use the folder and SQL names supplied with your downloaded version. A renamed AWS package may differ from the original EXIT release.

framework.lua

-- ============================================================
-- EXIT FRAGMENTATION β€” Framework Bridge (shared/framework.lua)
-- Desteklenen: QBCore | QBox | ESX | Standalone
-- ============================================================
-- NOT: Bu dosya hem client hem server tarafında çalışır.
-- IsDuplicityVersion() β†’ true = sunucu, false = istemci

ExitFramework = {}

-- ─────────────────────────────────────────────────────────────
-- Framework AlgΔ±lama
-- ─────────────────────────────────────────────────────────────
local _fw = nil   -- Γ–nbellek

function ExitFramework.GetType()
    if _fw then return _fw end

    -- Γ–ncelik sΔ±rasΔ±: Config varsa ΓΆnce ona bak
    if Config and Config.Framework and Config.Framework ~= 'auto' then
        _fw = Config.Framework
        return _fw
    end

    -- Otomatik algΔ±lama
    if GetResourceState('qb-core') == 'started' then
        _fw = 'qb'
    elseif GetResourceState('qbx_core') == 'started' then
        _fw = 'qbox'
    elseif GetResourceState('es_extended') == 'started' then
        _fw = 'esx'
    else
        _fw = 'standalone'
    end

    return _fw
end

-- ─────────────────────────────────────────────────────────────
-- Core Object (Lazy-loaded)
-- ─────────────────────────────────────────────────────────────
local _core = nil

function ExitFramework.GetCore()
    if _core then return _core end
    local fw = ExitFramework.GetType()

    local ok, result = false, nil

    if fw == 'qb' then
        ok, result = pcall(function() return exports['qb-core']:GetCoreObject() end)
    elseif fw == 'qbox' then
        ok, result = pcall(function() return exports['qbx_core']:GetCoreObject() end)
    elseif fw == 'esx' then
        ok, result = pcall(function() return exports['es_extended']:getSharedObject() end)
    else
        ok, result = true, {}
    end

    if ok and result then
        _core = result
    else
        -- Hata logla ve boş fallback dândür (crash ânle)
        print(string.format('[EXIT-FRAMEWORK] UYARI: "%s" framework core nesnesi alΔ±namadΔ±!', fw))
        print('[EXIT-FRAMEWORK] Config.Framework ayarΔ±nΔ± kontrol edin.')
        _core = { Functions = {} }  -- Minimum boş tablo
    end

    return _core
end

-- ─────────────────────────────────────────────────────────────
-- SERVER TARAFI YARDIMCI FONKSΔ°YONLARI
-- ─────────────────────────────────────────────────────────────
if IsDuplicityVersion() then

    -- ─── Δ°Γ§ yardΔ±mcΔ±: ESX/Standalone player'Δ± QB formatΔ±na sar ──
    local function WrapESXPlayer(raw, fw)
        if not raw then return nil end
        -- QBCore/QBox zaten QB formatΔ±nda, dokunma
        if fw == 'qb' or fw == 'qbox' then return raw end

        -- ESX β†’ QB-uyumlu wrapper
        if fw == 'esx' then
            local identifier = raw.identifier or tostring(raw.source or 0)
            local name = (type(raw.getName) == 'function' and raw.getName()) or ''
            local firstName = name:match('^(%S+)') or name
            local lastName  = name:match('%s(.+)$') or ''
            local job = raw.job or {}

            return {
                PlayerData = {
                    citizenid = identifier,
                    source    = raw.source,
                    charinfo  = { firstname = firstName, lastname = lastName },
                    job = {
                        name   = job.name or '',
                        grade  = { level = job.grade or 0 },
                        onduty = true
                    },
                    money = { cash = 0, bank = 0 }
                },
                Functions = {
                    GetItemByName = function(item)
                        local ok, inv = pcall(function() return raw.getInventoryItem(item) end)
                        if ok and inv and (inv.count or 0) > 0 then
                            return { name = item, amount = inv.count }
                        end
                        return nil
                    end,
                    AddItem = function(item, amount)
                        pcall(function() raw.addInventoryItem(item, amount or 1) end)
                        return true
                    end,
                    RemoveItem = function(item, amount)
                        pcall(function() raw.removeInventoryItem(item, amount or 1) end)
                        return true
                    end,
                    AddMoney = function(account, amount)
                        local acc = account == 'cash' and 'money' or account
                        pcall(function() raw.addAccountMoney(acc, amount) end)
                    end,
                    RemoveMoney = function(account, amount)
                        local acc = account == 'cash' and 'money' or account
                        pcall(function() raw.removeAccountMoney(acc, amount) end)
                        return true
                    end,
                    HasPermission = function(level)
                        local ok2, g = pcall(function() return raw.getGroup() end)
                        return ok2 and g == 'admin'
                    end,
                }
            }
        end

        -- Standalone minimum
        local src = raw.source or 0
        return {
            PlayerData = {
                citizenid = tostring(src),
                source    = src,
                charinfo  = { firstname = 'Unknown', lastname = '' },
                job       = { name = '', grade = { level = 0 }, onduty = false },
                money     = { cash = 0, bank = 0 }
            },
            Functions = {
                GetItemByName  = function() return nil  end,
                AddItem        = function() return false end,
                RemoveItem     = function() return false end,
                AddMoney       = function() end,
                RemoveMoney    = function() return false end,
                HasPermission  = function() return false end,
            }
        }
    end

    --- Oyuncu nesnesini QB-uyumlu wrapper olarak dΓΆndΓΌrΓΌr
    function ExitFramework.GetPlayer(src)
        local fw   = ExitFramework.GetType()
        local core = ExitFramework.GetCore()
        local raw  = nil

        if fw == 'qb' or fw == 'qbox' then
            raw = core.Functions and core.Functions.GetPlayer(src)
        elseif fw == 'esx' then
            if core and type(core.GetPlayerFromId) == 'function' then
                raw = core.GetPlayerFromId(src)
                if raw then raw.source = src end
            end
        else
            raw = { source = src }
        end

        return WrapESXPlayer(raw, fw)
    end


    --- CitizenID / identifier al
    function ExitFramework.GetIdentifier(src)
        local fw = ExitFramework.GetType()
        local player = ExitFramework.GetPlayer(src)
        if not player then return nil end

        if fw == 'qb' or fw == 'qbox' then
            return player.PlayerData.citizenid
        elseif fw == 'esx' then
            return player.identifier
        else
            return tostring(src)
        end
    end

    --- Karakter adΔ± al
    function ExitFramework.GetPlayerName(src)
        local fw = ExitFramework.GetType()
        local player = ExitFramework.GetPlayer(src)
        if not player then return GetPlayerName(src) end

        if fw == 'qb' or fw == 'qbox' then
            local ci = player.PlayerData.charinfo
            return (ci.firstname or '') .. ' ' .. (ci.lastname or '')
        elseif fw == 'esx' then
            return player.getName()
        else
            return GetPlayerName(src)
        end
    end

    --- Item ekle (dΓΆnem dΓΆnemlik callback'siz basit versiyon)
    function ExitFramework.AddItem(src, item, amount)
        local fw = ExitFramework.GetType()
        local player = ExitFramework.GetPlayer(src)
        if not player then return false end
        amount = amount or 1

        if fw == 'qb' or fw == 'qbox' then
            return player.Functions.AddItem(item, amount)
        elseif fw == 'esx' then
            player.addInventoryItem(item, amount)
            return true
        elseif GetResourceState('ox_inventory') == 'started' then
            return exports.ox_inventory:AddItem(src, item, amount)
        else
            print('[EXIT] Standalone: AddItem çağrıldı ama envanter sistemi bulunamadı.')
            return false
        end
    end

    --- Item Γ§Δ±kar
    function ExitFramework.RemoveItem(src, item, amount)
        local fw = ExitFramework.GetType()
        local player = ExitFramework.GetPlayer(src)
        if not player then return false end
        amount = amount or 1

        if fw == 'qb' or fw == 'qbox' then
            return player.Functions.RemoveItem(item, amount)
        elseif fw == 'esx' then
            player.removeInventoryItem(item, amount)
            return true
        elseif GetResourceState('ox_inventory') == 'started' then
            return exports.ox_inventory:RemoveItem(src, item, amount)
        else
            return false
        end
    end

    --- Item kontrolΓΌ
    function ExitFramework.GetItem(src, item)
        local fw = ExitFramework.GetType()
        local player = ExitFramework.GetPlayer(src)
        if not player then return nil end

        if fw == 'qb' or fw == 'qbox' then
            return player.Functions.GetItemByName(item)
        elseif fw == 'esx' then
            local inv = player.getInventoryItem(item)
            return inv and {name = item, amount = inv.count} or nil
        elseif GetResourceState('ox_inventory') == 'started' then
            local count = exports.ox_inventory:Search(src, 'count', item)
            return count and count > 0 and {name = item, amount = count} or nil
        else
            return nil
        end
    end

    --- Para ver
    function ExitFramework.AddMoney(src, account, amount)
        local fw = ExitFramework.GetType()
        local player = ExitFramework.GetPlayer(src)
        if not player then return end

        if fw == 'qb' or fw == 'qbox' then
            player.Functions.AddMoney(account, amount)
        elseif fw == 'esx' then
            -- ESX account mapping: 'cash' β†’ 'money', 'bank' β†’ 'bank'
            local esxAccount = account == 'cash' and 'money' or account
            player.addAccountMoney(esxAccount, amount)
        else
            print('[EXIT] Standalone: AddMoney çağrıldı. Para: ' .. amount)
        end
    end

    --- Para al
    function ExitFramework.RemoveMoney(src, account, amount)
        local fw = ExitFramework.GetType()
        local player = ExitFramework.GetPlayer(src)
        if not player then return false end

        if fw == 'qb' or fw == 'qbox' then
            return player.Functions.RemoveMoney(account, amount)
        elseif fw == 'esx' then
            local esxAccount = account == 'cash' and 'money' or account
            player.removeAccountMoney(esxAccount, amount)
            return true
        else
            return false
        end
    end

    --- Meslek/iş kontrolü
    function ExitFramework.GetJob(src)
        local fw = ExitFramework.GetType()
        local player = ExitFramework.GetPlayer(src)
        if not player then return {name='', duty=false} end

        if fw == 'qb' or fw == 'qbox' then
            return {
                name  = player.PlayerData.job.name,
                grade = player.PlayerData.job.grade.level,
                duty  = player.PlayerData.job.onduty
            }
        elseif fw == 'esx' then
            return {
                name  = player.job.name,
                grade = player.job.grade,
                duty  = true -- ESX duty sistemi farklΔ±, true varsay
            }
        else
            return {name='', grade=0, duty=false}
        end
    end

    --- Sunucu tarafΔ± bildirim (client event ΓΌzerinden)
    function ExitFramework.ServerNotify(src, msg, ntype, duration)
        TriggerClientEvent('exit-fragmentation:client:showToast', src, msg, ntype, duration)
    end

    --- TΓΌm polisleri say
    function ExitFramework.CountPolice()
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()
        local count = 0

        if fw == 'qb' or fw == 'qbox' then
            local players = core.Functions.GetPlayers()
            for _, v in pairs(players) do
                local p = core.Functions.GetPlayer(v)
                if p and p.PlayerData.job.name == 'police' and p.PlayerData.job.onduty then
                    count = count + 1
                end
            end
        elseif fw == 'esx' then
            local players = core.GetPlayers()
            for _, v in pairs(players) do
                local p = core.GetPlayerFromId(v)
                if p and p.job.name == 'police' then
                    count = count + 1
                end
            end
        else
            count = 0
        end

        return count
    end

    --- Δ°zin/yetki kontrolΓΌ
    function ExitFramework.HasPermission(src, level)
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            return core.Functions.HasPermission(src, level)
        elseif fw == 'esx' then
            local player = ExitFramework.GetPlayer(src)
            if level == 'admin' or level == 'god' then
                return player and player.getGroup() == 'admin'
            end
            return false
        else
            return false
        end
    end

    --- TΓΌm oyuncular
    function ExitFramework.GetPlayers()
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            return core.Functions.GetPlayers()
        elseif fw == 'esx' then
            return core.GetPlayers()
        else
            return GetPlayers()
        end
    end

    --- Araç plakası al (server'da mevcut değil, client-side)
    function ExitFramework.CleanPlate(plate)
        -- Tutarlı format (boşluk trim)
        if plate then
            return plate:gsub('%s+', ''):upper()
        end
        return ''
    end

-- ─────────────────────────────────────────────────────────────
-- CLIENT TARAFI YARDIMCI FONKSΔ°YONLARI
-- ─────────────────────────────────────────────────────────────
else

    --- Oyuncu verisini al
    function ExitFramework.GetPlayerData()
        local fw  = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            return core.Functions.GetPlayerData()
        elseif fw == 'esx' then
            local data = core.GetPlayerData()
            -- QB formatΔ±na normalize et
            return {
                citizenid = data and data.identifier or '',
                charinfo  = {
                    firstname = data and data.firstName or '',
                    lastname  = data and data.lastName or ''
                },
                job = {
                    name  = data and data.job and data.job.name or '',
                    onduty = true
                },
                items = data and data.inventory or {}
            }
        else
            return {}
        end
    end

    --- Δ°tem kontrolΓΌ (client side)
    function ExitFramework.HasItem(item)
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            local pData = core.Functions.GetPlayerData()
            if pData and pData.items then
                for _, v in pairs(pData.items) do
                    if v.name == item and v.amount > 0 then return true end
                end
            end
            return false
        elseif fw == 'esx' then
            -- ESX client-side item check
            local pData = core.GetPlayerData()
            if pData and pData.inventory then
                for _, v in pairs(pData.inventory) do
                    if v.name == item and v.count > 0 then return true end
                end
            end
            return false
        elseif GetResourceState('ox_inventory') == 'started' then
            return (exports.ox_inventory:Search('count', item) or 0) > 0
        else
            return false
        end
    end

    --- AraΓ§ plakasΔ± al (client side)
    function ExitFramework.GetPlate(veh)
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            return core.Functions.GetPlate(veh)
        elseif fw == 'esx' then
            return GetVehicleNumberPlateText(veh):gsub('%s+', ''):upper()
        else
            return GetVehicleNumberPlateText(veh):gsub('%s+', ''):upper()
        end
    end

    --- AraΓ§ spawn et
    function ExitFramework.SpawnVehicle(model, cb, coords, warp)
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            core.Functions.SpawnVehicle(model, cb, coords, warp)
        elseif fw == 'esx' then
            -- ESX native spawn
            local hash = type(model) == 'string' and GetHashKey(model) or model
            RequestModel(hash)
            local t = 0
            while not HasModelLoaded(hash) and t < 200 do Wait(10); t = t + 1 end
            if HasModelLoaded(hash) then
                local veh = CreateVehicle(hash, coords.x, coords.y, coords.z, coords.w or 0.0, true, false)
                SetModelAsNoLongerNeeded(hash)
                if warp then
                    SetPedIntoVehicle(PlayerPedId(), veh, -1)
                end
                if cb then cb(veh) end
            end
        else
            -- Standalone basic spawn
            local hash = type(model) == 'string' and GetHashKey(model) or model
            RequestModel(hash)
            local t = 0
            while not HasModelLoaded(hash) and t < 200 do Wait(10); t = t + 1 end
            local veh = CreateVehicle(hash, coords.x, coords.y, coords.z, coords.w or 0.0, true, false)
            SetModelAsNoLongerNeeded(hash)
            if cb then cb(veh) end
        end
    end

    --- AraΓ§ sil
    function ExitFramework.DeleteVehicle(veh)
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            core.Functions.DeleteVehicle(veh)
        else
            if DoesEntityExist(veh) then
                SetEntityAsMissionEntity(veh, true, true)
                DeleteEntity(veh)
            end
        end
    end

    --- Araç âzellikleri al (QBCore âzelliği, diğerleri için temel versiyon)
    function ExitFramework.GetVehicleProperties(veh)
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            return core.Functions.GetVehicleProperties(veh)
        else
            return {
                model = GetEntityModel(veh),
                plate = GetVehicleNumberPlateText(veh)
            }
        end
    end

    --- Progressbar
    function ExitFramework.Progressbar(label, duration, opts, cbDone, cbCancel)
        local fw = ExitFramework.GetType()
        local core = ExitFramework.GetCore()

        if fw == 'qb' or fw == 'qbox' then
            if core.Functions and core.Functions.Progressbar then
                core.Functions.Progressbar(
                    'exit_frag_action', label, duration, false, true,
                    opts or {disableMovement=true, disableCarMovement=true, disableMouse=false, disableCombat=true},
                    {}, {}, {}, cbDone, cbCancel
                )
                return
            end
        end

        -- ox_lib progressBar (exports ile β€” 'lib' global'i kullanma)
        if GetResourceState('ox_lib') == 'started' then
            local ok = pcall(function()
                exports['ox_lib']:progressBar({
                    duration     = duration,
                    label        = label,
                    useWhileDead = false,
                    canCancel    = true,
                    disable = {
                        move   = opts and opts.disableMovement,
                        car    = opts and opts.disableCarMovement,
                        combat = opts and opts.disableCombat
                    }
                }, cbDone, cbCancel)
            end)
            if ok then return end
        end

        -- qb-skillbar fallback
        if GetResourceState('qb-skillbar') == 'started' then
            local ok = pcall(function()
                exports['qb-skillbar']:Start(
                    { duration = duration, pos = 50, width = 20 },
                    function() if cbDone   then cbDone()   end end,
                    function() if cbCancel then cbCancel() end end
                )
            end)
            if ok then return end
        end

        -- Son Γ§are: Timer tabanlΔ± sahte progress
        CreateThread(function()
            local startT = GetGameTimer()
            while GetGameTimer() - startT < duration do Wait(100) end
            if cbDone then cbDone() end
        end)
    end

    -- ─── AraΓ§ PlakasΔ±nΔ± Getir ────────────────────────────────
    function ExitFramework.GetPlate(vehicle)
        if not vehicle or vehicle == 0 then return nil end
        local fw = ExitFramework.GetType()
        if fw == 'qb' or fw == 'qbox' then
            local core = ExitFramework.GetCore()
            if core and core.Functions and core.Functions.GetPlate then
                return core.Functions.GetPlate(vehicle)
            end
        end
        return GetVehicleNumberPlateText(vehicle)
    end

end -- IsDuplicityVersion()