# Integrations

Supported skin reload types:

* `'illenium'` → Uses `illenium-appearance`
* `'qb'` → Uses `qb-clothing`
* `'esx_skin'` → Uses `esx_skin` + `skinchange`
* `'custom'`    &#x20;

{% tabs %}
{% tab title="integrations/client/reloadskin.lua" %}

```lua
-- Supported systems:
--  - illenium-appearance
--  - qb-clothing
--  - esx_skin / skinchanger
--  - custom (external clothing systems)
--
-- Usage:
--  ReloadPlayerSkin()
--
-- Config:
--  Config.ReloadSkinType = 'illenium' | 'qb' | 'esx_skin' | 'custom'
-- =====================================================

local function ApplySkinWithModel(skin)
    local model = (skin.sex == 0) and 'mp_m_freemode_01' or 'mp_f_freemode_01'
    local modelHash = joaat(model)

    RequestModel(modelHash)
    while not HasModelLoaded(modelHash) do Wait(50) end

    SetPlayerModel(PlayerId(), modelHash)
    SetModelAsNoLongerNeeded(modelHash)

    Wait(250)
    TriggerEvent('skinchanger:loadSkin', skin)
end

local function ReloadESXSkin()
    if lastSkinBackup then
        ApplySkinWithModel(lastSkinBackup)
        return
    end

    ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
        if skin and skin.sex ~= nil then
            ApplySkinWithModel(skin)
        else
            TriggerEvent('skinchanger:loadDefaultModel', true)
        end
    end)
end
RegisterNetEvent('izaap_punishment:client:restoreQBSkin', function(data)
    if Config.ReloadSkinType ~= 'qb' then return end
    if not data or not data.skin then return end

    CreateThread(function()
        local modelName = data.model or 'mp_m_freemode_01'
        local modelHash = joaat(modelName)

        RequestModel(modelHash)
        while not HasModelLoaded(modelHash) do Wait(50) end

        SetPlayerModel(PlayerId(), modelHash)
        SetModelAsNoLongerNeeded(modelHash)

        Wait(500)
        local ped = PlayerPedId()


        SetPedDefaultComponentVariation(ped)

        TriggerEvent('qb-clothing:client:loadPlayerClothing', data.skin, ped)
    end)
end)

-- =====================================================
function ReloadPlayerSkin()
    if Config.ReloadSkinType == 'illenium' then
        TriggerEvent('illenium-appearance:client:reloadSkin')

    elseif Config.ReloadSkinType == 'qb' then
        TriggerServerEvent('izaap_punishment:server:restoreQBSkin')

    elseif Config.ReloadSkinType == 'esx_skin' then
        ReloadESXSkin()

    elseif Config.ReloadSkinType == 'custom' then
        TriggerEvent('izaap_punishment:customReloadSkin')

    else
        print('[izaap_punishment] Invalid ReloadSkinType in config.lua')
    end
end

-- External trigger (usable by other resources)
RegisterNetEvent('izaap_punishment:reloadSkin', ReloadPlayerSkin)

```

{% endtab %}

{% tab title="integrations/server/reloadskin.lua" %}

```lua
-- Default implementation: qb-clothing new
--
-- Developers can integrate their own clothing systems
-- by following the EXAMPLE TEMPLATE below.
-- =====================================================

if Config.ReloadSkinType ~= 'qb' then return end

local QBCore = exports['qb-core']:GetCoreObject()
local qbSkinBackup = {}

RegisterNetEvent('izaap_punishment:server:saveQBSkin', function()
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)
    if not Player then return end

    local result = MySQL.query.await(
        'SELECT skin, model FROM playerskins WHERE citizenid = ? AND active = 1 LIMIT 1',
        { Player.PlayerData.citizenid }
    )

    if not (result and result[1] and result[1].skin) then
        print(('[izaap_punishment] No QB skin found for %s'):format(Player.PlayerData.citizenid))
        return
    end

    local model = result[1].model

    -- qb-clothing requires freemode models
    if model ~= 'mp_m_freemode_01' and model ~= 'mp_f_freemode_01' then
        model = 'mp_m_freemode_01'
    end

    qbSkinBackup[src] = {
        skin  = json.decode(result[1].skin),
        model = model
    }
end)


RegisterNetEvent('izaap_punishment:server:restoreQBSkin', function()
    local src = source
    local data = qbSkinBackup[src]

    if not data then
        return
    end

    TriggerClientEvent('izaap_punishment:client:restoreQBSkin', src, data)
    qbSkinBackup[src] = nil
end)


AddEventHandler('playerDropped', function()
    qbSkinBackup[source] = nil
end)

-- =====================================================
--  EXAMPLE: CUSTOM CLOTHING INTEGRATION 
-- =====================================================
-- Use this section as a reference if you want to add
-- support for another clothing system.
--
-- 1) Change in config.lua:
--      Config.ReloadSkinType = 'custom'
--
-- 2) Save skin BEFORE punishment:
--
-- RegisterNetEvent('izaap_punishment:server:saveCustomSkin', function()
--     local src = source
--
--     -- Example: get skin data from your own system
--     local skinData = exports['my-clothing']:GetPlayerSkin(src)
--
--     if skinData then
--         customSkinBackup[src] = skinData
--     end
-- end)
--
-- 3) Restore skin AFTER punishment:
--
-- RegisterNetEvent('izaap_punishment:server:restoreCustomSkin', function()
--     local src = source
--     local data = customSkinBackup[src]
--
--     if not data then return end
--
--     TriggerClientEvent('my-clothing:client:loadSkin', src, data)
--     customSkinBackup[src] = nil
-- end)
--
-- 4) Client side:
--    Hook into:
--      izaap_punishment:customReloadSkin
-- =====================================================

```

{% endtab %}
{% endtabs %}
