Accueil › Documentation › Personnalisation · origen_graffiti
Le dossier custom/ te permet d’étendre origen_graffiti sans toucher au cœur. Tous les fichiers ici sont escrow_ignore : ils survivent aux mises à jour.
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)custom/client/hooks.luaDéclenchés par le cœur côté client. Ajoute ta logique dans chaque handler.
graffiti:hook:onTagAddedDéclenché quand le client reçoit un nouveau tag à afficher, à la sauvegarde ou lors de la synchronisation de zone.
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:onTagRemovedDéclenché quand le client retire un tag du monde local.
AddEventHandler('graffiti:hook:onTagRemoved', function(id, coords)
-- id — tag DB ID
-- coords — vector3 where the tag was
end)graffiti:hook:onCanvasModeChangedDéclenché quand le joueur local entre dans le mode toile (session de peinture active) ou en sort. Utile pour masquer ou afficher le HUD, les menus radiaux, etc.
AddEventHandler('graffiti:hook:onCanvasModeChanged', function(active, context)
-- active — boolean (true = enter canvas, false = exit canvas)
-- context.state — current state string
-- context.sessionId
-- context.isOwner — boolean
end)custom/server/hooks.luaDéclenchés par le cœur côté serveur. Ajoute ta logique dans chaque handler.
graffiti:hook:onTagCreatedDéclenché quand un joueur sauvegarde un graffiti avec succès.
AddEventHandler('graffiti:hook:onTagCreated', function(src, data)
-- src — server ID of the player
-- data.id — DB tag ID
-- data.coords — vector3 center
-- data.created_by — license identifier
-- data.image_url — public image URL (Fivemanage)
-- data.created_at — UTC timestamp string
end)Exemple — journaliser la création de graffitis :
AddEventHandler('graffiti:hook:onTagCreated', function(src, data)
print(('[graffiti] Player %s painted tag #%d at %s'):format(
data.created_by, data.id, tostring(data.coords)
))
end)graffiti:hook:onTagDeletedDéclenché quand un tag est supprimé, par un administrateur ou par un joueur avec un effaceur.
AddEventHandler('graffiti:hook:onTagDeleted', function(src, id, coords)
-- src — server ID of the player
-- id — deleted tag DB ID
-- coords — vector3 where the tag was
end)custom/client/permissions.luaAppelées par le cœur avant chaque action pour donner un retour immédiat à l’utilisateur. Si elles renvoient false, l’action est annulée côté client.
Les vérifications côté client ne servent qu’à l’expérience utilisateur : elles peuvent être contournées. Les permissions serveur restent toujours la barrière décisive.
GraffitiPerms.canPaint(coords) → booleanAppelée au début de activateGraffiti(), avant toute opération asynchrone.
function GraffitiPerms.canPaint(coords)
-- coords — vector3 player position when activating the spray
return true
endGraffitiPerms.canErase(coords) → booleanAppelée juste avant d’entrer en mode effacement, une fois le tag ciblé identifié.
function GraffitiPerms.canErase(coords)
-- coords — vector3 center of the tag to erase
return true
endGraffitiPerms.canShop(coords) → booleanAppelée quand le joueur appuie sur E près d’un point de boutique, avant l’ouverture de la NUI.
function GraffitiPerms.canShop(coords)
-- coords — vector3 shop location coordinates
return true
endcustom/server/permissions.luaVérifications décisives appelées côté serveur avant chaque action. Celles-ci bloquent réellement l’opération.
GraffitiPerms.isAdmin(src) → booleanAppelée dans tous les callbacks et commandes d’administration. Valide par rapport à Config.AdminGroups avec trois niveaux de repli :
IsPlayerAceAllowed (QBCore, QBX, tout framework basé sur ace)xPlayer.getGroup()Framework.GetIsFrameworkAdminfunction GraffitiPerms.isAdmin(src)
-- src — server ID
return true -- or your custom check
endGraffitiPerms.canPaint(src, coords) → booleanAppelée dans graffiti:server:startSession après la validation de la distance.
function GraffitiPerms.canPaint(src, coords)
-- src — server ID
-- coords — vector3 canvas center
return true
endGraffitiPerms.canErase(src, coords) → booleanAppelée dans graffiti:server:deleteWorldTag après la lecture des coordonnées en base de données.
function GraffitiPerms.canErase(src, coords)
-- src — server ID
-- coords — vector3 tag coordinates
return true
endGraffitiPerms.canShop(src, coords) → booleanAppelée dans graffiti:server:shopBuy avant la vérification des fonds du joueur.
function GraffitiPerms.canShop(src, coords)
-- src — server ID
-- coords — vector3 player position at purchase time (may be nil)
return true
end