Agency-Lifeinvader V3 Configuración
La agencia de publicidad de la ciudad para FiveM con QBCore, Qbox, ESX o totalmente independiente.

01Configuración
Instalación rápida · config.lua · Agency-Lifeinvader V3
--[[ ============================================================================
AGENCY LIFEINVADER 3.2 · config.lua
----------------------------------------------------------------------------
The ad agency of the city. Players write ads that run across the screen of
every player: categories, boosts, scheduling, drafts, a live feed, review
by admins or the staff of the agency job, and an Auto-Check for spam.
Finds QBCore, Qbox or ESX by itself and runs fully standalone without any
of them, with or without a database.
Admins change prices, review and the categories in the menu (/aladmin,
tab Settings). Those values are saved for the whole server and win over
this file until "Reset to config.lua" is pressed.
============================================================================ ]]
Config = {}
-- =============================================================================
-- 1. GENERAL
-- =============================================================================
Config.Framework = 'auto' -- 'auto' | 'qbcore' (also Qbox) | 'esx' | 'standalone'
Config.Locale = 'en' -- en de fr es it pt nl pl cs sv da no fi ro hu hr bg el tr ru uk ar hi ja ko zh
-- Debug mode: every request and every ad of the queue in the server console.
-- Admins can switch it in the menu as well.
Config.Debug = false
-- Where ads, drafts and player settings are saved. 'auto' uses oxmysql when
-- it runs (the V3 tables, created and upgraded by themselves) and otherwise
-- the server's own key value store, so a server without a database works too.
Config.Storage = 'auto' -- 'auto' | 'mysql' | 'kvp'
-- How messages are shown: 'auto' = Agency-Notify when it runs, then a
-- notification on Agency Phone, then your framework, then the GTA feed.
-- While the app is open, messages appear in it.
-- Agency-Notify is free: https://agencyscripts.dev/en/product/notify
Config.Notify = 'auto' -- 'auto' | 'agency' | 'framework' | 'gta'
-- =============================================================================
-- 2. LOOK
-- =============================================================================
Config.UI = {
brand = 'LIFEINVADER', -- name in the app and on every ad
subtitle = '', -- line under the name, '' = "Ad agency" in the server language
-- A file in html/, a nui:// or https:// link, or '' for a megaphone icon.
-- Best as a square PNG with a transparent background (logo.png is the
-- gold Agency logo).
logo = 'logo.png',
tintLogo = false, -- true draws the logo in the accent colour (good for a white logo)
accent = '#E2B649', -- accent colour of app and ads (Agency gold)
scale = 1.0, -- size of the app, 0.8 to 1.3 (players size their ad banners themselves)
}
-- =============================================================================
-- 3. KEYS AND COMMANDS
-- =============================================================================
-- Players can change both keys in the GTA settings (Key Bindings > FiveM).
-- F6 is free in all Agency scripts (Vehiclekeys F5, Housing F7, Admin F10).
Config.Keys = {
open = 'F6', -- opens the app
feed = '', -- opens the live feed directly, '' = no key (players can set one)
}
Config.Commands = {
open = 'alad', -- the app
feed = 'alfeed', -- the live feed
test = 'altest', -- shows a sample ad to yourself, to try the banner position
admin = 'aladmin', -- admin panel
agency = 'alagency', -- staff panel of the ad agency job
}
-- =============================================================================
-- 4. ADS
-- =============================================================================
Config.Ads = {
minLength = 10, -- characters an ad needs at least
maxLength = 300, -- characters at most
maxLines = 6, -- lines one ad may have
maxRepetitions = 5, -- how often one ad may run (categories can lower it)
interval = { min = 30, max = 300, default = 60 }, -- seconds between two runs of the same ad
duration = { min = 5, max = 60, default = 8 }, -- seconds an ad stays on screen
delays = { 0, 10, 30, 60, 300 }, -- start delays the form offers, in seconds
anonymous = true, -- players may post without their name
schedule = { enabled = true, maxHoursAhead = 24 }, -- post an ad for a later time
-- Seconds between two ads across the whole city. Ads wait in a queue and
-- never flood the screen, however many are booked.
gap = 15,
maxOnScreen = 3, -- banners on a player's screen at the same time
}
Config.Boost = {
enabled = true,
multiplier = 2.0, -- a boosted ad costs this many times the price
priority = 8, -- and jumps this far ahead in the queue
}
-- =============================================================================
-- 5. PRICES AND PAYMENT
-- =============================================================================
-- Price of one run = (base + perSecond x seconds on screen) x category factor,
-- times 2 with a boost. The total is that times the number of runs.
Config.Pricing = {
base = 5000,
perSecond = 500,
}
Config.Money = {
-- What players pay with. The first one is picked in the form, the player
-- can switch when there are more. 'bank' | 'cash'
methods = { 'bank', 'cash' },
currency = '$',
-- Rejected, withdrawn and stopped ads pay back what has not run yet.
-- A player who is offline gets it the next time he joins.
refunds = true,
-- Agency Pay from Agency Phone: the phone opens, the player confirms the
-- payment there, the money comes from his bank account. Offered as soon
-- as the phone runs; enabled = false hides it.
agencyPay = { enabled = true, resource = 'agency-phone', timeout = 90 },
}
-- =============================================================================
-- 6. CATEGORIES
-- =============================================================================
-- id stays the same once ads use it
-- label used when the language files have no text for this id
-- icon briefcase car home wrench party pin food shop music heart star megaphone tag bolt
-- price factor on the price (0.9 = 10 % cheaper)
-- priority places ahead in the queue
-- review ads of this category always wait for a staff member
-- maxRepetitions runs at most (below Config.Ads.maxRepetitions)
-- minInterval seconds at least between two runs
Config.Categories = {
{ id = 'jobs', label = 'Jobs', icon = 'briefcase', price = 0.9, priority = 2, review = false, maxRepetitions = 4, minInterval = 30 },
{ id = 'vehicles', label = 'Vehicles', icon = 'car', price = 1.15, priority = 1, review = false, maxRepetitions = 5, minInterval = 45 },
{ id = 'realestate', label = 'Real Estate', icon = 'home', price = 1.25, priority = 1, review = true, maxRepetitions = 4, minInterval = 60 },
{ id = 'services', label = 'Services', icon = 'wrench', price = 1.0, priority = 2, review = false, maxRepetitions = 5, minInterval = 30 },
{ id = 'events', label = 'Events', icon = 'party', price = 1.1, priority = 3, review = false, maxRepetitions = 5, minInterval = 30 },
{ id = 'other', label = 'Other', icon = 'pin', price = 1.0, priority = 0, review = false, maxRepetitions = 3, minInterval = 45 },
}
-- =============================================================================
-- 7. REVIEW
-- =============================================================================
Config.Review = {
-- Every ad waits for an admin or a staff member of the agency before it
-- runs. Admins switch this in the menu.
required = false,
-- Auto-Check: simple rules on your own server, no outside service. It
-- looks for shouting, links, phone number walls, repeated texts and spam
-- and holds such ads back for review. Admins see why.
autoCheck = {
enabled = true,
holdOnFlag = true, -- flagged ads wait for review
threshold = 4, -- penalty points that count as flagged
duplicateMinutes = 30, -- the same text again within this time is a repeat
duplicateLimit = 1, -- repeats allowed before it counts
links = { 'http://', 'https://', 'www.', 'discord.gg', 'bit.ly' },
suspicious = { '@everyone', 'free money', 'hack', 'exploit', 'cheap cash', 'real money' },
blocked = {}, -- ads with one of these words are refused outright
points = {
duplicate_message = 3, aggressive_frequency = 2, excessive_caps = 1, excessive_symbols = 1,
external_link = 2, contact_heavy = 1, suspicious_term = 2, long_copy = 1,
},
},
}
-- =============================================================================
-- 8. LIMITS PER PLAYER
-- =============================================================================
Config.Limits = {
cooldown = 45, -- seconds between two ads of one player
maxWaiting = 3, -- ads waiting for review
maxRunning = 4, -- ads running or scheduled
maxDrafts = 12,
staffBypass = true, -- admins are not limited
}
-- =============================================================================
-- 9. AD BANNERS
-- =============================================================================
-- Defaults for every player. Players change position, size, sound and the
-- categories they want to see in the app (tab Settings).
Config.Banner = {
position = 'middle-left', -- 'top-left' | 'top-right' | 'middle-left' | 'middle-right' | 'bottom-left' | 'bottom-right'
scale = 1.0, -- 0.8 to 1.3
sound = true,
width = 380, -- pixels
showAuthor = true, -- false hides who posted, on every ad
sounds = {
ad = { name = 'TEXT_ARRIVE_TONE', set = 'HUD_AWARDS' },
publish = { name = 'PURCHASE', set = 'HUD_LIQUOR_STORE_SOUNDSET' },
},
}
-- =============================================================================
-- 10. THE AD AGENCY (JOB)
-- =============================================================================
-- Staff of the agency get a panel (/alagency): the company account, what
-- the ads earn, and the review of waiting ads. The company earns a share of
-- every ad as it runs; the staff member who approved an ad gets a commission
-- on every run of it.
Config.Agency = {
enabled = true,
job = 'lifeinvader', -- job of the staff (QBCore, Qbox, ESX)
ace = 'agency.lifeinvader.staff', -- without a framework: players with this ACE are staff
grade = 0, -- lowest job grade that opens the panel
bossGrade = 3, -- grade that may take money out of the company account
review = true, -- staff may approve and reject waiting ads
revenue = 100, -- % of every ad's price that goes to the company account
commission = 10, -- % for the staff member who approved the ad, taken from the company share
account = 'lifeinvader', -- name of the company (society) account
-- 'auto' finds Renewed-Banking, qb-banking, qb-management, okokBanking and
-- esx_addonaccount (society_<account>). 'internal' keeps the money in
-- this script; bosses pay it out in the panel.
bank = 'auto',
payTo = 'bank', -- commission and payouts go to 'bank' or 'cash'
}
-- =============================================================================
-- 11. AGENCY PHONE AND AGENCY PAD
-- =============================================================================
-- When Agency Phone or Agency Pad (27.0.2 or newer) runs on the server,
-- Lifeinvader puts its own app on them by itself: the live feed, new ads,
-- my ads and drafts, right on the device. Nothing to set up.
Config.Devices = {
phone = true, -- app on Agency Phone
pad = true, -- app on Agency Pad
label = 'Lifeinvader',
installed = true, -- already on the home screen, not only in the App Store
-- Messages about your ads (approved, rejected, refunds) come as app
-- notifications on the phone while its app is there.
notifications = true,
}
-- =============================================================================
-- 12. ADMINS
-- =============================================================================
-- Admins: players with the ACE below, group.admin or group.superadmin, one of
-- the framework groups, or one of the identifiers.
Config.Admin = {
ace = 'agency.lifeinvader.admin',
groups = { 'admin', 'god', 'superadmin' },
identifiers = {
-- 'license:xxxxxxxx', 'discord:xxxxxxxx', 'steam:xxxxxxxx',
},
}
-- =============================================================================
-- 13. HISTORY
-- =============================================================================
Config.History = {
keepDays = 30, -- finished ads and admin log entries older than this are removed
feed = 30, -- ads in the live feed
mine = 20, -- a player's own ads in "My ads"
}
-- =============================================================================
-- 14. STANDALONE
-- =============================================================================
-- Without QBCore, Qbox or ESX:
-- money: 'auto' uses Agency-Banking when it runs, otherwise ads are free.
-- 'hooks' uses the functions below, 'free' never charges.
-- staff: players with Config.Agency.ace, admins by Config.Admin.
Config.Standalone = {
money = 'auto', -- 'auto' | 'banking' | 'hooks' | 'free'
-- getMoney = function(src, account) return 0 end, -- account: 'cash' | 'bank'
-- removeMoney = function(src, account, amount) return true end,
-- addMoney = function(src, account, amount) return true end,
-- getName = function(src) return GetPlayerName(src) end, -- the character name on ads
-- addCompanyMoney = function(account, amount) return true end, -- company account of the agency
}
-- =============================================================================
-- 15. YOUR OWN WORDING
-- =============================================================================
-- Any text of the language files can be replaced here and survives updates:
-- Config.Text = { ui_publish = 'Send it!', ad_published = 'Your ad is live.' }
Config.Text = {}
02Archivo SQL
Opcional: el recurso crea estas tablas por sí mismo al iniciarse. Importa este archivo solo si preparas la base de datos a mano:
-- =============================================================================
-- Agency Lifeinvader 3.2: database tables (OPTIONAL)
-- -----------------------------------------------------------------------------
-- You do not need to run this file. With oxmysql the script creates these
-- tables on the first start and upgrades the tables of Lifeinvader V2 and V3
-- in place. Run it only if your server creates tables by hand.
-- =============================================================================
CREATE TABLE IF NOT EXISTS `lifeinvader_ads` (
`id` INT NOT NULL AUTO_INCREMENT,
`identifier` VARCHAR(100) NOT NULL,
`author_name` VARCHAR(100) DEFAULT NULL,
`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` VARCHAR(16) NULL DEFAULT 'active',
`approved` TINYINT DEFAULT 1,
`approved_by` VARCHAR(100) DEFAULT NULL,
`rejected_reason` TEXT DEFAULT NULL,
`next_send_time` DATETIME DEFAULT NULL,
`scheduled_for` DATETIME DEFAULT NULL,
`review_requested_at` DATETIME DEFAULT NULL,
`reviewed_at` DATETIME DEFAULT NULL,
`review_decision` VARCHAR(32) DEFAULT NULL,
`queue_priority` INT DEFAULT 0,
`ai_score` INT DEFAULT 0,
`ai_flags` LONGTEXT DEFAULT NULL,
`admin_notes` LONGTEXT DEFAULT NULL,
`price_paid` INT DEFAULT NULL,
`paid_with` VARCHAR(16) DEFAULT NULL,
`refunded` INT DEFAULT 0,
`reviewer` VARCHAR(100) DEFAULT NULL,
`sent_count` INT DEFAULT 0,
`last_sent_at` DATETIME DEFAULT NULL,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_identifier` (`identifier`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `lifeinvader_ad_drafts` (
`id` INT NOT NULL AUTO_INCREMENT,
`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,
PRIMARY KEY (`id`),
KEY `idx_identifier` (`identifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `lifeinvader_player_settings` (
`id` INT NOT NULL AUTO_INCREMENT,
`identifier` VARCHAR(100) NOT NULL,
`notification_position` VARCHAR(20) DEFAULT 'middle-left',
`notification_enabled` TINYINT DEFAULT 1,
`notification_scale` FLOAT DEFAULT 1.0,
`ui_transparency` FLOAT DEFAULT 0.55,
`accent_color` VARCHAR(20) DEFAULT NULL,
`sound_enabled` TINYINT DEFAULT 1,
`admin_panel_scale` FLOAT DEFAULT 1.0,
`muted_categories` VARCHAR(255) DEFAULT NULL,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_identifier` (`identifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `lifeinvader_admin_logs` (
`id` INT NOT NULL AUTO_INCREMENT,
`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,
PRIMARY KEY (`id`),
KEY `idx_action` (`action`),
KEY `idx_ad_id` (`ad_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+Conviene saber
config.lua tiene 16 secciones comentadas, desde el framework hasta tus propios textos. Los precios, las reglas de revisión, las promociones y las categorías también se pueden cambiar en el panel de administración dentro del juego, para todo el servidor.
- General y apariencia
- Config.Framework, Config.Locale, Config.Debug, Config.Storage y Config.Notify permiten elegir el framework, el idioma, el modo de depuración, dónde se guardan los datos y cómo se muestran los mensajes. Config.UI establece el nombre de la marca, el subtítulo, el logotipo, el color de acento y el tamaño de la app.
- Teclas y comandos
- Config.Keys establece F6 y la tecla opcional para el feed en directo; Config.Commands establece los nombres de /alad, /alfeed, /altest, /aladmin y /alagency.
- Anuncios y promociones
- Config.Ads establece la duración, las líneas, las publicaciones, el intervalo, el tiempo en pantalla, los retrasos de inicio, los anuncios anónimos, la programación, el espacio entre dos anuncios y cuántos banners muestra una pantalla a la vez. Config.Boost establece el factor de precio y cuánto adelanta un anuncio promocionado.
- Precios y pagos
- Config.Pricing establece el precio base y el precio por segundo en pantalla. Config.Money establece el banco y el efectivo, la moneda, los reembolsos y Agency Pay.
- Categorías
- Config.Categories enumera las seis categorías con icono, factor de precio, prioridad, revisión, publicaciones y espacio entre anuncios.
- Revisión y Auto-Check
- Config.Review determina si todos los anuncios esperan una revisión y cómo Auto-Check puntúa los enlaces, los gritos, los símbolos, los números, las repeticiones y las palabras sospechosas o bloqueadas.
- Límites
- Config.Limits establece el tiempo de espera entre dos anuncios de un jugador, los anuncios en espera y en curso por jugador, los borradores y si los administradores tienen límites.
- Banners, trabajo y dispositivos
- Config.Banner establece la posición, el tamaño, el sonido y el ancho predeterminados de los banners. Config.Agency establece el trabajo, los rangos, el reparto de ingresos, la comisión y la cuenta de la empresa. Config.Devices establece la aplicación en Agency Phone y Agency Pad.
- Administradores, historial, modo independiente y textos
- Config.Admin indica el ACE, los grupos y los identificadores de administrador. Config.History establece durante cuánto tiempo se conservan los anuncios, Config.Standalone configura el dinero sin un framework y Config.Text reemplaza cualquier texto para que tu redacción se conserve tras las actualizaciones.
?Preguntas frecuentes
¿Qué cambian los ajustes del panel de administración?
Las reglas de revisión, Auto-Check, los anuncios anónimos, el modo de depuración, los precios, el intervalo entre anuncios, las mejoras y todas las categorías. Se guardan para todo el servidor y prevalecen sobre config.lua hasta que se pulse Reset to config.lua o se ejecute lifeinvader reset en la consola.
¿Cómo cambio un texto?
Añádelo a Config.Text con la clave de los archivos de idioma, por ejemplo: Config.Text = { ui_publish = 'Send it!' }. Se conservará tras las actualizaciones.