Skip to content

Retro Hidden Mic

This section covers exports, events, usable items, and integration points for developers. The framework, notification, progress bar, and target bridges all live in the open framework/ folder, so you can adapt them without touching escrowed code.


The script is driven entirely by inventory items and target interactions - there are no chat commands by default.

ActionTrigger
Plant a room bugUse the room_bug item, then place it on a surface
Plant a wearable wireox_target/qb-target option on another player (requires player_bug)
Plant a vehicle bugox_target/qb-target option on a vehicle (requires vehicle_bug)
Deploy a jammerUse the bug_jammer item
Deploy an amplifierUse the bug_signal_amplifier item
Detect / remove bugsEquip WEAPON_DIGISCANNER, then press the Config.KeyRemoveBug key
Open the wiretap panelTarget the command center point (job/grade gated)

The scanner module (client/scaner.lua) exposes exports so other resources can drive the detection UI.

Scanner exports
-- Start the scanner UI aimed at a target position
exports[GetCurrentResourceName()]:InitializeScannerUI(targetVector, parameters)
-- Update the target while the scanner is running (used for moving bugs)
exports[GetCurrentResourceName()]:RefreshScannerData(newCoords, newBugId, isDynamicState)
-- Stop the scanner UI
exports[GetCurrentResourceName()]:HaltScanner()
-- Returns true while the scanner UI is active
local running = exports[GetCurrentResourceName()]:IsScannerRunning()

Each device is registered as a usable inventory item on the server via the framework bridge. Changing the item names in config/config.lua automatically re-registers them.

server/server.lua
-- server/server.lua (registered through the framework bridge)
Framework.TS.RegisterUsableItem(Config.BugItem, function(source) ... end) -- room_bug
Framework.TS.RegisterUsableItem(Config.BugPlayerItem, function(source) ... end) -- player_bug
Framework.TS.RegisterUsableItem(Config.BugVehicleItem, function(source) ... end) -- vehicle_bug
Framework.TS.RegisterUsableItem(Config.JammerSetup.Item, function(source) ... end) -- bug_jammer
Framework.TS.RegisterUsableItem(Config.AmplifierSetup.Item, function(source) ... end) -- bug_signal_amplifier

Placement and persistence run through server events (namespaced ts_podsluch_v2:) and ox_lib callbacks.

Server events & callbacks
-- Placement
TriggerServerEvent('ts_podsluch_v2:server:placeBug', coords)
TriggerServerEvent('ts_podsluch_v2:server:placeBugOnPlayer', targetId)
TriggerServerEvent('ts_podsluch_v2:server:placeBugOnVehicle', netId, plate)
TriggerServerEvent('ts_podsluch_v2:server:placeJammer', coords)
TriggerServerEvent('ts_podsluch_v2:server:placeAmplifier', coords)
-- Removal
TriggerServerEvent('ts_podsluch_v2:server:removeJammer', jammerId)
TriggerServerEvent('ts_podsluch_v2:server:removeAmplifier', amplifierId)
-- Panel data, notes & rename
TriggerServerEvent('ts_podsluch_v2:server:requestBugList')
TriggerServerEvent('ts_podsluch_v2:server:saveNote', bugId, noteText)
TriggerServerEvent('ts_podsluch_v2:server:saveName', bugId, customName)
TriggerServerEvent('ts_podsluch_v2:server:startListening', bugId)
-- Pre-placement validation (ox_lib callbacks)
lib.callback.await('ts_podsluch_v2:server:canPlaceBugOnPlayer', false, targetId)
lib.callback.await('ts_podsluch_v2:server:canPlaceBugOnVehicle', false, netId)

Command centers are defined in config/config.lua and built into target zones in client/target.lua. Access is checked per center against the playerโ€™s job and grade.

client/target.lua
-- client/target.lua: canInteract check (open file)
canInteract = function()
local playerJob = Framework.TS.GetPlayerJob()
if not playerJob then return false end
if center.jobs then
for jobName, minGrade in pairs(center.jobs) do
if playerJob.name == jobName and playerJob.grade >= minGrade then
return true
end
end
return false
end
return true
end

If you run a non-standard framework resource name or a custom notification/progress system, adapt the open bridge files instead of the escrowed core.

FileResponsibility
framework/main.luaTextUI + target abstractions, localization (_U)
framework/cl-functions.luaCore getter, Framework.TS.Notification, Framework.TS.ProgressBar, callbacks
framework/sv-functions.luaServer-side framework helpers and RegisterUsableItem
framework/cl-functions.lua
-- framework/cl-functions.lua
local framework = Config.Framework or 'ESX'
if framework == 'ESX' then
Core = exports["es_extended"]:getSharedObject()
ESX = exports["es_extended"]:getSharedObject()
elseif framework == 'QBCore' then
Core = exports['qb-core']:GetCoreObject()
elseif framework == 'Qbox' then
Core = exports['qbx_core']
end