Agency Docs
QBESXStandalone

Agency-Lifeinvader V3 Configuration

The ad agency of the city for FiveM on QBCore, Qbox, ESX or fully standalone.

v3.2.1Paid5 Pages

01Configuration

Quick Installation · config.lua · Agency-Lifeinvader V3

Download config.lua

--[[ ============================================================================ 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 = {}

02SQL File

Optional: the resource creates these tables on its own when it starts. Import this file only if you set up the database by hand:

-- ============================================================================= -- 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;

+Good to know

config.lua has 16 commented sections, from the framework to your own wording. Prices, review rules, boosts and categories can also be changed in the Admin panel in game, for the whole server.

General and Look
Config.Framework, Config.Locale, Config.Debug, Config.Storage and Config.Notify choose the framework, the language, the debug mode, where data is kept and how messages are shown. Config.UI sets the brand name, subtitle, logo, accent colour and the size of the app.
Keys and Commands
Config.Keys sets F6 and the optional key for the live feed, Config.Commands the names of /alad, /alfeed, /altest, /aladmin and /alagency.
Ads and Boosts
Config.Ads sets the length, lines, runs, interval, time on screen, start delays, anonymous ads, scheduling, the gap between two ads and how many banners a screen shows at once. Config.Boost sets the price factor and how far a boosted ad jumps ahead.
Prices and Payment
Config.Pricing sets the base price and the price per second on screen. Config.Money sets bank and cash, the currency, refunds and Agency Pay.
Categories
Config.Categories lists the six categories with icon, price factor, priority, review, runs and gap.
Review and Auto-Check
Config.Review decides whether every ad waits for review and how Auto-Check scores links, shouting, symbols, numbers, repeats and suspicious or blocked words.
Limits
Config.Limits sets the cooldown between two ads of a player, the ads waiting and running per player, the drafts and whether admins are limited.
Banners, Job and Devices
Config.Banner sets the default position, size, sound and width of the banners. Config.Agency sets the job, grades, revenue share, commission and company account, Config.Devices the app on Agency Phone and Agency Pad.
Admins, History, Standalone and Wording
Config.Admin names the admin ACE, groups and identifiers, Config.History how long ads are kept, Config.Standalone the money without a framework, and Config.Text replaces any text so your wording survives updates.

?Frequently asked questions

What do the settings in the Admin panel change?

Review rules, Auto-Check, anonymous ads, the debug mode, prices, the gap between ads, boosts and every category. They are saved for the whole server and win over config.lua until Reset to config.lua is pressed or lifeinvader reset runs in the console.

How do I change a text?

Put it in Config.Text with the key from the language files, for example Config.Text = { ui_publish = 'Send it!' }. It survives updates.

Still stuck after this page? Our support team takes it from here.