Moderation
Moderation
Player-made designs can be reviewed before they are usable. It is off by default.
Config.Moderation = { enabled = false }
With moderation off, a saved design is approved immediately and usable at once.
The queue
/gunsmithadmin → Moderation queue
Needs the mod scope. Each entry can be:
| Action | Result |
|---|---|
| Approve | The design becomes usable |
| Reject | The design is refused, with a reason shown to its author |
| Revoke | An already-approved design is withdrawn |
Every decision is written to aty_gunsmith_audit, and fires the moderation webhook if one is set.
A design's status is one of draft, pending, approved, rejected, revoked.
Who may review
Config.Hooks.canModerate = function(src) return Perms.has(src, 'mod') end
The default is the mod scope, which resolves through your framework's own permission system — QBCore HasPermission, ESX group, or ACE. Replace the hook to use your own rule.
Automatic rejection
skinValidator runs on every design before it reaches the queue:
Config.Hooks.skinValidator = function(def)
-- return false, 'reason' to reject
return true, nil
end
This is the place for banned imagery, a word filter, or a rule about which layer types your server allows. It runs server-side, on the definition, so it sees exactly what will be drawn.
Queue limit
Config.Lanes.baked = { enabled = true, autoApprove = false, queueLimit = 200 }
Once the queue reaches queueLimit, further submissions are refused with "the moderation queue is full" rather than being silently dropped. That number is the signal that nobody is reviewing.
Rate limiting
Independent of moderation, Config.RateLimit.skinsPerMinute (6 by default) caps how fast one player can save designs. It is there to stop the queue being flooded by one person.
Supply limits
A design record can carry a supply — NULL for unlimited, or a number for a mint limit. Once minted reaches it, further attempts are refused with "this skin is sold out". This is the hook for limited-run or event skins, driven through the mintSkin export.
Exports and events
exports.aty_gunsmith:createSkin(author, def)
exports.aty_gunsmith:setSkinStatus(skinId, status, reason)
exports.aty_gunsmith:mintSkin(skinId, owner)
AddEventHandler('aty_gunsmith:skinModerated', function(data) end)
AddEventHandler('aty_gunsmith:skinApplied', function(data) end) -- { serial, skinId, lane }
See also
- Skin Studio
- Permissions