232 lines
7.4 KiB
Lua
232 lines
7.4 KiB
Lua
-- =============================================
|
|
-- This file is for base menu functionality (admin status,
|
|
-- visibility, keybinds, focus callbacks's, threads, etc)
|
|
-- =============================================
|
|
|
|
-- Global Variables
|
|
-- TODO: they should be upper case
|
|
menuIsAccessible = false
|
|
isMenuVisible = false
|
|
tsLastMenuClose = 0
|
|
menuPermissions = {}
|
|
lastTpCoords = false;
|
|
|
|
-- Locals
|
|
local noMenuReason = 'unknown reason'
|
|
local awaitingReauth = false
|
|
|
|
--- Logic to displaying the menu auth rejected snackbar
|
|
local function displayAuthRejectedError()
|
|
if noMenuReason == 'nui_admin_not_found' then
|
|
sendSnackbarMessage('error', 'nui_menu.misc.menu_not_admin', true)
|
|
else
|
|
sendSnackbarMessage('error', 'nui_menu.misc.menu_auth_failed', true, { reason = noMenuReason })
|
|
end
|
|
end
|
|
|
|
--- Tests for menu accessibility and displays error snackbar if needed
|
|
local function checkMenuAccessible()
|
|
if not TX_MENU_ENABLED then
|
|
sendSnackbarMessage('error', 'nui_menu.misc.not_enabled', true)
|
|
return false
|
|
end
|
|
if not menuIsAccessible then
|
|
displayAuthRejectedError()
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
|
|
-- Register txAdmin command
|
|
local function txadmin(_, args)
|
|
if not checkMenuAccessible() then return end
|
|
|
|
-- Make visible
|
|
toggleMenuVisibility()
|
|
|
|
-- Shortcut to open a specific players profile
|
|
if isMenuVisible and #args >= 1 then
|
|
local targetPlayer = table.concat(args, ' ')
|
|
sendMenuMessage('openPlayerModal', targetPlayer)
|
|
end
|
|
end
|
|
RegisterCommand('txadmin', txadmin)
|
|
RegisterCommand('tx', txadmin)
|
|
|
|
RegisterCommand('txAdmin:menu:openPlayersPage', function()
|
|
if not checkMenuAccessible() then return end
|
|
sendMenuMessage('setMenuPage', 1)
|
|
toggleMenuVisibility(true)
|
|
SetNuiFocus(true, true)
|
|
end)
|
|
|
|
|
|
-- This needs to run even when menu is disabled so the ServerCtx
|
|
-- is updated for react, needed by the Warn page
|
|
RegisterSecureNuiCallback('reactLoaded', function(_, cb)
|
|
debugPrint("React loaded, requesting ServerCtx.")
|
|
|
|
CreateThread(function()
|
|
updateServerCtx()
|
|
while ServerCtx == false do Wait(0) end
|
|
debugPrint("ServerCtx loaded, sending variables.")
|
|
sendMenuMessage('setGameName', GAME_NAME)
|
|
sendMenuMessage('setDebugMode', TX_DEBUG_MODE)
|
|
sendMenuMessage('setServerCtx', ServerCtx)
|
|
sendMenuMessage('setPermissions', menuPermissions)
|
|
end)
|
|
|
|
cb({})
|
|
end)
|
|
|
|
|
|
-- =============================================
|
|
-- The rest of the file will only run if menu is enabled
|
|
-- =============================================
|
|
|
|
-- Prevent running if menu is disabled
|
|
if not TX_MENU_ENABLED then return end
|
|
|
|
-- Checking with server if we are an admin
|
|
TriggerServerEvent('txsv:checkIfAdmin')
|
|
|
|
-- Triggered as callback of txsv:checkIfAdmin
|
|
RegisterNetEvent('txcl:setAdmin', function(username, perms, rejectReason)
|
|
if type(perms) == 'table' then
|
|
debugPrint("^2[AUTH] logged in as '" .. username .. "' with perms: " .. json.encode(perms or "nil"))
|
|
menuIsAccessible = true
|
|
menuPermissions = perms
|
|
if IS_FIVEM then
|
|
--NOTE: appending # to the desc so the sorting shows it at the top
|
|
RegisterKeyMapping('txadmin', 'Open Main Page', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:openPlayersPage', 'Open Players page', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:clearArea', 'Clear Area', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:healMyself', 'Heal Yourself', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:tpBack', 'Teleport: go Back', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:tpToCoords', 'Teleport: to Coords', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:tpToWaypoint', 'Teleport: to Waypoint', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:noClipToggle', 'Toggle NoClip', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:togglePlayerIDs', 'Toggle Player IDs', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:boostVehicle', 'Vehicle: Boost', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:deleteVehicle', 'Vehicle: Delete', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:fixVehicle', 'Vehicle: Fix', 'KEYBOARD', '')
|
|
RegisterKeyMapping('txAdmin:menu:spawnVehicle', 'Vehicle: Spawn', 'KEYBOARD', '')
|
|
end
|
|
else
|
|
noMenuReason = tostring(rejectReason)
|
|
debugPrint("^3[AUTH] rejected (" .. noMenuReason .. ")")
|
|
if awaitingReauth then
|
|
displayAuthRejectedError()
|
|
awaitingReauth = false
|
|
end
|
|
menuIsAccessible = false
|
|
menuPermissions = {}
|
|
end
|
|
sendMenuMessage('setPermissions', menuPermissions)
|
|
end)
|
|
|
|
|
|
--[[ Debug Events / Commands ]]
|
|
-- Command/event to trigger a authentication attempt
|
|
local function retryAuthentication()
|
|
debugPrint("^5[AUTH] Retrying menu authentication.")
|
|
menuIsAccessible = false
|
|
menuPermissions = {}
|
|
sendMenuMessage('setPermissions', menuPermissions)
|
|
TriggerServerEvent('txsv:checkIfAdmin')
|
|
end
|
|
RegisterNetEvent('txcl:reAuth', retryAuthentication)
|
|
RegisterCommand('txAdmin-reauth', function()
|
|
sendSnackbarMessage('info', 'Retrying menu authentication.', false)
|
|
awaitingReauth = true
|
|
retryAuthentication()
|
|
end)
|
|
|
|
|
|
-- Register chat suggestions
|
|
-- txAdmin starts before the chat resource, so we need to wait a bit
|
|
CreateThread(function()
|
|
Wait(1000)
|
|
TriggerEvent(
|
|
'chat:addSuggestion',
|
|
'/tx',
|
|
'Opens the main txAdmin Menu or specific for a player.',
|
|
{ { name = "player ID/name", help = "(Optional) Open player modal for specific ID or name." } }
|
|
)
|
|
TriggerEvent(
|
|
'chat:addSuggestion',
|
|
'/txAdmin-reauth',
|
|
'Retries to authenticate the menu NUI.'
|
|
)
|
|
end)
|
|
|
|
|
|
-- Will toggle debug logging
|
|
RegisterNetEvent('txcl:setDebugMode', function(enabled)
|
|
TX_DEBUG_MODE = enabled
|
|
sendMenuMessage('setDebugMode', TX_DEBUG_MODE)
|
|
end)
|
|
|
|
|
|
--[[ NUI Callbacks ]]
|
|
-- Triggered whenever we require full focus, cursor and keyboard
|
|
RegisterSecureNuiCallback('focusInputs', function(shouldFocus, cb)
|
|
debugPrint('NUI Focus + Keep Input ' .. tostring(shouldFocus))
|
|
-- Will prevent mouse focus on initial menu mount as the useEffect emits there
|
|
if not isMenuVisible then
|
|
return
|
|
end
|
|
SetNuiFocus(true, shouldFocus)
|
|
SetNuiFocusKeepInput(not shouldFocus)
|
|
cb({})
|
|
end)
|
|
|
|
|
|
-- When the escape key is pressed in menu
|
|
RegisterSecureNuiCallback('closeMenu', function(_, cb)
|
|
isMenuVisible = false
|
|
tsLastMenuClose = GetGameTimer()
|
|
debugPrint('Releasing all NUI Focus')
|
|
SetNuiFocus(false)
|
|
SetNuiFocusKeepInput(false)
|
|
playLibrarySound('enter')
|
|
cb({})
|
|
end)
|
|
|
|
|
|
-- Audio play callback
|
|
RegisterSecureNuiCallback('playSound', function(sound, cb)
|
|
playLibrarySound(sound)
|
|
cb({})
|
|
end)
|
|
|
|
-- Heals local player
|
|
RegisterNetEvent('txcl:heal', function()
|
|
debugPrint('Received heal event, healing to full')
|
|
local ped = PlayerPedId()
|
|
local pos = GetEntityCoords(ped)
|
|
local heading = GetEntityHeading(ped)
|
|
if IsEntityDead(ped) then
|
|
NetworkResurrectLocalPlayer(pos[1], pos[2], pos[3], heading, false, false)
|
|
end
|
|
ResurrectPed(ped)
|
|
SetEntityHealth(ped, GetEntityMaxHealth(ped))
|
|
ClearPedBloodDamage(ped)
|
|
RestorePlayerStamina(PlayerId(), 100.0)
|
|
if IS_REDM then
|
|
Citizen.InvokeNative(0xC6258F41D86676E0, ped, 0, 100) -- SetAttributeCoreValue
|
|
Citizen.InvokeNative(0xC6258F41D86676E0, ped, 1, 100) -- SetAttributeCoreValue
|
|
Citizen.InvokeNative(0xC6258F41D86676E0, ped, 2, 100) -- SetAttributeCoreValue
|
|
end
|
|
end)
|
|
|
|
-- Tell the user he is an admin and that /tx is available
|
|
AddEventHandler('playerSpawned', function()
|
|
Wait(15000)
|
|
if menuIsAccessible then
|
|
sendMenuMessage('showMenuHelpInfo', {})
|
|
end
|
|
end)
|