Première connexion
Le flux prévu déclenche le spawn avec spawnmanager, puis charge le personnage lié à la licence Rockstar. Sans personnage, l’identité s’ouvre, suivie du créateur de skin. Le point de départ est l’aéroport par défaut.
FRUITZ FA / DOCUMENTATION TECHNIQUE
Le socle FiveM de Fruitz FA, de la première connexion du joueur à la sauvegarde de son personnage.
01 / DÉMARRAGE
Place la ressource dans resources/[1.Base]/ev. EV dépend de oxmysql, spawnmanager et de OneSync. Prépare une base MariaDB compatible et garde le nom de dossier cohérent avec les appels exports.ev de tes ressources.
sql/install.sql. Pour une base existante, vérifie d’abord les migrations.server.cfg avant de démarrer oxmysql.server.cfg exécute ressources.cfg, place les lignes ensure dans ce dernier.set onesync on
set mysql_connection_string "mysql://UTILISATEUR:MOT_DE_PASSE@HOTE/BASE?charset=utf8mb4"
ensure oxmysql
ensure spawnmanager
ensure ev
Les identifiants de l’exemple sont à remplacer. La configuration partagée config/config.lua est lue par les clients, donc garde les secrets SQL dans la configuration serveur.
02 / CYCLE DE VIE
Le flux prévu déclenche le spawn avec spawnmanager, puis charge le personnage lié à la licence Rockstar. Sans personnage, l’identité s’ouvre, suivie du créateur de skin. Le point de départ est l’aéroport par défaut.
EV retrouve le premier personnage par ID pour la licence. Le serveur renvoie la dernière position enregistrée ou le point de départ si aucune position valide n’existe. L’apparence sauvegardée est ensuite appliquée.
AAAA-MM-JJ, de 1900 à aujourd’hui. Genre H ou F. Les champs sont validés côté serveur et persistés en SQL.MaxCharacters est fixé à 1. Les personnages supplémentaires d’une ancienne installation restent en base jusqu’à leur suppression.Le diagnostic de la copie locale décrit un blocage dans le fichier chargé au démarrage du client.
03 / RÉGLAGES
Les valeurs suivantes proviennent de config/config.lua. Les durées sont en millisecondes.
| Clé | Valeur par défaut | Usage |
|---|---|---|
Locale, Debug | fr, false | Langue et diagnostic. Des fichiers fr et en sont fournis. |
SaveInterval | 300 000 | Intervalle des sauvegardes des données modifiées. |
PositionCaptureInterval, PositionSaveInterval | 1 000, 15 000 | Capture de la position et persistance SQL. |
Spawn | -1037.6, -2737.8, 20.17 | Point de repli à l’aéroport, orientation 330, modèle initial mp_m_freemode_01. |
MaxCharacters | 1 | Limite du flux actuel. |
DefaultGroup, Groups | user, hiérarchie staff | Groupe initial et niveaux de permission. |
StartingAccounts | cash=500, bank=2500, black=0 | Soldes à la création. |
Modules | accounts, jobs actifs | Activation des modules inclus. |
RateLimits | 15 callbacks et 5 actions personnage par 10 s | Limites distinctes par source. |
CallbackTimeout | 15 000 | Délai d’attente côté client. |
BootstrapAdmins | Vide | Indications de promotion manuelle en console. Les promotions se font avec setgroup. |
SkinWipeQueries | Vide | Requêtes facultatives de nettoyage de skins externes. Chacune reçoit la licence comme seul paramètre. |
04 / FONCTIONNALITÉS
EV charge ses modules depuis modules/ avec son propre manifeste. Leur activation se règle dans EV.Config.Modules.
| Module | Par défaut | Comportement |
|---|---|---|
accounts | Actif | Comptes cash, bank et black. Les mutations passent par des montants entiers et des soldes entre 0 et 2 147 483 647. EV.Accounts.Transfer(src, target, amount) est une fonction serveur interne de virement bancaire journalisé. |
jobs | Actif | EV.Jobs.Set(src, job, grade) valide le métier et le grade via SQL. Le métier initial est unemployed au grade 0. Le salaire existe comme donnée de grade. |
inventory-bridge | Désactivé | Point d’extension livré avec le fournisseur none. |
vehicles | Désactivé | Squelette pour une future gestion des véhicules. |
society | Désactivé | Squelette dépendant de accounts et jobs. |
Les squelettes nécessitent une implémentation. Le champ salaire ne déclenche aucun versement automatique dans cette version.
05 / ADMINISTRATION
Chaque groupe hérite des permissions des rangs inférieurs. L’alias mod est normalisé en modo. EV conserve le groupe dans le personnage.
| Groupe | Niveau |
|---|---|
user | 0 |
helper | 10 |
modo | 20 |
admin | 30 |
superadmin | 40 |
gerant | 50 |
owner | 60 |
setgroup ID groupe en consolesetgroup 12 owner./setgroup ID groupe ou /evsetgroup ID groupesuperadmin. La cible et le groupe demandé doivent être strictement sous le rang de l’auteur. L’auto-attribution est réservée à la console via l’ID du joueur./mygroup et /evwhoami/wipe ID en jeu ou wipe ID en consolesuperadmin et plus. En jeu, les autres cibles de rang égal ou supérieur sont protégées. Le wipe supprime les personnages de la licence, leur identité, leur skin et les données en cascade. Après la suppression, le joueur est déconnecté et invité à revenir pour recréer son personnage.L’ID demandé est l’ID de session FiveM. La commande wipe efface les données persistantes de la licence ciblée.
06 / PERSISTANCE
| Objet SQL | Rôle |
|---|---|
ev_characters | Licence Rockstar, identité, skin JSON, groupe, métier, grade, coordonnées et date de création. |
ev_accounts | Solde de chaque compte par personnage. |
ev_jobs, ev_job_grades | Catalogue des métiers, grades, libellés et salaires. |
ev_account_ledger | Journal des virements, avec un transfer_id commun au débit et au crédit. |
ev_transfer_bank | Procédure de virement. Débit, crédit et journal sont validés dans une même transaction. Une erreur entraîne un rollback. |
Vérifie les colonnes déjà présentes et applique, dans l’ordre, les migrations manquantes 002_identity.sql, 003_skin.sql et 004_position.sql. Le pied de install.sql décrit le cas d’un ancien journal sans transfer_id. Le fichier d’installation recrée aussi la procédure de virement.
Le JSON du skin contient outfit.components et outfit.props, indexés par emplacement. Une entrée contient drawable et texture. Les entrées avec collection et localDrawable peuvent retrouver leur modèle via sa collection. Le pack correspondant doit être présent sur le serveur.
07 / RÉFÉRENCE LUA
| Export | Contrat |
|---|---|
GetPlayer(source) | Objet du personnage chargé ou nil. |
GetGroup(source) | Groupe du personnage ou nil. |
HasPermission(source, group) | Booléen selon la hiérarchie. La console, source 0, passe pour un groupe valide. |
GetVersion() | Version EV sous forme de chaîne. |
RegisterCallback(name, fn) | Enregistre un handler serveur recevant source puis les arguments. |
RegisterModule(name, spec) | Export historique. Pour un module avec une fonction d’initialisation, utilise le registre interne depuis un fichier serveur chargé par EV. |
PurchaseOutfit(source, outfit, price, account) | Réservé à clothingshop. Débite cash ou bank et sauvegarde la tenue dans une transaction. Renvoie true, skin ou false, motif. |
local player = exports.ev:GetPlayer(source)
if player and exports.ev:HasPermission(source, 'modo') then
print(('Personnage #%d'):format(player.characterId))
end
Dans EV, l’objet Player fournit GetAccount(name), SetAccount(name, amount), AddAccount(name, amount), RemoveAccount(name, amount) et Public(). L’instantané public contient source, characterId, firstname, lastname, birthdate, nationality, gender, skin, group, job, grade et accounts.
| Export | Contrat |
|---|---|
GetGroup() | Groupe connu localement ou nil avant chargement. |
HasPermission(group) | Test local pour l’affichage. Le serveur doit vérifier toute action privilégiée. |
if exports.ev:HasPermission('helper') then
-- Afficher les options disponibles dans le menu client.
end
L’événement ev:client:loaded fournit un instantané du personnage à l’ouverture de la session. L’ancienne référence décrit aussi GetPlayerData() pour lire cet instantané et Notify(message, kind) pour afficher une notification. Ces deux exports restent à vérifier après restauration du fichier principal.
08 / COMMUNICATION
Dans EV, EV.Callback.Trigger(name, cb, ...) demande un résultat au serveur. cb(ok, ...) reçoit le statut du transport en premier, puis les valeurs métier renvoyées par le handler. Un refus métier peut donc arriver avec ok == true. En l’absence de réponse, le client reçoit false, 'timeout'.
-- Côté serveur, depuis une ressource qui dépend d’EV.
exports.ev:RegisterCallback('fruitz:profil', function(src)
local player = exports.ev:GetPlayer(src)
if not player then
return false, 'personnage_indisponible'
end
return true, player.firstname, player.lastname
end)
Les noms sont limités à 80 caractères à la réception. Les erreurs de transport renvoyées par le serveur sont unknown_callback et internal_error. Les arguments du client doivent être validés dans chaque handler.
| Callback natif | Rôle |
|---|---|
spawn:get | Calcule la position de spawn pour la licence connectée. |
characters:load | Charge le personnage courant. |
characters:create | Valide et sauvegarde la première identité. |
skin:save | Valide et sauvegarde le skin initial. |
Dans l’autre sens, EV.Callback.Trigger(src, name, ...) côté serveur appelle un handler client enregistré via EV.Callback.Register(name, fn). Cet envoi est à sens unique.
| Événement réseau | Usage |
|---|---|
ev:server:callback | Demande client vers serveur, avec ID, nom et arguments. |
ev:client:callback | Réponse au client, avec ID, statut de transport et résultats. |
ev:client:request | Notification serveur vers handler client. |
ev:client:loaded | Instantané du personnage au chargement. |
ev:client:group | Groupe mis à jour. |
ev:client:outfit | Actualisation de la tenue du personnage. |
ev:server:positionReady | Signal client permettant au serveur de démarrer la capture de position. |
Le bus EV.Events.On(name, handler) et EV.Events.Emit(name, ...) est distinct des événements réseau FiveM.
playerLoaded(source, player)playerUnloaded(source)accountChanged(source, name, amount)jobChanged(source, job, grade)permissionChanged(source, group)09 / ORGANISATION
Les ressources Fruitz FA se démarrent séparément. Pour une ressource qui utilise EV, déclare dependency 'ev' dans son manifeste et démarre-la après EV.
| Ressource externe | Fonction |
|---|---|
fruitz_hud | HUD de Fruitz FA. |
fruitz_admin | Menu d’administration F10, utilisant les groupes staff EV. |
clothingshop | Boutiques, essayage et achat. Les packs streamés du groupe [clothing] alimentent le catalogue de vêtements. |
fruitz_loadingscreen | Écran de chargement autonome de la base. |
config/core/shared/, core/server/, core/client/modules/EV.Modules.Register.web/sql/, tests/vitrine/index.html dans ton navigateur.Un module fournit un nom, ses dépendances éventuelles et une fonction init(EV). Le registre démarre les dépendances avant le module. Une dépendance absente ou désactivée, un cycle ou une erreur d’initialisation empêche le démarrage du module concerné.
-- Exemple dans un fichier serveur chargé par EV.
EV.Modules.Register('exemple', {
dependencies = {'jobs'},
init = function(framework)
framework.Events.On('jobChanged', function(src, job, grade)
print(src, job, grade)
end)
end
})
10 / DIAGNOSTIC
État de la copie locale. Le fichier core/client/main.lua contient 2 340 octets nuls. Il figure parmi les scripts client du manifeste. Restaure une version valide pour vérifier le spawn, la création de personnage et les exports définis dans ce fichier.
Les journaux EV utilisent le préfixe [EV] suivi d’un objet JSON avec level, action, data, version et timestamp. Cherche l’action et les données associées dans la console serveur.
28000 et txAdmin 28001.spawnmanager, OneSync, la connexion oxmysql et les erreurs côté client dans F8./mygroup, puis le démarrage de fruitz_admin. Le joueur doit avoir terminé le chargement de son personnage.groups.test.lua couvre la hiérarchie. position.test.lua et spawn_client.test.lua ciblent le spawn et la persistance. skin_smoke.lua vérifie le skin.
Pour les virements, le guide de test accompagne CALL_SMOKE_TEST.sql et ledger_audit.sql. Exécute les scénarios de mutation dans une base de test.