Config = Config or {} Config.Debug = false -- Set to true ONLY for testing/debugging (Keep false for live server) Config.DefaultLocale = "en" Config.Locales = { "en" } --- ### FRAMEWORK ### --- Config.Framework = "auto" -- qb | esx | qbx | standalone | auto (auto-detect) --- ### TABLET ### --- Config.TabletPrefix = "GKS" -- Prefix for tablet unique ID Config.TabletCommand = "tablet" -- Command to open/close tablet Config.TabletKey = "F7" -- Key binding to open/close tablet Config.TabletKeyEnabled = false -- false: disables both keybind and chat command (item-only open) --- ### CUSTOM APPS ### --- -- Runtime iframe apps registered via exports['gks-tablet']:AddCustomApp(...) Config.CustomApps = {} --- ### TABLET ITEM / INVENTORY ### --- Config.InventoryScript = "auto" -- ox_inventory | none | auto (auto-detect) Config.TabletItemRequire = true -- true: tablet item required in inventory Config.TabletItemName = "tablet" -- inventory item name --- ### MDT EVIDENCE STASH ### --- Config.CaseStash = { slots = 50, maxWeight = 100000, -- 100kg prefix = "gks_mdt_case_", } Config.ReportStash = { slots = 50, maxWeight = 100000, -- 100kg prefix = "gks_mdt_report_", } --- ### JOBS ### --- -- You can add multiple jobs for each category -- These are used for dispatch notifications, side panel access, etc. Config.Jobs = { Police = { 'police', 'lspd', 'bcso', 'sahp', 'sheriff', 'fbi', 'doj', 'state' }, Ambulance = { 'ambulance', 'ems', 'hospital', 'doctor', 'medic' } } --- ### DISPATCH ### --- --[[ Dispatch system configuration. - Enabled: master switch for all dispatch (creation, bridges, MDT tab) - OverlayVisible: side panel + floating notifications outside MDT (O key) - BlipsEnabled / SoundsEnabled: map blips and alert sound (independent of overlay) - BlipDurationMinutes: map blip lifetime - Bridges: third-party dispatch event compatibility ]] Config.Dispatch = { Enabled = true, OverlayVisible = true, BlipsEnabled = true, SoundsEnabled = true, BlipDurationMinutes = 5, Bridges = { -- Set false when using GKS native AutoAlerts. true only if an external dispatch bridge runs without native auto-detect. ["0r_dispatch"] = false, ps_dispatch = false, qs_dispatch = false, cd_dispatch = true, rcore_dispatch = false, qb_police_alert = false, qb_ambulance_alert = false, emergencydispatch = false, wasabi_ambulance_v2 = false, }, -- Native CEvent auto-detection (when AutoAlerts.Enabled) AutoAlerts = { Enabled = true, CooldownSeconds = 5, SpeedMinKmh = 80, -- effective threshold = SpeedMinKmh + math.random(0, 20) per check SpeedExtraThrottleMs = 10000, SkipForPolice = true, SkipForAmbulance = false, DebugAllowEmergencyJobs = false, ExplosionRequireLocalPed = false, ExplosionLocalRadius = 50.0, -- Global / per-alert chance to trigger (0-100) Chance = 100, -- ChancePerAlert = { Autotheft = 80, Shooting = 90 }, -- Strip "Metallic"/"Matte" prefixes in dispatch color field (Graceful Red vs Metallic Graceful Red) SimpleColorNames = true, -- Nearby ambient NPC must call police before dispatch fires (optional RP layer) Witness = { Enabled = false, MaxDistance = 100.0, MinWitnessDistance = 5.0, CallPolice = true, }, -- Armed person visible weapon (interval poll) Armed = { CheckIntervalMs = 1000, CooldownSeconds = 120, }, Alerts = { Shooting = true, Melee = false, Autotheft = true, SeenCarStolen = true, Armed = false, Explosion = true, PlayerDowned = true, Speeding = false, PedRunOver = false, CarCrash = false, Fire = false, VehicleFire = true, InjuredPerson = false, ZoneChance = false, }, -- Weapons that do NOT trigger shooting alerts (NOT a whitelist — these are excluded) IgnoredWeapons = { '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_RAYCARBINE', 'WEAPON_STUNGUN', }, -- Weapon groups ignored for Shooting / Armed. See GetWeapontypeGroup hashes. IgnoredWeaponGroups = { 'DIGISCANNER', 'FIREEXTINGUISHER', 'HACKINGDEVICE', 'METALDETECTOR', 'NIGHTVISION', 'PARACHUTE', 'PETROLCAN', 'STUNGUN', 'TRANQILIZER', 'UNARMED', 'MELEE', 'UNKNOWN', }, CooldownGroups = { gun = { 'shooting', 'vehicleshots', 'hunting', 'armed' }, theft = { 'carjack', 'vehicletheft', 'copcarstolen' }, violence = { 'fight', 'pedrunover' }, destruction = { 'explosion', 'fire', 'vehiclefire' }, traffic = { 'speeding', 'carcrash' }, medical = { 'playerdowned', 'officerdown', 'emsdown', 'civdown' }, }, HuntingZones = { { label = 'Hunting Zone', radius = 650.0, coords = vector3(-938.61, 4823.99, 313.92) }, }, NoDispatchZones = { -- { label = 'Ammunation', coords = vector3(13.53, -1097.92, 29.8), length = 14.0, width = 5.0, heading = 70, minZ = 28.8, maxZ = 32.8 }, }, Presets = { shooting = { title = 'Streljanje', description = 'Prijave streljanja na območju', code = '10-11', priority = 'medium', job = 'police', blip = { sprite = 110, color = 1 }, }, vehicleshots = { title = 'Streljanje iz vozila', description = 'Prijave streljanja iz vozila', code = '10-60', priority = 'medium', job = 'police', blip = { sprite = 119, color = 1 }, }, hunting = { title = 'Lovska dejavnost', description = 'Prijave lova na območju', code = '10-13', priority = 'medium', job = 'police', blip = { sprite = 141, color = 2 }, }, fight = { title = 'Pretep v teku', description = 'Prijave fizičnega spopada', code = '10-10', priority = 'medium', job = 'police', blip = { sprite = 685, color = 69 }, }, carjack = { title = 'Ugrabitev vozila', description = 'Prijave ugrabitve vozila', code = '10-35', priority = 'medium', job = 'police', blip = { sprite = 595, color = 60 }, }, vehicletheft = { title = 'Kraja vozila', description = 'Prijave kraje vozila', code = '10-35', priority = 'medium', job = 'police', blip = { sprite = 595, color = 60 }, }, explosion = { title = 'Eksplozija', description = 'Prijave eksplozije na območju', code = '10-80', priority = 'medium', job = 'police', isRadius = true, radius = 75, blip = { sprite = 436, color = 1 }, }, officerdown = { title = 'Poškodovan policist', description = 'Policist potrebuje takojšnjo pomoč', code = '10-99', priority = 'high', job = 'police', blip = { sprite = 526, color = 1 }, }, emsdown = { title = 'Poškodovan reševalec', description = 'Reševalec potrebuje takojšnjo pomoč', code = '10-99', priority = 'high', job = 'ambulance', blip = { sprite = 526, color = 3 }, }, civdown = { title = 'Poškodovana oseba', description = 'Prijave poškodovane osebe', code = '10-69', priority = 'high', job = 'ambulance', blip = { sprite = 126, color = 3 }, }, speeding = { title = 'Prehitra vožnja', description = 'Prijave prehitre vožnje', code = '10-11', priority = 'medium', job = 'police', blip = { sprite = 326, color = 84 }, }, pedrunover = { title = 'Povožen pešec', description = 'Prijave povoženega pešca', code = '10-54', priority = 'medium', job = 'police', blip = { sprite = 380, color = 1 }, }, carcrash = { title = 'Prometna nesreča', description = 'Prijave prometne nesreče', code = '10-50', priority = 'medium', job = 'police', blip = { sprite = 380, color = 5 }, }, fire = { title = 'Prijavljen požar', description = 'Prijave požara na območju', code = '10-70', priority = 'medium', job = 'ambulance', blip = { sprite = 436, color = 1 }, }, vehiclefire = { title = 'Gorenje vozila', description = 'Prijave gorečega vozila', code = '10-70', priority = 'medium', job = 'police', blip = { sprite = 436, color = 1 }, }, copcarstolen = { title = 'Ukradeno interventno vozilo', description = 'Prijave kraje interventnega vozila', code = '10-99', priority = 'high', job = 'police', blip = { sprite = 595, color = 1 }, }, armed = { title = 'Oborožena oseba', description = 'Prijave oborožene osebe na območju', code = '10-11', priority = 'medium', job = 'police', blip = { sprite = 110, color = 1 }, }, }, }, } --- ### POLICE ### --- Config.Callsigns = { Auto = true, -- Should a callsign be automatically generated? Pattern = "11-1111",-- Pattern format (1: 0-9, A: A-Z, a: a-z) Strict = true, -- Enforce pattern format? ReadOnly = false -- Prevent users from editing callsigns? } --- ### JAIL SYSTEM ### --- --[[ Jail Script Options: - auto - p_policejob - wasabi_police_v2 - pickle_prisons - rcore_prison - xt-prison - esx-qalle-jail - qbx_prison - qb-prison - esx_jail ]] Config.JailScript = "rcore_prison" --- ### LICENSE SYSTEM ### --- --[[ License Script Options: - auto - esx_license - qbx_core - qb-core - bcs_licensemanager (when using auto, ensure it before gks-tablet in server.cfg) ]] Config.LicenseScript = "bcs_licensemanager" --- ### LICENSE TYPES (MDT) ### --- -- type: internal key (database); label: display name in MDT UI -- When using bcs_licensemanager, each type must exactly match a key in its config/licenses.lua. Config.Licenses = { { type = "driver_car", label = "Vozniško dovoljenje B" }, { type = "weapon", label = "Orožni list" }, { type = "identification", label = "Osebna izkaznica" }, { type = "driver_bike", label = "Vozniško dovoljenje A" }, { type = "driver_truck", label = "Vozniško dovoljenje C" }, -- Add your custom license types here: -- { type = "boat", label = "Boat License" }, -- { type = "taxi", label = "Taxi License" }, -- { type = "truck", label = "Truck License" }, } --- ### AUTOMATIC WEAPON REGISTRATION (MDT) ### --- --[[ Registers a weapon in the MDT firearm registry when a player buys it. Script Options: - auto - ox_inventory (buyItem hook) - qb (QBCore/QBX shop events, any inventory storing info.serie) - custom (export / event API only) - none Any shop can register a purchase itself: exports['gks-tablet']:RegisterWeaponPurchase(src, "WEAPON_PISTOL", serial) TriggerEvent('gkstablet:server:weapons:purchased', src, weapon, serial) ]] Config.WeaponRegistration = { Enabled = true, Script = "ox_inventory", -- Black market stock (ox_inventory: metadata = { registered = false }) RegisterIllegal = false, -- Shop name filters. IllegalShops wins; empty LegalShops allows all others. LegalShops = {}, IllegalShops = { "blackmarket", "black_market", "illegal", "darkweb" }, -- Never added to the firearm registry IgnoredWeapons = { "WEAPON_PETROLCAN", "WEAPON_HAZARDCAN", "WEAPON_FERTILIZERCAN", "WEAPON_FIREEXTINGUISHER", "WEAPON_KNIFE", "WEAPON_NIGHTSTICK", "WEAPON_HAMMER", "WEAPON_BAT", "WEAPON_GOLFCLUB", "WEAPON_CROWBAR", "WEAPON_BOTTLE", "WEAPON_DAGGER", "WEAPON_HATCHET", "WEAPON_MACHETE", "WEAPON_SWITCHBLADE", "WEAPON_BATTLEAXE", "WEAPON_POOLCUE", "WEAPON_WRENCH", "WEAPON_STONE_HATCHET", }, NotifyOwner = true, -- tablet notification with the registered serial -- Script = "qb" only QbShopEvents = { "qb-shops:server:purchaseItem", "qs-inventory:server:buyItem", "ps-inventory:server:buyItem", }, --[[ Bridge for any other shop script. A plain string expects the signature (source, weaponName, serial). CustomEvents = { "my_weaponshop:server:bought", { event = "other_shop:purchase", parse = function(data) return { source = data.src, weapon = data.item, serial = data.serial } end }, }, ]] CustomEvents = {}, } --- ### BILLING SYSTEM ### --- --[[ Billing Script Options: - auto - gksphone - esx_billing - direct -- Directly removes money from character (bank first, then cash) ]] Config.BillingScript = "bcs_companymanager" --- ### PHONE SYSTEM (MDT Phone tab) ### --- --[[ Phone Script Options: - auto (uses gksphone when started, otherwise none) - gksphone - none (MDT Phone tab disabled server-side) ]] Config.PhoneScript = "gksphone" Config.MDT = {} Config.MDT.Phone = { -- MDT Phone → Location tab (carrier trace / signal lock) Location = { CooldownSeconds = 300, CooldownOnFailedTrace = false, -- when false, cooldown only applies after a successful trace RadiusMinMeters = 75, -- approximate location radius (offline / not in call) RadiusMaxMeters = 200, RadiusInCallMinMeters = 50, -- tighter radius while target is in an active call RadiusInCallMaxMeters = 120, BlockIfSignalJammer = true, -- block when gksphone reports jammer / RF interference BlockIfAirplaneMode = true, -- block when device is in airplane mode RequireActiveCall = false, -- when true, target must be on an active call to acquire signal lock SignalLockSuccessRate = 50, -- 1-100 chance to acquire signal lock; 100 = always succeed when eligible }, MaxCallHistory = 50, MaxMessagesPerThread = 100, } --- ### MDT DUTY BLIPS (in-game map) ### --- -- On-duty police / EMS as GTA blips on the game map and minimap. -- Separate from the live unit markers inside the MDT map tab. Config.MDT.DutyBlips = { Enabled = true, ShowPolice = true, ShowAmbulance = true, CrossDepartment = false, -- police also see EMS blips and vice versa HideSelf = true, -- Pause-menu blip list grouping. Use ids no other resource uses. -- Same id for both departments lists them together. Category = 8, -- fallback when a department has no Category Scale = 0.9, ShortRange = true, -- minimap only when nearby ShowHeading = true, FriendIndicator = true, Label = "{name} - {callsign}", -- {name} {callsign} {status} {unit} Police = { Sprite = 1, Color = 38, Category = 8 }, -- 38 = blue Ambulance = { Sprite = 1, Color = 1, Category = 9 }, -- 1 = red -- Per vehicle type; falls back to the department sprite VehicleSprites = { car = 56, bike = 226, heli = 64, boat = 427, }, } --- ### MDT AUDIT LOG RETENTION ### --- -- gks_mdt_logs gets a row for every state-changing MDT/EMS action and was never -- pruned, so it grows for the lifetime of the server. Config.MDT.LogRetention = { Enabled = true, Days = 90, -- delete audit rows older than this; 0 or false disables BatchSize = 5000, -- rows deleted per pass, so a huge backlog never locks the table IntervalHours = 24, -- how often the cleanup runs } --- ### MAP LOCATIONS ### --- -- Seed locations for the Maps app (coords must be vector2) -- Fields: id (optional), name, description (optional), coords = vector2(x, y) Config.Locations = { { id = "pd", name = "PD", coords = vector2(424.9176, -990.3522), }, { id = "ems", name = "EMS", coords = vector2(-316.6257, -599.0009), }, { id = "hayes", name = "Hayes", coords = vector2(268.9636, -1827.5227), }, { id = "gun_club", name = "Gun Club", coords = vector2(16.7261, -1115.8896), }, { id = "ariba", name = "Ariba", coords = vector2(369.5256, -346.4583), }, { id = "arcade_bar", name = "Arcade Bar", coords = vector2(-1651.6277, -1082.7183), }, { id = "amir_kebab", name = "Amir kebab", coords = vector2(-1269.6393, -1208.7366), }, }