Permissions
F5 Combat HUD has two independent access systems, and they answer different questions:
| System | Question | Where | Enforced by |
|---|---|---|---|
F5Cfg.ModeratorAces | Who may moderate the marketplace? | config/features.lua | The server, on every moderation call |
F5Cfg.SectionOverrides | What does this group's menu show? | config/features.lua | The menu only |
Everything else — which features exist at all — is configuration, not permission.
Marketplace Moderators
F5Cfg.ModeratorAces = {
'command.combathud_admin',
'god',
'admin',
'mod',
}
A player who matches any entry gets the Moderation tab inside the marketplace: hiding and unhiding listings, deleting them, and banning or unbanning players from the marketplace.
How an entry is matched
Each entry is tried three ways, and any one of them is enough:
- As a bare ACE —
IsPlayerAceAllowed(src, 'admin') - As the ACE
group.<entry>—group.admin - On ESX, against the group the player carries on their character —
xPlayer.getGroup() == 'admin'
That is what makes one list work on all three frameworks. god, admin and mod are QBCore's own admin groups, admin is also the ESX group and the QBox group.admin ACE — so existing staff already qualify whichever framework you run.
mod is deliberately broad on QBCoreBecause entries are also matched as group.<entry>, listing 'mod' grants moderation to the ACE principal group.mod as well as to the QBCore group. Drop 'mod' from the list if marketplace moderation should stay above that rank.
A permission of this resource's own
command.combathud_admin exists for someone who moderates the marketplace without being a server admin:
add_ace group.moderator command.combathud_admin allow
Then add the players to that group:
add_principal identifier.license:110000112345678 group.moderator
Framework examples
QBCore / QBox — reuse your existing admin groups
Nothing to do. god, admin and mod are already in the list, and both frameworks expose them as group.<name> ACEs.
To grant a custom group instead:
add_ace group.helper command.combathud_admin allow
ESX — the group on the character
ESX stores the group on the character (users.group), and the bridge asks xPlayer.getGroup() before falling back to ACEs. A player whose group is admin matches the shipped list with no server.cfg changes at all.
For a custom ESX group, add the group name to the list:
F5Cfg.ModeratorAces = {
'command.combathud_admin',
'god', 'admin', 'mod',
'superadmin', -- matched against xPlayer.getGroup() and the ACE group.superadmin
}
The tab is not the permission
marketplaceModerate — the flag that shows the tab — is EnableMarketplace and <player is a moderator>. But the tab being visible is never what grants the power: every moderation call re-runs the same check on the server before it touches the database. A modified NUI that forces the tab open gets a refusal on every button.
Moderation is also unavailable to everyone when F5Cfg.EnableMarketplace = false, regardless of ACEs.
Per-Group Menu Overrides
SectionOverrides changes what the menu shows a given group. It is empty out of the box:
F5Cfg.SectionOverrides = {
-- trial = {
-- customImage = false, rainbow = false, glow = false,
-- },
}
A key matches the ACE group.<key> — and, on ESX, the group on the player's character. The example above hides the custom image, rainbow and glow sections from anyone in group.trial.
Overrides rewrite one thing only: the payload that decides what the menu shows this player. The server's validators and the HUD's own render gates both read the global config and never see a group's payload. So:
- Granting a group a section that is globally disabled gives them a visible panel whose values are pinned or wiped on the next save.
- Taking a section away from a group hides the controls, but anything they had already switched on keeps rendering. To actually switch a feature off, switch it off globally.
What you can override
| Key | Hides |
|---|---|
rainbow | Crosshair → Rainbow mode |
glow | Crosshair → Glow |
dynamic | Crosshair → Dynamic spread |
aimingVisibility | Crosshair → ADS visibility |
customImage | Crosshair → Custom image |
animated | Crosshair → Animation |
hpColor | Crosshair → HP-based colour |
killstreak | Scoreboard → Killstreak announcement and thresholds |
killstreakCounter | Scoreboard → Live streak counter |
kdHud | Scoreboard → K/D display |
kdHudPresets | Scoreboard → K/D preset grid |
killFeed | Scoreboard → Kill feed |
killFeedPresets | Scoreboard → Kill feed preset grid |
dragPosition | Scoreboard → Drag-to-position |
publish | Marketplace → publish / update / unpublish |
publishCustomImage | Marketplace → publishing a custom-image crosshair |
apply | Marketplace → applying someone else's listing |
likes | Marketplace → likes |
authorProfile | Marketplace → author profile |
search | Marketplace → search |
sort | Marketplace → sorting |
tags | Marketplace → tag filter |
The whole-feature flags can be overridden the same way — EnableCrosshair, EnableEffects, EnableScoreboard, EnableMarketplace, EnableHitmarker, EnableHitParticles, EnableDamageNumbers, EnableKillmarker, EnableHeadshotMarker, EnableHitDirection, EnableKillFlash, EnableKillstreak, EnableKDHud, EnableKillFeed, EnableWeaponCrosshairs — again only for hiding, never for granting.
presets, style, parameters, colors and preview have no override mapping. Writing them into a group's table does nothing — the menu keeps showing them. Switch them off globally in CrosshairSections / EffectsSections instead.
Any key the override system does not recognise is named at startup, so a typo is not silent:
[f5_combathud][config-validator] WARN: F5Cfg.SectionOverrides.trial.rainbwo is not a known section or Enable* flag — it will be ignored
false closes a sectionOverride values are used exactly as written and are never type-checked. customImage = false hides the section; customImage = 0, = 'no' or = nil all leave it open. Write the boolean.
killstreak, kdHud and killFeed address the Scoreboard sections — the configurator panels. The Enable* keys address the tab-level flags the payload is built from. Neither stops the feature rendering: what the HUD draws is decided by the global config, not by a group's payload.
Overriding a tab does not fold its sections
Turning off a tab for a group hides the tab, but the sections inside it are separate keys. If you want a group to lose the Scoreboard tab and have its sections stay hidden should you re-enable the tab later, list each key:
F5Cfg.SectionOverrides = {
trial = {
EnableScoreboard = false,
killstreak = false,
kdHud = false,
killFeed = false,
},
}
One player, two groups
When a player is in two groups that set the same key, the winner is undefined — the tables are merged in whatever order Lua walks them. Put the union in a single group instead of relying on precedence.
When Changes Take Effect
The feature payload is built per player when their character loads, and the client asks for it exactly once per session. There is no polling.
| You changed | The player sees it |
|---|---|
A file in config/ | After a resource restart, on their next character load |
| An ACE or a group | On their next reconnect — not after a timeout |
The client listens for f5_combathud:client:configChanged. Nothing inside the resource ever fires it — it exists so another resource of yours can push a refresh without a relog:
TriggerClientEvent('f5_combathud:client:configChanged', source)
The player's menu then re-fetches its payload. The server caches that payload for 30 seconds per player, so fire the event a moment after the change rather than in the same tick.
Audit Trail
When a player's client sends data for a section that is switched off — a modified NUI, or settings saved before you disabled the section — the server discards it and writes a row into f5_combathud_admin_audit with the action policy_strip and the actor system. Moderation actions are recorded there as well.
The table is write-only in game: nothing in the menu ever reads it. See Database → Audit.
See Also
- Configuration → Features — the global switches
- Marketplace — what a moderator can actually do
- Framework Compatibility → Groups — how a group is resolved per framework
- Database — the audit table
- Troubleshooting — "the Moderation tab is missing"