FiveM रेडियो और डिस्पैच सिस्टम: PMA, pma-voice और CADs
FiveM रेडियो, डिस्पैच और CAD सिस्टम सेट अप करें। pma-voice चैनल, MDT टूल्स और पुलिस, EMS और मैकेनिक टीमों के लिए सर्वश्रेष्ठ स्क्रिप्ट।
Agency Scripts
Agency Scripts के संस्थापक और प्रमुख डेवलपर
रेडियो और डिस्पैच सिस्टम आर्किटेक्चर
एक रेडियो और डिस्पैच सिस्टम FiveM रोलप्ले सर्वर पर आपातकालीन सेवाओं का संचार रीढ़ है। यह पुलिस, EMS, और फायर विभागों को संरचित रेडियो चैनलों के माध्यम से प्रतिक्रिया समन्वय करने, 911 कॉल और स्वचालित पहचान प्रणालियों से प्राथमिकता प्राप्त डिस्पैच अलर्ट प्राप्त करने, और GPS एकीकरण के माध्यम से वास्तविक समय में यूनिट स्थान ट्रैक करने में सक्षम बनाता है। वास्तुकला तीन जुड़े हुए सिस्टम से मिलकर बनती है: रेडियो चैनल फ्रेमवर्क जो प्रबंधित करता है कि कौन किस आवृत्ति पर बात कर सकता है, डिस्पैच कतार जो आने वाली कॉलों को संसाधित करती है और उन्हें उपयुक्त यूनिट्स को मार्गित करती है, और GPS ट्रैकिंग परत जो साझा मानचित्र पर यूनिट स्थितियों को दर्शाती है। सरल चैट-आधारित संचार के विपरीत, एक उचित रेडियो सिस्टम आवृत्तियों को स्विच करने, केवल ट्यून होने पर रेडियो बातचीत सुनने, और वास्तविक दुनिया की आपातकालीन सेवाओं के अनुरूप संरचित संचार प्रोटोकॉल का पालन करने का अनुभव जोड़ता है। पूरा सिस्टम धोखाधड़ी रोकने के लिए सर्वर-साइड स्थिति प्रबंधन के माध्यम से चलता है, क्लाइंट-साइड NUI रेडियो इंटरफ़ेस और डिस्पैच पैनल प्रदान करता है।
रेडियो चैनल सिस्टम
रेडियो चैनल संचार को व्यवस्थित करते हैं ताकि विभिन्न विभाग और इकाइयाँ बिना क्रॉस-टॉक के समन्वय कर सकें। प्रत्येक चैनल में एक फ्रीक्वेंसी नंबर, नौकरी भूमिकाओं के आधार पर एक्सेस प्रतिबंध, और वर्तमान में जुड़े खिलाड़ियों की सूची होती है। सिस्टम कई चैनल प्रकारों का समर्थन करता है: सामान्य संचार के लिए विभाग-व्यापी चैनल, विशिष्ट ऑपरेशनों जैसे पीछा या बैंक डकैती प्रतिक्रिया के लिए टैक्टिकल चैनल, और इंटर-डिपार्टमेंट चैनल जहां पुलिस और EMS साझा घटनाओं पर समन्वय कर सकते हैं। खिलाड़ी रेडियो आइटम या NUI इंटरफेस के माध्यम से चैनल में शामिल होते हैं, और उस चैनल पर भेजा गया सभी वॉइस या टेक्स्ट केवल उन्हीं खिलाड़ियों तक पहुंचता है जो उसी फ्रीक्वेंसी पर ट्यून हैं। एक प्राथमिकता स्पीकर सिस्टम लागू करें जहां डिस्पैच ऑपरेटर और कमांडिंग अधिकारी आपातकालीन अलर्ट के लिए सभी चैनलों पर एक साथ प्रसारण कर सकें:
Config.RadioChannels = {
-- Police Department
{ frequency = 1, label = 'PD Main', jobs = {'police'}, type = 'department' },
{ frequency = 2, label = 'PD Patrol', jobs = {'police'}, type = 'department' },
{ frequency = 3, label = 'PD Tactical', jobs = {'police'}, type = 'tactical', maxUsers = 8 },
{ frequency = 4, label = 'PD Detectives', jobs = {'police'}, type = 'tactical', minRank = 3 },
-- EMS / Fire
{ frequency = 10, label = 'EMS Main', jobs = {'ambulance'}, type = 'department' },
{ frequency = 11, label = 'EMS Field', jobs = {'ambulance'}, type = 'department' },
{ frequency = 12, label = 'Fire Main', jobs = {'fire'}, type = 'department' },
-- Inter-department
{ frequency = 20, label = 'Emergency Joint', jobs = {'police','ambulance','fire'}, type = 'inter' },
{ frequency = 21, label = 'Command Channel', jobs = {'police','ambulance','fire'}, type = 'command', minRank = 5 },
-- Civilian (if radio item owned)
{ frequency = 50, label = 'Civilian Band', jobs = {}, type = 'open' },
}
-- Server-side channel state
local radioState = {} -- [frequency] = { players = {}, priority = false }
RegisterNetEvent('radio:server:joinChannel', function(frequency)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local channel = nil
for _, ch in ipairs(Config.RadioChannels) do
if ch.frequency == frequency then channel = ch break end
end
if not channel then return end
-- Check job access
if #channel.jobs > 0 then
local playerJob = Player.PlayerData.job.name
local hasAccess = false
for _, job in ipairs(channel.jobs) do
if job == playerJob then hasAccess = true break end
end
if not hasAccess then
TriggerClientEvent('QBCore:Notify', src, 'No access to this frequency', 'error')
return
end
end
-- Check rank requirement
if channel.minRank and Player.PlayerData.job.grade.level < channel.minRank then
TriggerClientEvent('QBCore:Notify', src, 'Insufficient rank for this channel', 'error')
return
end
-- Check max users for tactical channels
if channel.maxUsers and radioState[frequency] then
if #radioState[frequency].players >= channel.maxUsers then
TriggerClientEvent('QBCore:Notify', src, 'Channel full', 'error')
return
end
end
-- Leave current channel
LeaveCurrentChannel(src)
-- Join new channel
if not radioState[frequency] then
radioState[frequency] = { players = {}, priority = false }
end
table.insert(radioState[frequency].players, src)
TriggerClientEvent('radio:client:joined', src, frequency, channel.label)
TriggerClientEvent('QBCore:Notify', src, 'Tuned to ' .. channel.label .. ' (' .. frequency .. ')', 'success')
end)
10-कोड सिस्टम
टेन-कोड्स मानकीकृत रेडियो संक्षिप्त रूप हैं जो आपातकालीन सेवा संचार में प्रामाणिकता जोड़ते हैं और डिस्पैच सिस्टम के माध्यम से त्वरित स्थिति अपडेट सक्षम करते हैं। 10-कोड्स को केवल चैट मैक्रोज़ के रूप में लागू करने के बजाय, उन्हें कार्यात्मक कमांड के रूप में बनाएं जो अधिकारी की स्थिति को डिस्पैच सिस्टम में अपडेट करते हैं और स्वचालित प्रतिक्रियाओं को ट्रिगर करते हैं। जब एक अधिकारी कॉल करता है 10-80 (पकड़ जारी है), सिस्टम को स्वचालित रूप से उनके स्थिति को डिस्पैच बोर्ड पर अपडेट करना चाहिए, सभी यूनिट्स के लिए एक पकड़ अलर्ट बनाना चाहिए, और अधिकारी के वाहन का GPS ट्रैकिंग शुरू करनी चाहिए। जब वे कॉल करते हैं 10-97 (arriving on scene), डिस्पैच सिस्टम उन्हें सक्रिय कॉल के लिए ऑन-सीन के रूप में चिह्नित करता है, जिसका वे जवाब दे रहे हैं। 10-कोड सिस्टम को एक कॉन्फ़िगर करने योग्य तालिका के रूप में बनाएं ताकि सर्वर मालिक अपने विभाग की पसंदीदा प्रोटोकॉल के अनुसार कोड कस्टमाइज़ कर सकें:
Config.TenCodes = {
['10-4'] = { label = 'Acknowledged', action = nil, status = nil },
['10-6'] = { label = 'Busy', action = nil, status = 'busy' },
['10-7'] = { label = 'Out of Service', action = 'setOffDuty', status = 'off_duty' },
['10-8'] = { label = 'In Service', action = 'setOnDuty', status = 'available' },
['10-11'] = { label = 'Traffic Stop', action = 'createTrafficStop', status = 'traffic_stop' },
['10-15'] = { label = 'Suspect in Custody', action = nil, status = 'transport' },
['10-20'] = { label = 'Location Request', action = 'shareLocation', status = nil },
['10-23'] = { label = 'Arrived at Scene', action = 'markOnScene', status = 'on_scene' },
['10-32'] = { label = 'Person with Weapon', action = 'createAlert', status = 'responding', priority = 'high' },
['10-41'] = { label = 'Beginning Tour of Duty', action = 'clockIn', status = 'available' },
['10-42'] = { label = 'Ending Tour of Duty', action = 'clockOut', status = 'off_duty' },
['10-71'] = { label = 'Shooting', action = 'createAlert', status = 'responding', priority = 'critical' },
['10-78'] = { label = 'Officer Needs Assistance', action = 'panicButton', status = 'emergency', priority = 'critical' },
['10-80'] = { label = 'Pursuit in Progress', action = 'startPursuit', status = 'pursuit', priority = 'high' },
['10-97'] = { label = 'Arriving on Scene', action = 'markOnScene', status = 'on_scene' },
['10-99'] = { label = 'Officer Down', action = 'officerDown', status = 'emergency', priority = 'critical' },
['code4'] = { label = 'No Further Assistance', action = 'clearScene', status = 'available' },
}
RegisterNetEvent('radio:server:tenCode', function(code)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local codeConfig = Config.TenCodes[code]
if not codeConfig then return end
-- Update officer status
if codeConfig.status then
UpdateUnitStatus(src, codeConfig.status)
end
-- Execute associated action
if codeConfig.action then
ExecuteCodeAction(codeConfig.action, src, codeConfig)
end
-- Broadcast to channel
local channel = GetPlayerChannel(src)
if channel then
local name = GetUnitCallsign(src) or Player.PlayerData.charinfo.firstname
BroadcastToChannel(channel, {
type = 'tencode',
code = code,
label = codeConfig.label,
unit = name,
priority = codeConfig.priority,
})
end
end)
डिस्पैच कॉल कतार
डिस्पैच कतार वह केंद्रीय हब है जो सभी आने वाली आपातकालीन कॉल्स को संसाधित करता है और उन्हें उपयुक्त यूनिट्स को मार्गदर्शित करता है। जब कोई नागरिक 911 कॉल करता है, जब बैंक या स्टोर में स्वचालित अलार्म ट्रिगर होता है, या जब कोई पुलिस अधिकारी बैकअप का अनुरोध करता है, तो सिस्टम प्राथमिकता स्तर, स्थान, विवरण, और आवश्यक सेवा के प्रकार के साथ एक डिस्पैच प्रविष्टि बनाता है। कतार सभी सक्रिय कॉल्स को प्राथमिकता के अनुसार डिस्पैच NUI पैनल पर दिखाती है, जिसमें कॉल समय, स्थान, स्थिति, और असाइन किए गए यूनिट्स दिखाए जाते हैं। एक समर्पित डिस्पैच ऑपरेटर भूमिका कॉल्स को विशिष्ट यूनिट्स को मैन्युअल रूप से असाइन कर सकती है, या अधिकारी स्वयं कॉल पर क्लिक करके और खुद को प्रतिक्रिया देने वाला चिह्नित करके स्वयं असाइन कर सकते हैं। स्वचालित कॉल वृद्धि लागू करें जहां अनुत्तरित कॉल्स एक कॉन्फ़िगर करने योग्य टाइमआउट के बाद प्राथमिकता बढ़ा देते हैं, यह सुनिश्चित करते हुए कि व्यस्त अवधि के दौरान कोई आपातकालीन अनदेखा न हो:
local dispatchQueue = {}
local callIdCounter = 0
function CreateDispatchCall(data)
callIdCounter = callIdCounter + 1
local call = {
id = callIdCounter,
type = data.type or 'general', -- police, ems, fire, general
priority = data.priority or 'standard', -- low, standard, urgent, critical
code = data.code or nil, -- e.g., '10-71', '211' (robbery)
title = data.title,
description = data.description or '',
coords = data.coords,
street = GetStreetName(data.coords),
blip = data.blip or nil,
caller = data.caller or 'Unknown',
callerId = data.callerId or nil,
timestamp = os.time(),
status = 'pending', -- pending, assigned, responding, on_scene, resolved
assignedUnits = {},
escalationTimer = nil,
metadata = data.metadata or {},
}
-- Set escalation timer
if call.priority ~= 'critical' then
call.escalationTimer = os.time() + Config.EscalationTimeout
end
table.insert(dispatchQueue, call)
-- Notify appropriate department
local targetJobs = GetJobsForCallType(call.type)
local players = QBCore.Functions.GetQBPlayers()
for _, player in pairs(players) do
local job = player.PlayerData.job
if job.onduty and TableContains(targetJobs, job.name) then
TriggerClientEvent('dispatch:client:newCall', player.PlayerData.source, call)
end
end
-- Play alert sound based on priority
if call.priority == 'critical' then
PlayDispatchAlert('critical', targetJobs)
end
return call.id
end
-- Automated dispatch triggers
AddEventHandler('banking:robberyStarted', function(bankId, coords)
CreateDispatchCall({
type = 'police',
priority = 'critical',
code = '211',
title = 'Bank Robbery in Progress',
description = 'Silent alarm triggered at ' .. GetBankLabel(bankId),
coords = coords,
blip = { sprite = 500, color = 1, scale = 1.5, flash = true },
})
end)
AddEventHandler('hospital:911call', function(callerId, coords, description, injuries)
CreateDispatchCall({
type = 'ems',
priority = injuries and injuries.maxSeverity >= 80 and 'critical' or 'urgent',
title = 'Medical Emergency',
description = description,
coords = coords,
callerId = callerId,
caller = GetPlayerName(callerId),
blip = { sprite = 153, color = 3, scale = 1.2 },
metadata = { injuries = injuries },
})
end)
GPS ट्रैकिंग और यूनिट मैप
GPS ट्रैकिंग मानचित्र पर सभी सक्रिय इकाइयों की वास्तविक समय दृश्यता प्रदान करता है, जिससे डिस्पैचर्स और कमांडिंग अधिकारियों को सूचित असाइनमेंट निर्णय लेने में मदद मिलती है। प्रत्येक ड्यूटी पर अधिकारी की स्थिति एक कॉन्फ़िगर करने योग्य अंतराल पर डिस्पैच सिस्टम को प्रसारित की जाती है, आमतौर पर हर 5-10 सेकंड में, और साझा NUI मैप पैनल पर प्रदर्शित होती है जो डिस्पैच ऑपरेटरों और पर्यवेक्षकों के लिए सुलभ है। मैप पर विभाग और स्थिति के अनुसार रंग-कोडित यूनिट ब्लिप्स होते हैं, जिनमें आइकन यह दर्शाते हैं कि वे उपलब्ध हैं, प्रतिक्रिया दे रहे हैं, स्थल पर हैं, या पीछा कर रहे हैं। एक ट्रेल फीचर शामिल करें जो पिछले कुछ मिनटों में यूनिट की गति को ट्रैक करता है ताकि डिस्पैचर्स पीछा के दौरान यात्रा की दिशा देख सकें। कॉल रेडियस विज़ुअलाइज़ेशन लागू करें जो सक्रिय डिस्पैच कॉल के चारों ओर एक वृत्त बनाता है जो अनुशंसित प्रतिक्रिया क्षेत्र दिखाता है। जब डिस्पैचर को नई कॉल के लिए सबसे नजदीकी उपलब्ध यूनिट खोजनी होती है, तो सिस्टम सभी उपलब्ध इकाइयों से दूरी की गणना कर सकता है और सर्वोत्तम असाइनमेंट सुझा सकता है। GPS प्रसारण को कुशल रखें केवल तब स्थिति अपडेट भेजकर जब यूनिट न्यूनतम दूरी सीमा से अधिक हिली हो ताकि व्यस्त सर्वरों पर नेटवर्क ट्रैफ़िक कम हो।
अलर्ट सिस्टम और पैनिक बटन
अलर्ट सिस्टम उच्च प्राथमिकता सूचनाओं को संभालता है जो सभी इकाइयों से तत्काल ध्यान मांगती हैं। सबसे महत्वपूर्ण अलर्ट पैनिक बटन है, जो तब सक्रिय होता है जब कोई अधिकारी कॉल करता है 10-78 या 10-99", जो अपनी GPS स्थिति सभी ऑन-ड्यूटी यूनिट्स को फ्लैशिंग ब्लिप और विशिष्ट अलार्म ध्वनि के साथ भेजता है। पैनिक अलर्ट को सामान्य डिस्पैच कतार प्राथमिकता से ऊपर होना चाहिए और हर अधिकारी की स्क्रीन पर प्रमुखता से दिखना चाहिए जब तक कि स्वीकार न किया जाए। विभिन्न अलर्ट स्तर लागू करें जो बढ़ती प्रतिक्रियाएं ट्रिगर करते हैं: एक मानक अलर्ट एक डिस्पैच कॉल बनाता है जिसमें नोटिफिकेशन ध्वनि होती है, एक आपातकालीन अलर्ट डिस्पैच पैनल को फ्लैश करता है और चेतावनी टोन बजाता है, और एक गंभीर अलर्ट पूर्ण स्क्रीन नोटिफिकेशन ट्रिगर करता है जिसमें सायरन ध्वनि और स्वचालित GPS रूटिंग अलर्ट स्थान पर होती है। स्वचालित अलर्ट अन्य सर्वर सिस्टम्स के साथ एकीकृत होते हैं ताकि सार्वजनिक क्षेत्रों में हथियार चलाने पर गनशॉट डिटेक्शन ज़ोन अलर्ट ट्रिगर करें, स्पीड कैमरे गति सीमा से अधिक वाहन को फ्लैग करें, और स्टोर अलार्म सिस्टम चोरी शुरू होने पर डिस्पैच कॉल बनाएं। प्रत्येक अलर्ट प्रकार के लिए कॉन्फ़िगर करने योग्य कूलडाउन होते हैं ताकि एक ही क्षेत्र में बार-बार ट्रिगर से स्पैम न हो।
डिस्पैच ऑपरेटर भूमिका
डिस्पैच ऑपरेटर एक समर्पित भूमिका है जो एक वर्कस्टेशन पर बैठता है और फील्ड यूनिट्स को आपातकालीन कॉल्स के प्रवाह का प्रबंधन करता है। अधिकारियों के विपरीत जो एक सरल डिस्पैच सूचना देखते हैं, ऑपरेटर के पास एक पूर्ण डिस्पैच कंसोल NUI होता है जिसमें कतार प्रबंधक, यूनिट रोस्टर, लाइव मैप, और संचार उपकरण होते हैं। ऑपरेटर कॉल्स को कतार में खींचकर प्राथमिकता दे सकता है, निकटता और उपलब्धता के आधार पर विशिष्ट यूनिट्स को कॉल असाइन कर सकता है, जब यूनिट्स साफ रिपोर्ट करते हैं तो कॉल्स को हल के रूप में चिह्नित कर सकता है, और विभागीय आवृत्ति पर सभी यूनिट्स को संदेश प्रसारित कर सकता है। एक वर्कस्टेशन सिस्टम लागू करें जहां डिस्पैच ऑपरेटरों को पूर्ण कंसोल तक पहुंचने के लिए निर्दिष्ट डिस्पैच डेस्क पर बैठना आवश्यक हो, जिससे वे फील्ड में रहते हुए डिस्पैच सिस्टम का संचालन न कर सकें। ऑपरेटर भूमिका के लिए अपनी नौकरी ग्रेड प्रगति होनी चाहिए जहां अनुभवी डिस्पैचर्स इंटर-डिपार्टमेंट समन्वय उपकरण और आपातकालीन प्रसारण क्षमताओं तक पहुंच प्राप्त करते हैं। औसत प्रतिक्रिया समय, प्रति शिफ्ट संभाले गए कॉल्स, और कॉल समाधान दर जैसे डिस्पैच प्रदर्शन मेट्रिक्स को ट्रैक करें ताकि ऑपरेटरों को उनके प्रदर्शन पर प्रतिक्रिया मिल सके और सर्वर प्रशासकों को स्टाफिंग निर्णयों के लिए डेटा प्रदान किया जा सके।
वॉइस रेडियो एकीकरण
pma-voice या mumble-voip जैसे वॉइस चैट समाधानों का उपयोग करने वाले सर्वरों के लिए, रेडियो सिस्टम को प्रॉक्सिमिटी वॉइस के साथ एकीकृत करें ताकि यथार्थवादी रेडियो संचार बनाया जा सके। जब कोई खिलाड़ी रेडियो चैनल पर एक कीबाइंड दबाकर प्रसारित करता है, तो उनकी आवाज़ सभी खिलाड़ियों द्वारा उसी आवृत्ति पर सुनी जानी चाहिए, भौतिक निकटता की परवाह किए बिना, रेडियो संचार को आमने-सामने की बातचीत से अलग करने के लिए रेडियो फ़िल्टर प्रभाव लागू किया जाना चाहिए। एक स्क्वेल्च सिस्टम लागू करें जहां खिलाड़ियों को बोलने से पहले अपना ट्रांसमिट की छोड़नी होती है, जो वास्तविक रेडियो हाफ-डुप्लेक्स व्यवहार का अनुकरण करता है। की-अप और की-डाउन के लिए रेडियो ध्वनि प्रभाव जोड़ें ताकि जब कोई प्रसारण शुरू या बंद करे तो ऑडियो फीडबैक मिले। वॉइस एकीकरण को रेडियो सिस्टम में परिभाषित चैनल एक्सेस नियंत्रण का सम्मान करना चाहिए, इसलिए जो खिलाड़ी रेडियो NUI के माध्यम से किसी आवृत्ति में शामिल नहीं हुए हैं, वे mumble चैनल ID जानने के बावजूद उसे सुन या प्रसारित नहीं कर सकते। वॉइस चैट के बिना सर्वरों के लिए, एक टेक्स्ट-आधारित रेडियो सिस्टम पर वापस जाएं जहां आवृत्ति पर भेजे गए संदेश एक स्टाइल्ड चैट फॉर्मेट में प्रेषक के कॉलसाइन और चैनल पहचानकर्ता के साथ दिखाई देते हैं।
एकीकरण और विस्तारशीलता
आपका रेडियो और डिस्पैच सिस्टम एक साफ API प्रदान करना चाहिए जिसे अन्य संसाधन डिस्पैच कॉल बनाने, अलर्ट भेजने, और यूनिट स्थिति पूछने के लिए उपयोग कर सकें बिना आंतरिक कार्यान्वयन को समझे। एक्सपोर्ट फ़ंक्शन जैसे CreateDispatchCall, SendAlert, GetAvailableUnits, और GetUnitStatus ताकि सर्वर पर कोई भी रिसोर्स डिस्पैच सिस्टम के साथ इंटीग्रेट हो सके। जब बैंक डकैती शुरू होती है, तो बैंकिंग रिसोर्स कॉल बनाता है। जब EMS को 911 कॉल मिलती है, तो अस्पताल रिसोर्स इसे उसी डिस्पैच सिस्टम के माध्यम से रूट करता है। यह केंद्रीकृत दृष्टिकोण सुनिश्चित करता है कि सभी आपातकालीन संचार एक ही सिस्टम के माध्यम से एकसमान प्राथमिकता हैंडलिंग, यूनिट ट्रैकिंग, और लॉगिंग के साथ प्रवाहित हो। डिस्पैच कॉल इतिहास को डेटाबेस में स्टोर करें ताकि एडमिन समीक्षा कर सके और शिफ्ट रिपोर्ट्स जनरेट करें जो कॉल वॉल्यूम, प्रतिक्रिया समय, और यूनिट गतिविधि को प्रत्येक ड्यूटी अवधि के लिए सारांशित करें। डिस्पैच सिस्टम को Discord वेबहुक से कनेक्ट करें ताकि अधिकारी-डाउन कॉल या बैंक डकैती जैसे महत्वपूर्ण अलर्ट एक समर्पित स्टाफ चैनल में दिखें, जिससे सर्वर एडमिन इन-गेम न होने पर भी सूचित रहें।