> For the complete documentation index, see [llms.txt](https://visionstore.gitbook.io/visionstore-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://visionstore.gitbook.io/visionstore-docs/scripts/weaponhub/developers/exports-and-events.md).

# Exports and events

The OpenHub and IsCustomizing exports, the saved event, and the weapon metadata the hub writes.

## Server exports

### OpenHub

Opens the hub for a player where they stand: for a shop NPC, a crafting table, an item or a command of your own. Returns `true` when it opened.

```lua
exports.vision_weaponhub:OpenHub(source)

exports.vision_weaponhub:OpenHub(source, {
    label = 'Gunsmith',
    jobs = { mechanic = 2 },                                    -- optional
    items = { 'weapon_toolkit' },                               -- optional, not used up
    price = { amount = 500, account = 'cash', charge = 'save' } -- optional
})
```

| Argument | Meaning                                                                                            |
| -------- | -------------------------------------------------------------------------------------------------- |
| `source` | The player's server id                                                                             |
| `rules`  | Optional. `label`, `jobs`, `items` and `price`, exactly like a workbench in `config/locations.lua` |

If the player is refused, they get the reason as a notification and the export returns `false`. The session ends when the player walks further than `Config.MaxDistance` from where it opened.

### IsCustomizing

```lua
local busy = exports.vision_weaponhub:IsCustomizing(source) -- true while the player has the hub open
```

## Server events

### vision\_weaponhub:saved

Fired after every successful save that changed something.

```lua
AddEventHandler('vision_weaponhub:saved', function(source, data)
    -- data.weapon    'WEAPON_CARBINERIFLE_MK2'
    -- data.slot      inventory slot of the weapon
    -- data.added     number of parts fitted
    -- data.removed   number of parts removed
    -- data.tint      true when the tint changed
    -- data.livery    true when the camo colour changed
    -- data.charged   { { amount = 300, account = 'cash' }, ... }
    -- data.summary   'WEAPON_CARBINERIFLE_MK2 slot 3: +2 -1 parts, tint'
end)
```

The same summary is also sent to `lib.logger` (ox\_lib's logger, if you configured one) under the event name `vision_weaponhub`.

{% hint style="warning" %}
Use **`AddEventHandler`**. This is a local server event: don't register it with `RegisterNetEvent`, which would let clients fake it.
{% endhint %}

## Client events

### vision\_weaponhub:openFromInventory

```lua
TriggerEvent('vision_weaponhub:openFromInventory', slot)
```

What the "Customize" button in ox\_inventory fires (local client event). Opens the hub on the weapon in that inventory slot, following `Config.InventoryButton`. The server checks the slot and the bench rules before anything opens.

## Common uses

{% tabs %}
{% tab title="Gunsmith NPC" %}

```lua
-- server.lua of your NPC script
RegisterNetEvent('my_gunsmith:talk', function()
    local src = source
    exports.vision_weaponhub:OpenHub(src, {
        label = 'Gunsmith',
        price = { amount = 250, account = 'cash', charge = 'save' },
    })
end)
```

{% endtab %}

{% tab title="Field kit command" %}

```lua
-- server.lua: /fieldkit opens the hub anywhere for players carrying a toolkit
RegisterCommand('fieldkit', function(source)
    if source <= 0 then return end
    exports.vision_weaponhub:OpenHub(source, {
        label = 'Field Kit',
        items = { 'weapon_toolkit' },   -- refused with a notification if missing
    })
end, false)
```

{% endtab %}

{% tab title="Discord log" %}

```lua
local WEBHOOK = 'https://discord.com/api/webhooks/...'

AddEventHandler('vision_weaponhub:saved', function(source, data)
    local text = ('🔧 **%s** (%d): %s'):format(GetPlayerName(source), source, data.summary)
    PerformHttpRequest(WEBHOOK, function() end, 'POST', json.encode({ content = text }),
        { ['Content-Type'] = 'application/json' })
end)
```

{% endtab %}

{% tab title="Leave players at the bench alone" %}

```lua
-- In your robbery / cuff / carry script (server)
if exports.vision_weaponhub:IsCustomizing(source) then
    return
end
```

{% endtab %}
{% endtabs %}

## Weapon metadata

The hub writes only these keys of an ox\_inventory weapon's metadata. Everything else is kept as is.

| Key             | Written by          | Meaning                                                                          |
| --------------- | ------------------- | -------------------------------------------------------------------------------- |
| `components`    | Hub + ox\_inventory | Item names of the installed parts (ox\_inventory's own format)                   |
| `tint`          | Hub + ox\_inventory | Tint index. Absent for tint 0                                                    |
| `liveryColor`   | Hub                 | MK II camo colour (0 to 31, or your palette's index)                             |
| `componentMeta` | Hub                 | Metadata of installed parts, given back when removed (`Config.KeepPartMetadata`) |

Parts installed by another script or by ox\_inventory's own "attach" are shown as installed when the hub knows them, and are never touched when it doesn't.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://visionstore.gitbook.io/visionstore-docs/scripts/weaponhub/developers/exports-and-events.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
