# Framework

The resource works out of the box with ESX and QBCore, but you can include your own framework. Also, the resource detects automatically if you are using ESX or QBCore.

## Manual framework set up

Navigate to `configs/sh_config.lua`.

There you will find the following lua code:

```lua
Framework = {
    ESX = 'esx',
    QBCore = 'qbcore',
    Custom = 'custom',
}
CONFIG.Framework = Framework.ESX -- ESX or QBCore or Custom
```

Here modify the code in the following ways:

```lua
CONFIG.Framework = Framework.ESX
-- or
CONFIG.Framework = Framework.QBCore
-- or
CONFIG.Framework = Framework.Custom
```

## Modify ESX or QBCore methods

### Client Side

You can find the client framework stuff inside `client/api/framework/bridge.lua`. In the client you will find a function like this for each framework with every method or event required inside:

```lua
local function loadESX()
    ESX = exports['es_extended']:getSharedObject()
    FRAMEWORK.GetPlayerName = function()
        return ESX.GetPlayerData().fistName
    end
    FRAMEWORK.GetPlayerLastname = function()
        return ESX.GetPlayerData().lastName
    end
    FRAMEWORK.GetPlayerJob = function()
        if ESX.GetPlayerData().job == nil then
            return nil
        end
        return ESX.GetPlayerData().job.name
    end
    FRAMEWORK.GetPlayerJobGrade = function()
        return ESX.GetPlayerData().job.grade
    end
    RegisterNetEvent('esx:playerLogout') -- When a player logs out (multicharacter), reset their data
    AddEventHandler('esx:playerLogout', function()
        TriggerServerEvent('rcore_dispatch:server:removePlayer')
    end)
end
```

Here you can modify each method to your needs.

### Server Side

You can find the server framework stuff inside `server/api/framework.lua`. In the server you will find a function like this for each framework with every method or event required inside:

```lua
local function loadESX()
    ESX = exports['es_extended']:getSharedObject()
    if not ESX then return dbg.error('[rcore_dispatch] [error] Are you sure that you are using ESX?') end
    GetPlayerFromId = function(source)
        dbg.info('GetPlayerFromId: ' .. source)
        local xPlayer = {}
        local xplayer = ESX.GetPlayerFromId(source)
        xPlayer.addMoney = function(money)
            return xplayer.addMoney(money)
        end
        xPlayer.removeMoney = function(money)
            return xplayer.removeMoney(money)
        end
        xPlayer.getMoney = function(money)
            if not xplayer then
                return nil
            end
            return xplayer.getMoney()
        end
        xPlayer.getRank = function()
            if not xplayer then
                return nil
            end
            local jobData = xplayer.getJob()
            return jobData.grade, jobData.grade_label
        end
        xPlayer.getJob = function()
            if not xplayer then
                return nil
            end
            local jobData = xplayer.getJob()
            return jobData.name, jobData.label
        end
        xPlayer.getSurname = function()
            if not xplayer then
                return nil
            end
            local name = xplayer.getName()
            local surname = string.match(name, '%S+%s(%S+)')
            return surname
        end
        return xPlayer
    end
    --- Event that loads the player into the dispatch
    RegisterNetEvent('esx:playerLoaded')
    AddEventHandler('esx:playerLoaded', function(playerId, xPlayer)
        local job = xPlayer.getJob().name
        if not job then return dbg.critical('No job detected in player with id ' .. xPlayer.source) end
        if CONFIG.JOBS[job] then
            LoadPlayer(xPlayer.source, job)
        end
    end)
    RegisterNetEvent('esx:setJob') -- The stored data does not sync with the framework unless we tell it to
    AddEventHandler('esx:setJob', function(playerId, job)
        if job then
            if CONFIG.JOBS[job.name] then
                LoadPlayer(playerId, job.name)
            else
                UnloadPlayer(playerId, job.name)
            end
        end
    end)
end
```

Here you can modify each method to your needs.

## Custom Framework

To use a custom framework, follow these steps:

1. Create your own framework methods or events.
2. Inside the client-side code (client/api/framework/bridge.lua), create a new function for your custom framework and define the required methods and events. It is required to follow the structure of the functions for the traditional frameworks, an example for client would be:

```lua
local function loadESX()
    RCORE = exports['rcore']:getSharedObject()
    FRAMEWORK.GetPlayerName = function()
        return RCORE.GetPlayerData().fistName
    end
    FRAMEWORK.GetPlayerLastname = function()
        return RCORE.GetPlayerData().lastName
    end
    FRAMEWORK.GetPlayerJob = function()
        if RCORE.GetPlayerData().job == nil then
            return nil
        end
        return RCORE.GetPlayerData().job.name
    end
    FRAMEWORK.GetPlayerJobGrade = function()
        return RCORE.GetPlayerData().job.grade
    end
    RegisterNetEvent('rcore:playerLogout') -- When a player logs out (multicharacter), reset their data
    AddEventHandler('rcor:playerLogout', function()
        TriggerServerEvent('rcore_dispatch:server:removePlayer')
    end)
end
```

3. Inside the server-side code (server/api/framework.lua), create a new function for your custom framework and define the required methods and events. We recommend copying the function for a traditional framework and replace the events and function for your own custom framework methods.
4. Modify the framework setup in configs/sh\_config.lua:

```lua
CONFIG.Framework = Framework.Custom
```

This ensures that the custom framework is used.
