System sądowy i prawny FiveM: oskryptuj realistyczne procesy
Dodaj działający system sądowy do swojego serwera FiveM. Narzędzia sędziowskie, role prawników, interfejsy dowodów i najlepsze skrypty systemu prawnego do głębokiego roleplayu.
Agency Scripts
Założyciel i główny deweloper w Agency Scripts
Architektura systemu prawnego
System sądowy i prawny wynosi serwer roleplay FiveM ponad zwykłą zabawę w policjantów i złodziei, tworząc zorganizowane społeczeństwo, w którym prawo ma znaczenie, a konsekwencje wynikają z procedur prawnych. System obejmuje nakazy używane przez policję do autoryzacji przeszukań i aresztowań, proces rozpraw sądowych z prezentacją spraw przed sędzią, role obrońców i oskarżycieli dla prawników, system zarządzania dowodami śledzący dowody fizyczne i cyfrowe oraz zasady wymierzania kar takich jak grzywny, więzienie i kary alternatywne. Architektura opiera się na bazie danych spraw, która rejestruje każde postępowanie od postawienia zarzutów, przez postawienie w stan oskarżenia, proces, aż po wyrok. Każda sprawa jest powiązana ze stronami, ich rolami, przedstawionymi dowodami i ostatecznym wynikiem. Dane te są trwale zapisywane, budując historię prawną serwera, do której gracze i urzędnicy mogą odwoływać się w przyszłych postępowaniach.
Schemat bazy danych dla kartotek prawnych
Twoja baza danych musi obsługiwać nakazy, sprawy sądowe, dowody i akta prawne. Schemat łączy śledztwa policyjne z postępowaniami sądowymi poprzez wspólny system dowodów, w którym przedmioty zebrane podczas dochodzenia stają się materiałem dowodowym na rozprawie. Zaprojektuj tabele tak, aby zachować pełną ścieżkę audytu każdego działania podjętego w postępowaniu prawnym:
CREATE TABLE IF NOT EXISTS warrants (
id INT AUTO_INCREMENT PRIMARY KEY,
type ENUM('arrest', 'search', 'bench') NOT NULL,
target_citizenid VARCHAR(50) NOT NULL,
target_name VARCHAR(100) NOT NULL,
reason TEXT NOT NULL,
issued_by VARCHAR(50) NOT NULL,
approved_by VARCHAR(50) DEFAULT NULL,
status ENUM('pending', 'active', 'executed', 'expired', 'revoked') DEFAULT 'pending',
issued_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP NULL,
executed_at TIMESTAMP NULL,
INDEX idx_target (target_citizenid),
INDEX idx_status (status)
);
CREATE TABLE IF NOT EXISTS court_cases (
id INT AUTO_INCREMENT PRIMARY KEY,
case_number VARCHAR(20) UNIQUE NOT NULL,
defendant_citizenid VARCHAR(50) NOT NULL,
defendant_name VARCHAR(100) NOT NULL,
prosecutor_citizenid VARCHAR(50) DEFAULT NULL,
defense_citizenid VARCHAR(50) DEFAULT NULL,
judge_citizenid VARCHAR(50) DEFAULT NULL,
charges TEXT NOT NULL,
status ENUM('filed', 'arraignment', 'pretrial', 'trial', 'verdict', 'closed', 'dismissed') DEFAULT 'filed',
plea ENUM('not_guilty', 'guilty', 'no_contest') DEFAULT NULL,
verdict ENUM('guilty', 'not_guilty', 'mistrial', 'dismissed') DEFAULT NULL,
sentence TEXT DEFAULT NULL,
fine_amount INT DEFAULT 0,
jail_minutes INT DEFAULT 0,
filed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
hearing_scheduled TIMESTAMP NULL,
closed_at TIMESTAMP NULL,
INDEX idx_defendant (defendant_citizenid),
INDEX idx_status (status)
);
CREATE TABLE IF NOT EXISTS evidence (
id INT AUTO_INCREMENT PRIMARY KEY,
case_id INT DEFAULT NULL,
type ENUM('physical', 'digital', 'testimony', 'document', 'photo') NOT NULL,
label VARCHAR(200) NOT NULL,
description TEXT DEFAULT NULL,
collected_by VARCHAR(50) NOT NULL,
collected_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
chain_of_custody TEXT DEFAULT NULL,
is_admitted BOOLEAN DEFAULT FALSE,
FOREIGN KEY (case_id) REFERENCES court_cases(id)
);
CREATE TABLE IF NOT EXISTS legal_records (
id INT AUTO_INCREMENT PRIMARY KEY,
citizenid VARCHAR(50) NOT NULL,
record_type ENUM('conviction', 'acquittal', 'fine', 'warning', 'restraining_order') NOT NULL,
description TEXT NOT NULL,
case_id INT DEFAULT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expunged BOOLEAN DEFAULT FALSE,
INDEX idx_citizen (citizenid),
FOREIGN KEY (case_id) REFERENCES court_cases(id)
);
System nakazów
Nakazy są prawnym pomostem między śledztwem policyjnym a działaniem. Nakaz aresztowania upoważnia funkcjonariuszy do zatrzymania konkretnej osoby, nakaz przeszukania pozwala na przeszukanie posiadłości lub pojazdu, a nakaz doprowadzenia jest wydawany przez sędziego, gdy ktoś nie stawi się w sądzie. Funkcjonariusze policji tworzą wnioski o nakaz przez MDT, które trafiają do kolejki oczekujących na weryfikację sądową. Sędzia lub upoważniony urzędnik sprawdza wniosek, analizuje opis uzasadnionego podejrzenia i zatwierdza go lub odrzuca. Zatwierdzone nakazy stają się aktywne i pojawiają się w policyjnym MDT, gdy funkcjonariusze wchodzą w interakcję z daną osobą, informując ich o istnieniu nakazu. Zaimplementuj wygasanie nakazów, aby nie trwały wiecznie, z nakazami aresztowania trwającymi 7 rzeczywistych dni i nakazami przeszukania trwającymi 48 godzin od zatwierdzenia:
-- Warrant request by police
RegisterNetEvent('legal:server:requestWarrant', function(data)
local src = source
local Officer = QBCore.Functions.GetPlayer(src)
if not Officer or Officer.PlayerData.job.name ~= 'police' then return end
local warrant = {
type = data.type,
target_citizenid = data.targetCitizenid,
target_name = data.targetName,
reason = data.reason,
issued_by = Officer.PlayerData.citizenid,
}
local id = MySQL.insert.await(
'INSERT INTO warrants (type, target_citizenid, target_name, reason, issued_by) VALUES (?, ?, ?, ?, ?)',
{ warrant.type, warrant.target_citizenid, warrant.target_name, warrant.reason, warrant.issued_by }
)
-- Notify judges
local players = QBCore.Functions.GetQBPlayers()
for _, player in pairs(players) do
if player.PlayerData.job.name == 'judge' then
TriggerClientEvent('legal:client:warrantPending', player.PlayerData.source, {
id = id,
type = warrant.type,
targetName = warrant.target_name,
reason = warrant.reason,
officerName = Officer.PlayerData.charinfo.firstname .. ' ' .. Officer.PlayerData.charinfo.lastname,
})
end
end
TriggerClientEvent('QBCore:Notify', src, 'Warrant request submitted for judicial review', 'success')
end)
-- Judge approval
RegisterNetEvent('legal:server:approveWarrant', function(warrantId)
local src = source
local Judge = QBCore.Functions.GetPlayer(src)
if not Judge or Judge.PlayerData.job.name ~= 'judge' then return end
local warrant = MySQL.single.await('SELECT * FROM warrants WHERE id = ? AND status = "pending"', { warrantId })
if not warrant then return end
local expiryHours = warrant.type == 'search' and 48 or 168
local expiresAt = os.date('!%Y-%m-%d %H:%M:%S', os.time() + (expiryHours * 3600))
MySQL.update('UPDATE warrants SET status = "active", approved_by = ?, expires_at = ? WHERE id = ?',
{ Judge.PlayerData.citizenid, expiresAt, warrantId })
-- Notify requesting officer if online
TriggerClientEvent('QBCore:Notify', src, 'Warrant #' .. warrantId .. ' approved', 'success')
end)
Przebieg rozprawy sądowej
Rozprawy sądowe opierają się na ustrukturyzowanym procesie, który prowadzi sprawę przez postawienie w stan oskarżenia, wnioski przedprocesowe, proces i wydanie wyroku. Gdy sprawa zostaje wniesiona, system generuje unikalny numer sprawy i przypisuje jej status filed. Sędzia przegląda sprawę i wyznacza termin posiedzenia wstępnego, na którym oskarżony składa oświadczenie o winie. Jeśli oskarżony nie przyznaje się do winy, sprawa przechodzi do etapu przedprocesowego, w którym prawnicy mogą składać wnioski i dowody, a następnie do procesu, gdzie obie strony przedstawiają swoje argumenty. Sędzia kontroluje przebieg rozprawy za pomocą komend, które zmieniają status sprawy i wywołują aktualizacje UI u wszystkich uczestników. Zaimplementuj NUI sali sądowej, które wyświetla informacje o sprawie, bieżącą fazę oraz udostępnia kontrolki specyficzne dla ról sędziego, prokuratora i obrońcy. Sędzia otrzymuje przyciski werdyktu oraz pola wymiaru kary, podczas gdy prawnicy otrzymują przyciski sprzeciwu i opcje prezentacji dowodów.
Rola prawnika i system obrony
Praca prawnika tworzy na serwerze całą ścieżkę kariery z odrębnymi mechanikami rozgrywki. Obrońcy mogą być zatrudniani przez oskarżonych za pośrednictwem katalogu prawników dostępnego z aresztu lub aplikacji w telefonie. Kiedy prawnik przyjmuje klienta, uzyskuje dostęp do akt sprawy w systemie prawnym, w tym do wszystkich dowodów przedstawionych przez prokuraturę. Prawnicy mogą składać wnioski o odrzucenie dowodów, wnioskować o odroczenie rozpraw, negocjować ugody z prokuratorem oraz przedstawiać własne dowody i zeznania świadków podczas procesu. Wdróż system egzaminu adwokackiego, w którym nowe postacie prawników muszą zdać test wiedzy przed otrzymaniem pracy prawnika, co zapewni minimalny poziom jakości roleplayu prawniczego. Śledź statystyki prawników, takie jak wygrane i przegrane sprawy oraz średnie skrócenie wyroku dla ich klientów, tworząc konkurencyjny rynek, na którym doświadczeni prawnicy mogą pobierać wyższe opłaty:
Config.LawyerSystem = {
barExamQuestions = 15,
passingScore = 11, -- 73% to pass
examCooldown = 86400, -- 24 hours between attempts
maxActiveClients = 5,
consultationFee = 500, -- base fee for initial consultation
trialFeeRange = { min = 2000, max = 25000 },
motionTypes = {
{ id = 'suppress_evidence', label = 'Motion to Suppress Evidence', description = 'Request exclusion of illegally obtained evidence' },
{ id = 'dismiss_charges', label = 'Motion to Dismiss', description = 'Request dismissal due to insufficient evidence' },
{ id = 'continuance', label = 'Motion for Continuance', description = 'Request to postpone the hearing' },
{ id = 'change_venue', label = 'Motion for Change of Venue', description = 'Request trial at different location' },
{ id = 'bail_reduction', label = 'Motion for Bail Reduction', description = 'Request lower bail amount' },
{ id = 'expungement', label = 'Motion for Expungement', description = 'Request to clear prior conviction' },
},
}
-- Hire a lawyer from jail
RegisterNetEvent('legal:server:hireLawyer', function(lawyerCitizenid)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local citizenid = Player.PlayerData.citizenid
-- Find active case for this player
local activeCase = MySQL.single.await(
'SELECT * FROM court_cases WHERE defendant_citizenid = ? AND status NOT IN ("closed", "dismissed") ORDER BY filed_at DESC LIMIT 1',
{ citizenid }
)
if not activeCase then
TriggerClientEvent('QBCore:Notify', src, 'No active case found', 'error')
return
end
-- Assign lawyer to case
MySQL.update('UPDATE court_cases SET defense_citizenid = ? WHERE id = ?',
{ lawyerCitizenid, activeCase.id })
-- Notify lawyer
local lawyerPlayer = QBCore.Functions.GetPlayerByCitizenId(lawyerCitizenid)
if lawyerPlayer then
TriggerClientEvent('QBCore:Notify', lawyerPlayer.PlayerData.source,
'New client: ' .. Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname ..
' | Case #' .. activeCase.case_number, 'success')
end
TriggerClientEvent('QBCore:Notify', src, 'Attorney assigned to your case', 'success')
end)
System zarządzania dowodami
System dowodów zapewnia łańcuch dowodowy łączący śledztwo na miejscu zbrodni z prezentacją na sali sądowej. Gdy policja zbiera dowody na miejscu zdarzenia za pomocą komendy zbierania dowodów, system tworzy wpis dowodowy z danymi funkcjonariusza, znacznikiem czasu i lokalizacją. Każdy dowód otrzymuje unikalny identyfikator, który zachowuje ważność przez cały proces prawny. Rodzaje dowodów obejmują przedmioty fizyczne, takie jak broń, narkotyki i odzież, dowody cyfrowe, takie jak bilingi telefoniczne i nagrania z monitoringu, zeznania świadków zapisane w formie tekstu oraz dokumenty, takie jak wyciągi finansowe czy podrobione dokumenty tożsamości. Prawnicy mogą podważać dopuszczalność dowodów poprzez wnioski kwestionujące sposób ich zebrania lub łańcuch dowodowy. Sędzia rozpatruje te wnioski i może uznać dowód za niedopuszczalny, usuwając go z akt sprawy. Wprowadź szafkę na dowody na komisariacie policji, w której przechowywane są dowody rzeczowe, korzystając z integracji z systemem ekwipunku do śledzenia faktycznych przedmiotów zabezpieczonych podczas śledztwa.
Mechanika mandatów i kaucji
Mandaty i kaucje niosą za sobą konsekwencje finansowe w systemie prawnym. Gdy oskarżony staje przed sądem, sędzia ustala kwotę kaucji na podstawie wagi zarzutów i historii kryminalnej oskarżonego. Oskarżony może wpłacić kaucję za pośrednictwem systemu sądowego, aby wyjść z aresztu w oczekiwaniu na proces, lub pozostać w areszcie do rozprawy. Płatność kaucji jest potrącana z konta bankowego gracza i zwracana po zakończeniu sprawy, jeśli oskarżony stawił się na wszystkich rozprawach. Jeśli oskarżony się nie stawi, kaucja przepada i wydawany jest nakaz aresztowania. Grzywny są nakładane w ramach wyroku i muszą zostać zapłacone w wyznaczonym terminie. Niezapłacone grzywny generują odsetki i mogą wywołać dodatkowe konsekwencje prawne, takie jak zawieszenie prawa jazdy lub zajęcie mienia. Wdróż system ratalnej spłaty wysokich grzywien, w którym oskarżony może płacić tygodniowe raty zamiast całej kwoty naraz, co tworzy stałe zobowiązanie finansowe i sprawia, że system prawny pozostaje istotną częścią codziennej rozgrywki na serwerze.
Komendy sędziego i wydawanie wyroków
Sędziowie potrzebują kompleksowego zestawu komend do prowadzenia postępowań sądowych i egzekwowania prawa. Podstawowe komendy obejmują /case aby przeglądać sprawy i nimi zarządzać, /warrant do zatwierdzania lub odrzucania wniosków o nakaz, /sentence aby nakładać wyroki więzienia i grzywny, /bail do ustalania kwot kaucji, /gag aby wyciszać przeszkadzających graczy podczas rozpraw oraz /contempt aby więzić graczy okazujących brak szacunku dla sądu. Komenda orzekania wyroku powinna odwoływać się do konfiguracji kodeksu karnego, która określa minimalne i maksymalne kary za każdy czyn, co zapewnia spójność między różnymi sędziami. Wdróż system wytycznych wymiaru kary, który sugeruje odpowiednie kary na podstawie zarzutów i kartoteki oskarżonego, jednocześnie dając sędziom swobodę odstępstwa w uzasadnionych przypadkach. Zapisuj wszystkie decyzje sądu w tabeli kartotek prawnych, aby serwer budował bazę precedensów, do której doświadczeni gracze mogą się odwoływać w przyszłych rozprawach. Dodaj procedurę rewizji sądowej, umożliwiającą odwołanie się od wyroku do sędziego wyższej rangi lub składu sędziowskiego, co stworzy dodatkowe poziomy roleplayu prawniczego dla zaangażowanych graczy.
Integracja z policją, więzieniem i MDT
System prawny musi bezproblemowo integrować się z istniejącymi resources policji, więzienia i MDT, tworząc spójny system wymiaru sprawiedliwości. Kiedy policja wnosi zarzuty za pośrednictwem MDT, system powinien automatycznie utworzyć sprawę sądową z odpowiednim numerem sprawy i podpiąć wszelkie dowody zebrane już podczas śledztwa. Gdy sędzia skazuje oskarżonego na karę więzienia, system powinien bezpośrednio wywołać funkcję exportu uwięzienia z resource więzienia, aby wyrok został wykonany automatycznie, bez konieczności ręcznego wpisywania komendy więzienia przez policjanta. Aktywne nakazy aresztowania powinny pojawiać się w MDT policji podczas wyszukiwania obywatela, z wyraźnymi wskaźnikami pokazującymi typ nakazu, organ wydający i datę ważności. Kartoteka kryminalna generowana na podstawie wyroków sądowych powinna być dostępna w MDT w profilu obywatela, pokazując jego pełną historię prawną, w tym wyroki skazujące, uniewinnienia, aktywne sprawy i zaległe grzywny. Wyeksportuj wszystkie funkcje systemu prawnego, aby inne resources mogły programowo sprawdzać status nakazów, weryfikować uprawnienia prawników, przeglądać kartotekę i wchodzić w interakcję z systemem sądowym.