Agency Docs
QBESXStandalone

Agency-Phone Configuración

Ahora con AgencyOS27: una actualización gratuita para todos los que ya tienen el teléfono.

v27.1.2De pago8 Páginas

01Configuración

Instalación rápida · config.lua · Agency-Phone

Descargar config.lua

--[[ ╔══════════════════════════════════════════════════════════════════════╗ ║ AGENCY PHONE - CONFIGURATION ║ ║ (c) Agency Scripts ║ ╚══════════════════════════════════════════════════════════════════════╝ CONTENTS 1. Core Framework, banking, language, data, debug 2. Controls Phone item, keys, commands 3. Phone Prop The model held in the hand during a call 4. Integrations Agency HUD, Notify, Reports, LifeInvader, Companion 5. Calls & Voice Calls, dialer, voice, walkie-talkie, payphones, video 6. Emergency MDT and dispatch 7. Network eSIM carrier plans and billing 8. Security Face Unlock, lock screen 9. Camera & Media Media storage, camera, video, screen capture, cloud 10. Communication Buzz, contacts, mail, Pulse, Bleeter, Snapr 11. Music & Radio Music library, review, GTA radio 12. Finance Wallet, Agency Pay, crypto, stocks, gambling 13. Darknet Market, levels, items, dead drops 14. Vehicles & Rides Garage, AutoRide 15. Jobs & Services Job apps, job listings, Agency Eats, maps 16. Angy Built-in assistant (fixed rules, no AI) 17. Logging Discord webhooks (addresses in config_server.lua) 18. Apps App Store, protected apps, app list Keys, tokens and webhook addresses go into config_server.lua, which is never sent to players. ]] AgencyConfig = {} --============================================================================== -- 1 · CORE --============================================================================== -- ── Framework ──────────────────────────────────────────────────────────────── -- 'auto' = detect QBCore or ESX -- 'qb' / 'esx' = force a framework -- 'standalone' = no framework -- 'oxide-banking' = alias for QBCore + Oxide banking AgencyConfig.Framework = 'qb' -- Only used in standalone mode. AgencyConfig.Standalone = { DefaultBankBalance = 5000, -- bank balance of a new player } -- ── Banking ────────────────────────────────────────────────────────────────── AgencyConfig.Banking = 'framework' -- 'framework' | 'oxide-banking' (QBCore only) AgencyConfig.InvoiceProvider = 'auto' -- 'auto' | 'okokBilling' | 'builtin' -- ── Language & data ────────────────────────────────────────────────────────── AgencyConfig.DefaultLanguage = 'en' -- 'en' | 'de' | 'fr' | 'es' | 'tr' | 'pl' AgencyConfig.DataStorageMode = 'phone' -- 'phone' = data per phone number, 'person' = per character AgencyConfig.AutoApplySqlSchema = true -- create the tables from agency-phone.sql on start AgencyConfig.PerformanceModeDefault = false -- performance mode for new players -- ── Debug ──────────────────────────────────────────────────────────────────── -- Prints diagnostics to the server console (NUI state, open-phone checks, -- keybinds, radio textures). Meant for support cases, keep false when live. AgencyConfig.Debug = false --============================================================================== -- 2 · CONTROLS --============================================================================== -- Keys use FiveM key names: 'M', 'F1', 'UP', 'OEM_4' ... -- https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/ -- These are the starting keys; players can rebind them under -- Settings > Key Bindings > FiveM. Changing one here resets it for everyone. -- false = no key (the command still works). -- Note: qb-radialmenu also uses F1. The console reports such clashes. AgencyConfig.PhoneItem = 'phone' -- item the player needs in the inventory AgencyConfig.OpenKey = 'M' -- opens the phone AgencyConfig.OpenCommand = 'phone' -- chat command that opens the phone (without /) AgencyConfig.AnswerKey = 'Y' -- answers a call AgencyConfig.DeclineKey = 'J' -- declines or ends a call AgencyConfig.AngyKey = 'P' -- opens Angy directly AgencyConfig.AllowMovement = true -- walk while the phone is open --============================================================================== -- 3 · PHONE PROP --============================================================================== -- The model the character holds during a call. -- model : default prop (streamed by agency-phone itself, stream/) -- fallback : used if the model is missing, keep this a vanilla prop -- bone : ped bone, 28422 = right hand -- pos/rot : fine-tune the position in the hand -- models : one prop per frame finish (Settings > Appearance) -- Custom models: the resource streaming them must start BEFORE agency-phone, -- and only use models you are licensed to use. AgencyConfig.PhoneProp = { model = 'agency_phone_silver', fallback = 'prop_npc_phone_02', bone = 28422, pos = { x = 0.0, y = 0.0, z = 0.0 }, rot = { x = 0.0, y = 0.0, z = 0.0 }, models = { silver = 'agency_phone_silver', graphite = 'agency_phone_graphite', starlight = 'agency_phone_starlight', blue = 'agency_phone_blue', desert = 'agency_phone_desert', green = 'agency_phone_green', pink = 'agency_phone_pink', violet = 'agency_phone_violet', }, } --============================================================================== -- 4 · INTEGRATIONS --============================================================================== -- ── Agency HUD ─────────────────────────────────────────────────────────────── AgencyConfig.UseAgencyHUD = true -- enable the Agency-HUD hooks AgencyConfig.SyncAgencyHUD = true -- share the phone open/close state with Agency-HUD -- ── Notifications ──────────────────────────────────────────────────────────── -- Agency-Notify (free): https://agency-script.tebex.io/package/6937769 AgencyConfig.UseAgencyNotify = true AgencyConfig.NotifyDuration = 5000 -- ms -- ── Agency Reports (Reports app) ───────────────────────────────────────────── -- Agency Reports (free): https://agency-script.tebex.io/package/6959744 AgencyConfig.UseAgencyReports = true AgencyConfig.AgencyReportsProvider = 'v2' -- 'v2' | 'v2_ad_free' | 'legacy' | 'auto' AgencyConfig.AgencyReportsCommand = 'areport' -- ── Agency LifeInvader V2 ──────────────────────────────────────────────────── -- true = the Life Invader app opens Agency-LifeInvaderV2 instead of the built-in app. AgencyConfig.EnableLifeInvaderV2Integration = false -- ── Companion App (Settings > Companion App) ───────────────────────────────── -- Pair the phone with the Agency Phone iOS app via QR code. No setup needed: -- the server connects outbound to the Agency relay (no port forwarding). AgencyConfig.Companion = { Enable = true, -- show the Companion page and allow pairing EnableRemote = true, -- paired devices may use the phone remotely RelayUrl = 'https://api.agencyg.de', -- do not change unless instructed TokenTTL = 300, -- seconds a pairing QR code stays valid -- Only for servers on the same network as the relay. Leave empty. RelayInternalUrl = '', } --============================================================================== -- 5 · CALLS & VOICE --============================================================================== -- ── Calls ──────────────────────────────────────────────────────────────────── AgencyConfig.CallTimeout = 30 -- seconds until an unanswered call ends AgencyConfig.CallRingInterval = 4000 -- ms between two rings AgencyConfig.CallMaxRings = 10 -- ── Dialer ─────────────────────────────────────────────────────────────────── AgencyConfig.EnableDeathEmergency = true -- show the emergency overlay when the player dies AgencyConfig.DialerEmergencyNumber = '911' AgencyConfig.DialerTestNumber = '511' -- always-answered test line ('' = off) AgencyConfig.DialerShowRecents = true AgencyConfig.DialerMaxRecents = 20 -- ── Voice system ───────────────────────────────────────────────────────────── -- 'auto' (recommended) | 'pma-voice' | 'saltychat' | 'mumble-voip' | 'tokovoip' AgencyConfig.VoiceSystem = 'auto' -- ── Walkie-talkie (Radio app) ──────────────────────────────────────────────── -- Channels only some jobs may join. -- 'auto' = take them from qb-radio / ps-radio (RestrictedChannels, MaxFrequency) -- table = set them here, e.g. { [1] = { police = true, ambulance = true } } -- false = no locks AgencyConfig.RadioChannelLocks = 'auto' AgencyConfig.RadioLockDecimals = true -- a lock on 1 also covers 1.1 - 1.9 -- ── Payphones ──────────────────────────────────────────────────────────────── -- Street phone boxes: dial any number without a phone or carrier contract. -- The person called sees the booth, not the caller. AgencyConfig.Payphones = { Enabled = true, -- false removes the payphones completely Price = 5, -- charged when the call is answered (0 = free) EmergencyCalls = true, -- dispatch numbers are free and alert police/EMS with the location Account = 'cash', -- 'cash' | 'bank' Currency = '$', -- shown on the keypad MaxCallSeconds = 300, -- the line drops after this (0 = no limit) CallerName = 'Payphone', -- name the person called sees ShowBoothNumber = true, -- false = "Hidden Number" NumberPrefix = '0800', -- booth number = prefix + 4 digits from its position Interaction = 'auto', -- 'auto' = ox_target > qb-target > key | 'key' = always the key Label = 'Use payphone', -- target option / key prompt Key = 38, -- control for keypad and hang up (38 = E) KeyLabel = 'E', -- key shown on the call card Distance = 1.6, -- how close you must stand WalkAwayDistance = 3.0, -- the call ends beyond this distance Models = { -- every phone box model on the map 'prop_phonebox_01a', 'prop_phonebox_01b', 'prop_phonebox_01c', 'prop_phonebox_02', 'prop_phonebox_03', 'prop_phonebox_04', 'p_phonebox_01b_s', 'p_phonebox_02_s', 'sf_prop_sf_phonebox_01b_s', 'sf_prop_sf_phonebox_01b_straight', }, } -- ── Video calls & live streams (FaceZoom, Pictogram Live) ──────────────────── -- Runs over Cloudflare TURN. The API token stays on the server. -- Sign up: https://dash.cloudflare.com/sign-up/realtime/turn -- Create app: https://dash.cloudflare.com/?to=/:account/realtime/turn AgencyConfig.StreamTransport = 'cloudflare-turn' AgencyConfig.CloudflareTurnEnabled = true -- Name, Token ID and API token of your TURN app: config_server.lua (Keys). AgencyConfig.CloudflareTurnApiUrl = 'https://rtc.live.cloudflare.com/v1/turn/keys/%s/credentials/generate-ice-servers' AgencyConfig.CloudflareTurnCredentialTTL = 43200 -- seconds --============================================================================== -- 6 · EMERGENCY --============================================================================== AgencyConfig.EnableMDT = true -- false disables the MDT for police and EMS -- ── Dispatch ───────────────────────────────────────────────────────────────── -- Where emergency calls and messages go: -- 'internal' (built-in) | 'cd_dispatch' | 'ps-dispatch' | 'qs-dispatch' -- 'core_dispatch' | 'custom' (fires agency-phone:dispatch:custom) AgencyConfig.DispatchSystem = 'internal' AgencyConfig.DispatchCodes = { ['911'] = { type = 'emergency', priority = 'high', label = 'Emergency Call', departments = {'police', 'ems'} }, ['110'] = { type = 'police', priority = 'high', label = 'Police Emergency', departments = {'police'} }, ['112'] = { type = 'ems', priority = 'high', label = 'Medical Emergency', departments = {'ems'} }, } AgencyConfig.DispatchTimeout = 300 -- seconds a dispatch stays active (0 = until cleared) AgencyConfig.DispatchSaveHistory = true -- keep the history in the database --============================================================================== -- 7 · NETWORK (eSIM carriers) --============================================================================== -- Without a paid plan the phone has no signal: no calls, messages or downloads. AgencyConfig.CarrierBilling = { Enabled = true, -- false = the plan is paid once, never again IntervalMinutes = 1440, -- real minutes between two charges (1440 = daily) BankReason = 'phone-carrier', -- text on the bank statement } -- speed : 1-5, affects downloads, message delay, mail and posting -- calls : 'unlimited' or calls per restart -- messages : 'unlimited' or messages per restart -- price : charged from the bank when taken, then every billing interval AgencyConfig.CarrierPlans = { { id = 'fleeca_mobile', name = 'Fleeca Mobile', icon = 'fa-solid fa-signal', color = '#34c759', speed = 2, calls = 50, messages = 100, price = 30, }, { id = 'maze_telecom', name = 'Maze Telecom', icon = 'fa-solid fa-tower-cell', color = '#007aff', speed = 3, calls = 'unlimited', messages = 200, price = 50, }, { id = 'lifeinvader_net', name = 'LifeInvader Net', icon = 'fa-solid fa-wifi', color = '#5856d6', speed = 4, calls = 'unlimited', messages = 'unlimited', price = 80, }, { id = 'lossantos_5g', name = 'LS 5G Ultra', icon = 'fa-solid fa-bolt', color = '#ff9500', speed = 5, calls = 'unlimited', messages = 'unlimited', price = 120, }, } --============================================================================== -- 8 · SECURITY --============================================================================== AgencyConfig.FaceIdDefault = false -- Face Unlock on for new players AgencyConfig.FaceIdAnimDuration = 2600 -- ms AgencyConfig.LockScreenEnabled = true --============================================================================== -- 9 · CAMERA & MEDIA --============================================================================== -- ── Media storage ──────────────────────────────────────────────────────────── -- Where photos, clips, screen captures and voice messages are stored. -- 'local' = on your own server, inside your database (oxmysql). -- Works right after install: no account, no API key. (default) -- 'cloudflare' = Cloudflare R2, free up to 10 GB. Faster for big servers. -- Put your keys in config_server.lua (never in this file, -- config.lua is sent to every player). -- Step by step guide: https://docs.agencyg.de/phone/media-storage AgencyConfig.MediaStorage = { Provider = 'local', -- 'local' or 'cloudflare' MaxFileMegabytes = 10, -- largest single file (clips, recordings) TransferKilobytesPerSecond = 1000, -- 'local': how fast files are sent to players, -- shared politely with the game connection. -- Uploads from players are capped by FiveM itself -- (about 165 KB/s): a photo takes ~1 s, a 15 s clip ~20 s. Local = { RetentionDays = 30, -- delete files older than this (0 = keep forever) MaxStorageGigabytes = 10, -- delete the oldest files above this (0 = no limit) }, } -- ── Camera & gallery ───────────────────────────────────────────────────────── AgencyConfig.CameraMaxPhotos = 50 -- photos in the camera roll AgencyConfig.CameraQuality = 0.85 -- JPEG quality (0-1) AgencyConfig.GalleryMaxPhotos = 50 -- photos per player AgencyConfig.GalleryColumnsCount = 3 -- grid columns (2, 3 or 4) -- ── Camera video (clips) ───────────────────────────────────────────────────── -- Short clips through the viewfinder, stored in the gallery. AgencyConfig.CameraVideo = { Enabled = true, -- false hides the VIDEO mode MaxDurationSeconds = 15, -- hard stop per clip (3-60) Fps = 60, Width = 480, -- px, the height follows the viewfinder BitrateKbps = 2000, -- higher = sharper, bigger upload MaxVideos = 20, -- clips per player (separate from photos) CooldownSeconds = 3, -- spam guard between two clips PoseClip = '', -- pose while filming ('' = first one the game ships) MaxUploadMegabytes = 6, -- bigger clips are rejected } -- ── Screen capture (Control Centre) ────────────────────────────────────────── -- Screenshots and recordings of the phone screen, saved to the gallery. -- Recordings count against CameraVideo.MaxVideos. AgencyConfig.ScreenCapture = { Enabled = true, -- false turns off both Screenshots = true, ScreenshotWidth = 1116, -- px (372-1860) Video = true, MaxDurationSeconds = 30, -- hard stop per recording (5-300) Fps = 20, -- max frame rate (5-30) Width = 540, -- px (240-1080) BitrateKbps = 1800, MaxUploadMegabytes = 10, -- also capped by MediaStorage.MaxFileMegabytes } -- ── Voice messages & Recorder ──────────────────────────────────────────────── AgencyConfig.VoiceMessages = { Enabled = true, MaxSeconds = 60, -- a voice message sends itself at this length } AgencyConfig.Recorder = { MaxSeconds = 300, -- longest recording MaxRecordings = 50, -- kept per character CloudSync = true, -- also save to AgencyCloud (player can switch it off) } -- ── AgencyCloud ────────────────────────────────────────────────────────────── -- Cloud storage for photos and documents. Personal for every player, -- Company per job. StorageTiers are the upgrades players can buy. AgencyConfig.AgencyCloud = { Enabled = true, GalleryAutoSyncDefault = false, Personal = { Label = 'Personal Cloud', BaseStorageMB = 200, BaseAssetLimit = 50, PurchaseStorageMB = 250, PurchaseAssetCount = 25, PurchasePrice = 5000, MaxStorageMB = 5000, MaxAssetLimit = 1000, GallerySavePrice = 150, DocumentSavePrice = 60, AllowGalleryAssets = true, AllowDocuments = true, StorageTiers = { { id = 'plus', label = 'Plus', storageMb = 250, assetCount = 25, price = 5000 }, { id = 'pro', label = 'Pro', storageMb = 750, assetCount = 75, price = 12000 }, { id = 'vault', label = 'Vault', storageMb = 1500, assetCount = 160, price = 22000 }, }, }, Company = { Label = 'Company Cloud', BossOnly = true, BaseStorageMB = 1000, BaseAssetLimit = 150, PurchaseStorageMB = 1000, PurchaseAssetCount = 100, PurchasePrice = 25000, MaxStorageMB = 20000, MaxAssetLimit = 5000, GallerySavePrice = 350, DocumentSavePrice = 180, AllowGalleryAssets = true, AllowDocuments = true, StorageTiers = { { id = 'team', label = 'Team', storageMb = 1000, assetCount = 100, price = 25000 }, { id = 'division', label = 'Division', storageMb = 2500, assetCount = 280, price = 52000 }, { id = 'enterprise', label = 'Enterprise', storageMb = 5000, assetCount = 650, price = 95000 }, }, }, DefaultGalleryStorageBytes = 2000000, -- size counted per photo DefaultVideoStorageBytes = 8000000, -- size counted per clip DefaultDocumentStorageBytes = 102400, -- size counted per document } --============================================================================== -- 10 · COMMUNICATION --============================================================================== -- ── Buzz (messages) ────────────────────────────────────────────────────────── AgencyConfig.BuzzMaxMessages = 50 -- messages loaded per chat AgencyConfig.BuzzAllowDelete = true AgencyConfig.BuzzShowTimestamps = true -- ── Contacts ───────────────────────────────────────────────────────────────── AgencyConfig.ContactsMaxCount = 100 -- per player AgencyConfig.ContactsAllowShare = true AgencyConfig.ContactsDefaultSort = 'name' -- 'name' | 'recent' -- ── Mail ───────────────────────────────────────────────────────────────────── AgencyConfig.PostboxLoadHours = 72 -- how far back mails are loaded AgencyConfig.PostboxMaxMails = 50 AgencyConfig.PostboxAllowDelete = true AgencyConfig.PostboxMaxAccounts = 5 -- mail addresses per player AgencyConfig.PostboxDefaultDomain = 'agencyg.de' -- players choose the part before the @ -- ── Pulse & Bleeter (social feeds) ─────────────────────────────────────────── AgencyConfig.PulseLoadHours = 12 -- how far back posts are loaded AgencyConfig.PulseMaxLength = 280 -- characters per post AgencyConfig.PulseAllowDelete = true -- delete own posts AgencyConfig.PulseRefreshInterval = 30 -- auto refresh in seconds (0 = off) AgencyConfig.BleeterMaxLength = 280 -- characters per bleet -- ── Snapr ──────────────────────────────────────────────────────────────────── AgencyConfig.Snapr = { -- How long a snap is shown; the sender picks within this range. MinDurationSeconds = 1, MaxDurationSeconds = 10, DefaultDurationSeconds = 5, KeepOpenedMinutes = 5, -- a seen snap is removed after this ExpireUnopenedHours = 48, -- an unopened snap expires after this MaxRecipients = 12, -- recipients per snap -- Text chat in a conversation. Read chats are kept ChatKeepHours. ChatEnabled = true, ChatMaxLength = 300, ChatKeepHours = 24, -- Stickers drawn into the picture: location and phone time. LocationSticker = true, TimeSticker = true, } --============================================================================== -- 11 · MUSIC & RADIO --============================================================================== -- ── Music library ──────────────────────────────────────────────────────────── -- The library starts empty. Players submit links (Submit tab), music admins -- approve them (Review tab), then everyone can play them. -- Make an admin: musicadmin <serverId> (console or ace 'command.musicadmin') -- Always admin: ace 'agency.musicadmin' -- Allowed: https links ending in .mp3 .ogg .oga .wav .m4a .aac .flac .opus AgencyConfig.MusicAutoApprove = false -- true = skip the review AgencyConfig.MusicMaxOpenSubmissions = 5 -- pending submissions per player -- Own hosts that serve audio without a file extension, e.g. { 'cdn.myserver.com' } AgencyConfig.MusicAllowedHosts = { } AgencyConfig.MusicSyncRadius = 30.0 -- meters in which others hear your music AgencyConfig.MusicMaxVolume = 0.5 -- 0.0 - 1.0 -- Also accept links to external media sites. You are responsible for the -- rights to that content on your server. AgencyConfig.MusicAllowExternalLinks = false -- ── Music review on Discord ────────────────────────────────────────────────── -- Every submission is posted to a Discord webhook. Its address is in -- config_server.lua (Keys.MusicDiscordWebhook), '' there = off. AgencyConfig.MusicDiscordMentionRoleId = '' -- role ID pinged per submission (optional) -- Public address of your server incl. port, no trailing slash, e.g. -- 'http://123.45.67.89:30120'. Adds one-time Approve / Reject links to the -- Discord post. '' = admins review in the phone (Music > Review). AgencyConfig.MusicReviewCallbackUrl ='' -- ── GTA radio (Music app > Radio tab) ──────────────────────────────────────── -- Plays the original GTA V stations; keeps playing with the phone put away. AgencyConfig.EnableRadioTab = true -- false hides the Radio tab AgencyConfig.RadioKeepStationInVehicle = true -- take the station into a vehicle AgencyConfig.RadioBlockWheelOnFoot = true -- block GTA's radio wheel on foot (vehicles stay vanilla) -- id = internal GTA station name | name, genre, color = how the tile looks. -- Reorder or remove freely. DLC stations need the DLC on the client. AgencyConfig.RadioStations = { { id = 'RADIO_01_CLASS_ROCK', name = 'Los Santos Rock Radio', genre = 'Classic Rock', color = '#e2564a' }, { id = 'RADIO_02_POP', name = 'Non-Stop-Pop FM', genre = 'Pop', color = '#ff4fa3' }, { id = 'RADIO_03_HIPHOP_NEW', name = 'Radio Los Santos', genre = 'Modern Hip Hop', color = '#f5a623' }, { id = 'RADIO_04_PUNK', name = 'Channel X', genre = 'Punk', color = '#8e8e93' }, { id = 'RADIO_05_TALK_01', name = 'West Coast Talk Radio', genre = 'Talk', color = '#4a90d9' }, { id = 'RADIO_06_COUNTRY', name = 'Rebel Radio', genre = 'Country', color = '#c08a4a' }, { id = 'RADIO_07_DANCE_01', name = 'Soulwax FM', genre = 'Electronic', color = '#7b5cff' }, { id = 'RADIO_08_MEXICAN', name = 'East Los FM', genre = 'Mexican', color = '#2fbf71' }, { id = 'RADIO_09_HIPHOP_OLD', name = 'West Coast Classics', genre = 'Classic Hip Hop', color = '#d4a017' }, { id = 'RADIO_11_TALK_02', name = 'Blaine County Radio', genre = 'Talk', color = '#6b8e5a' }, { id = 'RADIO_12_REGGAE', name = 'The Blue Ark', genre = 'Reggae / Dub', color = '#3ec46d' }, { id = 'RADIO_13_JAZZ', name = 'Worldwide FM', genre = 'Jazz / World', color = '#00b7c3' }, { id = 'RADIO_14_DANCE_02', name = 'FlyLo FM', genre = 'Experimental', color = '#a855f7' }, { id = 'RADIO_15_MOTOWN', name = 'The Lowdown 91.1', genre = 'Motown / Soul', color = '#b5651d' }, { id = 'RADIO_16_SILVERLAKE', name = 'Radio Mirror Park', genre = 'Indie / Electro', color = '#5ac8fa' }, { id = 'RADIO_17_FUNK', name = 'Space 103.2', genre = 'Funk', color = '#ff6b35' }, { id = 'RADIO_18_90S_ROCK', name = 'Vinewood Boulevard Radio', genre = 'Alternative Rock', color = '#e0457b' }, { id = 'RADIO_20_THELAB', name = 'The Lab', genre = 'Original Score', color = '#00d4ff' }, { id = 'RADIO_21_DLC_XM17', name = 'Blonded Los Santos 97.8', genre = 'R&B / Hip Hop', color = '#f0c419' }, { id = 'RADIO_22_DLC_BATTLE_MIX1_RADIO', name = 'LS Underground Radio', genre = 'House / Techno', color = '#9b59b6' }, { id = 'RADIO_23_DLC_XM19_RADIO', name = 'iFruit Radio', genre = 'Hip Hop / Grime', color = '#31c48d' }, { id = 'RADIO_27_DLC_PRHEI4', name = 'Still Slipping Los Santos', genre = 'Downtempo', color = '#ff8a5b' }, { id = 'RADIO_34_DLC_HEI4_KULT', name = 'Kult FM', genre = 'Post-Punk / New Wave',color = '#6c7a89' }, { id = 'RADIO_35_DLC_HEI4_MLR', name = 'The Music Locker', genre = 'House', color = '#e84393' }, { id = 'RADIO_37_MOTOMAMI', name = 'MOTOMAMI Los Santos', genre = 'Latin / Reggaeton', color = '#ff3b6b' }, } --============================================================================== -- 12 · FINANCE --============================================================================== -- ── Wallet ─────────────────────────────────────────────────────────────────── AgencyConfig.WalletMinTransfer = 1 AgencyConfig.WalletMaxTransfer = 1000000 AgencyConfig.WalletShowHistory = false -- transaction history (planned) AgencyConfig.WalletCurrency = '$' -- Fixed-term deposits. interest = % paid at the end of the term. AgencyConfig.WalletFixedTerms = { { id = 'fd_7', label = '7 Days', days = 7, interest = 2.0 }, { id = 'fd_14', label = '14 Days', days = 14, interest = 3.0 }, { id = 'fd_30', label = '30 Days', days = 30, interest = 5.0 }, } -- ── Agency Pay terminals ───────────────────────────────────────────────────── -- Payment points in the world, paid with the Wallet. -- coords : x, y, z, w (heading, optional) -- amount : price charged from the bank -- reward : item handed out after a successful payment (optional) AgencyConfig.AgencyPayTerminals = { { id = 'agency_water_terminal_1', coords = { x = 27.5543, y = -1343.0767, z = 29.4970, w = 0.6853 }, radius = 2.6, merchant = 'Agency Water Terminal', title = 'Agency Pay', subtitle = 'Tap to buy a bottle of water', label = 'Water Bottle', amount = 1.00, currency = '$', icon = 'fa-solid fa-bottle-water', accent = '#5ac8fa', manualConfirm = true, autoStart = false, showMarker = true, markerDistance = 18.0, textDistance = 6.0, markerType = 1, markerScale = 0.34, markerColor = { r = 90, g = 200, b = 250, a = 185 }, markerBob = true, showBlip = false, metadata = { terminalId = 'agency_water_terminal_1', rewardLabel = 'Water', }, reward = { item = 'water', amount = 1, }, serverEvent = 'agency-phone:server:handleAgencyPayTerminalPurchase', }, } -- ── Crypto ─────────────────────────────────────────────────────────────────── -- basePrice : starting price in $ -- volatility : typical move per hour (0.05 = about 5 %) -- realCrypto : real coin it is modelled on (display only) AgencyConfig.CryptoMarkets = { { id = 'digicoin', name = 'DigiCoin', symbol = 'DGC', icon = '₿', color = '#f7931a', basePrice = 45000, volatility = 0.05, realCrypto = 'Bitcoin' }, { id = 'etherchain', name = 'EtherChain', symbol = 'ETC', icon = '⟠', color = '#627eea', basePrice = 2800, volatility = 0.08, realCrypto = 'Ethereum' }, { id = 'litemark', name = 'LiteMark', symbol = 'LTM', icon = 'Ł', color = '#345d9d', basePrice = 150, volatility = 0.12, realCrypto = 'Litecoin' }, { id = 'ripplenet', name = 'RippleNet', symbol = 'RPN', icon = '✕', color = '#00aae4', basePrice = 0.85, volatility = 0.15, realCrypto = 'XRP' }, { id = 'cardania', name = 'Cardania', symbol = 'CDA', icon = '₳', color = '#0033ad', basePrice = 1.25, volatility = 0.13, realCrypto = 'Cardano' } } AgencyConfig.CryptoUpdateInterval = 10000 -- ms between price updates (also used for stocks) AgencyConfig.CryptoTradeAmount = 0.1 -- default amount per trade -- ── Stocks ─────────────────────────────────────────────────────────────────── -- Same fields as crypto; icon is a Font Awesome class. All prices and trades -- run on the server. Do not rename an id, players would lose their holdings. AgencyConfig.StockMarkets = { { id = 'lifeinvader', name = 'LifeInvader', symbol = 'LFI', color = '#5ac8fa', icon = 'fa-solid fa-share-nodes', basePrice = 125, volatility = 0.08 }, { id = 'redwood', name = 'Redwood Cigarettes', symbol = 'RWC', color = '#ff3b30', icon = 'fa-solid fa-smoking', basePrice = 85, volatility = 0.12 }, { id = 'burger', name = 'Burger Shot', symbol = 'BRG', color = '#ff9500', icon = 'fa-solid fa-burger', basePrice = 45, volatility = 0.15 }, { id = 'ecola', name = 'eCola', symbol = 'ECL', color = '#34c759', icon = 'fa-solid fa-bottle-water', basePrice = 65, volatility = 0.10 }, { id = 'mazebank', name = 'Maze Bank', symbol = 'MZB', color = '#007aff', icon = 'fa-solid fa-building-columns', basePrice = 180, volatility = 0.06 }, { id = 'ammu', name = 'Ammu-Nation', symbol = 'AMU', color = '#5856d6', icon = 'fa-solid fa-crosshairs', basePrice = 95, volatility = 0.14 }, { id = 'cluckin', name = 'Cluckin Bell', symbol = 'CLK', color = '#ffcc00', icon = 'fa-solid fa-drumstick-bite', basePrice = 52, volatility = 0.11 }, { id = 'postopto', name = 'Post OP', symbol = 'POP', color = '#af52de', icon = 'fa-solid fa-truck', basePrice = 38, volatility = 0.16 }, { id = 'gruppe6', name = 'Gruppe Sechs', symbol = 'GRP', color = '#00c7be', icon = 'fa-solid fa-shield-halved', basePrice = 142, volatility = 0.07 }, { id = 'vangelico', name = 'Vangelico', symbol = 'VGL', color = '#ffd60a', icon = 'fa-solid fa-gem', basePrice = 210, volatility = 0.09 }, { id = 'flyus', name = 'FlyUS', symbol = 'FLY', color = '#64d2ff', icon = 'fa-solid fa-plane', basePrice = 72, volatility = 0.11 }, { id = 'marketcore', name = 'Agency Market Core ETF', symbol = 'AMC', color = '#8e8e93', icon = 'fa-solid fa-chart-pie', basePrice = 100, volatility = 0.035, etf = true }, { id = 'stabilityplus', name = 'Stability Plus ETF', symbol = 'SPL', color = '#30d158', icon = 'fa-solid fa-scale-balanced', basePrice = 100, volatility = 0.025, etf = true }, } -- Trading hours in game time (crypto trades around the clock). false = always open. AgencyConfig.StockMarketHours = { open = 9, close = 17 } -- ── Gambling apps ──────────────────────────────────────────────────────────── AgencyConfig.EnableMoneyGames = true -- master switch, false hides all four games -- Single games. false removes the game from phone and store; the server -- refuses its bets. AgencyConfig.MoneyGameApps = { dice = true, coinflip = true, slots = true, roulette = true, } -- Highest win as a multiple of the stake, enforced on the server. AgencyConfig.MoneyGameMaxMultiplier = { dice = 5, -- 5x on a 12 coinflip = 2, slots = 12, -- 12x on three diamonds roulette = 36, -- 36x on green } --============================================================================== -- 13 · DARKNET --============================================================================== -- A market paid in crypto. Players order, wait while the package is prepared, -- then collect it at a dead drop only they know. Prices are in $ and paid at -- the live coin price. Items your inventory does not know are skipped. -- -- UseBlackmarket: 'auto' = use Agency-Blackmarket's market when it runs, -- false = always the items below. AgencyConfig.Darknet = { Enabled = true, UseBlackmarket = 'auto', Coin = 'digicoin', -- crypto id from AgencyConfig.CryptoMarkets Prep = { 4, 9 }, -- minutes until the package is ready (min, max) Expire = 45, -- minutes a drop waits before it goes cold Refund = 50, -- % of the coins refunded when it does MaxPieces = 5, -- pieces per order AlertChance = 25, -- % chance of an anonymous police tip on pickup AlertJobs = { 'police' }, PickupPrompt = 'Take the package', RepPerPickup = { per = 500, min = 2 }, -- 1 point per $500 ordered, at least 2 -- rep: reputation needed | discount: % off | orders: open orders at once Levels = { { name = 'Ghost', rep = 0, discount = 0, orders = 1 }, { name = 'Runner', rep = 40, discount = 3, orders = 1 }, { name = 'Broker', rep = 120, discount = 6, orders = 2 }, { name = 'Insider', rep = 280, discount = 10, orders = 2 }, { name = 'Phantom', rep = 500, discount = 15, orders = 3 }, }, -- category : tools | tech | gear (others are shown as written) -- stock : pieces available | restock: minutes per piece back -- level : level needed | amount : pieces handed over per piece ordered Items = { { id = 'lockpick', item = 'advancedlockpick', label = 'Advanced Lockpick', desc = 'Opens what the cheap ones cannot.', category = 'tools', price = 400, stock = 12, restock = 20, level = 1 }, { id = 'screwdriver', item = 'screwdriverset', label = 'Screwdriver Set', desc = 'Quiet tools for loud problems.', category = 'tools', price = 250, stock = 10, restock = 15, level = 1 }, { id = 'radio', item = 'radio', label = 'Encrypted Radio', desc = 'Frequency hopping. No serial number.', category = 'tech', price = 800, stock = 6, restock = 30, level = 1 }, { id = 'electronickit', item = 'electronickit', label = 'Electronic Kit', desc = 'For locks that think.', category = 'tech', price = 1200, stock = 6, restock = 30, level = 2 }, { id = 'armor', item = 'armor', label = 'Kevlar Vest', desc = 'Level III. Serial numbers filed off.', category = 'gear', price = 1500, stock = 5, restock = 40, level = 2 }, { id = 'trojan', item = 'trojan_usb', label = 'Trojan USB', desc = 'Plug it in, walk away.', category = 'tech', price = 2500, stock = 4, restock = 45, level = 3 }, { id = 'drill', item = 'drill', label = 'Heavy Drill', desc = 'Gets through the door, not quietly.', category = 'tools', price = 3500, stock = 3, restock = 60, level = 3 }, { id = 'thermite', item = 'thermite', label = 'Thermite', desc = 'Handle with gloves.', category = 'tools', price = 5000, stock = 3, restock = 60, level = 4 }, { id = 'laptop', item = 'laptop', label = 'Hacking Laptop', desc = 'Pre-loaded. Never online twice.', category = 'tech', price = 7500, stock = 2, restock = 90, level = 5 }, }, Drops = {}, -- dead drops; empty = DarknetPickupLocations below } -- Dead drop locations. One is picked at random per order and marked on the GPS. AgencyConfig.DarknetPickupLocations = { { x = 126.42, y = -1282.71, z = 29.27, label = 'Strawberry Alley' }, { x = -587.53, y = -1064.37, z = 22.34, label = 'La Mesa Backstreet' }, { x = 373.24, y = -826.52, z = 29.30, label = 'Mission Row Dumpster' }, { x = -1205.42, y = -906.28, z = 12.33, label = 'Vespucci Canal' }, { x = 1137.86, y = -982.34, z = 46.42, label = 'Murrieta Heights' }, { x = -46.83, y = -1758.64, z = 29.42, label = 'Davis Industrial' }, } --============================================================================== -- 14 · VEHICLES & RIDES --============================================================================== -- ── Garage ─────────────────────────────────────────────────────────────────── -- 'auto' tries: okokGarage, cd_garage, md-garage, qb-garages, qbx_garages, -- jg-advancedgarages, qs-advancedgarages, renewed-garage, loaf_garage, -- then the database. Or set one of those names to force it. AgencyConfig.GarageSystem = 'auto' AgencyConfig.GarageSpawnCost = 200 -- $ per vehicle request AgencyConfig.GarageMaxSpawned = 3 -- vehicles out at once per player AgencyConfig.GarageCooldown = 120 -- seconds between requests (0 = off) -- ── AutoRide (driverless pickup) ───────────────────────────────────────────── AgencyConfig.EnableAutoRideApp = true -- AutoRide app available AgencyConfig.EnableAutoRideViaAngy = true -- Angy can order a ride (independent of the app) AgencyConfig.AutoRideVehicleModel = 'stretch' -- default model -- Vehicles to choose from, in this order; the first one is preselected. -- image is optional (path relative to html/), otherwise a class icon is shown. AgencyConfig.AutoRideVehicleOptions = { { model = 'zero', label = 'Agency Zero', image = 'img/ar_zero.png' }, { model = 'stretch', label = 'Agency Limo', image = 'img/ar_stretch.svg' }, { model = 'neon', label = 'Agency E-Sport 4S', image = 'img/ar_neon.svg' }, { model = 'raiden', label = 'Agency Executive EV', image = 'img/ar_raiden.svg' }, } -- Models without a steering wheel: board the front first, doors open by themselves. AgencyConfig.AutoRideFrontEntryModels = { 'zero' } AgencyConfig.AutoRideCruiseSpeed = 22.0 -- speed during the ride AgencyConfig.AutoRidePickupSpeed = 34.0 -- speed while coming to the player AgencyConfig.AutoRideArrivalRadius = 18.0 AgencyConfig.AutoRideDropoffRadius = 22.0 AgencyConfig.AutoRideBoardingRadius = 12.0 -- distance to press E and get in AgencyConfig.AutoRideUseInvisibleDriver = true AgencyConfig.AutoRideIgnoreTrafficToPickup = true -- ignore traffic rules on the way to the player AgencyConfig.AutoRideBaseFare = 500 -- $ charged when ordering AgencyConfig.AutoRideCostPerKm = 100 -- $ per started kilometer --============================================================================== -- 15 · JOBS & SERVICES --============================================================================== -- ── Job apps ───────────────────────────────────────────────────────────────── -- Which framework jobs can see and download each job app. AgencyConfig.JobApps = { police = { appId = 'police_mdt', jobNames = {'police', 'pd', 'lspd', 'bcso', 'sheriff'}, }, ems = { appId = 'ems_mdt', jobNames = {'ambulance', 'ems', 'doctor', 'medic', 'fire'}, }, mechanic = { appId = 'mechanic_app', jobNames = {'mechanic', 'bennys', 'lscustoms', 'tuner'}, }, } -- ── Jobs app listings ──────────────────────────────────────────────────────── -- Offers in the Jobs app. x / y = map position, phone = contact number. AgencyConfig.EmploymentListings = { { id = 'ls-logistics', title = 'Delivery Driver', company = 'Los Santos Logistics', location = 'Mission Row, Los Santos', salary = '$3,200 / week', type = 'Full-Time', description = 'Deliver packages across the city with route bonuses and clean-driver rewards.', color = '#34c759', x = 121.4, y = -3031.9, phone = '310-555-0181', }, { id = 'dockyard-security', title = 'Night Security', company = 'Port Security Group', location = 'Elysian Island', salary = '$2,850 / week', type = 'Shift', description = 'Patrol restricted zones, report incidents, and coordinate with dispatch.', color = '#5ac8fa', x = -225.1, y = -2684.3, phone = '310-555-0172', }, { id = 'vinewood-cafe', title = 'Barista', company = 'Bean Machine', location = 'Vinewood', salary = '$2,100 / week', type = 'Part-Time', description = 'Prepare drinks, handle front desk orders, and keep service flowing during rush hours.', color = '#ff9f0a', x = -634.9, y = 236.1, phone = '310-555-0122', }, { id = 'city-maintenance', title = 'Street Maintenance', company = 'City Works', location = 'La Mesa', salary = '$3,000 / week', type = 'Contract', description = 'Repair public infrastructure and assist with emergency city maintenance tasks.', color = '#af52de', x = 727.7, y = -1079.7, phone = '310-555-0196', }, } -- ── Agency Eats (delivery job) ─────────────────────────────────────────────── -- Restaurants where drivers pick up orders. AgencyConfig.EatsRestaurants = { { name = 'Burger Shot', x = -1196.42, y = -891.35, z = 14.0 }, { name = "Cluckin' Bell", x = -72.68, y = 6253.11, z = 31.09 }, { name = 'Pizza This', x = 540.66, y = 101.25, z = 96.44 }, { name = 'Bean Machine', x = -628.16, y = 236.60, z = 81.97 }, { name = 'Up-n-Atom', x = 89.95, y = 289.42, z = 110.21 }, { name = 'Taco Bomb', x = 12.04, y = -1605.57, z = 29.37 }, } AgencyConfig.EatsPayPerKm = 20 -- $ per kilometer driven AgencyConfig.EatsPayMin = 15 -- lowest pay per delivery AgencyConfig.EatsPayMax = 200 -- highest pay per delivery AgencyConfig.EatsPickupRadius = 15.0 -- meters to the restaurant for pickup -- ── Maps quick navigation ──────────────────────────────────────────────────── -- Buttons in the Maps app that route to the nearest blip of these sprites. AgencyConfig.MapFastNavEntries = { { id = 'gas', labelKey = 'maps_gas_station', icon = 'fa-gas-pump', color = '#0a84ff', sprites = { 361 } }, { id = 'market', labelKey = 'maps_market', icon = 'fa-basket-shopping', color = '#ff9500', sprites = { 52, 77, 102 } }, { id = 'atm', labelKey = 'maps_atm', icon = 'fa-credit-card', color = '#30d158', sprites = { 277 } }, { id = 'clothing', labelKey = 'maps_clothing_store', icon = 'fa-shirt', color = '#bf5af2', sprites = { 73 } }, { id = 'tattoo', labelKey = 'maps_tattoo_parlor', icon = 'fa-wand-magic-sparkles', color = '#ff9f0a', sprites = { 75 } }, { id = 'barber', labelKey = 'maps_barber', icon = 'fa-scissors', color = '#5e72eb', sprites = { 71 } }, { id = 'bar', labelKey = 'maps_bar', icon = 'fa-martini-glass-citrus', color = '#ff7a00', sprites = { 93 } }, } --============================================================================== -- 16 · ANGY --============================================================================== -- Angy is the phone's built-in assistant: open apps, call or text contacts, -- order an AutoRide, set a waypoint, check balance and weather. It runs on -- fixed rules inside the phone. No AI, no outside service, no key needed. AgencyConfig.EnableAngy = true -- false removes the app and its key --============================================================================== -- 17 · LOGGING (Discord webhooks) --============================================================================== -- The webhook addresses are in config_server.lua (Webhooks), so players -- never receive them. --============================================================================== -- 18 · APPS --============================================================================== -- ── App Store ──────────────────────────────────────────────────────────────── AgencyConfig.AppStoreEnabled = true AgencyConfig.AppStorePersist = true -- remember installs in localStorage -- ── Developer mode ─────────────────────────────────────────────────────────── -- Shows developer/example apps such as "Agency Demo". Keep false when live. AgencyConfig.DeveloperMode = false -- ── Protected apps ─────────────────────────────────────────────────────────── -- Can never be uninstalled and are always restored on load. AgencyConfig.ProtectedApps = { 'appstore', 'settings', 'dialer', 'buzz', 'contacts', 'snap', 'gallery', 'clock', 'wallet', 'agencyai' } -- ── Apps from other resources ──────────────────────────────────────────────── -- Home screen slot for apps added via exports['agency-phone']:RegisterApp. -- 16 slots per page, counted from 0 (page 2 starts at 16). AgencyConfig.ExternalAppSlots = { topvsocial = 17, -- TopV Social (phone-topv), page 2 next to Weather } -- ── App list ───────────────────────────────────────────────────────────────── -- id app id, do not change -- label name on the home screen -- icon Font Awesome class | image: optional picture instead -- color icon colour | colorDark: colour in dark mode -- slot home screen position -- installed true = on the home screen, false = in the Store -- enabled false = hidden completely -- category Store category -- requiresJob only for jobs from AgencyConfig.JobApps -- requiresLogin app needs an account -- storeDesc / features text on the Store page -- Own apps go into the apps/ folder, see apps/README.md. AgencyConfig.Apps = { -- ═══════════════════════════════════════════════════════════ -- SYSTEM APPS -- ═══════════════════════════════════════════════════════════ { id = "dialer", label = "Phone", icon = "fa-solid fa-phone", color = "#4cd964", colorDark = "#34c759", slot = 1, installed = true, enabled = true, }, { id = "buzz", label = "Buzz", icon = "fa-solid fa-comment", color = "#34c759", colorDark = "#28a745", slot = 2, installed = true, enabled = true, }, { id = "contacts", label = "Contacts", icon = "fa-solid fa-user-group", color = "#ff9500", colorDark = "#e08600", slot = 3, installed = true, enabled = true, }, { id = "snap", label = "Camera", icon = "fa-solid fa-camera", color = "#8e8e93", colorDark = "#636366", slot = 4, installed = true, enabled = true, }, { id = "chirper", label = "Pulse", icon = "fa-solid fa-feather", color = "#af52de", colorDark = "#9b30d1", slot = 35, installed = false, enabled = false, }, { id = "postbox", label = "Mail", icon = "fa-solid fa-envelope", color = "#5ac8fa", colorDark = "#32ade6", slot = 6, installed = true, enabled = true, }, { id = "wallet", label = "Wallet", icon = "fa-solid fa-wallet", color = "#007aff", colorDark = "#0056cc", slot = 7, installed = true, enabled = true, }, { id = "gallery", label = "Photos", icon = "fa-solid fa-images", color = "#ff2d55", colorDark = "#d6204a", slot = 8, installed = true, enabled = true, }, { id = "report", label = "Reports", icon = "fa-solid fa-flag", color = "#ff3b30", colorDark = "#d63025", slot = 9, installed = true, enabled = true, }, { id = "settings", label = "Settings", icon = "fa-solid fa-gear", color = "#8e8e93", colorDark = "#636366", slot = 10, installed = true, enabled = true, }, { id = "agencyai", label = "Angy", icon = "fa-solid fa-wand-magic-sparkles", image = "img/Agencylogo.png", -- the Agency mark on gold, like the Agency Watch color = "#e2b649", colorDark = "#a8801f", slot = 11, installed = true, enabled = true, }, { id = "appstore", label = "Store", icon = "fa-solid fa-bag-shopping", color = "#007aff", colorDark = "#0056cc", slot = 12, installed = true, enabled = true, }, { id = "agencycloud", label = "AgencyCloud", icon = "fa-solid fa-cloud", color = "#4cc6ff", colorDark = "#0a84ff", category = "productivity", slot = 13, installed = true, enabled = true, storeDesc = "Your personal and company cloud storage. Sync files, photos, and documents across all your Agency devices.", features = {"Personal & company storage", "Cross-device sync", "Photo gallery backup", "Document management", "Storage tier upgrades"}, }, -- ═══════════════════════════════════════════════════════════ -- PRODUCTIVITY & NAVIGATION -- ═══════════════════════════════════════════════════════════ { id = "calculator", label = "Calculator", icon = "fa-solid fa-calculator", color = "#ff9500", colorDark = "#e08600", category = "productivity", slot = 13, installed = true, enabled = true, storeDesc = "A powerful calculator app for quick calculations on the go.", features = {"Basic arithmetic operations", "Percentage calculations", "AgencyOS26.5-style interface", "Instant results"}, }, { id = "clock", label = "Clock", icon = "fa-solid fa-clock", color = "#000000", colorDark = "#1c1c1e", category = "productivity", slot = 14, installed = true, enabled = true, storeDesc = "Keep track of time with world clocks, alarms, stopwatch, and timers.", features = {"World clock display", "Stopwatch with precision timing", "Multiple alarms", "Timer functionality"}, }, { id = "notes", label = "Notes", icon = "fa-solid fa-note-sticky", color = "#ffcc00", colorDark = "#e6b800", category = "productivity", slot = 15, installed = true, enabled = true, storeDesc = "Jot down ideas, tasks, and reminders instantly.", features = {"Quick note creation", "Persistent storage", "Easy organization", "Simple interface"}, }, { id = "calendar", label = "Calendar", icon = "fa-solid fa-calendar-days", color = "#ff3b30", colorDark = "#d70015", category = "productivity", slot = 14, installed = true, enabled = true, storeDesc = "Plan your day: events with time, place and reminder, repeating dates and a home-screen widget for what comes next.", features = {"Month view with event dots", "Reminders as notifications", "Repeating events", "Four colour-coded calendars", "Home-screen widget"}, }, { id = "weather", label = "Weather", icon = "fa-solid fa-cloud-sun", color = "#5ac8fa", colorDark = "#32ade6", category = "productivity", slot = 16, installed = true, enabled = true, storeDesc = "Stay informed about current weather conditions in Los Santos.", features = {"Real-time weather display", "Temperature info", "Current conditions", "Location-based data"}, }, { id = "compass", label = "Compass", icon = "fa-solid fa-compass", color = "#ff3b30", colorDark = "#d63025", category = "navigation", slot = 17, installed = false, enabled = true, storeDesc = "Navigate the city with an accurate digital compass.", features = {"Real-time heading direction", "Accurate navigation", "Always accessible", "Minimal interface"}, }, { id = "radio", label = "Radio", -- fa-walkie-talkie is Font Awesome Pro only and would show an empty box. icon = "fa-solid fa-tower-broadcast", color = "#ff6b6b", colorDark = "#d94848", category = "utilities", slot = 18, installed = false, enabled = true, storeDesc = "Connect to various radio channels and communicate on the go.", features = {"Multiple frequency channels", "Quick channel switching", "Clear audio", "Emergency frequencies"}, }, -- Flashlight lives in the Control Centre (swipe down top right). { id = "speedometer", label = "Speedo", icon = "fa-solid fa-gauge-high", color = "#ff2d55", colorDark = "#d6204a", category = "navigation", slot = 20, installed = false, enabled = true, storeDesc = "Monitor your vehicle's speed with a digital speedometer.", features = {"Real-time speed display", "Multiple unit options", "GPS speed tracking", "Always visible"}, }, { id = "gps", label = "Maps", icon = "fa-solid fa-map-location-dot", color = "#34c759", colorDark = "#28a745", category = "navigation", slot = 21, installed = false, enabled = true, storeDesc = "Navigate Los Santos with GPS waypoints and route planning.", features = {"Set custom waypoints", "Route guidance", "Real-time navigation", "Location sharing"}, }, -- ═══════════════════════════════════════════════════════════ -- FINANCE, SERVICES & GAMES -- ═══════════════════════════════════════════════════════════ { id = "crypto", label = "Crypto", icon = "fa-brands fa-bitcoin", color = "#f7931a", colorDark = "#d97c0e", slot = 22, installed = false, enabled = true, storeDesc = "Buy, sell, and track cryptocurrency markets in real-time.", features = {"Live market prices", "Portfolio tracking", "Trading functionality", "Transaction history"}, }, { id = "stocks", label = "Stocks", icon = "fa-solid fa-chart-line", color = "#007aff", colorDark = "#0056cc", slot = 33, installed = false, enabled = true, storeDesc = "Trade stocks of Los Santos companies and build your portfolio.", features = {"8 Los Santos companies", "Real-time price updates", "Buy/sell shares", "Portfolio tracking"}, category = "finance", }, { id = "dice", label = "Dice Game", category = "games", icon = "fa-solid fa-dice", color = "#ff2d55", colorDark = "#d6204a", slot = 23, installed = false, enabled = true, storeDesc = "Roll dice against other players. Classic gambling game.", features = {"1v1 dice duels", "Customizable bet amounts", "Roll history", "Fair random rolls"}, }, { id = "darkweb", label = "Darknet", icon = "fa-solid fa-skull-crossbones", color = "#1c1c1e", colorDark = "#000000", category = "darknet", slot = 24, installed = false, enabled = true, storeDesc = "Access the underground market. Anonymous and untraceable.", features = {"Anonymous browsing", "Encrypted transactions", "Black market access", "High-risk items"}, }, { id = "racing", label = "Races", icon = "fa-solid fa-flag-checkered", color = "#ff9500", colorDark = "#e08600", category = "services", slot = 25, installed = false, enabled = true, storeDesc = "Compete in street races and track your best times.", features = {"Create custom races", "Join active races", "Leaderboards", "Race statistics"}, }, { id = "services", label = "Services", icon = "fa-solid fa-book-open", color = "#ffd60a", colorDark = "#d4a800", category = "utilities", slot = 27, installed = false, enabled = true, storeDesc = "Request taxis, mechanics, and various city services.", features = {"Taxi services", "Mechanic calls", "Emergency services", "Quick booking"}, }, { id = "aipickup", label = "AutoRide", icon = "fa-solid fa-car-side", color = "#00c7be", colorDark = "#0a84ff", category = "services", slot = 26, installed = true, enabled = true, storeDesc = "Driverless limousine pickup and autonomous dropoff service.", features = {"Driverless 4-seat limousine", "Pickup at your location", "Set waypoint before or during ride", "Autonomous routing to destination"}, }, { id = "food", label = "AgencyEats", icon = "fa-solid fa-burger", color = "#ff3b30", colorDark = "#d62020", category = "services", slot = 28, installed = false, enabled = true, storeDesc = "Order food from local restaurants and get it delivered to your location.", features = {"Browse menus", "Place orders", "Track delivery", "Restaurant ratings"}, }, { id = "invoices", label = "Invoices", category = "finance", icon = "fa-solid fa-file-invoice-dollar", color = "#30d158", colorDark = "#28b54c", slot = 29, installed = false, enabled = true, storeDesc = "Manage and pay your invoices and outstanding bills.", features = {"View pending bills", "Pay invoices", "Transaction history", "Payment reminders"}, }, { id = "employment", label = "Jobs", category = "utilities", icon = "fa-solid fa-briefcase", color = "#007aff", colorDark = "#0056cc", slot = 30, installed = false, enabled = true, storeDesc = "Find employment opportunities and manage your career.", features = {"Job listings", "Application tracking", "Career information", "Salary details"}, }, { id = "garage", label = "Garage", category = "utilities", icon = "fa-solid fa-warehouse", color = "#5856d6", colorDark = "#4240b0", slot = 32, installed = true, enabled = true, storeDesc = "Access and manage your stored vehicles and garage.", features = {"Vehicle storage", "Quick spawn", "Vehicle information", "Garage locations"}, }, { id = "coinflip", label = "Coin Flip", category = "games", icon = "fa-solid fa-coins", color = "#ffcc00", colorDark = "#e6b800", slot = 37, installed = false, enabled = true, storeDesc = "Flip a coin and bet against other players. Heads or tails?", features = {"Heads or tails betting", "Fair coin flip", "Bet against players", "Flip history"}, }, { id = "slots", label = "Lucky Slots", category = "games", icon = "fa-solid fa-clover", color = "#34c759", colorDark = "#28a745", slot = 38, installed = false, enabled = true, storeDesc = "Try your luck at the slot machine. Match symbols to win big!", features = {"Classic slot machine", "Multiple symbol combos", "Win multipliers", "Jackpot system"}, }, { id = "roulette", label = "Roulette", category = "games", icon = "fa-solid fa-circle-dot", color = "#ff3b30", colorDark = "#d63025", slot = 39, installed = false, enabled = true, storeDesc = "Place your bets on the roulette wheel. Red, black, or green?", features = {"Red/Black/Green bets", "Number betting", "Realistic wheel spin", "Payout system"}, }, -- ── Arcade games (no money involved) ── { id = "skyhopper", label = "Sky Hopper", icon = "fa-solid fa-dove", color = "#4cd964", colorDark = "#3bb54a", slot = 40, installed = false, enabled = true, category = "games", storeDesc = "Tap to glide through the skyline, avoid the pipes and beat your best run.", features = {"Classic gameplay", "High score tracking", "Smooth animations", "Addictive fun"}, }, { id = "gametilemerge", label = "Tile Merge", icon = "fa-solid fa-border-all", color = "#f59563", colorDark = "#e07840", slot = 41, installed = false, enabled = true, category = "games", storeDesc = "Slide numbered tiles to combine them and reach the highest score!", features = {"Number puzzle", "Swipe controls", "Score tracking", "Addictive gameplay"}, }, { id = "snake", label = "Snake", icon = "fa-solid fa-staff-snake", color = "#30d158", colorDark = "#1f9a40", slot = 42, installed = false, enabled = true, category = "games", storeDesc = "Eat, grow and stay alive. Swipe to steer the snake and beat your best run.", features = {"Swipe or arrow keys", "Speeds up as you grow", "High score tracking", "Smooth animations"}, }, { id = "brickblast", label = "Brick Blast", icon = "fa-solid fa-table-cells-large", color = "#ff6b35", colorDark = "#d9491a", slot = 43, installed = false, enabled = true, category = "games", storeDesc = "Bounce the ball, clear every brick and climb through the levels.", features = {"Drag the paddle", "Levels that get harder", "Power ups", "High score tracking"}, }, -- ═══════════════════════════════════════════════════════════ -- MEDIA -- ═══════════════════════════════════════════════════════════ { id = "music", label = "Music", icon = "fa-solid fa-music", color = "#fc3c44", colorDark = "#d43039", category = "media", slot = 5, installed = true, enabled = true, storeDesc = "Play your server's own music library and share it with people nearby.", features = {"Your own music library", "Players submit, admins approve", "Nearby players hear your music", "Favorites, playlists & queue"}, }, -- ═══════════════════════════════════════════════════════════ -- JOB APPS (only for the jobs in AgencyConfig.JobApps) -- Police and EMS MDT are exclusive to the Agency Pad. -- ═══════════════════════════════════════════════════════════ { id = "mechanic_app", label = "Mechanic", icon = "fa-solid fa-wrench", color = "#ff9500", colorDark = "#e08600", category = "utilities", slot = 52, installed = false, enabled = true, requiresJob = true, storeDesc = "Manage repair orders and customer requests. Accept jobs and track your workload.", features = {"Incoming repair requests", "Job queue management", "Customer notifications", "Service history"}, }, -- ═══════════════════════════════════════════════════════════ -- SOCIAL -- ═══════════════════════════════════════════════════════════ { id = "snapr", label = "Snapr", category = "social", icon = "fa-solid fa-ghost", color = "#FFFC00", colorDark = "#E0B800", slot = 46, installed = false, enabled = true, requiresLogin = false, storeDesc = "Snaps that disappear. Point, filter, send - and it is gone once they have seen it.", features = {"Camera with live filters", "Snaps vanish after viewing", "Send to several friends at once", "Chats with snap history"}, }, { id = "pictogram", label = "Pictogram", category = "social", icon = "fa-solid fa-camera-retro", color = "#E1306C", colorDark = "#C13584", slot = 42, installed = false, enabled = true, requiresLogin = true, storeDesc = "Share photos and stories with your friends. The #1 photo sharing app.", features = {"Photo sharing", "Stories & Reels", "Direct messages", "Follow friends"}, }, { id = "bleeter", label = "Bleeter", category = "social", icon = "fa-solid fa-hashtag", color = "#1DA1F2", colorDark = "#0d8bd9", slot = 43, installed = false, enabled = true, requiresLogin = true, storeDesc = "What's happening in Los Santos? Follow trends and share your thoughts.", features = {"Trending topics", "Share bleets", "Follow people", "Real-time feed"}, }, { id = "recorder", label = "Recorder", category = "productivity", icon = "fa-solid fa-microphone-lines", color = "#ff453a", colorDark = "#d92d23", slot = 47, installed = true, enabled = true, storeDesc = "Record voice memos, play them back and send them to your chats in Buzz.", features = {"Voice memos", "Waveform playback", "Skip 15 seconds", "Send in Buzz"}, }, { id = "lifeinvader", label = "Life Invader", category = "social", icon = "fa-solid fa-thumbs-up", color = "#4267B2", colorDark = "#365899", slot = 44, installed = false, enabled = true, requiresLogin = true, storeDesc = "Connect with friends, family, and the world around you.", features = {"Friend profiles", "Status updates", "Photo albums", "Event planning"}, }, { id = "facezoom", label = "FaceZoom", category = "social", icon = "fa-solid fa-video", color = "#2D8CFF", colorDark = "#1a6fcc", slot = 45, installed = false, enabled = true, requiresLogin = false, storeDesc = "Video calls and meetings with anyone, anywhere.", features = {"Video calls", "Group meetings", "Screen sharing", "Chat messaging"}, }, -- ═══════════════════════════════════════════════════════════ -- PASSWORD MANAGER -- ═══════════════════════════════════════════════════════════ { id = "keychain", label = "Keychain", category = "utilities", icon = "fa-solid fa-key", color = "#8e8e93", colorDark = "#636366", slot = 46, installed = true, enabled = true, storeDesc = "View and manage your saved passwords and app accounts.", features = {"Saved passwords", "App accounts", "Secure storage", "Face Unlock access"}, }, -- ═══════════════════════════════════════════════════════════ -- EXAMPLE CUSTOM APP (source in apps/, off by default) -- ═══════════════════════════════════════════════════════════ { id = "testapp", label = "Test App", icon = "fa-solid fa-flask", color = "#5856d6", colorDark = "#4240b0", slot = 36, installed = false, enabled = false, storeDesc = "A demo app showing how custom apps work.", }, -- ═══════════════════════════════════════════════════════════ -- AGENCY DEVICES -- ═══════════════════════════════════════════════════════════ -- Health: condition from the phone, movement from the Agency Watch. { id = "health", label = "Health", icon = "fa-solid fa-heart-pulse", color = "#ff375f", colorDark = "#c72b4a", slot = 38, installed = true, enabled = true, -- Fallback text only: the Store prefers the translations in locales.js. storeDesc = "Condition, steps, distance and pulse. It shows the most alongside an Agency Watch.", features = {"Health and armour", "Steps and distance", "Pulse with history", "Seven-day review"}, }, { id = "watch", label = "Watch", icon = "fa-solid fa-clock", color = "#00d4ff", colorDark = "#0090ad", slot = 39, installed = true, enabled = true, -- Fallback text only, see Health. storeDesc = "Set up your Agency Watch completely: watch face, case, language and Agency Pay.", features = {"Watch face and case", "Agency Pay on your wrist", "Pair the companion", "Software updates"}, }, -- Zero: call and control your own Agency Zero. Without Agency Zero on the -- server the app explains where to get it; enabled = false hides it. { id = "zero", label = "Zero", icon = "fa-solid fa-car-side", color = "#e2b649", colorDark = "#a8801f", slot = 40, installed = true, enabled = true, storeDesc = "Call your Agency Zero, open its doors, lock it and see battery and range.", features = {"Call it to where you stand", "Doors, lock and lights", "Battery and range", "Free on the Agency Store"}, }, -- Agency Demo (working custom-app template added by Claude) { id = "agencydemo", label = "Agency Demo", icon = "fa-solid fa-rocket", color = "#00d4ff", colorDark = "#0090cc", slot = 37, installed = AgencyConfig.DeveloperMode, -- only on the home screen in developer mode enabled = AgencyConfig.DeveloperMode, -- hidden entirely when DeveloperMode = false storeDesc = "Example custom app: identity, live server stats and notifications.", }, }

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 Phone SQL Schema CREATE TABLE IF NOT EXISTS `agency_contacts` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `name` VARCHAR(100) NOT NULL, `number` VARCHAR(20) NOT NULL, `is_emergency` TINYINT(1) NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `identifier` (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_messages` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `number` VARCHAR(20) NOT NULL, `messages` LONGTEXT DEFAULT NULL, PRIMARY KEY (`id`), KEY `identifier` (`identifier`), KEY `number` (`number`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_chirper` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) DEFAULT NULL, `firstname` VARCHAR(50) DEFAULT NULL, `lastname` VARCHAR(50) DEFAULT NULL, `message` TEXT DEFAULT NULL, `post_id` VARCHAR(30) NOT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `identifier` (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_mail` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `recipient_email` VARCHAR(120) DEFAULT NULL, `sender` VARCHAR(100) DEFAULT NULL, `sender_email` VARCHAR(120) DEFAULT NULL, `subject` VARCHAR(200) DEFAULT NULL, `message` TEXT DEFAULT NULL, `mail_id` INT(11) DEFAULT NULL, `is_read` TINYINT(4) DEFAULT 0, `button` TEXT DEFAULT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `identifier` (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_mail_accounts` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `local_part` VARCHAR(64) NOT NULL, `email` VARCHAR(120) NOT NULL, `label` VARCHAR(100) DEFAULT NULL, `is_primary` TINYINT(4) DEFAULT 0, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`), KEY `identifier` (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_gallery` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `device_kind` VARCHAR(20) NOT NULL DEFAULT 'phone', `image_url` VARCHAR(512) NOT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `identifier` (`identifier`), KEY `identifier_device` (`identifier`,`device_kind`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_phone_dispatches` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `dispatch_id` INT(11) NOT NULL, `type` VARCHAR(60) DEFAULT NULL, `priority` VARCHAR(20) DEFAULT NULL, `code` VARCHAR(20) DEFAULT NULL, `label` VARCHAR(120) DEFAULT NULL, `message` TEXT DEFAULT NULL, `caller` VARCHAR(120) DEFAULT NULL, `caller_phone` VARCHAR(40) DEFAULT NULL, `location_x` FLOAT DEFAULT NULL, `location_y` FLOAT DEFAULT NULL, `location_z` FLOAT DEFAULT NULL, `street` VARCHAR(160) DEFAULT NULL, `status` VARCHAR(20) DEFAULT 'pending', `timestamp` INT(11) DEFAULT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `dispatch_id` (`dispatch_id`), KEY `status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_cloud_limits` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `scope_type` VARCHAR(20) NOT NULL, `scope_key` VARCHAR(80) NOT NULL, `storage_limit_mb` INT(11) NOT NULL DEFAULT 0, `storage_used_mb` DECIMAL(12,2) NOT NULL DEFAULT 0.00, `asset_limit` INT(11) NOT NULL DEFAULT 0, `asset_count` INT(11) NOT NULL DEFAULT 0, `purchased_storage_mb` INT(11) NOT NULL DEFAULT 0, `purchased_asset_count` INT(11) NOT NULL DEFAULT 0, `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `scope_lookup` (`scope_type`, `scope_key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_cloud_assets` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_uid` VARCHAR(64) NOT NULL, `scope_type` VARCHAR(20) NOT NULL, `scope_key` VARCHAR(80) NOT NULL, `owner_identifier` VARCHAR(60) DEFAULT NULL, `job_name` VARCHAR(60) DEFAULT NULL, `asset_type` VARCHAR(30) NOT NULL DEFAULT 'document', `title` VARCHAR(200) DEFAULT NULL, `description` VARCHAR(255) DEFAULT NULL, `url` VARCHAR(512) NOT NULL, `mime_type` VARCHAR(100) DEFAULT NULL, `storage_bytes` INT(11) NOT NULL DEFAULT 0, `meta_json` LONGTEXT DEFAULT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `asset_uid` (`asset_uid`), KEY `scope_lookup` (`scope_type`, `scope_key`), KEY `owner_identifier` (`owner_identifier`), KEY `job_name` (`job_name`), KEY `asset_type` (`asset_type`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_phone_emails` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `email` VARCHAR(120) NOT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `identifier` (`identifier`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_app_accounts` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `app_id` VARCHAR(60) NOT NULL, `email` VARCHAR(120) NOT NULL, `password` VARCHAR(60) NOT NULL, `display_name` VARCHAR(100) DEFAULT NULL, `faceid_enabled` TINYINT(4) DEFAULT 0, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `identifier_app` (`identifier`, `app_id`), KEY `identifier` (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_notes` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `note_id` VARCHAR(40) NOT NULL, `title` VARCHAR(200) DEFAULT NULL, `content` LONGTEXT DEFAULT NULL, `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `identifier` (`identifier`), UNIQUE KEY `note_id` (`note_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_call_history` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `caller_number` VARCHAR(20) NOT NULL, `receiver_number` VARCHAR(20) NOT NULL, `call_type` ENUM('incoming','outgoing','missed') DEFAULT 'outgoing', `duration` INT(11) DEFAULT 0, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `identifier` (`identifier`), KEY `caller_number` (`caller_number`), KEY `receiver_number` (`receiver_number`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_darknet_purchases` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `item_id` VARCHAR(60) NOT NULL, `item_label` VARCHAR(100) DEFAULT NULL, `price` DECIMAL(10,4) DEFAULT 0, `currency` VARCHAR(10) DEFAULT 'BTC', `status` ENUM('pending','collected','expired') DEFAULT 'pending', `pickup_x` FLOAT DEFAULT NULL, `pickup_y` FLOAT DEFAULT NULL, `pickup_z` FLOAT DEFAULT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `identifier` (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_invoices` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `sender_identifier` VARCHAR(60) NOT NULL, `receiver_identifier` VARCHAR(60) NOT NULL, `sender_name` VARCHAR(100) DEFAULT NULL, `receiver_name` VARCHAR(100) DEFAULT NULL, `amount` DECIMAL(10,2) NOT NULL, `reason` VARCHAR(200) DEFAULT NULL, `status` ENUM('pending','paid','declined') DEFAULT 'pending', `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `sender_identifier` (`sender_identifier`), KEY `receiver_identifier` (`receiver_identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_phone_settings` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `setting_key` VARCHAR(60) NOT NULL, `setting_value` TEXT DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `identifier_key` (`identifier`, `setting_key`), KEY `identifier` (`identifier`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `agency_housing` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `identifier` VARCHAR(60) NOT NULL, `house_id` VARCHAR(100) NOT NULL, `house_label` VARCHAR(200) DEFAULT NULL, `housing_script` VARCHAR(60) DEFAULT NULL, `is_locked` TINYINT(4) DEFAULT 1, `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `identifier` (`identifier`), UNIQUE KEY `house_id` (`house_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

¿Sigues atascado después de esta página? Nuestro soporte se encarga.