> For the complete documentation index, see [llms.txt](https://project-07.gitbook.io/project_07-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://project-07.gitbook.io/project_07-docs/scripts/project07-chat/configuration.md).

# Configuration

Config File

{% code title="Config.lua" overflow="wrap" lineNumbers="true" %}

```lua
Config = {}

-- ══════════════════════════════════════════════════════
--  FRAMEWORK  (auto | esx | qb | qbx | standalone)
-- ══════════════════════════════════════════════════════
Config.Framework = 'auto'
Config.ShowChatKey = 'T'

-- ══════════════════════════════════════════════════════
--  CHAT HISTORY  (viewable from the admin tablet's Player History page)
-- ══════════════════════════════════════════════════════
Config.ChatHistory = {
    Enabled       = true,
    RetentionDays = 2,    -- messages older than this are auto-deleted
    MaxEntries    = 5000, -- hard cap regardless of age, oldest evicted first
}

-- ══════════════════════════════════════════════════════
--  ADMIN-ONLY CHAT  (separate tab in the admin tablet)
-- ══════════════════════════════════════════════════════
Config.AdminChatHistory = {
    DefaultAutoClearDays = 3, -- 1-7, adjustable live from the admin tablet
    MaxEntries           = 3000,
}

-- Circular logo shown top-right of the admin tablet (next to the admin's
-- name). Leave blank to just show a generic icon.
Config.ServerLogoUrl = ''

-- Admin tablet's OWN accent color — independent from any individual
-- player's chat color, so it looks the same for every admin regardless of
-- what they've personally customized their own chat to. Changeable live
-- from inside the admin tablet itself (Settings page).
Config.AdminTheme = {
    AccentColor = '#ffffff',
}

-- ══════════════════════════════════════════════════════
--  DATABASE  (persists admin-tablet settings + chat history)
--
--  Enabled   = false → uses local JSON files (data/*.json) in the resource
--                       folder. Simple, but wiped if your host redeploys /
--                       resets the resource folder on restart.
--  Enabled   = true  → uses MySQL through the "oxmysql" resource. Make sure
--                       oxmysql is installed, configured (server.cfg
--                       "set mysql_connection_string ..."), and started
--                       ABOVE this resource in server.cfg.
--
--  AutoSetup = true  → automatically runs CREATE TABLE IF NOT EXISTS on
--                       start (no manual step needed).
--  AutoSetup = false → tables are NOT created automatically; import
--                       install.sql (in this resource's folder) into your
--                       database yourself first.
-- ══════════════════════════════════════════════════════
Config.Database = {
    Enabled   = true,
    AutoSetup = true,
}

-- ══════════════════════════════════════════════════════
--  CHAT UI DEFAULTS
--  Positions:  tl | tr | bl | br
--  Sizes:      sm | md | lg
--  Themes:     dark | midnight | carbon | ghost | neon |
--              military | ocean | crimson | void | ember | ice | toxic
--  Styles:     modern | compact | minimal | glass |
--              survival | terminal | bubble | bordered
-- ══════════════════════════════════════════════════════
Config.Chat = {
    DefaultPosition = 'tl',
    DefaultSize     = 'lg',
    DefaultTheme    = 'crimson',
    DefaultStyle    = 'bubble',
    DefaultColor    = '#ffffff', -- accent/border color — white, no blue
    DefaultBgColor  = '#1f1f1e', -- full black-ish background
    DefaultInputBgColor = '#1f1f1e',
}

-- ══════════════════════════════════════════════════════
--  OTHER SETTINGS
-- ══════════════════════════════════════════════════════
Config.YellowPageFee        = 500  -- cost to post in yellow pages (need bank money for this)
Config.WhisperDistance      = 3.0 -- for /whisper command
Config.ShowIdentityDistance = 3.0 -- for /id and /charinfo
Config.EnableEmojiMenu      = true -- Long-press chat key to show emoji menu
Config.OOCMessageWithoutCommand = false -- Allow sending OOC messages without /ooc prefix (true = global OOC, false = no OOC without command)
Config.MaxMessages          = 50 -- Max messages to keep in full chat history (scrollback)
Config.MaxVisibleMessages   = 6  -- Max messages shown at once in the message box; older ones fade out as new ones arrive
Config.MessageFadeDelay     = 5000 -- ms before the chat box hides itself after being idle (0 = disable)
Config.RateLimit = {  
    maxMessages = 6, -- max messages allowed in interval
    interval = 3000  -- interval length in ms
}

-- ══════════════════════════════════════════════════════
--  CHAT RADIUS  (per command, in GTA units)
--  Set any value to 0 to make that command GLOBAL (whole server)
-- ══════════════════════════════════════════════════════
Config.ChatRadius = {
    me  = 10.0, -- /me visibility radius
    do_ = 10.0, -- /do visibility radius
    ooc = 0.0,  -- /ooc visibility radius (0 = global, sent to everyone)
}

-- ══════════════════════════════════════════════════════
--  ADMIN TABLET  (/chatadmin)
--  Grant access in server.cfg, e.g.:
--     add_ace group.admin project07.admin allow
--  or for a specific person:
--     add_principal identifier.license:xxxxxxxx project07.admin
-- ══════════════════════════════════════════════════════
Config.AdminChat = {
    Command        = 'chatadmin',
    AcePermission  = 'project07.admin',
}


-- ══════════════════════════════════════════════════════
--  ANTI-EXPLOIT / ANTI-ABUSE
-- ══════════════════════════════════════════════════════
Config.AntiExploit = {
    Enabled         = true,
    MaxViolations   = 6,     -- violations allowed inside the window below before action is taken
    ViolationWindow = 60000, -- ms (1 minute)
    KickOnExploit   = false, -- set true to auto-kick players who cross MaxViolations
    KickReason      = 'Kicked for chat abuse / exploit attempts.',
    MaxMessageLength= 300,
}


-- ══════════════════════════════════════════════════════
--  WELCOME MESSAGES  (sent to player when they spawn)
-- ══════════════════════════════════════════════════════
Config.WelcomeMessages = {
    enabled = true, -- set to false to disable welcome messages
    delay   = 3000,  -- ms after spawn to send first message

    messages = {
        {
            header = 'Last Horizon Survival',
            text   = 'Welcome to the server! Enjoy your roleplay.',
            color  = '#ffffff',
            bg     = '#1e1e1e',
            delay  = 0,       -- ms after previous message
        },
        {
            header = 'SERVER RULES',
            text   = '1. No RDM/VDM  2. No meta-gaming  3. Stay IC  4. Respect all players',
            color  = '#e69332',
            bg     = '#1a1008',
            delay  = 0, -- ms after previous message
        },
        {
            header = 'DISCORD',
            text   = 'Join our community: discord.gg/lasthorizonlk — Get support & updates!',
            color  = '#5484FF',
            bg     = '#101828',
            delay  = 0,
        },
        {
            header = 'TIP',
            text   = 'Use /me for actions, /do for descriptions, /whisper [ID] for private RP.',
            color  = '#00C2FF',
            bg     = '#081620',
            delay  = 0,
        },
    }
}

-- ══════════════════════════════════════════════════════
--  PRIVACY MASK  (/me and /do)
--  If a player is wearing one of the listed ped components, their name
--  shows as MaskedName ("Someone") in the public chat box and head bubble
--  — but the admin tablet's Player History ALWAYS shows their real name,
--  regardless of this setting, for moderation purposes.
--
--  GTA ped component IDs (drawable slots) — the default (1) is the mask
--  slot. Add more if you want other components to also count, e.g.:
--  Components = { 1, 11 } (1 = mask, 11 = torso/accessory overlay).
--
--  Enabled can also be toggled live from the admin tablet's Settings page
--  (that takes priority once changed there — this is just the starting value).
-- ══════════════════════════════════════════════════════
Config.PrivacyMask = {
    Enabled    = true,
    MaskedName = 'Someone',
    Components = { 1 },
}

-- ══════════════════════════════════════════════════════
--  JOB COLORS  (role badge shown in chat next to name)
--  name = internal job name (lowercase)
-- ══════════════════════════════════════════════════════
Config.JobColors = {
    ['police']     = { 
        label = 'POLICE',    
        color = '#00C2FF' 
    },
    ['sheriff']    = { 
        label = 'SHERIFF',   
        color = '#4da6ff' 
    },
    ['fbi']        = { 
        label = 'FBI',       
        color = '#0066cc' 
    },
    ['ambulance']  = { 
        label = 'EMS',       
        color = '#FFAC60' 
    },
    ['doctor']     = { 
        label = 'DOCTOR',    
        color = '#ff8080' 
    },
    ['mechanic']   = { 
        label = 'MECHANIC',  
        color = '#FFD700' 
    },
    ['taxi']       = { 
        label = 'TAXI',      
        color = '#FFD700' 
    },
    ['judge']      = { 
        label = 'JUDGE',     
        color = '#c0a060' 
    },
    ['realestate'] = { 
        label = 'REAL ESTATE', 
        color = '#88ddaa' 
    },
    ['news']       = { 
        label = 'PRESS',     
        color = '#ff6699' 
    },
    -- Add more jobs as needed. Unemployed shows no badge.
}

-- ══════════════════════════════════════════════════════
--  GANG COLORS  (role badge for gang members)
--  name = internal gang name (lowercase)
-- ══════════════════════════════════════════════════════
Config.GangColors = {
    ['grove']      = { 
        label = 'GROVE ST',  
        color = '#00FF66' 
    },
    ['ballas']     = { 
        label = 'BALLAS',    
        color = '#9b30ff' 
    },
    ['vagos']      = { 
        label = 'VAGOS',     
        color = '#FFD700' 
    },
    ['marabunta']  = { 
        label = 'MARABUNTA', 
        color = '#00aaff' 
    },
    ['lost']       = { 
        label = 'LOST MC',   
        color = '#ff4422' 
    },
    ['kkk']        = { 
        label = 'GANG',      
        color = '#cccccc' 
    },
    -- Add more gangs as needed.
}

-- ══════════════════════════════════════════════════════
--  SHOW ROLE IN CHAT FOR THESE COMMANDS
-- ══════════════════════════════════════════════════════
Config.ShowRoleInChat = {
    me      = true, 
    do_     = true,
    ooc     = true,
    police  = false,   -- already implied by channel
    ems     = false,
}

-- ══════════════════════════════════════════════════════
--  SEND SOUND
--  SoundFile: path relative to resource root ('' = built-in)
--  SoundType: blip | pop | soft | click
-- ══════════════════════════════════════════════════════
Config.SendSound = {
    Enabled   = true,
    SoundFile = 'sounds/send.mp3',
    SoundType = 'soft',
    Volume    = 0.4,
}

-- ══════════════════════════════════════════════════════
--  HEAD BUBBLE  (speech bubble above player's head)
--  Style: modern | dark | hud | neon
--  Uses Config.ChatRadius (me / do_) to decide who can see it.
-- ══════════════════════════════════════════════════════
Config.HeadBubble = {
    Enabled     = true,
    ShowOnMe    = true,
    ShowOnDo    = true,    -- /do now also shows a bubble above the player's head
    MaxDistance = 12.0,    -- max render distance on screen (visual cutoff)
    Duration    = 6000,
    Style       = 'comic',
}

-- ══════════════════════════════════════════════════════
--  SERVER BRANDING  — shown in system/welcome chat messages
-- ══════════════════════════════════════════════════════
Config.ServerBranding = {
    Enabled              = true,
    Name                 = 'Your Server Name', -- change to your server's name
    ShowInSystemMessages = true, -- prefixes system/welcome/announcement headers with the name above
}

-- ══════════════════════════════════════════════════════
--  PLAYER SETTINGS CONTROL
--  Turn any of these OFF to hide/lock that customization
--  option from players in the in-chat Settings panel.
-- ══════════════════════════════════════════════════════
Config.PlayerSettings = {
    AllowPosition         = true, -- let players move the chat box (8 positions)
    AllowSize             = true, -- let players pick sm/md/lg presets
    AllowTextSize         = true, -- let players scale message text size
    AllowColors           = true, -- let players customize border/bg/input colors
    AllowStyle            = true, -- let players change the chat style skin
    AllowBubbleStyle      = true, -- let players change the /me //do head bubble style
    AllowSuggestionPicker = true, -- let players choose their own quick-suggestion commands
    AllowSound            = true, -- let players toggle the send sound
    AllowNotifications    = true, -- let players toggle chat auto-hide notifications
    AllowSettingsButton   = true, -- set false to hide the settings gear from players entirely
}

-- ══════════════════════════════════════════════════════
--  DEFAULT SUGGESTIONS
-- ══════════════════════════════════════════════════════
Config.DefaultSuggestions = {
    { 
        command = 'me',           
        color = '#FF69BA' 
    },
    { 
        command = 'do',           
        color = '#00C2FF' 
    },
    { 
        command = 'ooc',          
        color = '#5484FF' 
    },
    { 
        command = 'tweet',        
        color = '#5484FF' 
    },
    { 
        command = 'whisper',      
        color = '#4C6085' 
    },
    { 
        command = 'yellowpages',  
        color = '#FFC700' 
    },
    { 
        command = 'police',       
        color = '#00C2FF' 
    },
    { 
        command = 'ems',          
        color = '#FFAC60' 
    },
    { 
        command = 'mechanic',     
        color = '#FFD700' 
    },
    { 
        command = 'id',           
        color = '#00FF66' 
    },
    { 
        command = 'charinfo',     
        color = '#875CFF' 
    },
    { 
        command = 'showidentity', 
        color = '#875CFF' 
    },
    { 
        command = 'announce',     
        color = '#e69332' 
    },
    { 
        command = 'adminwhisper', 
        color = '#4C6085' 
    },
}

Config.TypeColors = {
    ['me']           = { 
        color = '#FF69BA', 
        bg = '#664160'  
    },
    ['do']           = { 
        color = '#00C2FF', 
        bg = '#3E768D'  
    },
    ['ooc']          = { 
        color = '#5484FF', 
        bg = '#323F61'  
    },
    ['admin']        = { 
        color = '#FF3E3E', 
        bg = '#472424'  
    },
    ['charinfo']     = { 
        color = '#875CFF', 
        bg = '#261F3A'  
    },
    ['ems']          = { 
        color = '#FFAC60', 
        bg = '#363120'  
    },
    ['police']       = { 
        color = '#00C2FF', 
        bg = '#3E768D'  
    },
    ['mechanic']     = { 
        color = '#FFD700', 
        bg = '#3a3200'  
    },
    ['error']        = { 
        color = '#FF3E3E', 
        bg = '#472424'  
    },
    ['whisper']      = { 
        color = '#4C6085', 
        bg = '#212834'  
    },
    ['tweet']        = { 
        color = '#5484FF', 
        bg = '#323F61'  
    },
    ['yellow_pages'] = { 
        color = '#FFC700', 
        bg = '#363120'  
    },
    ['gang']         = { 
        color = '#00FF66', 
        bg = '#233C2D'  
    },
    ['announcement'] = { 
        color = '#e69332', 
        bg = '#363120'  
    },
    ['system']       = { 
        color = '#ffffff', 
        bg = '#1e1e1e'  
    },
    ['local']        = { 
        color = '#888888', 
        bg = '#1a1a1a'  
    },
    ['welcome']      = { 
        color = '#00ff88', 
        bg = '#062018'  
    },
}

Config.Broadcasts = {
    enabled  = true, -- set to false to disable all broadcasts
    interval = 600, -- seconds between each message (random order if random=true)
    random   = true, -- set to true to show messages in random order instead of sequential
    messages = {
        { 
            header = 'Lotus City', -- message header/title
            text = 'Welcome! discord.gg/lotuscitylk', -- message body (supports basic HTML tags like <b> and <i>)                           
            color = '#ffffff', -- text color (hex or rgb)
            bg = '#1e1e1e' -- background color (hex or rgb)
        },
        { 
            header = 'DISCORD',    
            text = 'Join: discord.gg/lotuscitylk — Support & events!',      
            color = '#5484FF', 
            bg = '#101828' 
        },
        { 
            header = 'RULES',      
            text = '1. No RDM/VDM  2. No meta  3. Stay IC  4. Respect', 
            color = '#e69332', 
            bg = '#1a1008' 
        },
        { 
            header = 'COMMANDS',   
            text = '/me actions • /do descriptions • /whisper [ID]',      
            color = '#00C2FF', 
            bg = '#061418' 
        },
        { 
            header = 'STORE',      
            text = 'Custom cars, clothing & VIP at yourserver.tebex.io', 
            color = '#00FF66', 
            bg = '#061209' 
        },
    }
}

Config.ImagePreview = {
    enabled = true, -- set to false to disable image preview in chat
    maxHeight = 140, -- max height in pixels for previewed images (width auto-scales to maintain aspect ratio)
    allowAnyHttps = true, -- if true, allows previewing images from any HTTPS URL (if false, only allows URLs from trustedHosts list)
    trustedHosts={
        'i.imgur.com','imgur.com',
        'cdn.discordapp.com','media.discordapp.net',
        'i.redd.it','preview.redd.it',
        'i.gyazo.com','i.ibb.co',
        'pbs.twimg.com','steamuserimages-a.akamaihd.net',
        'prntscr.com','prnt.sc',
        'cdn.cloudflare.steamstatic.com','media.tenor.com'
    },
}

Config.Webhook = {
    enabled = false, -- set to true to enable webhook logging
    all = '', -- webhook URL for logging all messages (optional, can be empty string if you only want to log specific channels)
     -- individual channel webhooks (set to empty string '' to disable logging for that channel)
    ooc = '', 
    me = '', 
    do_ = '',
    police = '', 
    ems = '', 
    mechanic = '', 
    gang = '',
    tweet = '', 
    whisper = '', 
    yellowpages = '', 
    announce = '',
}

```

{% endcode %}
