terminalCustom

The custom/ folder lets you extend origen_graffiti without touching the core. All files here are escrow_ignore โ€” they survive updates.

textCopy

custom/
โ”œโ”€โ”€ client/
โ”‚   โ”œโ”€โ”€ hooks.lua        โ€” client-side event hooks
โ”‚   โ””โ”€โ”€ permissions.lua  โ€” client-side permission checks (UX feedback)
โ””โ”€โ”€ server/
    โ”œโ”€โ”€ hooks.lua        โ€” server-side event hooks
    โ””โ”€โ”€ permissions.lua  โ€” server-side permission checks (authoritative)

Client Hooks โ€” custom/client/hooks.lua

Fired by the core on the client side. Add your logic inside each handler.

graffiti:hook:onTagAdded

Fired when the client receives a new tag to render โ€” on save or zone sync.

luaCopy

AddEventHandler('graffiti:hook:onTagAdded', function(row)
    -- row.id         โ€” DB tag ID
    -- row.coords     โ€” vector3 center
    -- row.created_by โ€” license identifier
    -- row.image_url  โ€” public image URL
    -- row.created_at โ€” UTC timestamp string
end)

graffiti:hook:onTagRemoved

Fired when the client removes a tag from the local world.

luaCopy


graffiti:hook:onCanvasModeChanged

Fired when the local player enters or exits canvas mode (active painting session). Useful to hide/show HUD, radial menus, etc.

luaCopy


Server Hooks โ€” custom/server/hooks.lua

Fired by the core on the server side. Add your logic inside each handler.

graffiti:hook:onTagCreated

Fired when a player successfully saves a graffiti.

luaCopy

Example โ€” log graffiti creation:

luaCopy


graffiti:hook:onTagDeleted

Fired when a tag is deleted โ€” by an admin or by a player using an eraser.

luaCopy


Client Permissions โ€” custom/client/permissions.lua

Called by the core before each action for immediate UX feedback. Returning false cancels the action client-side.

Client checks are for UX only โ€” they can be bypassed. The server permissions are always the authoritative gate.

GraffitiPerms.canPaint(coords) โ†’ boolean

Called at the start of activateGraffiti(), before any async operation.

luaCopy


GraffitiPerms.canErase(coords) โ†’ boolean

Called just before entering erase mode, after the target tag is identified.

luaCopy


GraffitiPerms.canShop(coords) โ†’ boolean

Called when the player presses E near a shop point, before opening the NUI.

luaCopy


Server Permissions โ€” custom/server/permissions.lua

Authoritative checks called server-side before each action. These actually block the operation.

GraffitiPerms.isAdmin(src) โ†’ boolean

Called on all admin callbacks and commands. Validates against Config.AdminGroups using three fallback layers:

  1. FiveM Ace Permissions โ€” IsPlayerAceAllowed (QBCore, QBX, any ace-based framework)

  2. ESX group โ€” xPlayer.getGroup()

  3. Bridge fallback โ€” Framework.GetIsFrameworkAdmin

luaCopy


GraffitiPerms.canPaint(src, coords) โ†’ boolean

Called in graffiti:server:startSession after distance validation.

luaCopy


GraffitiPerms.canErase(src, coords) โ†’ boolean

Called in graffiti:server:deleteWorldTag after reading coords from DB.

luaCopy


GraffitiPerms.canShop(src, coords) โ†’ boolean

Called in graffiti:server:shopBuy before checking player funds.

luaCopy

Last updated