# Server

## Events (General)

### SetBodyCamState

* Registers a **server-side event** to manually control a player's bodycam state, typically used in scenarios such as **temporary permission overrides** or **anti-cheat bypasses**.

<details>

<summary>rcore_police:server:SetBodyCamState</summary>

* **Params:**

  | Name       | Type      | Description                                      |
  | ---------- | --------- | ------------------------------------------------ |
  | `playerId` | `number`  | Target playerId which you want to set permission |
  | `state`    | `boolean` | Used for listening for player state.             |
* **Example:**

```lua
AddEventHandler('rcore_police:server:SetBodyCamState', function(playerId, state)
    -- REGISTER PLAYER TEMP PERMISSION
end)
```

</details>

## Exports (Listeners)

### onGroups

* Used for listening for any onGroups actions

<details>

<summary>onGroups</summary>

* **Params:**

  | Name           | Type     | Description                                          |
  | -------------- | -------- | ---------------------------------------------------- |
  | `listenerName` | `string` | Name of the listener to register for onGroups events |
* **Returns:**
  * `string`: Type - current action/task being done
  * `table`: The data of player in that group
* **Example:**

```lua
-- return: type: string, data: table
exports["rcore_police"]:registerListener("onGroups", function(type, data)
    print("Received 'onGroups' event:")
    print("Type:", type)
    print("Data:", json.encode(data))
end)
```

</details>

### onState

* Used for listening for any interaction actions on players

<details>

<summary>onState</summary>

* **Params:**

  | Name           | Type     | Description                                         |
  | -------------- | -------- | --------------------------------------------------- |
  | `listenerName` | `string` | Name of the listener to register for onState events |
* **Returns:**
  * `type`: Current type (string)
  * `action`: Current action (string)
  * `playerId`: Performed state change on playerId (number)
* **Example:**

```lua
-- return: type: string, action: string, playerId: number
exports["rcore_police"]:registerListener("onGroups", function(type, action, playerId)
    print("Received 'onState' event:")
    print("Type:", type)
    print("Action:", action)
    print("Player ID:", playerId)
end)
```

</details>

## Exports (States)

### IsPlayerCuffed

* Used for checking if player is cuffed

<details>

<summary>IsPlayerCuffed</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                        |
  | ---------- | -------- | -------------------------------------------------- |
  | `playerId` | `number` | ID of player which you want to get state of cuffed |
* **Returns:**
  * `boolean`: `true` if player is cuffed, otherwise `false`.
* **Example:**

```lua
-- playerId: number
-- return: boolean
local isCuffed = exports['rcore_police']:IsPlayerCuffed(playerId)

if isCuffed then
    print('Player is cuffed')
else
    print('Player is not cuffed')
end
```

</details>

### IsPlayerEscorted

* Used for checking if player is escorted

<details>

<summary>IsPlayerEscorted</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                        |
  | ---------- | -------- | -------------------------------------------------- |
  | `playerId` | `number` | ID of player which you want to get state of escort |
* **Returns:**
  * `boolean`: `true` if player is escorted, otherwise `false`.
* **Example:**

```lua
-- playerId: number
-- return: boolean
local isEscorted = exports['rcore_police']:IsPlayerEscorted(playerId)

if isEscorted then
    print('Player is escorted')
else
    print('Player is not escorted')
end
```

</details>

### IsPlayerHeadBagged

* Used for checking if player is head bagged

<details>

<summary>IsPlayerHeadBagged</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                          |
  | ---------- | -------- | ---------------------------------------------------- |
  | `playerId` | `number` | ID of player which you want to get state of head bag |
* **Returns:**
  * `boolean`: `true` if player is head bagged, otherwise `false`.
* **Example:**

```lua
-- playerId: number
-- return: boolean
local isHeadBagged = exports['rcore_police']:IsPlayerHeadBagged(playerId)

if isHeadBagged  then
    print('Player is head bagged')
else
    print('Player is not head bagged')
end
```

</details>

## Exports (Actions)

### JailPlayer

* Used for jailing player, it will open Dialog form to put specific player in jail

<details>

<summary>JailPlayer</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                    |
  | ---------- | -------- | ---------------------------------------------- |
  | `playerId` | `number` | ID of player which is starting the interaction |
  | `target`   | `number` | ID of player which you want to get jailed      |
* **Returns:**
  * `boolean`: `true` if player is jailed, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- playerId: number
-- target: number
-- return: boolean, string
local isJailed, statusOrErr = exports['rcore_police']:JailPlayer(playerId, target)

if isJailed then
    print('Player is jailed')
else
    print('Player is not jailed an error occurred:', statusOrErr)
end
```

</details>

### SearchPlayer

* Used for searching player, it will try to open search of target player inventory

<details>

<summary>SearchPlayer</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                     |
  | ---------- | -------- | ----------------------------------------------- |
  | `playerId` | `number` | ID of player which is starting the interaction  |
  | `target`   | `number` | ID of player which you want to search inventory |
* **Returns:**
  * `boolean`: `true` if player is searched, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- playerId: number
-- target: number
-- return: boolean, string
local isSearched, statusOrErr = exports['rcore_police']:SearchPlayer(playerId, target)

if isSearched then
    print('Player is searched')
else
    print('Player is not searched an error occurred:', statusOrErr)
end
```

</details>

### Escort

* Used for setting/unsetting escort to target player

<details>

<summary>Escort</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                    |
  | ---------- | -------- | ---------------------------------------------- |
  | `playerId` | `number` | ID of player which is starting the interaction |
  | `target`   | `number` | ID of player which you want to get escorted    |
* **Returns:**
  * `boolean`: `true` if player is escorted, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- playerId: number
-- target: number
-- return: boolean, string
local isEscorted, statusOrErr = exports['rcore_police']:Escort(playerId, target)

if isEscorted then
    print('Player is escorted')
else
    print('Player is not escorted')
end
```

</details>

### Zipties

* Used for setting/unsetting Zipties to target player

<details>

<summary>Zipties</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                    |
  | ---------- | -------- | ---------------------------------------------- |
  | `playerId` | `number` | ID of player which is starting the interaction |
  | `target`   | `number` | ID of player which you want to set zipties     |
* **Returns:**
  * `boolean`: `true` if player is ziptied, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- playerId: number
-- target: number
-- return: boolean, string
local isZiptied, statusOrErr = exports['rcore_police']:Zipties(playerId, target)

if isZiptied then
    print('Player is ziptied')
else
    print('Player is not ziptied')
end
```

</details>

### Handcuff

* Used for setting/unsetting Handcuff to target player

<details>

<summary>Handcuff</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                    |
  | ---------- | -------- | ---------------------------------------------- |
  | `playerId` | `number` | ID of player which is starting the interaction |
  | `target`   | `number` | ID of player which you want to set handcuffs   |
* **Returns:**
  * `boolean`: `true` if player is handcuffs, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- playerId: number
-- target: number
-- return: boolean, string
local isCuffed, statusOrErr = exports['rcore_police']:Handcuff(playerId, target)

if isCuffed then
    print('Player is handcuffed')
else
    print('Player is not handcuffed')
end
```

</details>

### PutPlayerInVehicle

* Used for PutPlayerInVehicle target player into nearby vehicle seat

<details>

<summary>PutPlayerInVehicle</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                     |
  | ---------- | -------- | ----------------------------------------------- |
  | `playerId` | `number` | ID of player which is starting the interaction  |
  | `target`   | `number` | ID of player which you want to set into vehicle |
* **Returns:**
  * `boolean`: `true` if player is set into vehicle, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- playerId: number
-- target: number
-- return: boolean, string
local isInVehicle, statusOrErr = exports['rcore_police']:PutPlayerInVehicle(playerId, target)

if isInVehicle then
    print('Player is in vehicle')
else
    print('Player is not in vehicle')
end
```

</details>

### TakePlayerFromVehicle

* Used for TakePlayerFromVehicle target player from nearby vehicle

<details>

<summary>TakePlayerFromVehicle</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                     |
  | ---------- | -------- | ----------------------------------------------- |
  | `playerId` | `number` | ID of player which is starting the interaction  |
  | `target`   | `number` | ID of player which you want to get from vehicle |
* **Returns:**
  * `boolean`: `true` if player is outside of vehicle, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- playerId: number
-- target: number
-- return: boolean, string
local isFromVehicle, statusOrErr = exports['rcore_police']:TakePlayerFromVehicle(playerId, target)

if isFromVehicle then
    print('Player is not in vehicle')
else
    print('Player is in vehicle')
end
```

</details>

### RemoveHandcuff

* Used for removing handcuffs/zipties from target player

<details>

<summary>RemoveHandcuff</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name       | Type     | Description                                             |
  | ---------- | -------- | ------------------------------------------------------- |
  | `playerId` | `number` | ID of player which is starting the interaction          |
  | `target`   | `number` | ID of player which you want to remove handcuffs/zipties |
* **Returns:**
  * `boolean`: `true` if player handcuffs/zipties are removed, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- playerId: number
-- target: number
-- return: boolean, string
local isRemovedCuffs, statusOrErr = exports['rcore_police']:RemoveHandcuff(playerId, target)

if isRemovedCuffs then
    print('Player is free')
else
    print('Player not free')
end
```

</details>

### ForceUncuff

* Used for removing zipties/cuffs

<details>

<summary>ForceUncuff</summary>

* **Type:** `boolean`
* **Default value::** `false`
* **Params:**

  | Name     | Type     | Description                                             |
  | -------- | -------- | ------------------------------------------------------- |
  | `target` | `number` | ID of player which you want to remove handcuffs/zipties |
* **Returns:**
  * `boolean`: `true` if player handcuffs/zipties are removed, otherwise `false`.
  * `string`: Status code or error message
* **Example:**

```lua
-- target: number
-- return: boolean, string
local isRemovedCuffs, statusOrErr = exports['rcore_police']:ForceUncuff(target)

if isRemovedCuffs then
    print('Player is free')
else
    print('Player not free')
end
```

</details>

## Exports (General)

### GetPoliceOnline

* Used for getting all police officers online

<details>

<summary>GetPoliceOnline</summary>

* **Type:** `number`
* **Default value::** `0`
* **Returns:**
  * `number`: Number of officers online, by default returns 0 when not any online
* **Example:**

```lua
-- return: number
local policeOnline = exports['rcore_police']:GetPoliceOnline()

if policeOnline then
    print('Online units: ', retval)
end
```

</details>

### CreateInvoiceByServer

> ⚠️ **Warning:** This export is **not** a replacement for your invoice system. It is a hook over the rcore\_police invoice system when using the standalone bridge or a supported invoice system.

> ℹ️ **Configuration:** The distribution of invoice payments depends on the `InvoiceSystem.WhenInvoiceSentBalanceToAllDepartmentJobs` setting in your config:
>
> * **`true`**: The invoice amount will be split equally among all department society accounts
> * **`false`**: Only the issuing job's society account receives the money

* Used for creating an invoice for a player directly from the server-side (e.g., for automated billing systems, admin commands, or integration with other resources)

<details>

<summary>CreateInvoiceByServer</summary>

* **Params:**

  | Name       | Type     | Description                                          |
  | ---------- | -------- | ---------------------------------------------------- |
  | `targetId` | `number` | Player ID of the user who should receive the invoice |
  | `amount`   | `number` | The amount the player should pay                     |
  | `metadata` | `table`  | Additional data containing `job` and `reason`        |
* **Metadata Table:**

  | Name     | Type      | Description                                                                                                                                                                                                                                 |
  | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `job`    | `string?` | The job/department issuing the invoice (e.g., "police", "taxi"). Must be a valid department group defined in your configuration with an existing society account. If not provided, all department groups are used or defaults to `"police"` |
  | `reason` | `string`  | The reason for the invoice                                                                                                                                                                                                                  |
* **Returns:**
  * `boolean`: `true` if the invoice was created successfully, otherwise `false`
* **Example:**

```lua
-- Basic usage: Issue a speeding ticket
local success = exports["rcore_police"]:CreateInvoiceByServer(targetPlayerId, 500, {
    job = "police",
    reason = "Speeding violation - 120 km/h in a 50 km/h zone"
})

if success then
    print("Invoice created successfully")
else
    print("Failed to create invoice")
end
```

```lua
-- Example: Admin command to issue a fine
RegisterCommand("issuefine", function(source, args, rawCommand)
    local targetId = tonumber(args[1])
    local amount = tonumber(args[2])
    local reason = table.concat(args, " ", 3)

    if not targetId or not amount or not reason then
        print("Usage: /issuefine [playerId] [amount] [reason]")
        return
    end

    local success = exports["rcore_police"]:CreateInvoiceByServer(targetId, amount, {
        job = "police",
        reason = reason
    })

    if success then
        print(string.format("Fine of $%d issued to player %d for: %s", amount, targetId, reason))
    else
        print("Failed to issue fine")
    end
end, true) -- restricted to admins
```

</details>

### GetBodyCamPlayers

<details>

<summary>GetBodyCamPlayers</summary>

* **Type:** `(table, string)`
* **Returns:**
  * `table` - Array of active bodycam players
  * `string` - Status code (`"OK"` or `"EMPTY"`)
* **Return Structure:**

```lua
{
    [1] = {
        playerId = 1,                    -- Server player ID
        playerCoords = vector3(x, y, z), -- Player coordinates
        officerName = "John Doe",        -- Character name
        location = ""                    -- Location string
    },
    [2] = { ... }
}
```

* **Example:**

```lua
---@return table retval         -- Array of bodycam player data
---@return string statusCode    -- "OK" | "EMPTY"
local retval, statusCode = exports["rcore_police"]:GetBodyCamPlayers()

if statusCode == "OK" then
    for _, bodycam in ipairs(retval) do
        print("Officer:", bodycam.officerName, "ID:", bodycam.playerId)
    end
end
```

</details>

***

### SpectateBodycam

<details>

<summary>SpectateBodycam</summary>

* **Type:** `(boolean, string)`
* **Parameters:**
  * `playerId` (number) - The player who will spectate
  * `officerPlayerId` (number) - The officer whose bodycam to spectate
* **Returns:**
  * `boolean` - Success state
  * `string` - Status code (`"OK"`, `"INVALID_PLAYER_ID"`, `"INVALID_OFFICER_ID"`, `"SAME_PLAYER"`, `"NO_ACTIVE_BODYCAM"`)
* **Example:**

```lua
---@param playerId number        -- Player who will spectate
---@param officerPlayerId number -- Officer with active bodycam
---@return boolean retval        -- Success state
---@return string statusCode     -- "OK" | "INVALID_PLAYER_ID" | "INVALID_OFFICER_ID" | "SAME_PLAYER" | "NO_ACTIVE_BODYCAM"
local retval, statusCode = exports["rcore_police"]:SpectateBodycam(playerId, officerPlayerId)
```

</details>

***

### ActivateOfficerBodycam

<details>

<summary>ActivateOfficerBodycam</summary>

* **Type:** `(void)`
* **Parameters:**
  * `playerId` (number) - The officer player ID to activate bodycam for
* **Returns:**
  * `void` - Toggles bodycam state (activates if inactive, deactivates if active)
* **Example:**

```lua
---@param playerId number -- Officer player ID
exports["rcore_police"]:ActivateOfficerBodycam(playerId)
```

</details>

***

### DeactivateOfficerBodycam

<details>

<summary>DeactivateOfficerBodycam</summary>

* **Type:** `(void)`
* **Parameters:**
  * `playerId` (number) - The officer player ID to deactivate bodycam for
* **Returns:**
  * `void` - Toggles bodycam state (activates if inactive, deactivates if active)
* **Example:**

```lua
---@param playerId number -- Officer player ID
exports["rcore_police"]:DeactivateOfficerBodycam(playerId)
```

</details>

***

### GetActiveTackles

<details>

<summary>GetActiveTackles</summary>

* **Type:** `(table, string)`
* **Returns:**
  * `table` - Registry of active tackles
  * `string` - Status code (`"OK"` or `"EMPTY"`)
* **Return Structure:**

```lua
{
    [1] = {
        initiator = 1,           -- Server player ID of the cop doing the tackle
        target = 2,              -- Server player ID of the person being tackled
        startTime = 123456789    -- GetGameTimer() when tackle started
    },
    [2] = { ... }
}
```

* **Example:**

```lua
---@return table retval         -- TackleRegistry table
---@return string statusCode    -- "OK" | "EMPTY"
local retval, statusCode = exports["rcore_police"]:GetActiveTackles()

if statusCode == "OK" then
    for tackleId, tackle in pairs(retval) do
        print("Tackle #" .. tackleId .. ": Cop " .. tackle.initiator .. " tackling " .. tackle.target)
    end
end
```

</details>

***

### IsTackled

<details>

<summary>IsTackled</summary>

* **Type:** `(boolean, string)`
* **Parameters:**
  * `playerId` (number) - The player ID to check
* **Returns:**
  * `boolean` - Whether the player is currently tackled
  * `string` - Status code (`"OK"` or `"INVALID_PLAYER_ID"`)
* **Example:**

```lua
---@param playerId number        -- Player ID to check
---@return boolean retval        -- Is player tackled
---@return string statusCode     -- "OK" | "INVALID_PLAYER_ID"
local retval, statusCode = exports["rcore_police"]:IsTackled(playerId)

if retval then
    print("Player is currently tackled!")
end
```

</details>

***

### GetPlayerTackleInfo

<details>

<summary>GetPlayerTackleInfo</summary>

* **Type:** `(table|nil, string)`
* **Parameters:**
  * `playerId` (number) - The player ID to get tackle info for
* **Returns:**
  * `table|nil` - Tackle info object or nil if not tackled
  * `string` - Status code (`"OK"`, `"INVALID_PLAYER_ID"`, `"NOT_TACKLED"`, `"TACKLE_NOT_FOUND"`)
* **Return Structure:**

```lua
{
    tackleId = 1,            -- Unique tackle identifier
    role = "initiator",      -- "initiator" (cop) or "target" (tackled player)
    initiator = 1,           -- Server player ID of the cop doing the tackle
    target = 2,              -- Server player ID of the person being tackled
    startTime = 123456789    -- GetGameTimer() when tackle started
}
```

* **Example:**

```lua
---@param playerId number        -- Player ID to get info for
---@return table|nil retval      -- Tackle info object
---@return string statusCode     -- "OK" | "INVALID_PLAYER_ID" | "NOT_TACKLED" | "TACKLE_NOT_FOUND"
local retval, statusCode = exports["rcore_police"]:GetPlayerTackleInfo(playerId)

if retval then
    print("Role:", retval.role)
    print("Initiator:", retval.initiator)
    print("Target:", retval.target)
    print("Duration:", GetGameTimer() - retval.startTime, "ms")
end
```

</details>

***

### RemoveTackleByPlayer

<details>

<summary>RemoveTackleByPlayer</summary>

* **Type:** `(boolean, string)`
* **Parameters:**
  * `playerId` (number) - The player ID involved in the tackle
  * `skipClientReset` (boolean, optional) - Skip sending client reset events
* **Returns:**
  * `boolean` - Success state
  * `string` - Status code (`"OK"`, `"INVALID_PLAYER_ID"`, `"NOT_TACKLED"`, `"TACKLE_NOT_FOUND"`)
* **Example:**

```lua
---@param playerId number        -- Player ID to remove tackle for
---@param skipClientReset boolean? -- Optional: skip client reset
---@return boolean retval        -- Success state
---@return string statusCode     -- "OK" | "INVALID_PLAYER_ID" | "NOT_TACKLED" | "TACKLE_NOT_FOUND"
local retval, statusCode = exports["rcore_police"]:RemoveTackleByPlayer(playerId)

if retval then
    print("Tackle removed successfully!")
else
    print("Failed to remove tackle:", statusCode)
end
```

</details>


---

# 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://documentation.rcore.cz/paid-resources/rcore_police/index/index-1.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.
