# Blips Menu

<figure><img src="https://3626236831-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fa8uHYewwKFFVyUWKAUtL%2Fuploads%2FFv1LMOBE2Uaweb27nfSe%2Fblips.jpg?alt=media&#x26;token=4630d9a0-e31b-4bf8-9d79-95c7fe267091" alt=""><figcaption></figcaption></figure>

***

## Table of Contents

1. [Overview](#overview)
2. [Features Summary](#features-summary)
3. [Installation](#installation)
4. [Configuration](#configuration)
   * [Framework Settings](#framework-settings)
   * [Language Settings](#language-settings)
   * [Access Control](#access-control)
   * [Default Blip Settings](#default-blip-settings)
   * [Discord Webhook](#discord-webhook)
5. [Database](#database)
6. [How It Works](#how-it-works)
   * [Flow](#flow)
   * [Blip Types](#blip-types)
   * [Blip Properties](#blip-properties)
   * [Job Whitelisting](#job-whitelisting)
7. [NUI Interface](#nui-interface)
   * [Main Menu](#main-menu)
   * [Customize Panel](#customize-panel)
   * [Sprite Selector](#sprite-selector)
   * [Create Dialog](#create-dialog)
8. [Admin vs Player Permissions](#admin-vs-player-permissions)
9. [Exports & Events](#exports--events)
   * [Server Callbacks](#server-callbacks)
   * [Server Events](#server-events)
   * [Client Events](#client-events)
   * [Client Commands](#client-commands)
   * [NUI Callbacks](#nui-callbacks)
   * [Server Exports](#server-exports)
10. [Localization](#localization)
11. [File Structure](#file-structure)
12. [Security](#security)
13. [Troubleshooting](#troubleshooting)
14. [Changelog](#changelog)
15. [Support](#support)

***

## Overview

XeX Blips Manager is a premium, full-featured blip management system for FiveM servers. It provides a modern glassmorphism NUI interface that allows admins to create public blips visible to all players, and regular players to create private blips visible only to themselves. Built with multi-framework support and optimized for performance.

### Supported Frameworks

| Framework  | Version | Status         |
| ---------- | ------- | -------------- |
| ESX Legacy | 1.6.0+  | ✅ Full Support |
| QBCore     | Latest  | ✅ Full Support |
| QBox       | Latest  | ✅ Full Support |

***

## Features Summary

### Core Features

| Category       | Feature              | Description                                                                                          |
| -------------- | -------------------- | ---------------------------------------------------------------------------------------------------- |
| **Blips**      | Public Blips         | Admins can create blips visible to all players                                                       |
| **Blips**      | Private Blips        | Regular players can create blips visible only to themselves                                          |
| **Blips**      | 3 Blip Types         | Normal markers, square area blips, and radius circle blips                                           |
| **UI**         | Glassmorphism Design | Modern dark translucent glass-effect interface                                                       |
| **UI**         | Tab System           | Filter by All / Public / Private with live badge counters                                            |
| **UI**         | Search               | Instant search by blip name with debounced input                                                     |
| **UI**         | Responsive           | Auto-fill card grid, min 150px per card                                                              |
| **Customizer** | Sprite Selector      | Visual grid with 500+ GTA blip sprites, searchable by ID                                             |
| **Customizer** | Color Grid           | 86 GTA blip colors with hex preview                                                                  |
| **Customizer** | Full Properties      | Scale, opacity, rotation, outline, tick, short range, display mode                                   |
| **Customizer** | Advanced Properties  | Flashes, heading indicator, cone, GPS route, category, priority, hide legend, high detail (ESX only) |
| **Customizer** | Dynamic Controls     | Controls show/hide based on blip type                                                                |
| **Management** | Move Blip            | Relocate a blip by clicking on map (ESX only)                                                        |
| **Management** | Duplicate Blip       | Clone a blip with offset coordinates (ESX only)                                                      |
| **Management** | Export Blips         | Export all blips as JSON file, admin only (ESX only)                                                 |
| **Management** | Import Blips         | Import blips from JSON file, admin only (ESX only)                                                   |
| **Management** | Corrupt Recovery     | Corrupt blip cards shown in red with delete option                                                   |
| **Access**     | Job Whitelisting     | Restrict public blips to specific jobs (comma-separated)                                             |
| **Access**     | Admin Roles          | Configurable admin roles for public blip management                                                  |
| **Access**     | Private Toggle       | Allow/deny non-admins from opening the menu                                                          |
| **System**     | Auto SQL Table       | Creates database table automatically on first start                                                  |
| **System**     | Discord Webhooks     | Logs blip creation, updates, and deletions                                                           |
| **System**     | Auto Updater         | Checks for new versions via GitHub Gist on startup                                                   |
| **System**     | Multi-Framework      | ESX, QBCore, QBox with per-framework logic                                                           |
| **I18n**       | 2 Languages          | English, Spanish                                                                                     |
| **Perf**       | Optimized            | Sleep-based loops, only active when map is open                                                      |

***

## Installation

### Requirements

* FiveM Server Build 5181+
* [oxmysql](https://github.com/overextended/oxmysql)
* [ox\_lib](https://github.com/overextended/ox_lib) (required for all frameworks)
* Framework: ESX Legacy, QBCore, or QBox

### Quick Start

{% stepper %}
{% step %}

### Place resource

Place `xex_blipsmenu` in your resources folder.
{% endstep %}

{% step %}

### Add to server.cfg

Add:

```cfg
ensure xex_blipsmenu
```

{% endstep %}

{% step %}

### Configure

Edit `config.lua` as needed.
{% endstep %}

{% step %}

### Restart server

Restart server — the database table is created automatically on first start.
{% endstep %}
{% endstepper %}

> Note: No manual SQL import is needed. The table `user_blips` is auto-created on resource start.

### Recommended Resource Order

```cfg
# server.cfg
ensure oxmysql
ensure ox_lib
ensure es_extended     # or qb-core / qbx_core
ensure xex_blipsmenu
```

***

## Configuration

### Framework Settings

```lua
Config.Framework = 'auto' -- 'auto' | 'esx' | 'qb' | 'qbox'
```

| Value    | Framework                                  |
| -------- | ------------------------------------------ |
| `'auto'` | Auto-detect: QBox → QBCore → ESX (default) |
| `'esx'`  | ESX Legacy                                 |
| `'qb'`   | QBCore                                     |
| `'qbox'` | QBox (qbx\_core)                           |

### Language Settings

```lua
Config.Language = 'en' -- 'en' | 'es'
```

| Code | Language          |
| ---- | ----------------- |
| `en` | English           |
| `es` | Spanish (Español) |

### Access Control

```lua
Config.AllowPrivateBlips = true       -- Allow non-admin players to open the menu (private blips only)
Config.AdminRoles = {'admin', 'mod'}  -- Roles that can create/manage public blips
```

| Option              | Default            | Description                                                                                                       |
| ------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------- |
| `AllowPrivateBlips` | `true`             | When `true`, all players can open the menu and create private blips. When `false`, only admins can open the menu. |
| `AdminRoles`        | `{'admin', 'mod'}` | Roles/permissions checked for public blip access                                                                  |

Admin detection per framework:

| Framework | Method                                                                  |
| --------- | ----------------------------------------------------------------------- |
| ESX       | `xPlayer.group` compared against `Config.AdminRoles`                    |
| QBCore    | `QBCore.Functions.HasPermission` + `IsPlayerAceAllowed(src, 'command')` |
| QBox      | `IsPlayerAceAllowed(src, role)` for each role in `AdminRoles`           |

### Default Blip Settings

```lua
Config.DefaultNewBlipName = 'New Blip'   -- Default name for newly created blips
Config.DefaultNewBlipSprite = 123        -- Default sprite ID (Ammunation icon)
```

### Keybind

```lua
Config.OpenMenuMapping = 'SPACE'  -- Key to open menu while big map is open
```

### Discord Webhook

```lua
Config.WebhookEnabled = false              -- Enable/disable Discord logging
Config.WebhookServerName = 'My Server'     -- Server name in embeds
Config.Webhook = ''                        -- Discord webhook URL
Config.DateFormat = '%d/%m/%Y [%X]'        -- Timestamp format
Config.IconUrl = 'https://i.imgur.com/w3JYiO0.png'  -- Embed thumbnail
Config.BotName = 'Blips BOT'               -- Bot display name
```

| Option              | Default                     | Description                         |
| ------------------- | --------------------------- | ----------------------------------- |
| `WebhookEnabled`    | `false`                     | Enable Discord webhook logging      |
| `WebhookServerName` | `'My Server'`               | Server name shown in embed footer   |
| `Webhook`           | `''`                        | Discord webhook URL                 |
| `DateFormat`        | `'%d/%m/%Y [%X]'`           | Lua `os.date` format for timestamps |
| `IconUrl`           | `'https://i.imgur.com/...'` | Thumbnail URL for webhook embeds    |
| `BotName`           | `'Blips BOT'`               | Bot display name for webhooks       |

Webhook Events:

| Action | Color              | Description        |
| ------ | ------------------ | ------------------ |
| Create | 🟢 Green (65352)   | New blip created   |
| Update | 🔵 Blue (13172480) | Blip data modified |
| Delete | 🔴 Red (16515843)  | Blip deleted       |

Each embed includes: Player server ID, License identifier, Discord mention, Action description, Timestamp.

### Auto Updater

```lua
Config.CheckForUpdates = true  -- Check for updates on resource start
```

***

## Database

### SQL Table (Auto-Created)

The `user_blips` table is automatically created on first resource start via `server/scrow.lua`. No manual import needed.

```sql
CREATE TABLE IF NOT EXISTS `user_blips` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `identifier` VARCHAR(90) NOT NULL,
    `blipcoords` VARCHAR(120) NOT NULL,
    `blipdata` TEXT NOT NULL,
    `bliptype` VARCHAR(20) NOT NULL,
    `created` DATE DEFAULT (CURRENT_DATE),
    PRIMARY KEY (`id`),
    INDEX `idx_bliptype` (`bliptype`),
    INDEX `idx_identifier` (`identifier`)
);
```

| Column       | Type                | Description                          |
| ------------ | ------------------- | ------------------------------------ |
| `id`         | INT AUTO\_INCREMENT | Primary key                          |
| `identifier` | VARCHAR(90)         | Player identifier (license)          |
| `blipcoords` | VARCHAR(120)        | JSON string `{x, y, z}`              |
| `blipdata`   | TEXT                | JSON object with all blip properties |
| `bliptype`   | VARCHAR(20)         | `'public'` or `'private'`            |
| `created`    | DATE                | Auto-set to creation date            |

***

## How It Works

### Flow

{% stepper %}
{% step %}

### Resource Start

* `scrow.lua` auto-creates `user_blips` table
* Server loads all public blips into memory
* Updater checks for new versions
  {% endstep %}

{% step %}

### Player Join

* Client requests admin status (getMyRank / isAdmin)
* Client requests blip data (getStatus callback)
* Receives public blips + own private blips
* Renders all blips on GTA map
  {% endstep %}

{% step %}

### Opening Menu

* Player opens GTA big map (Pause menu → Map)
* Help notification shows "Press SPACE to open blips menu"
* Player presses SPACE → NUI menu opens
* Non-admins see Private blips only (Public button hidden)
* Admins see both Public and Private options
  {% endstep %}

{% step %}

### Creating a Blip

* Player clicks "Private" or "Public" button
* Dialog appears: "Enter Coordinates" or "Select on Map"
* Blip saved to database via server callback
* If public: broadcast to ALL clients via refreshPublicBlips
* If private: only visible to creator
  {% endstep %}

{% step %}

### Editing/Deleting

* Click blip card → Customize panel opens on left
* Modify properties and save
* Or click trash icon to delete
* Server validates ownership/admin permissions
  {% endstep %}
  {% endstepper %}

### Blip Types

| Type        | ID | Description                | GTA Native         |
| ----------- | -- | -------------------------- | ------------------ |
| Normal      | 1  | Standard map marker (pin)  | `AddBlipForCoord`  |
| Square Area | 2  | Rectangular area highlight | `AddBlipForArea`   |
| Circle      | 3  | Circular radius highlight  | `AddBlipForRadius` |

### Blip Properties

| Property        | Type   | Range    | Description                                   |
| --------------- | ------ | -------- | --------------------------------------------- |
| `title`         | string | —        | Display name (appears on map)                 |
| `sprite`        | int    | 0-500+   | GTA blip sprite ID                            |
| `colour`        | int    | 0-85     | GTA blip color index                          |
| `scale`         | string | 0-10     | Marker size (normal blips)                    |
| `alpha`         | int    | 0-255    | Transparency (0 = invisible, 255 = opaque)    |
| `display`       | int    | —        | GTA display mode                              |
| `tick`          | bool   | —        | Show tick mark on blip                        |
| `outline`       | bool   | —        | Show outline ring                             |
| `short`         | bool   | —        | Short range (disappears when zoomed out)      |
| `showon`        | int    | 2/3/5    | 2=Map & Minimap, 3=Map only, 5=Minimap only   |
| `whitelist`     | string | —        | Comma-separated job names (public blips only) |
| `type`          | int    | 1/2/3    | Blip type (Normal/Square/Circle)              |
| `w`             | int    | 0-1500   | Area/radius size (type 2 & 3 only)            |
| `h`             | int    | 0-1500   | Area height (type 2 only)                     |
| `rotation`      | int    | 0-90     | Rotation degrees (type 2 only)                |
| `flashes`       | bool   | —        | Blip flashes on/off (ESX only)                |
| `flashInterval` | int    | 100-2000 | Flash interval in ms (ESX only)               |
| `number`        | int    | 0-99     | Number displayed on blip (ESX only)           |
| `heading`       | bool   | —        | Show heading direction indicator (ESX only)   |
| `showCone`      | bool   | —        | Show vision cone on blip (ESX only)           |
| `category`      | int    | 1-10     | Blip category for map filtering (ESX only)    |
| `priority`      | int    | 0-10     | Blip render priority (ESX only)               |
| `hideLegend`    | bool   | —        | Hide from map legend (ESX only)               |
| `highDetail`    | bool   | —        | High detail rendering (ESX only)              |
| `gpsRoute`      | bool   | —        | Show GPS route line to blip (ESX only)        |
| `routeColour`   | int    | 0-29     | GPS route line color (ESX only)               |

### Job Whitelisting

Public blips can be restricted to specific jobs using the `whitelist` field:

```
police,ambulance,mechanic
```

* Players with matching jobs will see the blip
* Empty whitelist = visible to all
* Only applies to public blips
* Automatically re-evaluated when a player's job changes

***

## NUI Interface

### Main Menu

**Position:** Center screen, 52% width × 55% height

| Element       | Description                                                                                                                                     |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Header        | Title bar with "Private" and "Public" create buttons. Public button hidden for non-admins.                                                      |
| Tabs          | All / Public / Private with live badge counters showing blip counts                                                                             |
| Search        | Instant filtering by blip name with 300ms debounce                                                                                              |
| Blip Cards    | Responsive grid (`auto-fill`, min 150px). Shows sprite preview, name, type badge. Hover reveals 4 action buttons: Duplicate, Move, Edit, Delete |
| Corrupt Cards | Blips with missing/invalid data show as red "Corrupt #ID" cards with a delete-only button                                                       |
| Admin Toolbar | Export and Import buttons shown to admins (ESX only)                                                                                            |
| Empty State   | Helpful icon and text when no blips match current filter                                                                                        |

### Customize Panel

**Position:** Left sidebar, 320px wide, max 70vh. Opens when clicking a blip card.

| Control           | Visibility          | Description                                              |
| ----------------- | ------------------- | -------------------------------------------------------- |
| Blip Type         | Always              | Selector: Normal / Square Area / Circle                  |
| Title             | Always              | Text input for blip name                                 |
| Whitelisted Jobs  | Public blips only   | Comma-separated job names                                |
| Sprite            | Normal only         | Visual preview + "Change" button to open sprite selector |
| Color             | Always              | 86-color GTA blip color grid with hex values             |
| Area Scale        | Area/Circle only    | Slider 0-1500                                            |
| Rotation          | Square Area only    | Slider 0-90°                                             |
| Scale             | Normal only         | Slider 0-10x                                             |
| Opacity           | Always              | Slider 0-255                                             |
| Outline           | Normal only         | Toggle Yes/No                                            |
| Tick              | Normal only         | Toggle Yes/No                                            |
| Short Range       | Normal only         | Toggle Yes/No                                            |
| Show On           | Normal only         | Map & Minimap / Map only / Minimap only                  |
| Flashes           | Normal only         | Toggle Yes/No (ESX only)                                 |
| Flash Interval    | Normal + Flashes=on | Slider in milliseconds (ESX only)                        |
| Number            | Normal only         | Slider 0-99 (ESX only)                                   |
| Heading Indicator | Normal only         | Toggle Yes/No (ESX only)                                 |
| Show Cone         | Normal only         | Toggle Yes/No (ESX only)                                 |
| Category          | Normal only         | Dropdown selector (ESX only)                             |
| Priority          | Normal only         | Slider (ESX only)                                        |
| Hide Legend       | Normal only         | Toggle Yes/No (ESX only)                                 |
| High Detail       | Normal only         | Toggle Yes/No (ESX only)                                 |
| GPS Route         | Normal only         | Toggle Yes/No (ESX only)                                 |
| Route Color       | Normal + GPS=on     | 30-color grid (ESX only)                                 |
| Height            | Square Area only    | Slider 0-1500 (ESX only)                                 |

### Sprite Selector

**Position:** Center overlay, 55% × 55%

* Grid of 500+ GTA blip sprite images (40×40px each)
* Search by sprite ID **or name** with debounced filtering
* **Category tab filtering:** Services, Shops, Vehicles, Properties, Entertainment, Basic, Other
* Images loaded from `nui/img/bliptypes/` folder
* Click sprite to select and return to customize panel

### Create Dialog

**Position:** Full-screen overlay modal

When creating a new blip, the player chooses:

| Option            | Description                                     |
| ----------------- | ----------------------------------------------- |
| Enter Coordinates | Manually type X and Y coordinates               |
| Select on Map     | Click directly on the GTA map to place the blip |

***

## Admin vs Player Permissions

| Action                      | Player                            | Admin    |
| --------------------------- | --------------------------------- | -------- |
| Open menu                   | ✅ (if `AllowPrivateBlips = true`) | ✅ Always |
| Create private blips        | ✅                                 | ✅        |
| Create public blips         | ❌                                 | ✅        |
| Edit own private blips      | ✅                                 | ✅        |
| Edit public blips           | ❌                                 | ✅        |
| Delete own private blips    | ✅                                 | ✅        |
| Delete public blips         | ❌                                 | ✅        |
| Set job whitelisting        | ❌                                 | ✅        |
| Move blip coordinates (ESX) | Own only                          | Any      |
| Duplicate blips (ESX)       | ✅ (own type)                      | ✅        |
| Export all blips (ESX)      | ❌                                 | ✅        |
| Import blips (ESX)          | ❌                                 | ✅        |

***

## Exports & Events

### Server Callbacks

#### ESX

| Callback                            | Parameters                   | Returns                                 | Description                                                 |
| ----------------------------------- | ---------------------------- | --------------------------------------- | ----------------------------------------------------------- |
| `xex_blipsmenu:saveNewBlip`         | `coords`, `blipType`, `data` | Blip object or `{public = publicBlips}` | Creates a new blip. Only admins can create `'public'` type. |
| `xex_blipsmenu:getStatus`           | —                            | `{public, private}`                     | Returns all public blips + player's private blips           |
| `xex_blipsmenu:getMyRank`           | —                            | `string` (e.g., `'admin'`)              | Returns the player's ESX group                              |
| `xex_blipsmenu:isPaid` (*not used*) | —                            | —                                       | Reserved                                                    |

#### QBCore

| Callback                    | Parameters                   | Returns             | Description                                       |
| --------------------------- | ---------------------------- | ------------------- | ------------------------------------------------- |
| `xex_blipsmenu:saveNewBlip` | `coords`, `blipType`, `data` | Blip object         | Creates a new blip with QB permission checks      |
| `xex_blipsmenu:getStatus`   | —                            | `{public, private}` | Returns all public blips + player's private blips |
| `xex_blipsmenu:isAdmin`     | —                            | `boolean`           | Checks `HasPermission` + ACE permissions          |

#### QBox

| Callback                    | Parameters                   | Returns             | Description                                           |
| --------------------------- | ---------------------------- | ------------------- | ----------------------------------------------------- |
| `xex_blipsmenu:saveNewBlip` | `coords`, `blipType`, `data` | Blip object         | Uses `lib.callback.register` and `MySQL.insert.await` |
| `xex_blipsmenu:getStatus`   | —                            | `{public, private}` | Uses `lib.callback.register` and `MySQL.query.await`  |
| `xex_blipsmenu:isAdmin`     | —                            | `boolean`           | Uses `IsPlayerAceAllowed` for each role               |

#### ESX (Additional)

| Callback                    | Parameters | Returns      | Description                                  |
| --------------------------- | ---------- | ------------ | -------------------------------------------- |
| `xex_blipsmenu:exportBlips` | —          | `blipsArray` | Returns all blips from database. Admin only. |

### Server Events

| Event                       | Parameters            | Description                                                            |
| --------------------------- | --------------------- | ---------------------------------------------------------------------- |
| `xex_blipsmenu:updateBlip`  | `blipId`, `data`      | Updates blip data. Validates ownership or admin status.                |
| `xex_blipsmenu:removeBlip`  | `blipId`              | Deletes a blip. Validates ownership or admin status.                   |
| `xex_blipsmenu:moveBlip`    | `blipId`, `newCoords` | Moves a blip to new coordinates. Validates ownership/admin. (ESX only) |
| `xex_blipsmenu:importBlips` | `blipsArray`          | Bulk imports blips from JSON array. Admin only. (ESX only)             |

### Client Events

| Event                                 | Data                    | Description                                                            |
| ------------------------------------- | ----------------------- | ---------------------------------------------------------------------- |
| `xex_blipsmenu:refreshPublicBlips`    | `{public = blipsArray}` | Received when public blips change. Re-renders all public blips on map. |
| `esx:setJob` (ESX only)               | job data                | Listens for job changes to re-render job-whitelisted blips             |
| `QBCore:Client:OnJobUpdate` (QB/QBox) | job data                | Same purpose for QB/QBox frameworks                                    |

### Client Commands

| Command         | Key Mapping      | Description                                                           |
| --------------- | ---------------- | --------------------------------------------------------------------- |
| `showblipsmenu` | Default: `SPACE` | Opens the Blips Manager NUI. Only works when the GTA big map is open. |

### NUI Callbacks

| Callback         | Data                                | Description                                                                             |
| ---------------- | ----------------------------------- | --------------------------------------------------------------------------------------- |
| `closeButton`    | —                                   | Closes NUI, releases cursor focus                                                       |
| `create`         | `{visibility: 'public'\|'private'}` | Enters create mode (player clicks map to place blip)                                    |
| `createByCoords` | `{visibility, coords}`              | Creates blip at manually entered X/Y coordinates                                        |
| `refreshBlip`    | blip data                           | Updates a blip's data locally and re-renders map blips                                  |
| `removeBlip`     | blip id                             | Removes blip locally and triggers server delete event                                   |
| `saveBlip`       | blip data                           | Saves blip changes and triggers server update event                                     |
| `duplicateBlip`  | blip data                           | Clones a blip with +50 offset to coordinates and " (copy)" suffix. ESX only             |
| `moveBlip`       | blip data                           | Enters move mode — player clicks on map to set new coordinates. ESX only                |
| `exportBlips`    | —                                   | Triggers server export callback, downloads JSON file via Blob URL. Admin only, ESX only |
| `importBlips`    | JSON array                          | Sends blip array to server for bulk import. Admin only, ESX only                        |

### Server Exports

| Export            | Description                                                 |
| ----------------- | ----------------------------------------------------------- |
| `CheckForUpdates` | Programmatically trigger update check from another resource |

### Console Commands

| Command            | Access              | Description                          |
| ------------------ | ------------------- | ------------------------------------ |
| `blipsmenu_update` | Server console only | Manually triggers the update checker |

***

## Localization

### Supported Languages

| Code | Language |
| ---- | -------- |
| `en` | English  |
| `es` | Español  |

### Locale Keys

```lua
Locales = {
    ['en'] = {
        ['blips_menu']              = 'Press SPACEBAR to open blips menu',
        ['open_blips_menu']         = 'Blips Menu',
        ['blip_created']            = 'A new blip has been created',
        ['blip_created_title']      = 'Blip Created',
        ['blip_updated']            = 'Blip has been updated',
        ['blip_updated_title']      = 'Blip Updated',
        ['blip_removed']            = 'A blip has been removed',
        ['blip_removed_title']      = 'Blip Removed',
        ['blip_moved']              = 'Blip has been moved',
        ['blip_moved_title']        = 'Blip Moved',
        ['move_hint']               = 'Click on the map to set new position',
        ['blip_duplicated']         = 'Blip has been duplicated',
        ['blip_duplicated_title']   = 'Blip Duplicated',
        ['export_success']          = 'Blips exported successfully',
        ['import_success']          = 'Blips imported successfully',
    },
}
```

### Adding Languages

{% stepper %}
{% step %}

### Add language block

Add a new language block in `locales.lua` with all keys.
{% endstep %}

{% step %}

### Configure language

Set `Config.Language` to your language code.
{% endstep %}
{% endstepper %}

***

## File Structure

```
xex_blipsmenu/
├── config.lua              # All configuration options
├── fxmanifest.lua          # Resource manifest
├── locales.lua             # EN/ES translations
├── readme.md               # Quick reference
├── DOCS.md                 # This documentation
├── client/
│   ├── esx.lua             # ESX client logic
│   ├── qb.lua              # QBCore client logic
│   ├── qbox.lua            # QBox client logic
│   └── scrow.lua           # Shared utility (isBigMapOpen)
├── server/
│   ├── esx.lua             # ESX server callbacks & webhooks
│   ├── qb.lua              # QBCore server callbacks
│   ├── qbox.lua            # QBox server callbacks
│   ├── scrow.lua           # Auto SQL table creation + cleanTargets
│   └── updater.lua         # Auto update checker
└── nui/
    ├── index.html           # Main UI structure
    ├── script.js            # UI controller & logic (jQuery)
    ├── styles.css           # Glassmorphism styling
    └── img/
        └── bliptypes/       # 500+ blip sprite PNG images
```

***

## Security

### Permission Validation

* **Create:** Only admins can create public blips. Server-side role check before insert.
* **Update:** Server validates that the requesting player owns the blip (private) or is an admin (public).
* **Delete:** Same ownership/admin validation as update.
* **Move:** Server validates ownership (private) or admin (public). ESX only.
* **Export/Import:** Server-side admin check before operation. ESX only.
* **NUI:** Public create button is hidden for non-admins in the UI, but also validated server-side.

### Identifier Handling

| Framework | Method                                                                 |
| --------- | ---------------------------------------------------------------------- |
| ESX       | `xPlayer.identifier`                                                   |
| QBCore    | `GetPlayerIdentifierByType(src, 'license')`                            |
| QBox      | `GetPlayerIdentifierByType(src, 'license2')` with `'license'` fallback |

***

## Troubleshooting

| Issue                           | Solution                                                                                             |
| ------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Menu not opening                | Ensure you have the GTA **big map** open (not minimap). Press the configured key (default: `SPACE`). |
| "No blips" showing              | Check that the resource started without errors. Verify `oxmysql` is running.                         |
| Public blips not visible        | Verify the blip doesn't have a job whitelist that excludes your job.                                 |
| Private blips aren't saving     | Check `oxmysql` connection. Look for SQL errors in server console.                                   |
| Players can't open menu         | Set `Config.AllowPrivateBlips = true` to allow non-admins.                                           |
| Webhook not sending             | Set `Config.WebhookEnabled = true` and provide a valid `Config.Webhook` URL.                         |
| Blip not showing on map         | Check blip `alpha > 0`, `scale > 0`, and appropriate `showon` value.                                 |
| ox\_lib errors                  | Ensure `ox_lib` is started before `xex_blipsmenu` in server.cfg.                                     |
| Admin can't create public blips | Check `Config.AdminRoles` matches your admin group name.                                             |
| SQL table not created           | Check `oxmysql` is running and database connection is valid.                                         |

***

## Changelog

### v2.1.0

* Added QBox (qbx\_core) framework support
* Uses native QBox exports and `lib.callback` (ox\_lib) instead of deprecated QBCore bridge
* Admin detection via ACE permissions (`IsPlayerAceAllowed`)
* Player identification via `GetPlayerIdentifierByType` (license2 with license fallback)
* Notifications via `lib.notify` (ox\_lib)
* Loads ox\_lib internally via `pcall(load(LoadResourceFile(...)))` in QBox client/server files

### v2.0.0

* Complete UI rewrite with modern glassmorphism design
* Dynamic sprite and color grids (no more hardcoded HTML)
* Tab system with search and filtering
* Migrated from mysql-async to oxmysql
* All MySQL queries converted to async (no more `MySQL.Sync` blocking calls)
* Server-side permission validation on blip update/delete
* Auto-create SQL table on startup
* Dedicated update checker via GitHub Gist
* Debounced search inputs
* Fixed `removeBlipFromEntities` unsafe iteration bug
* Fixed QBCore job detection storing object instead of name
* Fixed `blipdata` column from `VARCHAR(230)` to `TEXT`
* Added database indexes for `bliptype` and `identifier`
* Removed obsolete `GetSharedObject` patterns
* Removed duplicate version checkers
* Removed hardcoded webhook URL from default config
* Fixed global `privateBlips` variable leak between player sessions

### v1.0.2

* Fix for non-export sharedObject on ESX

### v1.0.1

* Added support for ESX getSharedObject export

***

## Support

| Channel | Link                                                   |
| ------- | ------------------------------------------------------ |
| Discord | [discord.gg/9yY3Jxnhh8](https://discord.gg/9yY3Jxnhh8) |

***


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jesus-gimenez.gitbook.io/xex-scripts/premium-mods/blips-menu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
