QB / ESX
Agency-LifeinvaderV3
Système publicitaire moderne pour FiveM avec interface Liquid Glass, tarification par paliers, catégories d'annonces, boost de priorité, annonces anonymes et panneau d'administration. Supporte ESX, QBCore et Standalone.

01 Installation
Extraire dans le répertoire resources
Importer agency_lifeinvader.sql (optionnel, dispose d'un auto-upgrader)
Ajouter ensure Agency-LifeinvaderV3 dans server.cfg
Configurer config.lua (framework, tarification, notifications)
Dépendances
oxmysql — requis si utilisation de la base de donnéesESX ou QBCore — optionnel, prend en charge le standalone
Fichier SQL
Importez ce fichier SQL dans votre base de données avant de démarrer la ressource :
-- ═══════════════════════════════════════════
-- AGENCY LIFEINVADER V3 - DATABASE SETUP
-- by Agency Scripts
-- ═══════════════════════════════════════════
CREATE TABLE IF NOT EXISTS `lifeinvader_ads` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`identifier` VARCHAR(100) NOT NULL,
`author_name` VARCHAR(100) DEFAULT 'Anonymous',
`message` TEXT NOT NULL,
`category` VARCHAR(50) DEFAULT 'other',
`anonymous` TINYINT DEFAULT 0,
`boosted` TINYINT DEFAULT 0,
`repetitions_total` INT DEFAULT 1,
`repetitions_left` INT DEFAULT 1,
`interval_seconds` INT DEFAULT 60,
`display_duration` INT DEFAULT 8,
`status` ENUM('pending','active','completed','rejected') DEFAULT 'active',
`approved` TINYINT DEFAULT 1,
`approved_by` VARCHAR(100) DEFAULT NULL,
`rejected_reason` TEXT DEFAULT NULL,
`next_send_time` DATETIME DEFAULT NULL,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_identifier` (`identifier`),
INDEX `idx_status` (`status`),
INDEX `idx_approved` (`approved`),
INDEX `idx_category` (`category`),
INDEX `idx_boosted` (`boosted`),
INDEX `idx_next_send` (`next_send_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `lifeinvader_player_settings` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`identifier` VARCHAR(100) NOT NULL UNIQUE,
`notification_position` VARCHAR(20) DEFAULT '0,50',
`notification_enabled` TINYINT DEFAULT 1,
`notification_scale` FLOAT DEFAULT 1.0,
`ui_transparency` FLOAT DEFAULT 0.55,
`accent_color` VARCHAR(20) DEFAULT '#3b82f6',
`sound_enabled` TINYINT DEFAULT 1,
`admin_panel_scale` FLOAT DEFAULT 1.0,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_identifier` (`identifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `lifeinvader_ad_drafts` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`identifier` VARCHAR(100) NOT NULL,
`title` VARCHAR(120) DEFAULT NULL,
`message` TEXT NOT NULL,
`category` VARCHAR(50) DEFAULT 'other',
`anonymous` TINYINT DEFAULT 0,
`boosted` TINYINT DEFAULT 0,
`repetitions_total` INT DEFAULT 1,
`interval_seconds` INT DEFAULT 60,
`display_duration` INT DEFAULT 8,
`delay` INT DEFAULT 0,
`scheduled_for` DATETIME DEFAULT NULL,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_identifier` (`identifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `lifeinvader_admin_logs` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`admin_identifier` VARCHAR(100) DEFAULT NULL,
`admin_name` VARCHAR(100) DEFAULT NULL,
`action` VARCHAR(64) NOT NULL,
`ad_id` INT DEFAULT NULL,
`metadata` LONGTEXT DEFAULT NULL,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX `idx_action` (`action`),
INDEX `idx_ad_id` (`ad_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ═══ AUTO UPGRADE SYSTEM ═══
-- Safely adds missing columns without throwing errors on existing databases
DROP PROCEDURE IF EXISTS `UpgradeLifeinvaderColumns`;
DELIMITER //
CREATE PROCEDURE `UpgradeLifeinvaderColumns`()
BEGIN
DECLARE _dbName VARCHAR(255) DEFAULT DATABASE();
DECLARE cnt INT;
-- Add category column
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'category';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `category` VARCHAR(50) DEFAULT 'other' AFTER `message`;
END IF;
-- Add anonymous column
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'anonymous';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `anonymous` TINYINT DEFAULT 0 AFTER `category`;
END IF;
-- Add boosted column
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'boosted';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `boosted` TINYINT DEFAULT 0 AFTER `anonymous`;
END IF;
-- Add ui_transparency column to player settings
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_player_settings' AND COLUMN_NAME = 'ui_transparency';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_player_settings` ADD COLUMN `ui_transparency` FLOAT DEFAULT 0.55 AFTER `notification_scale`;
END IF;
-- Add accent_color column to player settings
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_player_settings' AND COLUMN_NAME = 'accent_color';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_player_settings` ADD COLUMN `accent_color` VARCHAR(20) DEFAULT '#3b82f6' AFTER `ui_transparency`;
END IF;
-- Add admin_panel_scale column to player settings
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_player_settings' AND COLUMN_NAME = 'admin_panel_scale';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_player_settings` ADD COLUMN `admin_panel_scale` FLOAT DEFAULT 1.0 AFTER `sound_enabled`;
END IF;
-- Add display_duration column to drafts
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ad_drafts' AND COLUMN_NAME = 'display_duration';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ad_drafts` ADD COLUMN `display_duration` INT DEFAULT 8 AFTER `interval_seconds`;
END IF;
-- Add delay column to drafts
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ad_drafts' AND COLUMN_NAME = 'delay';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ad_drafts` ADD COLUMN `delay` INT DEFAULT 0 AFTER `display_duration`;
END IF;
-- Add scheduling / review / AI fields
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'scheduled_for';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `scheduled_for` DATETIME DEFAULT NULL AFTER `next_send_time`;
END IF;
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'review_requested_at';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `review_requested_at` DATETIME DEFAULT NULL AFTER `approved`;
END IF;
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'reviewed_at';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `reviewed_at` DATETIME DEFAULT NULL AFTER `review_requested_at`;
END IF;
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'review_decision';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `review_decision` VARCHAR(32) DEFAULT NULL AFTER `reviewed_at`;
END IF;
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'queue_priority';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `queue_priority` INT DEFAULT 0 AFTER `review_decision`;
END IF;
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'ai_score';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `ai_score` INT DEFAULT 0 AFTER `queue_priority`;
END IF;
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'ai_flags';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `ai_flags` LONGTEXT DEFAULT NULL AFTER `ai_score`;
END IF;
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'admin_notes';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `admin_notes` LONGTEXT DEFAULT NULL AFTER `ai_flags`;
END IF;
-- Add display_duration column
SELECT COUNT(*) INTO cnt FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = _dbName AND TABLE_NAME = 'lifeinvader_ads' AND COLUMN_NAME = 'display_duration';
IF cnt = 0 THEN
ALTER TABLE `lifeinvader_ads` ADD COLUMN `display_duration` INT DEFAULT 8 AFTER `interval_seconds`;
END IF;
-- Indexes cannot be safely checked inline as easily in older MySQL,
-- but usually they don't break queries if missing. We only add them on fresh install via CREATE TABLE above.
END //
DELIMITER ;
CALL UpgradeLifeinvaderColumns();
DROP PROCEDURE IF EXISTS `UpgradeLifeinvaderColumns`;