Developer
Overview
Integration uses the open/ folder handlers. Server handlers in open/server.lua control access, item flow, and action lifecycle. Client handlers in open/client.lua control UI and placement. Shared handlers in open/shared.lua run on both sides for global action gating and cooldowns.
Server Handlers
Located in open/server.lua.
Item Control
open/server.lua
1function OpenServer.BeforeGiveItem(src, item, amount)
2 return true -- return false to block
3end
4
5function OpenServer.BeforeRemoveItem(src, item, amount)
6 return true -- return false to block
7endBeforeGiveItem: Called before giving a filled/empty container to the player. Returnfalseto block.BeforeRemoveItem: Called before removing an item from the player. Returnfalseto block.
Action Lifecycle
open/server.lua
1function OpenServer.OnActionComplete(src, actionType, data)
2end
3
4function OpenServer.OnTankPlaced(src, tankData)
5endOnActionComplete: Fires after any tank action completes.actionTypeis one of:'fillTank','takeWater','repairTank','dismantleTank'.OnTankPlaced: Fires after a tank is saved to the database.
Access Control
open/server.lua
1function OpenServer.CanAccessTank(src, tankData)
2 return true -- return false to block
3end
4
5function OpenServer.CanPlaceTank(src, tankType, coords)
6 return true -- return false to block
7end
8
9function OpenServer.CanDismantleTank(src, tankData)
10 return true -- return false to block
11endCanAccessTank: Gate access to a tank. Use for owner-only, gang territory, or job-lock checks.CanPlaceTank: Gate placement. Use for zone restrictions or coordinate blacklists.CanDismantleTank: Gate dismantling. Use for protected zones or admin overrides.
Jerry Can
open/server.lua
1function OpenServer.OnJerryCanTransfer(src, tankId, canItem, amount, direction)
2 return true -- return false to block
3endOnJerryCanTransfer: Called before a jerry can fill or drain.directionis'fill'or'drain'. Returnfalseto block.
Client Handlers
Located in open/client.lua.
Interaction
open/client.lua
1function OpenClient.BeforeOpenUI(data)
2 return true -- return false to cancel
3end
4
5function OpenClient.CanInteract(tankData)
6 return true -- return false to hide target
7endBeforeOpenUI: Called before the tank context menu opens. Returnfalseto cancel.CanInteract: Pre-check for target visibility. Block if the player is cuffed, dead, in a vehicle, etc.
Placement
open/client.lua
1function OpenClient.OnPlacementStart(tankType)
2 return true -- return false to block
3end
4
5function OpenClient.OnPlacementConfirm(tankType, coords, heading)
6 return true -- return false to reject
7endOnPlacementStart: Called when entering placement mode. Returnfalseto block.OnPlacementConfirm: Called before confirming position. Returnfalseto reject coordinates.
Shared Handlers
Located in open/shared.lua. These run on both server and client.
open/shared.lua
1function OpenHandlers.OnPlayerAction(src, data)
2 return true -- return false to block
3end
4
5function OpenHandlers.ValidateAction(src, actionType)
6 return true -- return false to block
7end
8
9function OpenHandlers.GetCooldown(actionType)
10 return 0 -- seconds, 0 or nil to disable
11end
12
13function OpenHandlers.CanUseTankType(src, tankType)
14 return true -- return false to block
15endOnPlayerAction: Global hook before any action is dispatched. Returnfalseto block entirely.ValidateAction: Pre-flight validation before the tank UI opens. Returnfalseto block.GetCooldown: Returns cooldown in seconds for an action type. Action types:'fillTank','takeWater','repairTank','fillJerryCan','drainJerryCan'.CanUseTankType: Controls access to specific tank types. Use for tier/rank/job-based restrictions.
Item Metadata
Tank and jerry can items store dynamic data via inventory metadata:
Tank items
Key. Type. Description
lifetank: float. Remaining durability when dismantled
Jerry can items
Key. Type. Description
fuelType: string. Liquid type stored in the can
fuelAmount: float. Current liquid amount stored on the can
maxCapacity: float. Maximum capacity of the can
Examples
open/server.lua
1function OpenServer.CanAccessTank(src, tankData)
2 local job = Bridge.GetJob(src)
3 if tankData.type == 'fuel' and (not job or job.name ~= 'mechanic') then
4 return false
5 end
6 return true
7endopen/shared.lua
1function OpenHandlers.GetCooldown(actionType)
2 if actionType == 'fillTank' then return 30 end
3 if actionType == 'takeWater' then return 10 end
4 return 0
5endopen/shared.lua
1function OpenHandlers.CanUseTankType(src, tankType)
2 if tankType == 'large_tank' then
3 local job = Bridge.GetJob(src)
4 return job and job.name == 'vip'
5 end
6 return true
7endopen/client.lua
1function OpenClient.OnPlacementStart(tankType)
2 if GetInteriorFromEntity(cache.ped) ~= 0 then
3 Bridge.Notify('Cannot place tanks indoors', 'error')
4 return false
5 end
6 return true
7end