Developer

4 min readUpdated 2 weeks ago

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 are loaded on both sides and called on the server, for 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
7end
  • BeforeGiveItem: Called before giving a filled/empty container to the player. Return false to block.
  • BeforeRemoveItem: Called before removing an item from the player. Return false to block.

Action Lifecycle

open/server.lua
1function OpenServer.OnActionComplete(src, actionType, data)
2end
3
4function OpenServer.OnTankPlaced(src, tankData)
5end
  • OnActionComplete: Fires after any tank action completes. actionType is 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 BaseGate.MayUseTank(src, tankData)
3end
4
5function OpenServer.CanPlaceTank(src, tankType, coords)
6    return BaseGate.CanPlace(src, coords)
7end
8
9function OpenServer.CanDismantleTank(src, tankData)
10    return BaseGate.MayUseTank(src, tankData)
11end
  • CanAccessTank: 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.

The shipped bodies apply the Outpost base rules. Keep the BaseGate call as the last return when you add your own checks.

Jerry Can

open/server.lua
1function OpenServer.OnJerryCanTransfer(src, tankId, canItem, amount, direction)
2    return true -- return false to block
3end
  • OnJerryCanTransfer: Called before a jerry can fill or drain. direction is 'fill' or 'drain'. Return false to 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
7end
  • BeforeOpenUI: Called before the tank context menu opens. Return false to cancel.
  • CanInteract: runs when the player picks the target option or presses E. Return false to cancel, for example while cuffed or in a vehicle

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
7end
  • OnPlacementStart: Called when entering placement mode. Return false to block.
  • OnPlacementConfirm: Called before confirming position. Return false to reject coordinates. The shipped body checks the Outpost base rules

Shared Handlers

Located in open/shared.lua. Loaded on both sides and called on the server.

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
15end
  • OnPlayerAction: Global hook before any action is dispatched. Return false to block entirely.
  • ValidateAction: runs before the tank menu opens, with actionType set to 'interact'. Return false to 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    local container = Config.Containers[tankData.tankType]
4    if container and container.type == 'fuel' and (not job or job.name ~= 'mechanic') then
5        return false
6    end
7    return BaseGate.MayUseTank(src, tankData)
8end
open/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
5end
open/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
7end
open/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