mirror of
https://github.com/ND-Framework/ND_Core.git
synced 2026-08-17 05:56:01 +01:00
Add files via upload
This commit is contained in:
61
ND_ShotSpotter/config_client.lua
Normal file
61
ND_ShotSpotter/config_client.lua
Normal file
@@ -0,0 +1,61 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
config = {
|
||||
shotSpotterDelay = 10, -- delay (in seconds) when cops will receive a notification after there has been a shooting.
|
||||
shotSpotterTimer = 120, -- How long should the shot spotter stay on the map.
|
||||
shotSpotterCooldown = 30, -- Cooldown for the next time a player can trigger it again.
|
||||
|
||||
shotSpotterUsePostal = true, -- if you're using the nearest postal script turn this to true.
|
||||
postalResourceName = "nearest-postal", -- the resource name of the nearest postal script, this is used for the export.
|
||||
|
||||
-- This is the departments that will receive the shot spotter alerts.
|
||||
receiveAlerts = {
|
||||
"SAHP",
|
||||
"LSPD",
|
||||
"BCSO"
|
||||
},
|
||||
|
||||
-- Weapon that won't be triggered by the shot spotter.
|
||||
weaponBlackList = {
|
||||
"weapon_flaregun",
|
||||
"weapon_stungun_mp",
|
||||
"weapon_grenade",
|
||||
"weapon_bzgas",
|
||||
"weapon_molotov",
|
||||
"weapon_stickybomb",
|
||||
"weapon_proxmine",
|
||||
"weapon_snowball",
|
||||
"weapon_pipebomb",
|
||||
"weapon_ball",
|
||||
"weapon_smokegrenade",
|
||||
"weapon_flare",
|
||||
"weapon_petrolcan",
|
||||
"weapon_fireextinguisher",
|
||||
"weapon_hazardcan",
|
||||
"weapon_fertilizercan"
|
||||
},
|
||||
|
||||
useRealisticShotSpotter = false, -- this is if you want to enable the shot spotter only when the player is inside one of the zones below. The zones are in the city and a little around it.
|
||||
realisticShotSpotterLocations = {
|
||||
{x = 653.4214, y = -648.7440, z = 57.1897},
|
||||
{x = 1015.9837, y = -255.2573, z = 85.5857},
|
||||
{x = 329.9973, y = 288.9604, z = 120.1029},
|
||||
{x = -202.7689, y = -327.3490, z = 66.0497},
|
||||
{x = 31.3205, y = -875.2959, z = 31.4629},
|
||||
{x = 70.1372, y = -1718.3291, z = 34.2056},
|
||||
{x = 1196.9178, y = -1624.6641, z = 50.3403},
|
||||
{x = -852.9095, y = -1215.8782, z = 9.2463},
|
||||
{x = -932.7648, y = -448.8844, z = 42.9436},
|
||||
{x = -1713.6848, y = 478.4267, z = 130.3795},
|
||||
{x = -596.5602, y = 515.0753, z = 109.675},
|
||||
{x = 716.6274, y = -1958.7434, z = 44.7564}
|
||||
},
|
||||
|
||||
testing = false -- if you're adding zones above and want to enable the blips on the map to see where the zone is then turn this on, otherwise turn it off.
|
||||
}
|
||||
|
||||
function notify(message)
|
||||
BeginTextCommandThefeedPost("STRING")
|
||||
AddTextComponentSubstringPlayerName(message)
|
||||
EndTextCommandThefeedPostTicker(0,1)
|
||||
end
|
||||
4
ND_ShotSpotter/config_server.lua
Normal file
4
ND_ShotSpotter/config_server.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
server_config = {
|
||||
useDiscordLogging = false,
|
||||
discordWebhook = "",
|
||||
}
|
||||
157
ND_ShotSpotter/source/client.lua
Normal file
157
ND_ShotSpotter/source/client.lua
Normal file
@@ -0,0 +1,157 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
local alreadyShot = false
|
||||
local setRoute = false
|
||||
local route = false
|
||||
|
||||
-- Suppressors hash, if a weapon has these then it won't trigger the shot spotter.
|
||||
local suppresors = {
|
||||
"0x65EA7EBB", -- Pistol.
|
||||
"0x837445AA", -- Carbine Rifle, Advanced Rifle, Bullpup Rifle, Assault Shotgun, Marksman Rifle.
|
||||
"0xA73D4664", -- .50 Pistol, Micro SMG, Assault SMG, Assault Rifle, Special Carbine, Bullpup Shotgun, Heavy Shotgun, Sniper Rifle.
|
||||
"0xC304849A", -- Combat Pistol, AP Pistol, Heavy Pistol, Vintage Pistol, SMG.
|
||||
"0xE608B35E" -- Pump Shotgun.
|
||||
}
|
||||
|
||||
-- check if the players location is inside the shot spotter locations, this will only be used in the code when realistic shot spotter is turned on.
|
||||
function isInShotSpotterLocation(pedCoords)
|
||||
for _, location in pairs(config.realisticShotSpotterLocations) do
|
||||
if #(pedCoords - vector3(location.x, location.y, location.z)) < 450.0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- check if the players department can receive shot spotter alerts.
|
||||
function isCop()
|
||||
local selectedDepartment = exports["ND_Core"]:getCharacterInfo().department
|
||||
for _, department in pairs(config.receiveAlerts) do
|
||||
if department == selectedDepartment then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function triggerShotSpotter(ped)
|
||||
local pedCoords = GetEntityCoords(ped)
|
||||
if config.shotSpotterUsePostal then
|
||||
postal = exports[config.postalResourceName]:getPostal()
|
||||
else
|
||||
postal = false
|
||||
end
|
||||
|
||||
-- if the player isn't in the realistic shot spotter locations then the shot spotter won't trigger.
|
||||
if config.useRealisticShotSpotter and not isInShotSpotterLocation(pedCoords) then
|
||||
return
|
||||
end
|
||||
|
||||
-- if the player has a blacklisted weapon then the shot spotter won't trigger.
|
||||
local selectedWeapon = GetSelectedPedWeapon(ped)
|
||||
for _, weapon in pairs(config.weaponBlackList) do
|
||||
if GetHashKey(weapon) == selectedWeapon then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- if the player has a suppresor attached to their weapon then the shot spotter won't trigger.
|
||||
for _, suppresor in pairs(suppresors) do
|
||||
if HasPedGotWeaponComponent(ped, selectedWeapon, tonumber(suppresor)) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- if the player is a cop then they won't trigger the shotspotter.
|
||||
if isCop() then
|
||||
return
|
||||
end
|
||||
|
||||
-- the alreadyShot variable is used for checking if the player has already shot and to add a cooldown until it turns to false.
|
||||
if alreadyShot then return end
|
||||
alreadyShot = true
|
||||
Citizen.Wait(config.shotSpotterDelay * 1000)
|
||||
local zoneName = GetLabelText(GetNameOfZone(pedCoords.x, pedCoords.y, pedCoords.z))
|
||||
local street = GetStreetNameFromHashKey(GetStreetNameAtCoord(pedCoords.x, pedCoords.y, pedCoords.z))
|
||||
TriggerServerEvent("ND_ShotSpotter:Trigger", street, pedCoords, postal, zoneName)
|
||||
Citizen.Wait(config.shotSpotterCooldown * 1000)
|
||||
alreadyShot = false
|
||||
end
|
||||
|
||||
-- Check if the player is shooting.
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(0)
|
||||
local ped = PlayerPedId()
|
||||
if IsPedShooting(ped) then
|
||||
triggerShotSpotter(ped)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("ND_ShotSpotter:Report")
|
||||
AddEventHandler("ND_ShotSpotter:Report", function(street, pedCoords, postal)
|
||||
-- if the player isn't a cop then they won't receive the alert.
|
||||
if not isCop() then
|
||||
return
|
||||
end
|
||||
|
||||
-- if the player is close to the shots then they won't receive a shot spotter alert.
|
||||
if #(GetEntityCoords(PlayerPedId()) - pedCoords) < 50.0 then
|
||||
return
|
||||
end
|
||||
|
||||
blip = AddBlipForCoord(pedCoords.x, pedCoords.y, pedCoords.z)
|
||||
setRoute = true
|
||||
route = false
|
||||
TriggerEvent("ND_shotSpotter:setRoute")
|
||||
notify("~w~Press ~g~G ~w~to respond to the latest shot spotter.")
|
||||
SetBlipSprite(blip, 161)
|
||||
SetBlipAsShortRange(blip, true)
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
SetBlipColour(blip, 1)
|
||||
if not postal then
|
||||
msg = "Shotspotter detected in " .. street .. "."
|
||||
AddTextComponentString("Shot Spotter: " .. street)
|
||||
else
|
||||
msg = "Shotspotter detected in " .. street .. ", postal: " .. postal .. "."
|
||||
AddTextComponentString("Shot Spotter: " .. street .. ", postal: " .. postal)
|
||||
end
|
||||
TriggerEvent("chat:addMessage", {
|
||||
color = {255, 0, 0},
|
||||
args = {"^*Dispatch ", msg}
|
||||
})
|
||||
EndTextCommandSetBlipName(blip)
|
||||
Citizen.Wait(config.shotSpotterTimer * 1000)
|
||||
RemoveBlip(blip)
|
||||
setRoute = false
|
||||
route = false
|
||||
end)
|
||||
|
||||
-- set route to latest shot spotter location.
|
||||
RegisterNetEvent("ND_shotSpotter:setRoute")
|
||||
AddEventHandler("ND_shotSpotter:setRoute", function()
|
||||
while setRoute do
|
||||
Citizen.Wait(0)
|
||||
if IsControlJustPressed(0, 113) then
|
||||
if route then
|
||||
route = false
|
||||
SetBlipRoute(blip, route)
|
||||
else
|
||||
route = true
|
||||
SetBlipRoute(blip, route)
|
||||
SetBlipRouteColour(blip, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if config.testing then
|
||||
Citizen.CreateThread(function()
|
||||
Citizen.Wait(0)
|
||||
for k, v in pairs(config.realisticShotSpotterLocations) do
|
||||
k = AddBlipForRadius(v.x, v.y, v.z, 450.0)
|
||||
SetBlipAlpha(k, 100)
|
||||
end
|
||||
end)
|
||||
end
|
||||
36
ND_ShotSpotter/source/server.lua
Normal file
36
ND_ShotSpotter/source/server.lua
Normal file
@@ -0,0 +1,36 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
RegisterNetEvent("ND_ShotSpotter:Trigger")
|
||||
AddEventHandler("ND_ShotSpotter:Trigger", function(street, pedCoords, postal, zoneName)
|
||||
if server_config.useDiscordLogging then
|
||||
local embed = {
|
||||
{
|
||||
title = "ShotSpotter Alert",
|
||||
description = "Gunshots detected on " .. zoneName .. ", " .. street .. "." ,
|
||||
fields = {
|
||||
{
|
||||
name = "Location:",
|
||||
value = zoneName .. ", **" .. street .. "**"
|
||||
}
|
||||
},
|
||||
footer = {
|
||||
icon_url = "https://i.imgur.com/notBtrZ.png",
|
||||
text = "Created by Andyyy#7666"
|
||||
},
|
||||
thumbnail = {
|
||||
url = "https://i.imgur.com/BTbxJZu.png"
|
||||
},
|
||||
color = 16722976
|
||||
}
|
||||
}
|
||||
if postal then
|
||||
embed[1].description = "Gunshots detected on " .. zoneName .. ", " .. street .. " (" .. postal .. ")."
|
||||
embed[1].fields[2] = {
|
||||
name = "Postal:",
|
||||
value = postal
|
||||
}
|
||||
end
|
||||
PerformHttpRequest(server_config.discordWebhook, function(err, text, headers) end, 'POST', json.encode({username = "ND Shotspotter", embeds = embed}), {["Content-Type"] = "application/json"})
|
||||
end
|
||||
TriggerClientEvent("ND_ShotSpotter:Report", -1, street, pedCoords, postal)
|
||||
end)
|
||||
Reference in New Issue
Block a user