Dans ce guide, vous apprendrez comment programmer un téléphone de centre de contrôle pour FiveM. Nous allons Langage de script LUA utiliser pour développer un système fonctionnel et efficace. Ce guide vous guidera à travers les différentes phases de mise en œuvre, notamment la préparation de l'environnement de développement, la création de l'interface utilisateur, la gestion des appels et l'optimisation de votre système.
Contenu
1. Introduction à FiveM et LUA
Qu’est-ce que FiveM ?
CinqM est une modification pour Grand Theft Auto V qui permet aux utilisateurs de serveurs multijoueurs dédiés pour héberger et créer des expériences multijoueurs personnalisées. FiveM permet aux développeurs de créer du contenu personnalisé qui va au-delà de ce qui est possible dans le jeu standard.
Compréhension de base de LUA
LUA est un langage de script léger et puissant, particulièrement adapté au développement de jeux. Dans la communauté FiveM, LUA est largement utilisé pour les scripts serveur et la modification client car il est flexible et facile à apprendre.
2. Préparation du projet
Mise en place de l'environnement de développement
Avant de commencer la programmation, nous devons préparer notre environnement de développement :
- Installez le serveur FiveM : Comment configurer un serveur FiveM – instructions
- Éditeur d'installation : Utilisez un éditeur de texte approprié – Notepad++ est recommandé
- Extension LUA (facultatif) : installez une extension LUA dans votre éditeur pour activer la coloration syntaxique et la saisie semi-automatique.
Ressources et outils nécessaires
- Serveur MySQL (facultatif) : Pour la persistance des données d'appel, nous pouvons utiliser MySQL.
- oxmysql ou ghmattimysql : Ces ressources sont nécessaires pour interagir avec la base de données MySQL.
Création d'un nouveau serveur FiveM
- Configurez un nouveau serveur FiveM en extrayant les fichiers du serveur dans leur propre dossier.
- Créez un nouveau dossier pour la ressource téléphonique de votre centre de contrôle dans le répertoire du serveur. Nommez ce dossier par exemple
dispatch_phone
. - Démarrez votre serveur pour vous assurer qu'il est correctement configuré.
3. Structure de base du script
Structure de répertoire pour une ressource FiveM
Une ressource FiveM typique se compose de divers scripts et ressources organisés dans une structure spécifique.
Nous devons utiliser la structure suivante pour notre téléphone de centre de contrôle :
/ressources
/[locale]
/dispatch_phone
/html
index.html
style.css
script.js
__resource.lua
client.lua
serveur.lua
Créer à partir de __resource.lua
Le dossier __resource.lua
est le cœur d’une ressource FiveM. Il définit les métadonnées de la ressource et détermine quels fichiers doivent être utilisés.
ressource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
ui_page 'html/index.html'
fichiers {
'html/index.html',
'html/style.css',
'html/script.js'
}
client_script 'client.lua'
script_serveur 'serveur.lua'
Bases de la gestion des événements dans FiveM
FiveM utilise un système de gestion d'événements qui permet aux scripts de communiquer entre eux. Fonctionnalités LUA telles que S'inscrireNetEvent
et Événement déclencheur
sont utilisés pour enregistrer et déclencher des événements.
4. Création du téléphone du centre de contrôle
4.1 Définition des exigences
Avant de commencer le codage, nous devons définir les exigences de base pour le téléphone du centre de contrôle :
- Interface utilisateur (UI) : Une interface simple et intuitive permettant aux répartiteurs de gérer les appels.
- Gestion des appels : Prise en charge des appels entrants et sortants avec stockage de l'identification de l'appelant, de l'heure de l'appel et du motif de l'appel.
- Communication: Communication fiable entre le client et le serveur.
- Gestion des données : Stockage et récupération des informations d'appel.
- Gestion des erreurs : Mécanismes pour gérer les erreurs inattendues ou les problèmes de communication.
4.2 Implémentation de l'interface utilisateur (UI)
1. Création de la base NUI
Nous commençons par créer une nouvelle ressource dans le dossier du serveur FiveM et la nommons dispatch_phone
. Dans ce dossier, nous créons un répertoire appelé HTML
, où nous plaçons nos fichiers d'interface utilisateur.
2. Structure HTML (index.html)
Créer un fichier index.html
dans le dossier /html
et ajoutez la structure suivante :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <title>Téléphone du centre de contrôle</title> </head> <body> <div id="phone"> <div id="header">Téléphone du centre de contrôle</div> <div id="call-list"> <!-- Anrufliste hier --> </div> <div id="controls"> <button id="accept">Supposer</button> <button id="end">Finition</button> </div> </div> <script src="script.js"></script> </body> </html>
3. Conception CSS (style.css)
Créer un fichier style.css
pour concevoir l'interface utilisateur :
corps { marge : 0 ; remplissage : 0 ; affichage : flexible ; justifier-contenu : centre ; align-items : centre ; hauteur : 100vh ; couleur d'arrière-plan : #f0f0f0 ; } #phone { largeur : 300 px ; bordure : 1px solide #333 ; couleur d'arrière-plan : #fff ; box-shadow : 0 0 10px rgba(0,0,0,0.5); rayon de bordure : 8 px ; débordement : caché ; } #header { couleur d'arrière-plan : #333 ; couleur : #fff ; alignement du texte : centre ; remplissage : 10 px ; taille de police : 18 px ; } #call-list { remplissage : 10 px ; hauteur : 300px ; débordement-y : auto ; couleur d'arrière-plan : #eee ; } #controls { display: flex; justifier-contenu : espace autour ; remplissage : 10 px ; } bouton { remplissage : 10 px ; bordure : aucune ; couleur d'arrière-plan : #28a745 ; couleur : blanc ; rayon de bordure : 5 px ; curseur : pointeur ; } bouton#end { couleur d'arrière-plan : #dc3545 ; }
4. Logique JavaScript (script.js)
Créer un fichier script.js
et implémentez la logique pour gérer les événements de l'interface utilisateur :
document.getElementById('accept').addEventListener('click', function() { fetch('https://dispatch_phone/acceptCall', { méthode : 'POST', en-têtes : { 'Content-Type' : 'application/ json' }, corps : JSON.stringify({}) }); document.getElementById('end').addEventListener('click', function() { fetch('https://dispatch_phone/endCall', { méthode : 'POST', en-têtes : { 'Content-Type' : 'application/ json' }, corps : JSON.stringify({}) }); window.addEventListener('message', function(event) { if (event.data.type === 'updateCallList') { updateCallList(event.data.calls); } }); function updateCallList(calls) { const callListDiv = document.getElementById('call-list'); callListDiv.innerHTML = ''; // Ancienne liste vide appels.forEach(call => { const callDiv = document.createElement('div'); callDiv.textContent = `Appelant : ${call.caller}, Raison : ${call.reason}`; callListDiv .appendChild(appelDiv); }
4.3 Script de gestion des appels
4.3.1 Script client (client.lua)
Le script client reçoit les messages NUI et traite les entrées de l'utilisateur.
local isPhoneOpen = false appels locaux = {} -- Ouvre le téléphone RegisterCommand('openphone', function() SetNuiFocus(true, true) SendNUIMessage({type = 'showPhone'}) isPhoneOpen = true end, false) -- Ferme cela Registre téléphoniqueNUICallback('closePhone', function(data, cb) SetNuiFocus(false, false) isPhoneOpen = false cb('ok') end) -- Accepte un appel RegisterNUICallback('acceptCall', function(data, cb) TriggerServerEvent('dispatch:acceptCall') cb('ok') end) -- Termine un appel RegisterNUICallback(' endCall ', function(data, cb) TriggerServerEvent('dispatch:endCall') cb('ok') end) -- Met à jour la liste d'appels RegisterNetEvent('dispatch:updateCallList') AddEventHandler('dispatch:updateCallList', function(callData) appels = callData SendNUIMessage({ type = 'updateCallList', appels = appels }) fin)
4.3.2 Script serveur (server.lua)
Le script serveur gère la logique de gestion des appels et stocke les données des appels.
appels locaux = {} -- Un nouvel appel est reçu RegisterCommand('newcall', function(source, args, rawCommand) local caller = source local Reason = table.concat(args, " ") local call = { caller = caller, Reason = Reason, time = os.time() } table.insert(calls, call) -- Informe tous les employés du centre de contrôle du nouvel appel TriggerClientEvent('dispatch:updateCallList', -1, appels) fin, faux) -- Accepter l'appel RegisterServerEvent('dispatch:acceptCall') AddEventHandler('dispatch:acceptCall', function() local src = source print("Appel accepté par : "..src) -- Logique pour gérer la fin de l'appel accepté) -- Fin de l'appel RegisterServerEvent('dispatch:endCall') AddEventHandler('dispatch:endCall', function() local src = source print("Appel terminé from: "..src) -- Logique pour gérer la fin de l'appel terminé)
4.4 Communication entre client et serveur
La communication entre client et serveur repose sur un système d'événements spécialement développé pour être utilisé dans le contexte d'un serveur multi-joueurs.
4.4.1 Communication client-serveur
Dans le script client que nous utilisons TriggerServerEvent
pour envoyer des événements au serveur.
-- Accepter l'appel RegisterNUICallback('acceptCall', function(data, cb) TriggerServerEvent('dispatch:acceptCall') cb('ok') end) -- Terminer l'appel RegisterNUICallback('endCall', function(data, cb) TriggerServerEvent( 'dispatch:endCall') cb('ok') fin)
4.4.2 Communication serveur-client
Le serveur envoie des événements aux clients pour les informer des modifications.
-- Informe tous les employés du centre de contrôle du nouvel appel TriggerClientEvent('dispatch:updateCallList', -1, appels)
4.5 Gestion des appels entrants et sortants
1. Créez un appel
Un appel est effectué par une commande /nouvel appel
lancé et l’appel est ajouté à la liste d’appels.
RegisterCommand('newcall', function(source, args, rawCommand) local caller = source local Reason = table.concat(args, " ") local callTime = os.time() local call = { caller = caller, Reason = Reason, time = callTime } table.insert(appels, appel) TriggerClientEvent('dispatch:updateCallList', -1, appels) fin, faux)
2. Accepter l'appel
Lorsqu'un répartiteur répond à un appel, l'appel est supprimé de la file d'attente.
RegisterServerEvent('dispatch:acceptCall') AddEventHandler('dispatch:acceptCall', function() local src = source print("Appel accepté par : "..src) -- Fin de la logique de gestion des appels acceptés)
3. Terminer l'appel
Un événement similaire est déclenché à la fin d'un appel.
RegisterServerEvent('dispatch:endCall') AddEventHandler('dispatch:endCall', function() local src = source print("Appel terminé par : "..src) -- Logique pour gérer la fin de l'appel terminé)
5. Gestion des données
Pour un stockage et une récupération efficaces des données d'appel, nous utilisons une base de données telle que MySQL ou SQLite.
5.1 Configuration de la base de données
- Choix de la base de données :
- Utilisez SQLite pour des déploiements et des tests simples.
- Utilisez MySQL pour des applications évolutives.
- Connexion à la base de données :Exemple d'utilisation
oxmysql
:MySQL.ready(function() print("Connexion à la base de données établie.") fin)
5.2 Stockage des données d'appel
Enregistrer les appels dans la base de données :
RegisterCommand('newcall', function(source, args, rawCommand) local caller = source local Reason = table.concat(args, " ") local callTime = os.time() local call = { caller = caller, Reason = Reason, time = callTime } table.insert(calls, call) -- Enregistre l'appel dans la base de données MySQL.Async.execute('INSERT INTO appels (appelant, raison, time) VALEURS (@caller, @reason, @time)', { ['@caller'] = appelant, ['@reason'] = raison, ['@time'] = callTime }, function(rowsChanged) print( "L'appel a été enregistré dans la base de données.") fin) TriggerClientEvent('dispatch:updateCallList', -1, appels) fin, faux)
5.3 Récupération des données d'appel
Récupérer les données d'appel au démarrage du serveur :
AddEventHandler('onResourceStart', function(resourceName) if resourceName == GetCurrentResourceName() then MySQL.Async.fetchAll('SELECT * FROM lists', {}, function(result) for _, call in ipairs(result) do table. insert(appels, appel) end print("Les données d'appel ont été chargées depuis la base de données.") end) end end)
6. Corrections de bugs et optimisation
6.1 Outils et techniques de débogage
- Utiliser
imprimer()
à des fins de débogage simples. - Journalisation avancée : Écrivez des journaux détaillés dans des fichiers.
- Gestion des erreurs : Utilisez PCall dans LUA pour détecter les erreurs.
6.2 Optimisation du script
- Requêtes de base de données efficaces : Optimisez les requêtes et utilisez les index.
- Réduisez le nombre d’événements : Regroupez les données pour les envoyer efficacement.
- Minimisez l’utilisation du réseau : Envoyez des données agrégées pour réduire la charge du réseau.
On continue avec une extension :
7. Extensions et ajustements
Une fois que vous avez implémenté les fonctionnalités de base de votre téléphone de centre de contrôle pour FiveM, il existe différentes manières d'étendre et de personnaliser le système. Ces extensions améliorent l’expérience utilisateur et offrent des fonctions supplémentaires qui peuvent être utiles dans la vie quotidienne d’un centre de contrôle. Dans cette section, nous aborderons en détail certaines extensions et personnalisations avancées.
7.1 Ajout de fonctionnalités telles que les enregistrements
Une fonctionnalité précieuse d’un système téléphonique de centre de contrôle est la possibilité d’enregistrer les appels et de les lire plus tard. Ceci est particulièrement utile à des fins de formation, de préservation des preuves ou d’assurance qualité. La fonction d'enregistrement pourrait également inclure la prise de notes importantes lors d'un appel.
Mise en place d'une fonction d'enregistrement
- Ajustez la structure de la base de données :
Développez votre base de données d'appels pour stocker les enregistrements. Vous pouvez ajouter une colonne supplémentaire dans leappels
-Ajouter un tableau pour sauvegarder les données d'enregistrement ou les notes.
ALTER TABLE appelle ADD COLUMN enregistrant TEXT ;
- Démarrer et arrêter l'enregistrement :
Dans le script client et serveur, vous implémentez des mécanismes pour démarrer et arrêter un enregistrement lors d'un appel. Personnalisations du script client (client.lua
):
-- Commencer l'enregistrement RegisterNUICallback('startRecording', function(data, cb) TriggerServerEvent('dispatch:startRecording', data.callId) cb('ok') end) -- Arrêter l'enregistrement RegisterNUICallback('stopRecording', function(data, cb) TriggerServerEvent('dispatch:stopRecording', data.callId) cb('ok') fin)
Ajustements du script du serveur (serveur.lua
):
-- Commence l'enregistrement d'un appel RegisterServerEvent('dispatch:startRecording') AddEventHandler('dispatch:startRecording', function(callId) local src = source -- Logique d'enregistrement print("Enregistrement démarré pour l'ID d'appel : "..callId) - - Mettre à jour la base de données des appels pour marquer l'enregistrement MySQL.Async.execute('UPDATE Calls SET Recording = @recording WHERE id = @id', { ['@recording'] = 'Enregistrement démarré...', ['@id'] = callId }) end) -- Arrête l'enregistrement d'un appel RegisterServerEvent('dispatch:stopRecording') AddEventHandler(' dispatch :stopRecording', function(callId) local src = source -- Logique pour arrêter l'enregistrement print("Enregistrement arrêté pour l'ID d'appel : "..callId) -- Sauvegarder l'enregistrement dans la base de données MySQL.Async.execute('UPDATE appelle SET Recording = @recording WHERE id = @id', { ['@recording'] = 'Enregistrement terminé...', ['@id'] = callId }) end)
- Afficher et lire des enregistrements :
Vous pouvez ajouter une fonctionnalité qui permet aux utilisateurs de visualiser et de lire les enregistrements des appels précédents. Cette fonctionnalité peut être intégrée à l'interface utilisateur. Ajustements de l'interface utilisateur : Dans leindex.html
:
Dans le script.js
:
document.getElementById('playRecording').addEventListener('click', function() { fetch('https://dispatch_phone/playRecording', { méthode : 'POST', en-têtes : { 'Content-Type' : 'application/ json' }, body : JSON.stringify({ callId: selectedCallId }) // `selectedCallId` est l'ID de l'appel en cours de lecture devrait être }); });
7.2 Intégration du GPS et des données de localisation
L'intégration des données de localisation GPS peut améliorer considérablement l'efficacité d'un centre de contrôle. Il permet au personnel du centre de contrôle de déterminer l'emplacement exact des appelants et de répondre plus rapidement. Nous pouvons collecter les données GPS des joueurs et les intégrer dans l'historique des appels.
Implémentation de l'intégration GPS
- Collecte de données GPS :
Utilisez çaObtenirEntityCoords
-Commande de FiveM pour capturer les coordonnées GPS de l'appelant. Script client (client.lua
):
RegisterCommand('newcall', function(source, args, rawCommand) local caller = source local Reason = table.concat(args, " ") local playerPed = GetPlayerPed(-1) local coords = GetEntityCoords(playerPed) TriggerServerEvent('dispatch: newCall', appelant, raison, coordonnées) fin, faux)
- Script serveur pour gérer les données GPS : Développez la base de données d'appels pour stocker les données de localisation :
ALTER TABLE appelle ADD COLUMN gps_coords VARCHAR(255);
Ajustements du script du serveur (serveur.lua
):
RegisterServerEvent('dispatch:newCall') AddEventHandler('dispatch:newCall', function(appelant, raison, coordonnées) local callTime = os.time() local gpsCoords = coords.x .. ", " .. coords.y .. ", " .. coords.z MySQL.Async.execute('INSERT INTO appels (appelant, raison, heure, gps_coords) VALEURS (@caller, @reason, @time, @gps_coords)', { ['@caller'] = appelant, ['@reason'] = raison, ['@time'] = callTime, ['@gps_coords '] = gpsCoords }, function(rowsChanged) print("Nouvel appel avec coordonnées GPS enregistrées dans la base de données.") end) table.insert(calls, {appelant = appelant, raison = raison, heure = callTime, gps_coords = gpsCoords}) TriggerClientEvent('dispatch:updateCallList', -1, appels) fin)
- Affichage des données GPS dans l'interface utilisateur : Ajustements de l'interface utilisateur (script.js) :
function updateCallList(calls) { const callListDiv = document.getElementById('call-list'); callListDiv.innerHTML = ''; // Ancienne liste vide appels.forEach(call => { const callDiv = document.createElement('div'); callDiv.textContent = `Appelant : ${call.caller}, Raison : ${call.reason}, Emplacement : ${call.gps_coords}`; callListDiv.appendChild(callDiv }); }
- Affichage de l'emplacement sur la carte :
Incluez une fonctionnalité qui affiche l'emplacement d'un appelant sur la carte. Pour cela, utilisez la fonction native FiveMDéfinir un nouveau point de cheminement
. Personnalisations du script client (client.lua
):
RegisterNUICallback('showOnMap', function(data, cb) coordonnées locales = data.coords SetNewWaypoint(coords.x, coords.y) cb('ok') end)
7.3 Personnalisation de l'interface utilisateur
L'interface utilisateur joue un rôle important dans l'expérience utilisateur. Vous pouvez personnaliser l’interface utilisateur du téléphone du centre de contrôle pour améliorer l’efficacité et la convivialité.
Fonctionnalités avancées de filtrage et de tri
- Filtrage de la liste d'appels :
Ajoutez une option de filtre pour filtrer l'historique des appels en fonction de critères spécifiques tels que l'identification de l'appelant, le motif de l'appel ou l'emplacement. Extension de l'interface utilisateur (index.html) :
<div id="filters"> <label for="filterCaller">Filtrer par appelant :</label> <input type="text" id="filterCaller"> <button id="applyFilter">Appliquer</button> </div>
Extension JavaScript (script.js) :
document.getElementById('applyFilter').addEventListener('click', function() { const filterCaller = document.getElementById('filterCaller').value.toLowerCase(); const filteredCalls = appels.filter(appel => appel.caller .toLowerCase().includes(filterCaller)); updateCallList(filteredCalls });
- Tri de la liste d'appels :
Ajoutez une option de tri pour trier les appels par date, appelant ou urgence. Extension de l'interface utilisateur (index.html) :
<div id="sorting"> <label for="sortCalls">Trier par:</label> <select id="sortCalls"> <option value="time">Temps</option> <option value="caller">demandeur</option> </select> <button id="applySort">Trier</button> </div>
Extension JavaScript (script.js) :
document.getElementById('applySort').addEventListener('click', function() { const sortCriteria = document.getElementById('sortCalls').value; const sortedCalls = [...calls].sort((a, b) => { if (sortCriteria === 'time') { return new Date(a.time) - new Date(b.time); } else if (sortCriteria === 'caller') { return a.caller.localeCompare(b.caller); } }); updateCallList(sortedCalls); });
Personnalisation de la conception de l'interface utilisateur
- Thématisation : Implémentez différents thèmes pour le téléphone du centre de contrôle afin d'adapter le style visuel aux préférences de l'utilisateur ou à un design d'entreprise. Créez plusieurs fichiers CSS et laissez l'utilisateur choisir entre eux.
- Conception réactive : Assurez-vous que l'interface s'affiche et fonctionne bien sur différentes tailles et résolutions d'écran. Utilisez CSS Media Queries pour ajuster dynamiquement la mise en page.
- Options d'interaction avancées : Ajoutez des éléments interactifs supplémentaires tels que des menus contextuels, des listes déroulantes ou des fenêtres modales pour étendre les fonctionnalités.
Résumé
L'extension et l'adaptation d'un téléphone de centre de contrôle pour FiveM permettent de créer un environnement plus flexible et plus convivial pour le personnel du centre de contrôle. Des fonctionnalités telles que les enregistrements d'appels, l'intégration GPS et les interfaces utilisateur personnalisées améliorent non seulement l'expérience utilisateur mais également l'efficacité et la réactivité du centre de contrôle. En utilisant les techniques décrites dans ce guide, vous pouvez adapter votre système aux besoins et exigences spécifiques de votre communauté.
8. Publication et maintenance
8.1 Publication
- Conditionnement de la ressource : Assurez-vous que tous les fichiers sont correctement référencés.
- Documentation: Créer la documentation utilisateur et développeur.
8.2 Entretien
- Mises à jour régulières : Gardez le système à jour.
- Surveillance: Mettre en œuvre un système de suivi des audits de performance.
Avec ce guide complet, vous devriez désormais être en mesure de développer un téléphone de centre de contrôle entièrement fonctionnel pour FiveM. Utilisez la flexibilité de LUA, NUI et de l’intégration de bases de données pour créer un système robuste et efficace qui répond aux besoins d’un centre de contrôle professionnel.