Bablo ResourcesDocs

State Bags, Exports & Events

Other resources can see what staff are doing (noclip, freecam, spectate and every other quick menu tool), see who is frozen, jailed or in community service, ask who is staff, ban, kick or jail players through Bablo Admin, react to zones drawn on the Map page, open the panel and show notifications.


State bags

Bablo Admin keeps a set of player state bags up to date. They are set by the server, so players can’t fake them, and they are readable everywhere: Player(source).state on the server, LocalPlayer.state or Player(serverId).state on any client. A bag is set while the thing is on and removed (nil) when it ends. Bags left over from an earlier run are cleared when the resource starts.

LUA
-- server
if Player(source).state.babloNoclip then
    -- staff noclip, don't flag it
end
 
-- client
if LocalPlayer.state.babloFreecam then
    -- hide the HUD while the staff member is in freecam
end
 
-- react the moment it changes, on the server or the client
AddStateBagChangeHandler('babloNoclip', nil, function(bagName, key, value)
    local player = GetPlayerFromStateBagName(bagName)
    print(('player %s noclip: %s'):format(player, tostring(value)))
end)

Staff tools

One bag per quick menu toggle. The value is true while the tool is on.

State bagTool
babloNoclipNoclip
babloFreecamFreecam
babloGodModeGod mode
babloInvisibleInvisible
babloSuperJumpSuper jump
babloFastRunFast run
babloInfiniteStaminaInfinite stamina
babloInfiniteAmmoInfinite ammo
babloNoRagdollNo ragdoll
babloRocketEngineRocket engine
babloAutoHealAuto heal
babloNightVisionNight vision
babloThermalVisionThermal vision
babloHeadLightHead light
babloGlobalVoiceGlobal voice
babloPlayerNamesPlayer names
babloPlayerBlipsPlayer blips
babloCoordsDisplayCoordinates display
babloEntityInspectorEntity inspector
babloVehicleDebugVehicle debug
babloPedDebugPed debug
babloFreezeTimeFreeze time
babloBlackoutBlackout

babloStaffTag is set while the staff tag is shown. Its value is { text, colour }, the text and HUD colour of the tag.

Player states

State bagSet onValue
babloSpectatingThe staff member spectating in personServer ID of the player they watch
babloControllingThe staff member using ControlServer ID of the player they control
babloControlledThe player being controlledServer ID of the staff member
babloFrozenA player frozen by stafftrue
babloCuffedA player cuffed by stafftrue
babloMutedA player muted by stafftrue
babloJailedA jailed playerUnix time (seconds) when they are released
babloCommunityServiceA player in community serviceTasks left

State bags also reach other players’ games, so a modded client can read them, including whether a staff member is invisible or spectating.


Server exports

IsStaff

Returns true when the player is staff (has a rank, or is an owner from Config.Owners / Config.OwnerAce).

LUA
local isStaff = exports['bablo-admin']:IsStaff(source)
ArgumentTypeDescription
sourcenumberServer ID of an online player

HasPermission

Returns true when the player is staff and their rank grants the permission. Full-access staff (*) get true for every key. See the permission keys.

LUA
if exports['bablo-admin']:HasPermission(source, 'player.kick') then
    -- allowed
end
ArgumentTypeDescription
sourcenumberServer ID of an online player
keystringA permission key, for example 'vehicle.manage'

GetStaff

Returns the player’s staff details, or nil when they are not staff.

LUA
local staff = exports['bablo-admin']:GetStaff(source)
if staff then
    print(staff.name, staff.tier and staff.tier.label, staff.hierarchy)
end
FieldTypeDescription
memberIdnumber | nilStaff member ID (nil for an owner who has no member record)
namestringStaff display name
tiertable | nil{ id, label, hierarchy } of their rank
hierarchynumberTheir hierarchy (0–100; owners are always 100)
permissionsstring[]Permission keys of their rank ({ '*' } for full access)
ownerbooleantrue for owners from Config.Owners or Config.OwnerAce

RegisterZoneHandler

Zones drawn on the Map page can name a custom handler. Register a handler with that name and it is called when a player enters or leaves the zone.

LUA
exports['bablo-admin']:RegisterZoneHandler('my_safezone', function(playerId, zone, inside)
    if inside then
        print(('%s entered zone %s (#%d)'):format(GetPlayerName(playerId), zone.name, zone.id))
    else
        print(('%s left zone %s'):format(GetPlayerName(playerId), zone.name))
    end
end)
ArgumentTypeDescription
namestringThe handler name typed in the zone editor
handlerfunction(playerId, zone, inside)playerId is the server ID, zone is { id, name }, inside is true on enter and false on leave

Returns true when registered. Player positions are checked once per second on the server, and only for zones that have a custom handler.

Handlers are kept in memory, so register yours again when bablo-admin restarts (for example in an onResourceStart handler for bablo-admin).

Player state

The same information as the state bags, for scripts that prefer exports.

LUA
if exports['bablo-admin']:IsNoclipping(source) then
    -- staff noclip
end
ExportReturns
IsNoclipping(source)true while noclip is on
IsInFreecam(source)true while freecam is on
IsInvisible(source)true while invisible is on
HasGodMode(source)true while god mode is on
IsSpectating(source)true while they spectate someone in person
GetSpectateTarget(source)Server ID of the player they spectate, or nil
IsToolActive(source, tool)true while that quick menu tool is on, for example IsToolActive(source, 'superJump')
GetActiveTools(source)List of the tools that are on, for example { 'noclip', 'godMode' }
IsFrozen(source)true while frozen by staff
IsJailed(source)true while jailed
IsInCommunityService(source)true while in community service
GetPlayerStates(source)Every Bablo Admin state bag the player has, for example { babloNoclip = true }

Tool names are the staff tools without bablo, starting with a small letter: noclip, godMode, superJump and so on.

Actions from other scripts

Ban, kick, warn, jail and more through Bablo Admin, for example from an anticheat. The action shows up in the ban list, the player’s history and the action log like any other, with the name of the resource that called it and Another script as the place it came from.

LUA
local ok, problem = exports['bablo-admin']:BanPlayer(source, 'Speed hack', 60 * 24)
if not ok then print('ban failed: ' .. problem) end
ExportWhat it does
BanPlayer(source, reason, minutes)Bans the player. Leave minutes out (nil) for a permanent ban.
KickPlayer(source, reason)Kicks the player.
WarnPlayer(source, reason)Gives the player a warning.
JailPlayer(source, minutes, reason)Jails the player.
UnjailPlayer(source)Releases the player from jail.
GiveCommunityService(source, tasks, reason)Gives the player community service.
FreezePlayer(source, on)Freezes the player, or unfreezes them with false.
SendAnnouncement(message, seconds, appearance)Announces to everyone. seconds is 3 to 60 (default 10), appearance is 'banner' (default) or 'notification'.

Every action returns true and its result when it worked, or false and a reason:

ReasonMeaning
player_offlineNo player with that server ID is online.
rank_lockedThe player is an owner. Scripts can’t act on owners.
invalidA value is missing or out of range, for example an empty reason.
not_activeUnjailPlayer on a player who isn’t jailed.
cooldownSendAnnouncement again too soon after the last one.

These exports only work from server scripts and skip all rank permissions, so only call them from resources you trust.

Internal exports

GetHostStats and ListImageFiles exist for the resource’s own use (dashboard CPU and memory, vehicle pictures). Don’t call GetHostStats from another resource: each call resets the CPU sample the dashboard uses.


Shared exports

These work on the server and the client.

GetConfig

Returns the Config table, with auto values already resolved (for example Config.Framework is 'qbcore', 'qbox' or 'esx').

LUA
local config = exports['bablo-admin']:GetConfig()

GetFramework

Returns the detected framework: 'qbcore', 'qbox', 'esx', or nil when none was found.

LUA
local framework = exports['bablo-admin']:GetFramework()

Client exports

For the local player. They read the same state bags.

LUA
if exports['bablo-admin']:IsInFreecam() then
    -- hide the HUD
end
ExportReturns
IsNoclipping()true while noclip is on
IsInFreecam()true while freecam is on
IsInvisible()true while invisible is on
HasGodMode()true while god mode is on
IsSpectating()true while spectating someone in person
GetSpectateTarget()Server ID of the player being spectated, or nil
IsToolActive(tool)true while that quick menu tool is on
GetActiveTools()List of the tools that are on
IsFrozen()true while frozen by staff
IsJailed()true while jailed
IsInCommunityService()true while in community service
GetPlayerStates()Every Bablo Admin state bag on the local player
IsMenuOpen()true while the admin menu is open
IsQuickMenuOpen()true while the quick menu is open

Client events

Open the admin panel

Triggers the same access check as /admin and opens the panel for the local player. Players who are not staff get the “no access” notification. Does nothing while the panel is already open.

LUA
TriggerEvent('bablo-admin:openPanel')

Panel opened or closed

Fired on the local client whenever the admin panel opens or closes.

LUA
AddEventHandler('bablo-admin:panelVisible', function(visible)
    -- visible is true when the panel opened, false when it closed
end)

Show a notification

Shows a notification through the provider set in Config.Notifications (the built-in notifications, ox_lib, your framework or Config.CustomNotify).

LUA
-- server
TriggerClientEvent('bablo-admin:notify', playerId, {
    kind = 'success',
    title = 'Garage',
    body = 'Your vehicle was returned.',
    duration = 6000,
})
 
-- client
TriggerEvent('bablo-admin:notify', { kind = 'info', body = 'Hello' })
FieldTypeDescription
kindstring'success', 'error' or 'info' ('warning' and 'inform' show as 'info')
titlestring?Optional title
bodystringThe message
durationnumber?Milliseconds, default 6000

Zone handler events

When a zone’s custom handler name contains a : and no server handler is registered under that name, the name is sent as a client event to the player who entered or left:

LUA
-- zone editor: custom handler = 'myresource:zone'
RegisterNetEvent('myresource:zone', function(zone, inside)
    -- zone = { id = number, name = string }, inside = true on enter, false on leave
end)

Other bablo-admin:* events are internal. They can change between versions, so don’t trigger or rely on them.