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

# Exports

> Guide to the exports for the n4_queue resource

Exports let other resources interact with `n4_queue`. All exports are **server-side only**; the queue has no client exports.

## Server exports overview

| Export                      | Arguments                                                                   | Returns   | Description                                                                                                          |
| --------------------------- | --------------------------------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------- |
| `HandleConnection`          | `name: string`, `source: number`, `deferrals: table`, `identifier?: string` | —         | Manually start the queue connection flow. Only used when `queue:manual_connection` is `1`.                           |
| `GetDiscordUser`            | `identifier: string`                                                        | `table?`  | Discord user data for a player by their primary identifier. `nil` if not found or Discord disabled.                  |
| `GetDiscordUserBySource`    | `source: number`                                                            | `table?`  | Discord user data for a player by server id. `nil` if not found or Discord disabled.                                 |
| `AddDiscordPrioRole`        | `roleId: string \| number`, `points: number`                                | —         | Add a Discord role → priority points mapping at runtime.                                                             |
| `RemoveDiscordPrioRole`     | `roleId: string \| number`                                                  | —         | Remove a Discord priority role.                                                                                      |
| `AddWhitelistRoleId`        | `roleId: string \| number`                                                  | —         | Add a Discord role ID to the whitelist (no duplicates).                                                              |
| `RemoveWhitelistRoleId`     | `roleId: string \| number`                                                  | —         | Remove a Discord role ID from the whitelist.                                                                         |
| `AddBypassIdentifier`       | `identifier: string`                                                        | —         | Add a full identifier to the queue bypass list (skips queue, can use reserved slots).                                |
| `RemoveBypassIdentifier`    | `identifier: string`                                                        | —         | Remove an identifier from the bypass list.                                                                           |
| `IsPlayerInQueue`           | `identifier: string`                                                        | `boolean` | Whether a player with that identifier is currently in the queue.                                                     |
| `GetPlayerPosition`         | `identifier: string`                                                        | `table?`  | Queue position info for a player (`position`, `totalInQueue`). `nil` if not in queue.                                |
| `GetQueueLength`            | —                                                                           | `number`  | Current number of players in the queue.                                                                              |
| `GetPlayerPriorityPoints`   | `identifier: string`                                                        | `number?` | Priority points for a player in the queue. `nil` if not in queue.                                                    |
| `GetTopQueuePlayers`        | `count?: number`                                                            | `table[]` | Top N players in queue (default 10). Each entry: `priorityPoints`, `username`, `avatar`.                             |
| `GetEstimatedWaitString`    | `position: number`, `startupDelay: number`                                  | `string?` | Human-readable estimated wait (e.g. `"2m 30s"`). Uses startup delay or advance history. `nil` if unknown.            |
| `GetConnectingPlayersCount` | —                                                                           | `number`  | Number of players currently in the connecting state (post-queue, before fully loaded in).                            |
| `SetGracePriority`          | `identifier: string`, `durationSeconds: number`                             | —         | Grant temporary grace priority; uses `queue:grace_priority_points` on next connect. Pass `0` or negative to clear.   |
| `GetGracePriorityExpiry`    | `identifier: string`                                                        | `number?` | Unix timestamp when grace priority expires, or `nil` if none.                                                        |
| `RemoveGracePriority`       | `identifier: string`                                                        | —         | Remove grace priority for an identifier (e.g. as an admin action).                                                   |
| `Locale`                    | `key: string`, `...any`                                                     | `string`  | Get a localized string by key (same as queue UI). Supports format args, e.g. `Locale('card_position', 1, 10, 5000)`. |
| `GetQueueConfig`            | —                                                                           | `table`   | Read-only snapshot of queue config (reserved\_slots, max\_slots, grace settings, etc.).                              |

***

## HandleConnection (manual connection)

When `queue:manual_connection` is `1`, you must call this export from your own `playerConnecting` handler **after** your checks (bans, whitelists, etc.). The queue then takes over the rest of the connection flow.

**Signature:** `HandleConnection(name, source, deferrals, identifier?)`

* `name` **(required)** — Player name from the connection event.
* `source` **(required)** — Player server id (`source` from `playerConnecting`).
* `deferrals` **(required)** — Deferrals table from the connection callback.
* `identifier` **(optional)** — Primary identifier for the player (e.g. `license2:xxx`). If omitted, the queue will attempt to resolve it internally.

```lua theme={null}
local queue = exports.n4_queue

AddEventHandler('playerConnecting', function(name, _, deferrals)
    local source = source
    local identifier = GetPlayerIdentifierByType(source, 'steam')

    deferrals.defer()
    Wait(0)
    deferrals.update('Checking if you are banned...')

    if IsPlayerBanned(identifier) then
        return deferrals.done('You are banned!')
    end

    queue:HandleConnection(name, source, deferrals, identifier) -- identifier optional
end)
```

***

## Discord exports

Only apply when Discord integration is enabled (`queue:discord:enabled` = `1`).

* **GetDiscordUser** / **GetDiscordUserBySource** — Look up cached Discord user data (e.g. username, nickname, avatar, roles) by primary identifier or by `source`.
* **AddDiscordPrioRole** / **RemoveDiscordPrioRole** — Add or remove a Discord role → priority points entry at runtime without editing config.
* **AddWhitelistRoleId** / **RemoveWhitelistRoleId** — Add or remove a role ID from the Discord whitelist at runtime.

```lua theme={null}
local queue = exports.n4_queue

-- Add a priority role when your resource starts
queue:AddDiscordPrioRole('123456789', 5000)

-- Check if a connected player has Discord data
local discord = queue:GetDiscordUserBySource(source)
if discord then
    print(discord.username, discord.avatar)
end
```

***

## Bypass identifiers

Players whose identifier is in the bypass list skip the queue and can use reserved slots. When the server is full, they are still queued like everyone else.

* **AddBypassIdentifier(identifier)** — `identifier` must be a full identifier string (e.g. `license2:xxx`, `discord:yyy`). No duplicates added.
* **RemoveBypassIdentifier(identifier)** — Removes that identifier from the bypass list.

```lua theme={null}
local queue = exports.n4_queue

-- Grant bypass to a specific license (e.g. through an admin command)
queue:AddBypassIdentifier('license2:abc123...')

-- Revoke bypass
queue:RemoveBypassIdentifier('license2:abc123...')
```

***

## Queue state

* **IsPlayerInQueue(identifier)** — Returns `true` if a player with that primary identifier is currently in the queue, `false` otherwise.
* **GetPlayerPosition(identifier)** — Returns a table with `position` (1-based) and `totalInQueue`, or `nil` if the player is not in the queue.
* **GetQueueLength()** — Returns the current number of players in the queue.
* **GetPlayerPriorityPoints(identifier)** — Returns the priority points for that player if they are in the queue, or `nil` if not.
* **GetTopQueuePlayers(count?)** — Returns the top `count` players (default `10`) in the queue. Each entry has `priorityPoints`, `username`, and `avatar`.
* **GetEstimatedWaitString(position, startupDelay)** — Returns a human-readable estimated wait (e.g. `"2m 30s"`) for someone at the given queue position. Uses `startupDelay` (seconds) when the server is still in startup; otherwise uses recent advance history. Returns `nil` when an estimate cannot be computed.
* **GetConnectingPlayersCount()** — Returns how many players are currently in the connecting state (past the queue, not yet fully loaded in).

```lua theme={null}
local queue = exports.n4_queue

-- Check if in queue and get position
local inQueue = queue:IsPlayerInQueue('license2:abc123...')
local pos = queue:GetPlayerPosition('license2:abc123...')
if pos then
    print('Position:', pos.position, 'of', pos.totalInQueue)
end

-- Queue size and priority
local length = queue:GetQueueLength()
local points = queue:GetPlayerPriorityPoints('license2:abc123...')

-- Top players for a leaderboard
local top = queue:GetTopQueuePlayers(5)
for i, p in ipairs(top) do
    print(i, p.username, p.priorityPoints)
end

-- Estimated wait (e.g. for UI)
local waitStr = queue:GetEstimatedWaitString(3, 0)  -- position 3, no startup delay
if waitStr then
    print('Estimated wait:', waitStr)
end

-- Players past queue but still connecting
local connecting = queue:GetConnectingPlayersCount()
```

***

## Grace priority

Grace priority gives a player temporary priority points when they next connect (e.g. after a crash or disconnect). The queue uses `queue:grace_priority_points` and `queue:grace_priority_timer` for the actual points and duration unless you only set expiry.

* **SetGracePriority(identifier, durationSeconds)** — Grant grace priority for `durationSeconds` seconds. Pass `0` or a negative number to clear.
* **GetGracePriorityExpiry(identifier)** — Returns the Unix timestamp when grace expires, or `nil` if the player has no grace priority.
* **RemoveGracePriority(identifier)** — Remove grace priority (e.g. as an admin action).

```lua theme={null}
local queue = exports.n4_queue

-- Grant 10 minutes of grace (e.g. after purchase)
queue:SetGracePriority('license2:abc123...', 600)

-- Check if they still have grace
local expiry = queue:GetGracePriorityExpiry('license2:abc123...')
if expiry and os.time() < expiry then
    print('Grace active until ' .. os.date('%c', expiry))
end

-- Revoke grace priority
queue:RemoveGracePriority('license2:abc123...')
```

***

## Locale

* **Locale(key, ...)** — Returns the localized string for `key` (same keys as the queue UI). Extra arguments are used for formatting (e.g. `Locale('card_position', position, queueLength, points)`).

```lua theme={null}
local queue = exports.n4_queue
local msg = queue:Locale('card_position', 1, 10, 5000)
```

***

## GetQueueConfig

* **GetQueueConfig()** — Returns a read-only table with the current queue configuration (e.g. `reserved_slots`, `max_slots`, `stack_priority`, `grace_priority_enabled`, `grace_priority_points`, `grace_priority_timer`, `connection_delay`, `server_startup_delay`, `modify_hostname`, `queue_list_display`). Useful for other resources that need to respect queue limits or display info.

```lua theme={null}
local queue = exports.n4_queue
local cfg = queue:GetQueueConfig()
print('Reserved slots:', cfg.reserved_slots, 'Max slots:', cfg.max_slots)
```

***

## Client exports

`n4_queue` does **not** expose any client exports. All logic runs on the server; nothing from this resource runs on the client.
