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

# Arquitetura do Framework (vRP)

> Como os recursos da Base Five conversam entre si pela API do framework vRP e como inicializar um recurso novo para consumi-la.

Este documento descreve a arquitetura interna do framework **vRP** usado pela Base Five. O conteúdo foi extraído diretamente do código em `resources/vrp/` e descreve como os recursos conversam entre si e como inicializar (bootstrap) um recurso novo para consumir a API.

***

## 1. Visão geral

O coração do servidor é o resource `vrp`. Ele define dois objetos de interface (tabelas Lua) publicados via os primitivos de RPC:

<CardGroup cols={2}>
  <Card title="vRP — servidor" icon="server">
    Tabela do **servidor** com a lógica de negócio: dinheiro, inventário, identidade, grupos…
  </Card>

  <Card title="tvRP — cliente" icon="display">
    Tabela do **cliente**: manipulação do ped, anim, veículos próximos…
  </Card>
</CardGroup>

Em `resources/vrp/modules/vrp.lua` (servidor):

```lua theme={null}
Proxy = module("lib/Proxy")
Tunnel = module("lib/Tunnel")
vRPC = Tunnel.getInterface("vRP")   -- proxy server -> client

vRP = {}
tvRP = {}

Proxy.addInterface("vRP", vRP)        -- publica a interface server<->server
Tunnel.bindInterface("vRP", tvRP)     -- expõe handlers que o cliente pode chamar
```

Em `resources/vrp/client/base.lua` (cliente):

```lua theme={null}
tvRP = {}
Proxy.addInterface("vRP", tvRP)
Tunnel.bindInterface("vRP", tvRP)
vRPS = Tunnel.getInterface("vRP")    -- proxy client -> server
```

***

## 2. Proxy vs Tunnel

Os dois primitivos ficam em `resources/vrp/lib/Proxy.lua` e `resources/vrp/lib/Tunnel.lua`.

<AccordionGroup>
  <Accordion title="Proxy — mesma realm (server↔server ou client↔client)" icon="arrows-left-right">
    Comunicação **dentro da mesma realm**. Baseado em `TriggerEvent` local.

    * `Proxy.addInterface(name, table)`: publica uma interface.
    * `Proxy.getInterface(name)`: retorna um proxy que chama os métodos da interface.

    É assim que todo script de servidor obtém o framework:

    ```lua theme={null}
    local Proxy = module("vrp","lib/Proxy")
    vRP = Proxy.getInterface("vRP")
    ```
  </Accordion>

  <Accordion title="Tunnel — entre realms (server↔client)" icon="tower-broadcast">
    Comunicação **entre servidor e cliente** via eventos de rede.

    * `Tunnel.bindInterface(name, table)`: expõe as funções da tabela para a outra realm.
    * `Tunnel.getInterface(name)`: retorna um proxy chamável para a outra realm.

    <Note>
      **Detalhe importante:** quando o **servidor** chama uma função de cliente via Tunnel, o **primeiro argumento é sempre o `source`** (player de destino):

      ```lua theme={null}
      vRPC.SetHealth(source, 200)   -- source = destino, depois os args reais
      ```
    </Note>
  </Accordion>

  <Accordion title="O prefixo _ (fire-and-forget)" icon="bolt">
    Prefixar o método com `_` faz a chamada **não esperar retorno** (mais rápido):

    ```lua theme={null}
    local health = vRPC.GetHealth(source)   -- espera o retorno
    vRPC._SetHealth(source, 200)            -- não espera (fire-and-forget)
    ```

    Use `_` sempre que não precisar do valor de retorno.
  </Accordion>
</AccordionGroup>

***

## 3. Convenção vRP / tvRP / vRPC / vRPS

| Nome   | Onde     | O que é                              | Como obter                              |
| ------ | -------- | ------------------------------------ | --------------------------------------- |
| `vRP`  | Servidor | Interface Proxy (funções de negócio) | `Proxy.getInterface("vRP")`             |
| `tvRP` | Cliente  | Funções expostas via Tunnel          | declarada no `vrp`                      |
| `vRPC` | Servidor | Proxy Tunnel **server → client**     | `Tunnel.getInterface("vRP")` (servidor) |
| `vRPS` | Cliente  | Proxy Tunnel **client → server**     | `Tunnel.getInterface("vRP")` (cliente)  |

<Note>
  Em muitos recursos da base o proxy server→client é nomeado `vRPclient`: é o mesmo `Tunnel.getInterface("vRP")`, só muda o nome da variável.
</Note>

<Warning>
  **Nunca misture as tabelas:** `vRP.*` (Proxy, servidor) é indexado por **Passport** (id do personagem), não por `source`. Quem espera `source` é `vRPC.*` (Tunnel).
</Warning>

***

## 4. Bootstrap padrão de um recurso

<Steps>
  <Step title="Obtenha a interface do servidor">
    Lado servidor (ex. real de `five-bank/config/functions.lua`):

    ```lua theme={null}
    local Proxy = module("vrp", "lib/Proxy")
    vRP = Proxy.getInterface("vRP")
    ```
  </Step>

  <Step title="Exponha funções para a NUI/cliente (se necessário)">
    ```lua theme={null}
    local Tunnel = module("vrp", "lib/Tunnel")
    local src = {}
    Tunnel.bindInterface(GetCurrentResourceName(), src)
    local clientAPI = Tunnel.getInterface(GetCurrentResourceName())
    ```
  </Step>

  <Step title="Declare a dependência no fxmanifest.lua">
    ```lua theme={null}
    shared_scripts {
        "@vrp/lib/utils.lua",
        "@vrp/config/Global.lua",
        "config/config.lua",
    }

    server_scripts {
        "@oxmysql/lib/MySQL.lua",
        "config/functions.lua",
        "server-side/core.lua",
    }
    ```
  </Step>
</Steps>

<Note>
  A função `module()` (de `lib/utils.lua`) recebe `(Resource, Patch)`. De **dentro** do `vrp`, use `module("lib/Proxy")`. De **outro** resource, use `module("vrp","lib/Proxy")`.
</Note>

### Acesso ao banco de dados

Passa por oxmysql via prepared statements nomeados: `vRP.Prepare(Nome, SQL)` e depois `vRP.Query`, `vRP.SingleQuery`, `vRP.Scalar` ou `vRP.Update`. Recursos próprios costumam usar `exports.oxmysql:query_async(...)` diretamente.

***

## 5. Módulos em `resources/vrp/modules/`

| Módulo            | Responsabilidade                                                            |
| ----------------- | --------------------------------------------------------------------------- |
| `vrp.lua`         | Inicialização: cria `vRP`/`tvRP`, publica interfaces, obtém `vRPC`.         |
| `base.lua`        | Núcleo de sessão: acesso a DB, contas, dados do player, conexão/desconexão. |
| `banned.lua`      | Banimento por HWID/conta.                                                   |
| `drugs.lua`       | Timers de efeitos (maconha, álcool, químicos).                              |
| `groups.lua`      | Grupos, empregos e serviço (ponto), salários.                               |
| `identity.lua`    | Identidade do personagem, placas, tokens, prisão, gemas.                    |
| `inventory.lua`   | Inventário, itens, peso, baús.                                              |
| `permissions.lua` | Metadados das permissões (tabela `permissions`).                            |
| `money.lua`       | Banco/dinheiro.                                                             |
| `player.lua`      | Estado físico do player (vida, fome/sede, XP, teleporte).                   |
| `misc.lua`        | Aliases de compatibilidade (camelCase → funções reais).                     |
| `prepare.lua`     | Registra todos os prepared statements nomeados.                             |
| `vehicles.lua`    | `vRP.SelectVehicle`: consulta veículo do dono.                              |

<Note>
  A pasta `modules/` tem três arquivos que **não são carregados** pelo `fxmanifest.lua`: `jester.lua` e `lb-phone.lua` (implementações alternativas de integração com celular, ativadas conforme o celular usado) e `playing.lua` (`vRP.UpdatePlaying`, `vRP.TimePlaying`, `vRP.WipePlaying`). Enquanto não forem adicionados ao manifesto, essas funções não existem em runtime.
</Note>

<Warning>
  **Aviso sobre `misc.lua`:** ele cria aliases por atribuição direta. Vários apontam para funções que **não existem** e resultam em `nil`. NÃO dependa de: `vRP.setWeight`, `vRP.userPremium`, `vRP.falseIdentity`, `vRP.getFines`/`addFines`/`delFines`, `vRP.generateStringNumber`. (Multas/faturas são tratadas pelo `five-bank` via `exports`.) Os aliases cujo alvo existe estão listados em [Funções do Servidor](/base-five/framework/servidor).
</Warning>
