# Server

### IsPlayerAllowedToOpenMenu

This function determines if player that is trying to open admin menu should be added to database as an administrator. If it returns `true` player can open admin menu, but he can't do anything because he has no permissions set.

```lua
---@param targetId number
---@return boolean
IsPlayerAllowedToOpenMenu = function(targetId)
  local xPlayer = ESX.GetPlayerFromId(targetId)

  if IsPlayerAceAllowed(targetId, 'lc_adminmenu.open') then
    return true
  end

  for i = 1, #allowed_groups do
    if xPlayer.group == allowed_groups[i] then
      return true
    end
  end

  return false
end
```

### GetPermissionGroup

```lua
---@param targetId number
---@return string
GetPermissionGroup = function(targetId)
  local xPlayer = ESX.GetPlayerFromId(targetId)
  
  for i = 1, #allowed_groups do
    local group = allowed_groups[i]
    if xPlayer.group == group then
      return group
    end
  end

  return 'user'
end
```

{% content-ref url="/pages/RBRzNOqLlcDo1o6KoZrZ" %}
[Permission Groups](/docs/lc_adminmenu/permissions/permission-groups.md)
{% endcontent-ref %}

### GetAvatar

{% hint style="info" %}
GetDiscordAvatarFromId is our custom function that requests discord API and stores player's avatar in cache.\
See: [Discord functions](/docs/lc_adminmenu/discord-functions.md#getdiscordavatarfromid)
{% endhint %}

```lua
---@param targetId number
---@return string
GetAvatar = function(targetId)
  return GetDiscordAvatarFromId(targetId)
end
```

### GetBridgeIdentifier

If your framework has character-specific identifiers, you can put it here. (char1:xxxxx etc.)

```lua
---@param targetId number
---@return string
GetBridgeIdentifier = function(targetId)
  local xPlayer = ESX.GetPlayerFromId(targetId)
  return xPlayer?.identifier
end
```

### GetGlobalIdentifier

Rockstar license, you can change it to IP if you host  an sv\_lan server.

```lua
---@param targetId number
---@return string
GetGlobalIdentifier = function(targetId)
  return GetPlayerIdentifierByType(targetId, 'license')
end
```

### GetIdentifiers

```lua
---@param targetId number
---@return string[]
GetIdentifiers = function(targetId)
  local identifiers = GetPlayerIdentifiers(targetId)

  for i = 1, #identifiers do
    if identifiers[i]:find('ip') or identifiers[i]:find('license2') then
      identifiers[i] = nil
    end
  end

  return identifiers
end
```

### GetPlayerCard

```lua
---@class PlayerCard
---@field player_id number
---@field unique_id? string | number
---@field player_name string
---@field character_name? string

---@param targetId number
---@return PlayerCard
GetPlayerCard = function(targetId)
  local xPlayer = ESX.GetPlayerFromId(targetId)

  return {
    player_id = targetId,
    unique_id = 'yay',
    player_name = GetPlayerName(targetId),
    character_name = xPlayer.name
  }
end
```

<div align="center" data-full-width="false"><figure><img src="/files/nyhKIPqcnylKDXITutUp" alt="" width="375"><figcaption></figcaption></figure></div>

### GetOwnedVehicles

`lc_admin:getVehicleLabels` callback executes Bridge.GetOwnedVehicleLabel, it's used to get vehicle labels from client-side\
[Client](/docs/lc_adminmenu/bridge/client.md#getownedvehiclelabel)

```lua
---@class Vehicle
---@field plate string
---@field label string

---@param sourceId number
---@return Vehicle[]
GetOwnedVehicles = function(sourceId, identifier)
  local result = MySQL.query.await('SELECT plate, vehicle from `owned_vehicles` WHERE `owner` = ?', { identifier })
  local formatted = lib.callback.await('lc_admin:getVehicleLabels', sourceId, result)
  return formatted
end
```

<figure><img src="/files/ryJ6gByB7QDA6hNzLRIS" alt="" width="465"><figcaption></figcaption></figure>

### GetAccounts

```lua
---@class Account
---@field name string
---@field money number
---@field label string
---@field icon 'bank' | 'dollar_sign' | 'cash' | 'coins' | 'cent'

---@param targetId string
---@return Account[]
GetAccounts = function(targetId)
  local xPlayer = ESX.GetPlayerFromId(targetId)
  return {
    {
      name = 'bank',
      money = xPlayer.getAccount('bank').money,
      label = 'Bank',
      icon = 'bank'
    },
    {
      name = 'money',
      money = xPlayer.getAccount('money').money,
      label = 'Cash',
      icon = 'cash'
    },
    {
      name = 'black_money',
      money = xPlayer.getAccount('black_money').money,
      label = 'Dirty Cash',
      icon = 'dollar_sign'
    },
  }
end
```

<figure><img src="/files/KN42eNiLJMWKfyAR1tIV" alt=""><figcaption></figcaption></figure>

### GetAccountMoney

```lua
---@param targetId number
---@param account_name string
---@return number
GetAccountMoney = function(targetId, account_name)
  local xPlayer = ESX.GetPlayerFromId(targetId)
  return xPlayer.getAccount(account_name)?.money or 0
end
```

### SetAccountMoney

```lua
---@param targetId number
---@param account_name string
---@param money number
SetAccountMoney = function(targetId, account_name, money)
    local xPlayer = ESX.GetPlayerFromId(targetId)
    xPlayer.setAccountMoney(account_name, money == '' and 0 or tonumber(money))
end
```

### GetCharacterInfo

```lua
---@class Tooltip
---@field label string
---@field value string

---@class InfoField
---@field label string
---@field value string
---@field tooltip? Tooltip

---@param targetId number
---@return InfoField[]
GetCharacterInfo = function(targetId)
  local xPlayer = ESX.GetPlayerFromId(targetId)
  return {
    {
      label = 'Name',
      value = xPlayer.name
    },
    {
      label = 'Employment',
      value = xPlayer.job.label,
      tooltip = {
        {
          label = 'Name',
          value = xPlayer.job.name
        },
        {
          label = 'Grade label',
          value = xPlayer.job.grade_label .. ' (' .. xPlayer.job.grade .. ')'
        },
        {
          label = 'Salary',
          value = '$' .. xPlayer.job.grade_salary
        }
      }
    },
    {
      label = 'Date Of Birth',
      value = xPlayer.variables.dateofbirth
    },
    {
      label = 'Height',
      value = xPlayer.variables.height .. 'cm'
    },
    {
      label = 'Owned vehicles',
      value = MySQL.scalar.await('SELECT COUNT(*) from `owned_vehicles` WHERE owner = ?', { xPlayer.identifier })
    }
  }
end
```

<figure><img src="/files/cLF4BpOsrg6rx4tN3JbB" alt="" width="563"><figcaption></figcaption></figure>

### DeleteVehicle

```lua
---@param src string Admin's server ID
---@param targetId number
---@param plate string
DeleteVehicle = function(src, targetId, plate)
  MySQL.query.await('DELETE FROM `owned_vehicles` WHERE plate = ?', { plate })
end
```

### IsPlateTaken

```lua
---@param plate string
---@return boolean
IsPlateTaken = function(plate)
  return MySQL.scalar.await('SELECT plate FROM `owned_vehicles` WHERE plate = ?', { plate }) ~= nil
end
```

### AddVehicle

```lua
---@param src string Admin's server ID
---@param targetId number
---@param plate string
---@param vehicle string
AddVehicle = function(src, targetId, plate, vehicle)
  local xPlayer = ESX.GetPlayerFromId(targetId)    
  MySQL.insert.await('INSERT INTO `owned_vehicles` (owner, plate, vehicle) VALUES (?, ?, ?)', { xPlayer.identifier, plate, vehicle })
end
```

### GetCharacterInfoToEdit

`param` is just name that is used later to save character edit

```lua
---@class EditField
---@param label string
---@param value string | number
---@param param string

---@param targetId number
---@return EditField
GetCharacterInfoToEdit = function(targetId)
  local xPlayer = ESX.GetPlayerFromId(targetId)
  return {
    {
      label = 'First name',
      value = xPlayer.variables.firstName,
      param = 'firstName'
    },
    {
      label = 'Last name',
      value = xPlayer.variables.lastName,
      param = 'lastName'
    },
    {
      label = 'Height',
      value = xPlayer.variables.height,
      param = 'height'
    },
    {
      label = 'Date Of Birth (DD/MM/YYYY)',
      value = xPlayer.variables.dateofbirth,
      param = 'dob'
    },
    {
      label = 'Job',
      value = xPlayer.job.name,
      param = 'job'
    },
    {
      label = 'Grade',
      value = xPlayer.job.grade,
      param = 'grade'
    }
  }
end
```

<figure><img src="/files/o3wikW1LQGoDrq4x4JqL" alt="" width="252"><figcaption></figcaption></figure>

### ValidateCharacterEdit

If this function returns false, the administrator will be notified that he entered invalid data.

```lua
---@param adminId number
---@param targetId number
---@param params { [string]: string | number }
ValidateCharacterEdit = function(adminId, targetId, params)
  local check = true
  
  if not ESX.DoesJobExist(params.job, params.grade) then
    check = false
  end
  
  if not string.match(params.dob, '^%d%d/%d%d/%d%d%d%d$') then
    check = false
  end

  return check
end
```

### SaveCharacterEdit

```lua
---@param targetId number
---@param params { [string]: string | number }
SaveCharacterEdit = function(targetId, params)
  local xPlayer = ESX.GetPlayerFromId(targetId)
  xPlayer.setName(params.firstName .. ' ' .. params.lastName)
  xPlayer.set('firstName', params.firstName)
  xPlayer.set('lastName', params.lastName)
  xPlayer.set('height', params.height)
  xPlayer.set('dateofbirth', params.dob)
  xPlayer.setJob(params.job, params.grade)

  local identifier = getIdentifier(targetId)
  if identifier then
    MySQL.update('UPDATE users SET firstname = :firstName, lastname = :lastName, height = :height, dateofbirth = :dob WHERE identifier = :identifier', {
      firstName = params.firstName,
      lastName = params.lastName,
      height = params.height,
      dob = params.dob,
      identifier = identifier
    })
  end
end
```

### GetLicensesList

```lua
---@class License
---@field type string
---@field label string

---@return License[]
GetLicensesList = function()
  return MySQL.query.await('SELECT * FROM `licenses` ORDER BY `label` ASC')
end
```

### GetUserLicenses

* src - ID of administrator that is trying to check player's licenses.
* identifier - Target identifier received from Bridge.GetBridgeIdentifier function.
* `lc_admin:formatLicense` callback checks if any of user's license types are in the list from Bridge.GetLicensesList function, and then sets the `active` property to true or false.

```lua
---@param src number
---@param identifier string
GetUserLicenses = function(src, identifier)
  local licenses = MySQL.query.await('SELECT type FROM `user_licenses` WHERE owner = ?', { identifier })
  local userLicenses = lib.callback.await('lc_admin:formatLicenses', src, licenses)
  return userLicenses
end
```

### ToggleUserLicense

```lua
---@param targetId number
---@param type string
---@param active boolean
ToggleUserLicense = function(targetId, type, active)
  local xPlayer = ESX.GetPlayerFromId(targetId)
  local identifier = xPlayer.identifier
  if active then
    MySQL.query.await('INSERT INTO `user_licenses` (type, owner) VALUES (?, ?)', { type, identifier })
  else
    MySQL.query.await('DELETE FROM `user_licenses` WHERE type = ? AND owner = ?', { type, identifier })
  end
end
```

### SuccessNotify

```lua
---@param targetId number
---@param title? string
---@param description? string
---@param duration? number
---@param id? string
SuccessNotify = function(targetId, title, description, duration, id)
  local data = {
    position = 'top',
    style = {
        width = 'fit-content',
        backgroundColor = '#000000',
        borderRadius = '0.5rem',
        color = '#ffffff',
        ['.description'] = {
          color = '#cccccc'
        }
    },
    icon = 'check',
    iconColor = '#3fad00'
  }
  data.title = title or nil
  data.description = description or nil
  data.id = id or nil
  data.duration = duration or nil

  TriggerClientEvent('ox_lib:notify', targetId, data)
end
```

### InfoNotify

```lua
---@param targetId number
---@param title? string
---@param description? string
---@param id? string
InfoNotify = function(targetId, title, description, id)
  local data = {
    position = 'top',
    style = {
        width = 'fit-content',
        backgroundColor = '#000000',
        borderRadius = '0.5rem',
        color = '#ffffff',
        ['.description'] = {
          color = '#cccccc'
        }
    },
    icon = 'info',
    iconColor = '#4287f5'
  }
  data.title = title or nil
  data.description = description or nil
  data.id = id or nil

  TriggerClientEvent('ox_lib:notify', targetId, data)
end
```

### FailNotify

```lua
---@param targetId number
---@param title? string
---@param description? string
---@param id? string
FailNotify = function(targetId, title, description, id)
  local data = {
    position = 'top',
    style = {
        width = 'fit-content',
        backgroundColor = '#000000',
        borderRadius = '0.5rem',
        color = '#ffffff',
        ['.description'] = {
          color = '#cccccc'
        }
    },
    icon = 'ban',
    iconColor = '#C53030'
  }
  data.title = title or nil
  data.description = description or nil
  data.id = id or nil

  TriggerClientEvent('ox_lib:notify', targetId, data)
end
```


---

# 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://libertycode.gitbook.io/docs/lc_adminmenu/bridge/server.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.
