> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dkscripts.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Hooks

> Reaja a compras, outfits, compartilhamentos e pontos sem alterar o core do script

# ⚡ Hooks

Os hooks são funções chamadas pelo script em momentos específicos. Eles existem para integrar o dk\_skinshop com o resto do servidor **sem alterar o core**.

Ficam em:

* `config/client/config.lua` → `hooks`
* `config/server/config.lua` → `hooks`

<Info>
  Todos rodam sob `pcall`: um erro dentro de um hook aparece no console, mas **nunca derruba o recurso**.
</Info>

<Warning>
  Os hooks que começam com `onBefore` **cancelam a ação** quando retornam exatamente `false`. Retornar `nil` ou esquecer o `return` não cancela.
</Warning>

***

## Client

| Hook                               | Quando dispara                                                               |
| ---------------------------------- | ---------------------------------------------------------------------------- |
| `onBeforeOpenUi(mode, blipConfig)` | Antes de abrir a interface, e antes da checagem de permissão. `false` impede |
| `onOpenUi(mode, blipConfig)`       | Depois que a interface abriu, a câmera foi criada e a privacidade começou    |
| `onCloseUi(mode)`                  | Ao fechar. `mode` pode ser `nil` quando não havia ponto ativo                |
| `onClothesApplied(clothes, ped)`   | Quando um **conjunto completo** de roupas é aplicado ao ped                  |
| `onCreateBlip(blipConfig)`         | Depois que o servidor aceitou e salvou um ponto novo                         |

<Note>
  O `onClothesApplied` dispara no login, ao carregar um outfit, ao visualizar um outfit recebido e ao cancelar a prova. Ele **não dispara** na troca de uma peça isolada dentro da loja.

  É o lugar certo para reaplicar tatuagens, overlays ou props de outros scripts.
</Note>

### Bloquear a abertura

```lua theme={null}
hooks = {
    onBeforeOpenUi = function(mode, blipConfig)
        if IsPedCuffed(PlayerPedId()) then
            return false
        end

        return true
    end,

    onOpenUi = function(mode, blipConfig) end,
    onCloseUi = function(mode) end,
    onClothesApplied = function(clothes, ped) end,
    onCreateBlip = function(blipConfig) end,
}
```

<Tip>
  Casos comuns para o `onBeforeOpenUi`: jogador algemado, em combate, ferido, dentro de um veículo ou com outra interface aberta.
</Tip>

### Reaplicar overlays depois de vestir

```lua theme={null}
onClothesApplied = function(clothes, ped)
    exports.meu_tattoos:reaplicar(ped)
end,
```

***

## Server

### Compra

| Hook                               | Quando dispara                               |
| ---------------------------------- | -------------------------------------------- |
| `onBeforeBuy(source, items)`       | Antes da cobrança. `false` cancela           |
| `onBuy(source, items, totalPrice)` | Depois da compra e do registro das variações |

<Note>
  O `totalPrice` é o valor **efetivamente debitado**, já com os descontos aplicados. Ele pode ser `0` quando o jogador já era dono de todas as peças.
</Note>

```lua theme={null}
onBeforeBuy = function(source, items)
    if #items > 20 then
        return false
    end

    return true
end,
```

### Roupa atual

| Hook                             | Quando dispara                                                               |
| -------------------------------- | ---------------------------------------------------------------------------- |
| `onSaveClothes(source, clothes)` | Depois de persistir a roupa atual do jogador — ou seja, a cada troca de peça |

<Tip>
  Use para sincronizar a roupa com outros recursos que mantêm o próprio cache.
</Tip>

### Outfits pessoais

| Hook                                             | Quando dispara                   |
| ------------------------------------------------ | -------------------------------- |
| `onBeforeSaveOutfit(source, slot, pieces, name)` | Antes de salvar. `false` cancela |
| `onSaveOutfit(source, slot, pieces, name)`       | Depois de salvar                 |
| `onDeleteOutfit(source, slot, name)`             | Depois de excluir                |

### Compartilhamento

| Hook                                          | Quando dispara                                     |
| --------------------------------------------- | -------------------------------------------------- |
| `onBeforeShareOutfit(source, target, pieces)` | Antes de pedir o compartilhamento. `false` cancela |
| `onShareOutfit(source, target, pieces)`       | Depois de entregar o outfit ao destinatário        |

```lua theme={null}
onBeforeShareOutfit = function(source, target, pieces)
    -- Ex.: bloquear compartilhamento entre facções rivais.
    return true
end,
```

### Outfits de organização

| Hook                                                           | Quando dispara                                     |
| -------------------------------------------------------------- | -------------------------------------------------- |
| `onBeforeSaveGroupOutfit(source, groupId, name, pieces)`       | Antes de um líder criar um outfit. `false` cancela |
| `onSaveGroupOutfit(source, groupId, name, pieces)`             | Depois de criar                                    |
| `onUpdateGroupOutfit(source, groupId, outfitId, name, pieces)` | Depois de editar                                   |
| `onDeleteGroupOutfit(source, groupId, outfitId)`               | Depois de excluir                                  |

### Pontos do mapa

| Hook                                 | Quando dispara                                                                  |
| ------------------------------------ | ------------------------------------------------------------------------------- |
| `onCreateBlip(source, blipId, blip)` | Depois de criar um ponto                                                        |
| `onUpdateBlip(source, blipId, blip)` | Depois de editar um ponto. `blip` pode ser `nil` se a releitura não o encontrar |
| `onDeleteBlip(source, blipId)`       | Depois de remover um ponto                                                      |

***

## Client ou server?

<CardGroup cols={2}>
  <Card title="Client" icon="display">
    Efeitos visuais, bloqueio de abertura, integração com outras interfaces e reaplicação de overlays no ped.
  </Card>

  <Card title="Server" icon="server">
    Regras de negócio, cobrança, permissões, persistência e qualquer coisa que **não pode** depender do client.
  </Card>
</CardGroup>

<Warning>
  Regra de decisão: se o hook precisa **impedir alguma coisa de verdade**, coloque a lógica no servidor. Um hook de client protege contra acidente, não contra má-fé.
</Warning>

<Card title="Exports" icon="code" href="/scripts/skinshop/dev/exports" horizontal>
  As funções que outros scripts podem chamar no dk\_skinshop.
</Card>
