Skip to content

feat: major overhaul with new features and performance updates V2#557

Open
LeSiiN wants to merge 263 commits into
Project-Sloth:mainfrom
LeSiiN:full-changes
Open

feat: major overhaul with new features and performance updates V2#557
LeSiiN wants to merge 263 commits into
Project-Sloth:mainfrom
LeSiiN:full-changes

Conversation

@LeSiiN

@LeSiiN LeSiiN commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

🚓 ps-mdt — Full Changes

Major feature update built on top of the original Project-Sloth/ps-mdt. This PR adds several brand-new systems (Court calendar, in-MDT radio, housing integration, dashcam, patrol zones, EMS multi-domain support, officer status) and substantially reworks existing areas (CCTV, tracking, dashboard analytics, citizen/vehicle/weapon records, bulletin board).


✨ Highlights at a Glance

Area What's new?
🗓️ Court / DOJ Calendar Full hearing & event system with reminders
🎙️ Radio in the MDT Push-to-talk keeps working while the MDT is open
🚑 EMS Multi-Domain Separate EMS workspace (roster, calendar, map, tags)
🏠 Housing Integration A citizen's owned properties right in their profile
🟢 Officer Status Active/Busy availability, live on the map and per-patrol
📹 Dashcam Front/rear view with the unit's live position
📡 CCTV Rework Decoupled feed + CCTV overlay (live time, REC)
🗺️ Patrol Zones Polygon zones drawn on the map + live tracking
📊 Dashboard Analytics Live stats: units, BOLOs, reports, playtime
🏷️ Tag System Citizen tags with job types, descriptions & pills
📋 Bulletin Board Dynamic, per-job categories
🧾 Citizen Charges Combined, paginated charge history in the citizen profile

🆕 New Systems

🗓️ Court / DOJ Calendar

A complete calendar system for the justice department, integrated into the DOJ section.

  • Event types: arraignment, trial, sentencing, appeal, motion, hearing, plus trainings & meetings.
  • Separate permissions per category: court events via court_*, trainings/meetings/other via training_*.
  • Enforced status lifecycle (scheduled → in_session → completed, including "adjourned"/"cancelled"/reopen transitions).
  • Attendee management with roles (prosecutor, defense, officer, witness, judge, trainee, instructor, …) and predefined attendee groups (All Officers, Judges, Lawyers, All EMS, …).
  • Automatic reminder SMS via lb-phone (configurable lead time), optional invite e-mails and automatic status changes.
  • New tables mdt_court_hearings and mdt_court_attendees.

🎙️ Radio in the MDT (Push-to-Talk)

Players can talk on the radio even while the MDT is open and holding NUI focus.

  • Auto-detects the player's actual radio keybind and reuses it — configurable fallback key.
  • Supports pma-voice, SaltyChat and YACA (auto-detection or a forced choice).
  • Supports mouse buttons as the PTT key.
  • A watchdog cleanly stops transmission on focus loss.

🚑 EMS / Multi-Domain Support

The MDT is now domain-aware so it can serve both law enforcement and EMS from the same resource.

  • Jobs are grouped into two domains: police (police + DOJ share calendar/map data) and ems (its own separate workspace).
  • Roster, calendar attendee groups, map/patrol data and tags are all scoped to the caller's domain — EMS sees EMS, police sees police.
  • Domain-aware labelling (e.g. "Personnel" for EMS where police see "Officer").
  • Driven by Config.MedicalJobs / Config.MedicalJobType via the helpers IsEmsJob, GetDomainForJob, GetMdtDomain.

🏠 Housing / Property Integration

Shows a citizen's owned properties directly in their record.

  • Schema-agnostic and configurable: ready-made presets for qbx_properties, ps-housing, qb-houses, plus a custom mapping (incl. two-table joins).
  • Switching housing systems usually only requires a single line (Config.Housing.system).
  • "Set waypoint" button to ping a property.
  • Fully toggleable (Config.Housing.enabled = false).

🟢 Officer Status

Lets officers set their own availability (e.g. Active / Busy) directly from the Map tab, fully synced in real time across every open MDT.

  • Config-driven status list (Config.OfficerStatus.list) — colors, labels and icons; new statuses can be added without touching any other file.
  • Self-service status picker with an optional free-text note (e.g. "Traffic Stop"), shown next to the officer's name in the Map tab's officer list.
  • Live status filter chips to show only officers on a given status.
  • Map marker indicator: a small colored dot pinned to each officer's tracking marker, restyled instantly on change — no polling delay.
  • Patrol-level status, derived (not stored) from its members: a patrol with no members on duty shows no indicator at all; as soon as any member is on a non-default status (e.g. Busy), the whole patrol reflects it — and falls back automatically once everyone returns to the default. Shown in the officer sidebar, the Patrols panel and the patrol's map label.
  • Real-time broadcast to every officer in the same domain, independent of the regular tracking poll, plus a short server-side anti-spam cooldown.
  • New table mdt_officer_status.

🔧 Reworked Systems

📹 CCTV Cameras

  • Decoupled feed: prop placement (via gizmo) and the feed's view direction are separate — the camera can look in a different direction than the model faces (its own coords/rotation/FOV).
  • CCTV overlay HUD while viewing: real server time, blinking REC indicator, camera label.
  • Configurable heading offset for player-placed props (default 180°).
  • Deferred spawning: physical camera props are only spawned once a player is online.
  • DB: new columns feed_coords, feed_rotation, feed_fov in mdt_cameras.

📹 Dashcam (new within the camera system)

  • Front/rear toggle via keypress while viewing.
  • Per-vehicle-model configurable offsets for the camera position.
  • Callsign-based IDs and the unit's live position (including speed display in km/h).
  • Restricted to emergency vehicles (vehicle class 18).

🗺️ Patrol & Live Tracking

  • Polygon zones can be drawn directly on the Leaflet map, including GTA↔map coordinate conversion.
  • Patrol CRUD with ordering and zone storage (mdt_patrols).
  • Zone notifications: players are notified about patrol-zone events; toggleable per player in Settings (preference is persisted).
  • Audit logging of every patrol change.
  • Officer highlight on the map with live-updating popups.
  • Dedicated permissions: map_patrols_view / map_patrols_manage / map_patrols_edit.
  • Performance: shared tracking cache (TTL), vehicle cache with expiry, debounced DB saves, and coalesced broadcasts.
  • Tracking responses now also carry each officer's live Officer Status (see above), folded in from a lightweight in-memory snapshot — no extra DB hit on the polling path.

📊 Dashboard Analytics

The dashboard gained a real statistics layer, served by dedicated server callbacks.

  • Live metrics: active units, active BOLOs, recent dispatches.
  • Report statistics and usage metrics (total reports, arrests, active warrants, reports in the last 7 days, …).
  • Time statistics (playtime / duty-based stats).
  • Callsign feature with validation (PD- prefix) and display.
  • Global court reminders (toast + sound, even when the MDT is closed).
  • Bulletins surfaced directly on the dashboard.

🏷️ Tag System (Citizens & Personnel)

  • Full CRUD management for tags in the management area, with a type filter (all / report / officer / citizen).
  • Job types leo / ems / all plus tag type including citizen.
  • Tag descriptions shown via a hover tooltip.
  • Rendered as colored pills in the citizen profile and as a dedicated column in the citizen list.

📋 Bulletin Board

  • Dynamic per-job categories, stored as database rows (mdt_bulletin_categories).
  • Posts with priority (low/normal/high/urgent) and pinning (mdt_bulletin_posts).
  • Management UI with drag-to-reorder plus icon and color pickers.

👤 Citizen Record

  • Image gallery with a lightbox.
  • Editable notes.
  • Property section (see housing integration) with a direct jump to the property.
  • Fingerprint (read from player metadata) shown in the profile and searchable in the citizen list.
  • Charges section, listed directly after Linked Reports: every charge the citizen has ever received, grouped by charge type across all of their reports (e.g. 3x Grand Theft Auto instead of one line per report). Loaded on demand and paginated server-side — only the 20 most recent charge types are fetched initially, with a "Load 20 more" button to fetch further pages — so opening a heavily-charged citizen's profile never pulls their full history at once. Each line shows the report id, combined fine/time totals, and a charge-class badge (Felony/Misdemeanor/Infraction).

🚗 Vehicle Record

  • Editable notes per vehicle.
  • A vehicle image can be attached.
  • Status flag via the new mdt_vehicle_status column.

🔫 Weapon Record

  • Flag system (e.g. Stolen / Wanted) with template texts.
  • Weapon history and owner search.
  • DB: new flags (JSON) column in mdt_weapons.

🧾 Evidence (Records, Reports & Cases)

  • Image attachments on evidence items, with title field and a lightbox viewer.
  • Add images by URL — available both in the standalone Evidence page and inside the report/case editor.
  • Unified evidence handling for cases and reports.
  • New columns title, images on mdt_reports_evidence.

🎨 UI, Immersion & Hardening

  • Tablet prop & animation: opening the MDT attaches a tablet prop to the player's hand with a configurable idle animation (Config.Animation), cleanly removed on close.
  • Clip-safe tooltips: a reusable tip action renders hover tooltips into <body> (position: fixed) so they're never clipped by scrolling/overflow parents — works around CEF clipping limits. Also used for the new Officer Status dots/badges and the Charges section.
  • Gizmo placement hardening: while placing a prop, the player's movement/attack/melee controls are disabled so gizmo mode keys (W/S/R) don't make the player walk or shoot.
  • Frontend security: XSS/forbidden-character checks, code-injection pattern filtering, and a total localStorage size cap to guard the NUI.

🗄️ Database Changes

New tables:

  • mdt_court_hearings, mdt_court_attendees
  • mdt_patrols
  • mdt_bulletin_categories, mdt_bulletin_posts
  • mdt_officer_status

Extended tables (self-healing ALTER … IF NOT EXISTS migrations):

  • mdt_camerasfeed_coords, feed_rotation, feed_fov
  • mdt_weaponsflags (JSON)
  • mdt_vehiclesmdt_vehicle_status
  • mdt_reportslawyer_requested
  • mdt_reports_evidencetitle, images

SQL is provided for both QBCore (sql/qbcore.sql) and QBX (sql/qbx.sql).


⚙️ New Config Sections

  • Config.Court — reminder lead time, SMS sender, e-mail invites, auto-status, attendee groups (incl. EMS domain).
  • Config.Radio — voice system, PTT fallback key, per-system triggers.
  • Config.Housing — system preset (qbx/ps/qb/custom) + column mapping.
  • Config.Dashcam — update interval and per-model positions.
  • Config.Animation — tablet prop dict/name and attach offsets.
  • Config.OfficerStatus — selectable statuses (id/label/color), default status, note length cap, change cooldown.
  • Camera.HeadingOffset & Camera.Overlay — overlay/REC settings.
  • Fingerprint scan trigger toggle.

✅ Compatibility & Notes

  • Tested with QBCore / QBX (abstracted via the ps wrapper).
  • Dependencies: ox_lib, oxmysql, lb-phone (court reminders), a voice system (pma-voice / SaltyChat / YACA for the radio feature).
  • SQL migrations are self-healing and create missing tables/columns automatically on startup.
  • New features can be disabled individually via the config.

📌 Pre-Merge Checklist

  • SQL from sql/ imported (or self-healing startup awaited)
  • Config.Housing.system set to the housing resource in use
  • Config.Radio.VoiceSystem verified
  • Config.MedicalJobs / Config.MedicalJobType set for the EMS domain
  • Config.OfficerStatus.list reviewed (defaults: Active/Busy)
  • Permissions (court_*, training_*, map_patrols_*) granted in the permissions management

LeSiiN added 30 commits April 28, 2026 03:21
added RegisterNUICallback
added ps-mdt:server:saveWeaponFlags
Added `SAVE_WEAPON_FLAGS` to `NUI_EVENTS.WEAPON`
changes from files to link, added hover for picture to make it bigger
changes stuff in cases.lua (sry)
added title and images to mdt_reports_evidence database

ALTER TABLE mdt_reports_evidence
  ADD COLUMN title VARCHAR(255) NOT NULL DEFAULT '' AFTER reportid,
  ADD COLUMN images LONGTEXT NULL DEFAULT NULL AFTER stored;
added title and images to mdt_reports_evidence
added profile images as link not file and gallery, removed mugshot
profile images as links not files
gallery to add picture manually usage of mdt_citizen_gallery
remove mugshot button ( broken rn )
added new callbacks
removed log entry for profile pic
- fivemanage doesnt support links, only base64, so removed check for fivemanageupload
added title and images, fixed evidence in reports
added title and images, fixed evidence
added title and images, fixed evidence
added little icon in vehicles overview and added edit/zoom button
added this to UpdateVehicle:
 
   if payload.image ~= nil then
        updates[#updates + 1] = 'mdt_vehicle_image = ?'
        values[#values + 1] = payload.image
    end
changed picture to 108x108pxa and also added little icons per gun
added notes interactions
added check for ems
- not allow ems to edit this note
added callbacks and streetname grabber
added callbacks and changed some sql stuff to match qbx housing
added entire new property modul to showcase info
added new events
removed german debug
fixed not allowing callsign changes
changed from property_name to property_id
changed from property_name to property_id
changed from property_name to property_id
changed SELECT citizenid to owner
changed picture to 108x108pxa and also added little icons per gun
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant