Skip to main content

Statebags

In v3 the handcuff status is replicated through player statebags. The server is the only writer; clients and other resources only read them. This is the recommended way to check status — no export call or callback needed.

Keys

Statebag keyTypeMeaning
isHandcuffedbooleanPlayer is cuffed
isHardcuffedbooleanPlayer is hardcuffed (can't move)
cuffItemstring | falseThe item the player was cuffed with
hasAnkleTrackerbooleanPlayer wears an ankletracker
hasHeadbagbooleanPlayer has a headbag (blackscreen)
hasTapebooleanPlayer is taped (muted)
cuffedbooleanMirror of isHandcuffed — read by ox_inventory to block the inventory

Reading on the client

-- Local player
local isCuffed = LocalPlayer.state.isHandcuffed

-- Any player by server id
local isCuffed = Player(targetServerId).state.isHandcuffed

-- Via msk_core mirror
local isCuffed = MSK.Player[targetServerId].state.isHandcuffed

Reading on the server

local isCuffed = Player(playerServerId).state.isHandcuffed
local cuffItem = Player(playerServerId).state.cuffItem

Reacting to changes

Because the keys are real statebags you can subscribe with a change handler:

AddStateBagChangeHandler('isHandcuffed', nil, function(bagName, key, value)
local ply = GetPlayerFromStateBagName(bagName)
if ply == 0 then return end
-- value is true/false
end)
Security note

Statebags are the transport / read layer. Security-relevant decisions (can this player be hardcuffed? is the target really cuffed?) are made by the server against its own authoritative state, not against a client-written statebag.