[{"data":1,"prerenderedAt":924},["ShallowReactive",2],{"site":3,"docs-slug-site":15,"docs-product-en-x3d-phone":21,"docs-products-en":95,"docs-html-en-x3d-phone":868},{"site":4,"contact":10,"seo":13,"payment":14},{"name":5,"host":6,"default_locale":7,"locales":8},"X3D Developer","fivem.x3d-developer.com","th",[7,9],"en",{"discord_invite":11,"email":12,"line":12},"https:\u002F\u002Fdiscord.gg\u002FNA5kPVynFv","",{"google_site_verification":12,"bing_site_verification":12},{"bank_name":12,"account_name":12,"account_no":12,"promptpay_id":12},{"site":16,"contact":18,"seo":19,"payment":20},{"name":5,"host":6,"default_locale":7,"locales":17},[7,9],{"discord_invite":11,"email":12,"line":12},{"google_site_verification":12,"bing_site_verification":12},{"bank_name":12,"account_name":12,"account_no":12,"promptpay_id":12},{"id":22,"slug":23,"name":24,"summary":25,"price_thb":26,"license_mode":27,"cover_key":28,"cover_url":29,"category_slugs":30,"tags":32,"latest_version":55,"latest_released_at":56,"published_at":57,"has_docs":58,"config":59,"rent_price_satang":60,"description_md":61,"docs_md":62,"seo_title":63,"seo_description":64,"media":65,"versions":81},"879a5a5d-5b22-4fb5-9274-6ac3ee631904","x3d-phone","X3D Phone","Free ESX smartphone: pma-voice calls, SMS with location sharing, mobile banking, a camera with self-hosted photos, Buzz and anonymous Dark Chat.",0,"none","public\u002Fproducts\u002Fx3d-phone\u002Fcover\u002F9e0b9e2f9bc7352d.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-phone\u002Fcover\u002F9e0b9e2f9bc7352d.jpg",[31],"hud",[33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54],"phone","โทรศัพท์","โทรศัพท์ fivem","esx phone","phone script","sms","pma-voice","dispatch","แจ้งเหตุ","ธนาคารมือถือ","buzz","dark chat","กล้อง","esx","ฟรี","free","เบอร์หน่วยงาน","ออกบิล","แชร์ตำแหน่ง","เรียกหมอ","กล้องโทรศัพท์","ไอเทมโทรศัพท์","1.1.3","2026-10-12T17:18:13.372348Z","2026-09-25T15:32:10.424119Z",true,"public",null,"A free smartphone for ESX. It comes with Phone, Messages, Contacts, Banking, Bills, Buzz, Dark Chat and Settings apps. The UI is built with Nuxt 4 and works with mouse or keyboard. Fits any city style (school \u002F community \u002F RP).\n\n---\n\n## Features\n\n- [+] Easy setup: tune everything in config, or set it from the web builder\n- [+] Real voice calls through pma-voice, mute your mic, 5 ringtones\n- [+] SMS grouped by conversation, share your location and tap to set a GPS waypoint\n- [+] Service numbers for police, EMS and mechanics, sent to the whole job with your spot\n- [+] Dispatch app: call EMS, a medic responds and gets a waypoint set\n- [+] Bill any number; police, EMS and admin bills are locked, only admins can cancel\n- [+] Mobile banking with transfers by phone number, with your own min and max\n- [+] Camera with photos stored on your own server, and an hourly limit per player\n- [+] Server-wide Buzz feed with 5 post card skins that admins can lock\n- [+] Dark Chat: anonymous rooms with nicknames and an optional room password\n- [+] Require a phone item to use it, with your own item name, or switch it off\n- [+] Write your own hooks to other scripts in addons\u002F\n\n---\n\n## What's inside\n\n- **Phone**: keypad and call history, with a badge for missed calls. Voice calls run through **pma-voice**. You can mute your microphone and pick one of five ringtones.\n- **Messages (SMS)**: one conversation per contact, with unread badges. You can **share your location**. The person who gets it taps it to set a GPS waypoint there.\n- **Contacts**: mark favourites. Contact names also show in call history and in chats.\n- **Service numbers**: text the police, EMS or mechanics and every member of that job gets it with your location. Job scripts can add or remove numbers through the `x3d_phone:registerNumber` \u002F `x3d_phone:removeNumber` events.\n- **Dispatch**: a player hits \"call EMS\" and every medic gets the call in their phone with distance and a map blip. Respond sets a waypoint and tells the caller help is coming. Any script can raise a call with one export.\n- **Bills**: bill any phone number, personally or on behalf of a job (police, EMS, mechanic, add your own). The recipient pays or declines in the phone (locked job bills such as police, EMS and admin cannot be declined or cancelled; an admin cancels them from the admin menu) and a double tap never charges twice. Personal bills pay into the biller's bank account; business bills need your own society account wired in `addons\u002Fbilling\u002Fserver.lua`.\n- **Every emoji**: a picker with groups and search, in SMS, Buzz and Dark Chat.\n- **Mobile banking**: balance and history, plus transfers to an online player's phone number. Uses the ESX `bank` account, or plug in your own banking system.\n- **Camera**: take a photo in game and send it by SMS or post, or use it for a contact, your Buzz avatar or your wallpaper. **Photos are stored on your own server.** No image host and no API key.\n- **Buzz**: one feed for the whole server. Post, like and delete your own posts. New posts show up in the in-game chat as a card with **5 skins** (default, Halloween, Christmas, Songkran, Night). Players pick one, or you lock one for the whole server.\n- **Phone item**: by default a `phone` item is required. No phone means no calls in or out, and the server enforces it.\n- **Dark Chat**: anonymous rooms with nicknames and an optional password. Nobody sees the sender's real phone number.\n- **Settings**: wallpaper, ringtone, notification sound, a keyboard-only mode, and **Alt** to switch to game controls without closing the phone.\n\n---\n\n## Copies to Discord\n\nAdd a webhook to `server.cfg` and every photo a player takes is copied to your admin Discord channel, with the player's name and identifier. The photo itself stays on your server, so in-game links never expire. A separate webhook can log SMS, posts and transfers.\n\n---\n\n## Server-side safety\n\n- The server checks every callback again. It never trusts values sent by the client.\n- SMS, posts, likes and calls are rate-limited.\n- Players can only delete their own contacts, posts and history.\n- External image links are accepted only from the hosts in `Config.ImageHosts` (or from any https site if you switch that on).\n- Uploads need a single-use token, are capped per hour, and must be real JPG\u002FPNG files.\n- Webhook URLs never reach players, and Discord posts never ping anyone.\n\n---\n\n## Make it fit your server\n\nEverything that differs between servers lives in `addons\u002F`, one file for each job:\n\n| File | Job |\n|---|---|\n| `addons\u002Fnotify\u002Fclient.lua` | Notifications: uses esx_notify or ox_lib if either is present, otherwise ESX's own. |\n| `addons\u002Fvoice\u002Fclient.lua` | Voice system. The default is pma-voice. |\n| `addons\u002Fbanking\u002Fserver.lua` | Banking. The default is the ESX `bank` account. |\n| `addons\u002Fbilling\u002Fserver.lua` | Billing: charges the payer and pays the biller (a society account must be wired by you). |\n| `addons\u002Fframework\u002Fserver.lua` \u002F `client.lua` | The framework bridge: ESX if present, else standalone. |\n| `addons\u002Fupload\u002Fclient.lua` | Photo storage. The default stores photos on your own server. |\n| `addons\u002Ffilter\u002Fserver.lua` | Blocks banned words before a message is sent. |\n| `addons\u002Flog\u002Fserver.lua` | Logs SMS, posts and Dark Chat messages. Includes a Discord webhook example. |\n\n---\n\n## Requirements\n\n- `oxmysql`\n- `es_extended` (ESX Legacy). Without it the script runs standalone, and you wire banking and billing yourself in `addons\u002F`\n- `pma-voice` (optional: without it, calls still connect but carry no audio)\n- `screenshot-basic` (optional, needed for the camera; a copy is bundled in `optional\u002F`)\n","## Installation\n\n1. Extract the zip and put the `x3d_phone` folder in `resources\u002F`. **Do not rename the folder**: every export and event uses this name.\n2. Run `install.sql` on your server database. It is safe to run again and keeps existing data.\n3. If your server has no `phone` item, run `optional\u002Fphone_item.sql`. With ox_inventory, add the item to `ox_inventory\u002Fdata\u002Fitems.lua` instead; the file has an example.\n4. If your server has no `screenshot-basic`, move `optional\u002Fscreenshot-basic\u002F` into `resources\u002F`. You can skip this; only the camera needs it.\n5. Add these lines to `server.cfg`, in this order:\n\n```\nensure oxmysql\nensure es_extended\nensure pma-voice\nensure screenshot-basic\nensure x3d_phone\n```\n\nPlayers open the phone with **F1**, the `\u002Fopenphone` command, or by using the `phone` item. While the phone is open, **Alt** switches to game controls; press it again to get the cursor back.\n\n## Requirements\n\n| Resource | Required | Used for |\n|---|---|---|\n| `es_extended` | no | ESX Legacy. Without it the script runs standalone and you wire banking and billing yourself in `addons\u002F` (see `Config.Framework`) |\n| `oxmysql` | yes | database |\n| `pma-voice` | no | call audio; without it calls connect but carry no audio |\n| `screenshot-basic` | no | the camera; a copy is bundled in `optional\u002F` |\n| `chat` (FiveM) | no | post cards in chat |\n\nNo image host, no API key, and no other software to install.\n\n---\n\n## All settings: `config\u002Fconfig.lua`\n\n### General\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.Locale` | `'th'` | Language of the phone and its messages: `'th'` or `'en'` |\n| `Config.Framework` | `'auto'` | `'auto'` (ESX if present, else standalone) `\\| 'esx' \\| 'standalone'` |\n| `Config.Debug` | `false` | `true` prints logs to the server console |\n| `Config.OpenKey` | `'F1'` | Key that opens the phone. Players can rebind it in Settings > Key Bindings > FiveM. This value only applies to a player's first join. |\n| `Config.DefaultContacts` | `{}` | Contacts added to every new number, e.g. `{ phone = '911', name = 'Police' }` |\n\n### Phone item\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.UseItem` | `true` | The item must be in the inventory to open the phone, call, answer and get SMS alerts |\n| `Config.PhoneItem` | `'phone'` | Item name. You can use one your server already has, e.g. `'iphone'` |\n\nWith `UseItem` on:\n- No item: the phone does not open, and every server callback refuses. Triggering events by hand does not get past this.\n- A player without the item cannot be called. The caller sees \"unavailable\" and the call is logged as missed.\n- SMS are still stored, but no alert shows until the player has the item.\n- If the item leaves the inventory while the phone is open (dropped or taken), the phone closes and any call ends.\n\n### Calls\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.UseVoice` | `true` | Use pma-voice for call audio |\n| `Config.CallChannelStart` | `1000` | First pma-voice channel used for calls. Change it only if it collides with another script. |\n| `Config.CallTimeout` | `30` | Seconds before an unanswered call ends |\n| `Config.Ringtones` | 5 sounds | Ringtones; each maps to a GTA V sound |\n| `Config.NotificationSounds` | 3 sounds | Message alert sounds |\n| `Config.RingtonePreviewMs` | `3000` | Length of `\u002Ftestringtone` and `\u002Ftestdialtone` |\n\n> `Config.Ringtones`, `Config.NotificationSounds` and `Config.Wallpapers` are what the server checks a player's choice against. You can remove an option in the config. Adding a new option also needs a change to the phone's web UI.\n\n### Messages\n\nEmoji work in every text box (SMS, Buzz, Dark Chat), with a picker holding all 3,600+ emoji in 9 groups plus search. Lengths are counted in real characters, so Thai text and emoji are not over-counted.\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.MaxMessageLength` | `500` | Maximum length of an SMS or a Dark Chat message |\n\n### Buzz and post card skins\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.Buzz.ToChat` | `true` | New posts appear in everyone's in-game chat |\n| `Config.Buzz.Themes` | all 5 | Skins on offer: `default`, `halloween`, `christmas`, `songkran`, `night` |\n| `Config.Buzz.DefaultTheme` | `'default'` | Skin for players who have not picked one |\n| `Config.Buzz.PlayerTheme` | `true` | `true`: players pick their skin in Settings. `false`: everyone uses `DefaultTheme`. |\n\n**Example:** lock the whole server to Halloween for the event:\n\n```lua\nConfig.Buzz = {\n    ToChat = true,\n    Themes = { 'halloween' },\n    DefaultTheme = 'halloween',\n    PlayerTheme = false,\n}\n```\n\nPost cards use FiveM's standard `chat` resource. x3d_phone adds its own styles through `chat_theme` and leaves your chat theme alone. Post text is always escaped, so players cannot inject HTML into chat.\n\n### Service numbers (police \u002F EMS \u002F mechanic) and job scripts\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.Dispatch.Numbers` | police, ambulance, mechanic | Service numbers: `number = { label = 'Shown name', jobs = { 'job' }, coords = true }` |\n| `Config.Dispatch.OnDutyOnly` | `false` | `true` delivers only to players on duty (ESX Legacy `job.onDuty`) |\n\n- Service numbers appear as special contacts for everyone and cannot be edited or deleted.\n- Texting `police` delivers `[Police] ...` to every online player with a job in `jobs` who has a phone. It arrives from the sender's own number with their location, so a tap sets a GPS waypoint and a reply goes straight back to the sender.\n- The location comes from the character's position on the server, so it cannot be faked. One message per service every 20 seconds.\n- If nobody from the service is online, the sender is told.\n\n**Hooking up job scripts:** the `police`, `ambulance` and `mechanic` numbers already ship in the config, and your job scripts can add or remove numbers with these events.\n\n| Event | What it does |\n|---|---|\n| `TriggerEvent('x3d_phone:registerNumber', number, label, isDispatch, hasCoords)` (server) | Adds a service number from a job script (an existing number is left alone) |\n| `TriggerEvent('x3d_phone:removeNumber', number)` (server) | Removes a registered number (numbers in the config stay) |\n| `TriggerServerEvent('x3d_phone:send', number, message, anonymous)` | Scripts that alert the police automatically (robberies etc.) send a message to a service number. With `anonymous = true` the message comes from the service number instead of the player's. |\n\n> Job scripts that call the old `esx_phone:*` event names do not work with x3d_phone; point them at the events above.\n\n#### Dispatch app\n\nResponders (players with a job in `jobs`) get a **Dispatch** app. Each call shows a title, message, distance, age and the caller's number, plus a flashing map blip, a notification and a sound.\n- **Respond** sets a GPS waypoint, tells the caller \"X accepted and is on the way\", and shows the other responders that someone has it.\n- **Close call** removes it from every phone and map. Calls nobody closes expire after `AlertSeconds`.\n- Calls come from texts to a service number, or from other scripts requesting a service.\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.Dispatch.AlertSeconds` | `600` | How long a call stays in the app |\n| `Config.Dispatch.CallNeedsPhone` | `false` | Whether the caller needs the phone item (a \"call EMS\" button while downed should not) |\n| `Numbers.\u003Cnumber>.request` | | Call title when someone requests the service, e.g. `'Person injured, EMS needed'` |\n| `Numbers.\u003Cnumber>.blip` | | `{ sprite, color }` of the responder's map blip |\n\n**Requesting a service from other scripts (e.g. a \"call EMS\" button on the death screen):**\n\n```lua\n-- client\nexports['x3d_phone']:RequestService('ambulance', 'Unconscious in the street')\n-- or\nTriggerServerEvent('x3d_phone:requestService', 'ambulance', 'Unconscious in the street')\n\n-- server (set your own title \u002F coords)\nexports['x3d_phone']:SendAlert('police', { source = src, title = 'Bank robbery', message = 'Pacific Standard' })\nexports['x3d_phone']:SendAlert('police', { coords = vector3(x, y, z), title = 'Alarm triggered' })\n```\n\n`RequestService` reads the location from the caller's character on the server, so it cannot be faked, and a player can call the same service once every 60 seconds.\n\n### Bills app\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.Billing.Enabled` | `true` | Shows the Bills app |\n| `Config.Billing.AllowPersonal` | `true` | Allows personal bills. The money goes to the biller's bank account, even when they are offline. |\n| `Config.Billing.AllowDecline` | `true` | The recipient can decline. With `false` they can only pay (the biller can still cancel). |\n| `Config.Billing.MinAmount` \u002F `MaxAmount` | `1` \u002F `1000000` | Smallest \u002F largest bill |\n| `Config.Billing.MaxOpenPerTarget` | `10` | Most unpaid bills one biller can have open to one number (anti-spam) |\n| `Config.Billing.PayFrom` | `'bank'` | Which account the payer pays from: `'bank'` or `'money'` |\n| `Config.Billing.UsersTable` | `'users'` | ESX players table, used to credit a biller who is offline |\n| `Config.Billing.Jobs` | police, ambulance, mechanic, taxi | Jobs that can bill on behalf of the business: `jobname = { label = 'Shown name', minGrade = 0, locked = true }` · `locked = true` = the biller cannot cancel and the recipient cannot decline; it is paid or an admin cancels it in x3d_adminpanel (default: police, ambulance) |\n| `Config.Billing.Admin` | `{ enabled = true, label = 'แอดมิน', groups = { 'admin', 'superadmin' }, locked = true }` | Admins can bill as \"Admin\" (e.g. fines); the money goes to `Billing.PayAdmin` at the end of `addons\u002Fbilling\u002Fserver.lua`, credited to nobody by default |\n\nLocked bills can only be cancelled in x3d_adminpanel → Phone → Unpaid bills (search by number or description, hold to cancel, with a cancel log).\n\nBusiness bills: by default there is no society account (`Billing.PaySociety` returns `false`), so the payer is not charged and the bill stays unpaid. Wire your server's society account (for example `esx_addonaccount`) in `addons\u002Fbilling\u002Fserver.lua` before you use business bills.\n\n- The recipient gets an alert at once if online. If offline, the bill waits in the app.\n- A bill can be paid once; tapping repeatedly never charges twice.\n- One bill every 5 seconds per player, and descriptions go through `FilterMessage` like other messages.\n\n**Billing from other scripts (server):**\n\n```lua\nlocal ok, idOrError = exports['x3d_phone']:CreateBill(source, '48213', 500, 'Parking fine', 'police')\n-- issuer: 'personal', a job name in Config.Billing.Jobs (the biller must actually have that job) or 'admin' (the biller must be in Config.Billing.Admin.groups)\n```\n\n### Images: camera, uploads and external links\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.Uploads.Enabled` | `true` | Enables the camera and wallpaper uploads from the PC |\n| `Config.Uploads.BaseUrl` | `''` | Can stay empty; see below |\n| `Config.Uploads.MaxBytes` | 3 MB | Maximum size per image (hard ceiling 8 MB) |\n| `Config.Uploads.PerPlayerPerHour` | `30` | Uploads allowed per player per hour |\n| `Config.Uploads.Keep` | `1000` | How many recent images to keep. After that the oldest is overwritten, and its link stops working. |\n| `Config.Uploads.Quality` | `0.85` | JPG quality of camera photos (0–1) |\n| `Config.ImageHosts` | imgur, ibb | External hosts players may paste image links from (chat, posts, wallpaper). `{}` turns external links off. |\n| `Config.AnyImageHost` | `false` | `true` accepts https links from any site |\n\n**Where images are stored:** in `x3d_phone\u002Fdata\u002Fuploads\u002F` on your server. They are served through FXServer's own game port (30120), with no outside service. Worst-case disk use is `Keep × MaxBytes`, about 3 GB by default, but a camera photo is normally under 400 KB.\n\n**`BaseUrl`:** when empty, image links are stored as `\u002Fi\u002F\u003Ctoken>.jpg`. Each player's client adds the address of the server it is connected to, so this works with no setup. Set `BaseUrl` only when:\n- you have an https domain pointing at the server (for example through a reverse proxy), and you want photos to show inside post cards in chat.\n- Example: `BaseUrl = 'https:\u002F\u002Fimg.myserver.com\u002Fx3d_phone'`\n\n**Why `cdn.discordapp.com` is not a default host:** Discord file links expire after about 24 hours when opened outside Discord, so the image would be gone the next day.\n\n> ⚠️ **`AnyImageHost = true`:** the image host sees the IP address of every player who views the image, and you do not control what the image shows. Prefer listing the hosts you trust in `ImageHosts`.\n\n### Mobile banking\n\n| Setting | Default | Meaning |\n|---|---|---|\n| `Config.Banking.Enabled` | `true` | Shows the Banking app |\n| `Config.Banking.MinTransfer` | `1` | Smallest transfer |\n| `Config.Banking.MaxTransfer` | `1000000` | Largest transfer |\n\nTransfers go to the phone number of an online player. They use the ESX `bank` account and are logged in the `x3d_phone_bank_history` table. A transfer cannot start while another one is still running, and a player can transfer once every 3 seconds.\n\n---\n\n## Copies to Discord\n\nAdd these to `server.cfg`. The webhook URLs stay on the server; players never see them.\n\n```\nset x3d_phone_upload_webhook \"https:\u002F\u002Fdiscord.com\u002Fapi\u002Fwebhooks\u002F...\"\nset x3d_phone_log_webhook    \"https:\u002F\u002Fdiscord.com\u002Fapi\u002Fwebhooks\u002F...\"\n```\n\n| Convar | What it sends |\n|---|---|\n| `x3d_phone_upload_webhook` | A copy of every photo a player takes or uploads, with name, server id, identifier and type (messages \u002F twitter \u002F wallpaper) |\n| `x3d_phone_log_webhook` | Logs of SMS, posts, Dark Chat and transfers (optional) |\n\n- Mentions are off in every post, so a player named `@everyone` pings nobody.\n- Posts are queued, one every 1.5 seconds, to stay under Discord's rate limit. When more than 20 are waiting, new ones are skipped.\n- The photo itself stays on your server, so in-game links never expire.\n- Only URLs that look like real Discord webhooks are accepted.\n\n---\n\n## Fitting your server: `addons\u002F`\n\nEdit these files freely. Each one works out of the box.\n\n| File | Functions | Default |\n|---|---|---|\n| `addons\u002Fnotify\u002Fclient.lua` | `Notify(message, kind)` | esx_notify → ox_lib → `ESX.ShowNotification` |\n| `addons\u002Fvoice\u002Fclient.lua` | `Voice.Enabled()`, `Voice.SetCallChannel(ch)`, `Voice.SetMuted(bool)` | pma-voice (mumble-voip example included) |\n| `addons\u002Fupload\u002Fclient.lua` | `Upload.Screenshot(kind, cb)`, `Upload.Target(kind, cb)` | screenshot-basic → stored on your server |\n| `addons\u002Fframework\u002Fserver.lua` \u002F `client.lua` | The framework bridge (`Framework.*`), identical across every X3D product | ESX if present, else standalone |\n| `addons\u002Fbilling\u002Fserver.lua` | `Billing.Charge`, `Billing.Refund`, `Billing.PaySociety`, `Billing.PayPerson`, `Billing.PayAdmin` | Charges \u002F refunds and pays the biller's bank through `Framework.*`; `PaySociety` returns `false`, wire it yourself |\n| `addons\u002Fbanking\u002Fserver.lua` | `Banking.GetBalances`, `Banking.Transfer`, `Banking.History` | ESX `bank` account |\n| `addons\u002Ffilter\u002Fserver.lua` | `FilterMessage(src, kind, message)` | blocks words in `Config.BannedWords` |\n| `addons\u002Flog\u002Fserver.lua` | `PhoneLog(src, kind, data)`, `UploadCopy(p, file)` | Discord webhooks from convars |\n| `addons\u002Flocale\u002Fshared.lua` | `T(th, en)` | follows `Config.Locale` |\n\n**Example:** to use your own banking system, change `Banking.Transfer` to call it and return `true`, or `false, 'error message'`. The server has already checked the amount, the recipient and the rate limit.\n\n**Example:** banned words:\n\n```lua\nConfig.BannedWords = { 'badword1', 'badword2' }\n```\n\n---\n\n## Exports (client)\n\n```lua\nexports['x3d_phone']:OpenPhone()\nexports['x3d_phone']:ClosePhone()\nexports['x3d_phone']:IsPhoneOpen()     --> boolean\nexports['x3d_phone']:GetPhoneNumber()  --> string | nil\nexports['x3d_phone']:IsInCall()        --> boolean\nexports['x3d_phone']:GetCallData()     --> { phoneNumber, displayName, isOutgoing } | nil\n```\n\n## Commands\n\n| Command | What it does |\n|---|---|\n| `\u002Fopenphone` | Open or close the phone |\n| `\u002Ftestringtone` | Play your selected ringtone |\n| `\u002Ftestnotification` | Play your selected alert sound |\n| `\u002Ftestdialtone` | Play the outgoing-call tone |\n\n## Troubleshooting\n\n| Symptom | Cause \u002F fix |\n|---|---|\n| F1 says \"You don't have a phone\" | `Config.UseItem = true` and the item is not in the inventory. Give the `phone` item, or set `UseItem = false`. |\n| No camera button | `screenshot-basic` is not ensured, or `Config.Uploads.Enabled = false` |\n| A photo fails with `upload_failed` | Check the console. If it says `cannot write data\u002Fuploads\u002F`, create the `data\u002Fuploads\u002F` folder in the resource. |\n| Calls connect but carry no audio | pma-voice is not installed, or is ensured after x3d_phone |\n| Posts do not appear in chat | `Config.Buzz.ToChat = false`, or the server does not run FiveM's `chat` resource |\n| A pasted image link will not send | The host is not in `Config.ImageHosts`, or the link does not start with https |\n","Free FiveM ESX Phone Script: Calls, SMS, Buzz","Free FiveM ESX phone: pma-voice calls, SMS with GPS sharing, contacts, Buzz and anonymous Dark Chat. Thai and English, optional phone item.",[66,69,71,73,75,77,79],{"kind":67,"url":68},"image","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-phone\u002Fmedia\u002F8704c36bb000ed04.png",{"kind":67,"url":70},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-phone\u002Fmedia\u002F8da2ccf3c9cb7166.png",{"kind":67,"url":72},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-phone\u002Fmedia\u002F463104ac8d020f1b.png",{"kind":67,"url":74},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-phone\u002Fmedia\u002F49fd564a93b137ce.png",{"kind":67,"url":76},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-phone\u002Fmedia\u002F60eb9d61acfcc2ed.png",{"kind":67,"url":78},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-phone\u002Fmedia\u002F7bfa7b032cc0179b.png",{"kind":67,"url":80},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-phone\u002Fmedia\u002Faea505b6f18ed953.png",[82,84,88,91],{"version":55,"released_at":56,"changelog_md":83},"### Changed\n\n- Store images now carry English captions for the English store page",{"version":85,"released_at":86,"changelog_md":87},"1.1.1","2026-10-12T03:26:38.605628Z","### Changed\n\n- UI font is now Kanit (one family for Thai and English), bundled inside the script; the Thai font now really loads in game (FiveM's browser dropped the old font declaration and fell back to a system font)",{"version":89,"released_at":90,"changelog_md":12},"1.0.1","2026-09-26T12:42:43.462227Z",{"version":92,"released_at":93,"changelog_md":94},"1.0.0","2026-09-25T15:31:53.651524Z","First public release.\r\n\r\n### Added\r\n\r\n- Phone app: keypad, recent calls, missed-call badge, voice calls through pma-voice (mute, ringtone, dial tone).\r\n- Messages: SMS conversations, unread badges, location sharing that sets a GPS waypoint on tap.\r\n- Contacts with favourites and photos.\r\n- Mobile banking: balance, history and transfers to an online player's phone number (ESX `bank` account by default, swappable in `addons\u002Fbanking\u002Fserver.lua`).\r\n- Camera: take a photo in game with screenshot-basic for messages, posts, contacts, Buzz avatar and wallpaper. Photos are stored on your own server (`data\u002Fuploads\u002F`), no image host or API key needed.\r\n- Post card skins in the in-game chat: default, halloween, christmas, songkran, night. Players pick one in Settings, or the server locks one with `Config.Buzz`. Uses FiveM's standard chat through `chat_theme`.\r\n- Phone item required by default (`Config.UseItem = true`, `Config.PhoneItem = 'phone'`): gates opening, calling, answering and SMS alerts on the server; the phone closes when the item leaves the inventory. `optional\u002Fphone_item.sql` adds the item.\r\n- Service numbers (`Config.Dispatch`): texting `police` \u002F `ambulance` \u002F `mechanic` reaches every online member of that job with the sender's server-side location; answers the old `esx_phone` API (`registerNumber`, `removeNumber`, `cancelMessage`, `esx_phone:send`) so esx_policejob \u002F esx_ambulancejob \u002F esx_mechanicjob work unchanged.\r\n- Dispatch app for responders: calls with distance, map blip and sound; Respond sets a waypoint and tells the caller help is coming. Client export `RequestService` \u002F event `x3d_phone:requestService` (e.g. a death-screen \"call EMS\" button) and server export `SendAlert`.\r\n- Bills app: bill any phone number personally or on behalf of a job (`Config.Billing.Jobs`, paid into `society_\u003Cjob>`); the recipient pays or declines in the phone; paying twice is impossible and a failed payout refunds the payer. Server export `CreateBill`.\r\n- Full emoji picker (3,600+ emoji, 9 groups, search) in SMS, Buzz and Dark Chat; text limits count real characters so Thai and emoji are not over-counted.\r\n- Optional Discord copies: every photo is posted to `x3d_phone_upload_webhook`, and SMS \u002F post \u002F Dark Chat \u002F transfer logs to `x3d_phone_log_webhook`. Webhooks stay server-side, mentions are disabled, and posts are queued.\r\n- External image links in messages, posts and wallpaper from `Config.ImageHosts`, or from any https site with `Config.AnyImageHost`.\r\n- `optional\u002Fscreenshot-basic\u002F` bundled (MIT, CitizenFX) for servers that do not have it.\r\n- Alt switches between the phone cursor and game controls while the phone stays open.\r\n- Buzz: server-wide feed, likes, delete own posts, new posts posted to in-game chat (`Config.Buzz.ToChat`).\r\n- Dark Chat: anonymous channels with handles and optional password.\r\n- Settings: wallpapers (preset, photo, upload from PC or image link), ringtones, notification sounds, keyboard-only mode.\r\n- Optional phone item (`Config.UseItem`), Thai \u002F English (`Config.Locale`).\r\n- Editable adapters in `addons\u002F`: notify, voice, banking, upload, message filter, log.",{"items":96,"page":866,"size":867,"total":867},[97,133,155,184,206,235,268,293,320,350,375,401,429,456,481,484,508,527,550,577,607,632,656,680,701,729,754,775,799,824,845],{"id":98,"slug":99,"name":100,"summary":101,"price_thb":102,"license_mode":103,"cover_key":104,"cover_url":105,"category_slugs":106,"tags":109,"latest_version":128,"latest_released_at":129,"published_at":130,"has_docs":58,"config":131,"rent_price_satang":132},"6bdadea7-4316-4a4a-a38e-87c5e841077d","x3d-replay","X3D Replay","BETA pricing. Records every player, every session. Watch it back in game: 4 cameras, kill\u002Fdeath timeline, pressed keys, script usage, macro flags.",59900,"shop_license","public\u002Fproducts\u002Fx3d-replay\u002Fcover.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-replay\u002Fcover.jpg",[107,108],"anticheat","admin",[46,110,111,112,113,114,115,116,117,118,119,120,121,122,107,123,124,125,126,127],"ESX Legacy","replay","fivem replay script","replay system","รีเพลย์","ดูย้อนหลัง","ย้อนดูผู้เล่น","บันทึกผู้เล่น","เคสรีพอร์ต","จับโกง","จับมาโคร","macro detection","กันโปร","แอดมิน","admin tool","demo recorder","spectate","BETA","1.0.2","2026-10-14T06:14:23.677549Z","2026-10-14T06:14:23.700289Z","owners",12000,{"id":134,"slug":135,"name":136,"summary":137,"price_thb":102,"license_mode":103,"cover_key":138,"cover_url":139,"category_slugs":140,"tags":141,"latest_version":92,"latest_released_at":153,"published_at":154,"has_docs":58,"config":131,"rent_price_satang":132},"ff948fa9-6fc5-410e-b952-ee88b15f0c9d","x3d-anticheat","X3D Anti-Cheat","BETA pricing, join the testing. Evidence-first anti-cheat: Discord embeds with screenshots, HWID bans, Steam\u002FDiscord account lock, two-line event guard.","public\u002Fproducts\u002Fx3d-anticheat\u002Fcover\u002Fd90612eed4448164.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-anticheat\u002Fcover\u002Fd90612eed4448164.jpg",[107],[46,142,143,107,144,145,146,122,147,148,149,150,151,152],"standalone","แอนตี้โกง","ป้องกันแฮก","กันโกง","HWID ban","ภาพหลักฐาน","ล็อกบัญชี Steam Discord","แบนเครื่อง","คิวยศ Discord","กัน event สแปม","แอนตี้โกง ESX","2026-09-16T09:45:51.78533Z","2026-09-16T09:46:00.05928Z",{"id":156,"slug":157,"name":158,"summary":159,"price_thb":160,"license_mode":103,"cover_key":161,"cover_url":162,"category_slugs":163,"tags":167,"latest_version":180,"latest_released_at":181,"published_at":182,"has_docs":58,"config":131,"rent_price_satang":183},"47a33337-7dcf-4a78-b056-4b3e324a648d","x3d-slots","X3D Slots 1024 Ways","1,024-way cascading slot, Mahjong style, 97.5% RTP. Server-authoritative spins, anti-exploit, with free spins, multipliers and big-win scenes.",250000,"public\u002Fproducts\u002Fx3d-slots\u002Fcover\u002Fd09c2066a6ea2968.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-slots\u002Fcover\u002Fd09c2066a6ea2968.jpg",[164,165,166],"casino","economy","entertainment",[46,142,168,169,164,170,171,172,173,174,175,176,177,178,179],"คาสิโน","สล็อต","slot","มินิเกม","minigame","RTP 97.5%","มาห์จอง","คาสเคด","ฟรีสปิน","ตู้สล็อต","ซื้อฟีเจอร์","ปรับ RTP","1.1.4","2026-10-12T17:13:01.863556Z","2026-09-14T15:28:02.281478Z",50000,{"id":185,"slug":186,"name":187,"summary":188,"price_thb":26,"license_mode":27,"cover_key":189,"cover_url":190,"category_slugs":191,"tags":193,"latest_version":203,"latest_released_at":204,"published_at":205,"has_docs":58,"config":59,"rent_price_satang":60},"1fb91794-3e8b-4955-bc54-dc6b1491912e","x3d-mapevents","X3D Map Events","Free event panel on the pause-menu map: name + countdown, click to set a waypoint. Other scripts push events like notifications; admins can create their own.","public\u002Fproducts\u002Fx3d-mapevents\u002Fcover\u002F8e738f2dfcf0ea2f.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-mapevents\u002Fcover\u002F8e738f2dfcf0ea2f.jpg",[31,192],"gameplay",[194,195,196,197,198,199,200,201,202,47,48],"อีเวนต์","อีเวนต์บนแผนที่","แผนที่","จุดนำทาง","นับถอยหลัง","pause menu","map events","event","waypoint","1.0.3","2026-10-12T17:13:20.327337Z","2026-10-12T04:21:56.480796Z",{"id":207,"slug":208,"name":209,"summary":210,"price_thb":26,"license_mode":27,"cover_key":211,"cover_url":212,"category_slugs":213,"tags":215,"latest_version":232,"latest_released_at":233,"published_at":234,"has_docs":58,"config":59,"rent_price_satang":60},"58697b89-cbe5-4b1f-8a29-c5289727202e","x3d-weaponskins","X3D Weapon Skins","Free collectible ESX weapon skins: each skin is an add-on weapon tied to its base gun. Unlock with an item, same damage, tradable, held-weapon effects.","public\u002Fproducts\u002Fx3d-weaponskins\u002Fcover\u002F25e3c37b23545ec8.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-weaponskins\u002Fcover\u002F25e3c37b23545ec8.jpg",[192,214],"inventory",[216,217,218,219,220,221,222,223,224,225,46,47,48,226,227,228,229,230,231],"weapon skins","สกินอาวุธ","สกินอาวุธ fivem","สกินปืน","gun skin","weapon skin fivem","คลังสกิน","เทรดสกิน","skin collection","x3d_inventory","ปลดล็อกสกิน","สกินสะสม","เอฟเฟกต์อาวุธ","ความหายากสกิน","สกิน add-on","แปลงสกินเป็นไอเทม","1.1.2","2026-10-12T17:13:35.599698Z","2026-10-10T11:46:16.716284Z",{"id":236,"slug":237,"name":238,"summary":239,"price_thb":26,"license_mode":27,"cover_key":240,"cover_url":241,"category_slugs":242,"tags":244,"latest_version":128,"latest_released_at":266,"published_at":267,"has_docs":58,"config":59,"rent_price_satang":60},"d82d8eb1-ed6a-43e3-86ef-24e45ae2b39d","x3d-damage","X3D Damage","Set every weapon's damage yourself, with bleed, slow, stun, knockdown and lifesteal effects. Weapon skins supported. ESX or standalone.","public\u002Fproducts\u002Fx3d-damage\u002Fcover\u002F8ce8864c16843fe6.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-damage\u002Fcover\u002F8ce8864c16843fe6.jpg",[192,243],"gangs",[245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,46,142,47,48,260,261,262,263,264,265],"weapon damage","ดาเมจอาวุธ","ดาเมจปืน","fivem weapon damage","damage script","headshot","headshot kill","เลือดออก","bleed","สตัน","stun","lifesteal","ดูดเลือด","เมืองปืน","pvp","ทะลุเกราะ","ดาเมจเสริม","ปิดท่าต่อยหนัก","ปรับดาเมจ","ทำให้ช้า","กันกระโดดหลบ","2026-10-12T17:14:19.289254Z","2026-10-10T11:45:52.279629Z",{"id":269,"slug":270,"name":271,"summary":272,"price_thb":26,"license_mode":27,"cover_key":273,"cover_url":274,"category_slugs":275,"tags":277,"latest_version":128,"latest_released_at":291,"published_at":292,"has_docs":58,"config":59,"rent_price_satang":60},"93def22a-9501-4b66-bdf0-158cc6a0093c","x3d-vehiclestorage","X3D Vehicle Storage","Free ESX trunk storage on the x3d_inventory screen: capacity by vehicle class and model, owner-only access, job cars and an admin view.","public\u002Fproducts\u002Fx3d-vehiclestorage\u002Fcover\u002F2c2d97cb47678e1b.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-vehiclestorage\u002Fcover\u002F2c2d97cb47678e1b.jpg",[214,276],"garage",[278,279,280,281,282,283,284,225,46,47,48,285,286,287,288,289,290],"trunk","ท้ายรถ","ท้ายรถ fivem","vehicle storage","trunk inventory","esx trunk","เก็บของในรถ","ตู้ท้ายรถ","รถงาน","กล่องเก็บของหน้ารถ","น้ำหนักท้ายรถ","ล็อกรถ","เปิดท้ายรถ","2026-10-12T17:14:46.845123Z","2026-10-05T04:28:52.749188Z",{"id":294,"slug":295,"name":296,"summary":297,"price_thb":26,"license_mode":27,"cover_key":298,"cover_url":299,"category_slugs":300,"tags":302,"latest_version":128,"latest_released_at":318,"published_at":319,"has_docs":58,"config":59,"rent_price_satang":60},"b642bb91-9f6d-4c3c-8830-e594c2a92fcb","x3d-vault","X3D Vault","Free ESX vaults on the x3d_inventory screen: player vaults with levels and sharing, job vaults per society, Thai and English.","public\u002Fproducts\u002Fx3d-vault\u002Fcover\u002F72ea3a88a64e0034.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-vault\u002Fcover\u002F72ea3a88a64e0034.jpg",[214,301],"jobs",[303,304,305,306,307,308,309,310,225,46,47,48,311,312,313,314,315,316,317],"vault","stash","ตู้เซฟ","ตู้เก็บของ","ตู้เซฟ fivem","esx stash","job vault","ตู้หน่วยงาน","ตู้เซฟแก๊ง","ตู้ส่วนตัว","แชร์ตู้","อัปเกรดตู้","ตู้เซฟตำรวจ","ตู้เซฟอาชีพ","ลิมิตตู้","2026-10-12T17:15:03.928293Z","2026-10-05T04:28:43.828514Z",{"id":321,"slug":322,"name":323,"summary":324,"price_thb":26,"license_mode":27,"cover_key":325,"cover_url":326,"category_slugs":327,"tags":328,"latest_version":347,"latest_released_at":348,"published_at":349,"has_docs":58,"config":59,"rent_price_satang":60},"70fa1474-294a-49ad-91cb-1de0ab4dc8d8","x3d-adminpanel","X3D Admin Panel","A free all-in-one FiveM admin panel: players, bans and warnings, alt detection, bags, items, vehicles, weather, player logs and menus for X3D scripts.","public\u002Fproducts\u002Fx3d-adminpanel\u002Fcover\u002F5cb8420f481eee28.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-adminpanel\u002Fcover\u002F5cb8420f481eee28.jpg",[108],[329,330,331,332,333,334,149,335,336,337,338,339,126,340,46,142,47,48,341,342,343,344,345,346],"admin panel","admin menu","แผงแอดมิน","เมนูแอดมิน","เมนูแอดมิน fivem","fivem admin menu","token ban","จับบัญชีสำรอง","alt detection","txadmin","noclip","log","แอดมินไทย","ยึดไอเทม","ประวัติแบน","โน้ตแอดมิน","นำเข้า txAdmin","บทบาทแอดมิน","1.0.5","2026-10-12T17:15:53.66615Z","2026-10-05T04:11:47.352812Z",{"id":351,"slug":352,"name":353,"summary":354,"price_thb":26,"license_mode":27,"cover_key":355,"cover_url":356,"category_slugs":357,"tags":358,"latest_version":180,"latest_released_at":373,"published_at":374,"has_docs":58,"config":59,"rent_price_satang":60},"d76ff7ae-ded6-4f39-b63f-734181952698","x3d-inventory","X3D Inventory","Free ESX inventory with big readable text, hotkeys 1–9 saved per character, coupon-based capacity and a storage panel for any vault or trunk script.","public\u002Fproducts\u002Fx3d-inventory\u002Fcover\u002Ffc3857e556cf31f3.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-inventory\u002Fcover\u002Ffc3857e556cf31f3.jpg",[214,31],[214,359,360,361,362,363,364,365,366,367,46,47,48,368,369,370,371,372],"กระเป๋า","กระเป๋า fivem","ui กระเป๋า","esx inventory","inventory fivem","ช่องลัด","hotbar","ไอเทม","nui","คูปองขยายช่อง","คูปองน้ำหนัก","ความหายากไอเทม","ค้นกระเป๋า","จำกัดน้ำหนัก","2026-10-12T17:16:22.733967Z","2026-10-05T04:10:14.693356Z",{"id":376,"slug":377,"name":378,"summary":379,"price_thb":26,"license_mode":27,"cover_key":380,"cover_url":381,"category_slugs":382,"tags":383,"latest_version":180,"latest_released_at":399,"published_at":400,"has_docs":58,"config":59,"rent_price_satang":60},"f782bbab-0321-4d3f-832f-797a2aa198f5","x3d-fortune","X3D Fortune","Free ESX fortune teller: daily horoscope, zodiac from your birthday, 28 siamsi sticks, 22-card tarot on 9 topics and a 10-card monthly spread.","public\u002Fproducts\u002Fx3d-fortune\u002Fcover\u002Fab130eeac9fbc029.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-fortune\u002Fcover\u002Fab130eeac9fbc029.jpg",[166],[384,385,386,387,388,389,390,391,392,46,47,48,393,394,395,396,397,398],"หมอดู","ดูดวง","เซียมซี","ไพ่ยิปซี","tarot","ราศี","ดวงรายวัน","fortune teller","npc","ดวงรายเดือน","ไพ่ทาโร่","เลขมงคล","สีมงคล","ไพ่กลับหัว","จุดหมอดู","2026-10-12T17:16:40.12128Z","2026-09-26T14:59:27.315955Z",{"id":402,"slug":403,"name":404,"summary":405,"price_thb":26,"license_mode":27,"cover_key":406,"cover_url":407,"category_slugs":408,"tags":409,"latest_version":426,"latest_released_at":427,"published_at":428,"has_docs":58,"config":59,"rent_price_satang":60},"9cb293aa-8b2c-447d-b810-3a7e385f6e81","x3d-banking","X3D Banking","Free ESX bank and ATM: deposit, withdraw, transfer by player ID, transaction history, every ATM on the map, every action checked on the server.","public\u002Fproducts\u002Fx3d-banking\u002Fcover\u002Fe7e66ab29819a980.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-banking\u002Fcover\u002Fe7e66ab29819a980.jpg",[165],[410,411,412,413,414,415,416,417,418,419,46,47,48,420,421,422,423,424,425],"banking","ธนาคาร","ระบบธนาคาร","atm","ตู้ atm","โอนเงิน","โอนด้วยเบอร์โทร","esx banking","bank script","ประวัติรายการ","ถอนด่วน","วงเงินโอน","สาขาธนาคาร","ฝากเงิน","ถอนเงิน","เพิ่มตู้ ATM","1.1.8","2026-10-12T17:16:55.98941Z","2026-09-26T14:59:08.07128Z",{"id":430,"slug":431,"name":432,"summary":433,"price_thb":26,"license_mode":27,"cover_key":434,"cover_url":435,"category_slugs":436,"tags":437,"latest_version":180,"latest_released_at":454,"published_at":455,"has_docs":58,"config":59,"rent_price_satang":60},"c72d91e0-6bcd-4fae-bde9-0e140e02b0cb","x3d-music","X3D Music","Free ESX boombox: place it on the ground or mount it on a car, play YouTube with a shared queue and distance falloff; speakers survive restarts.","public\u002Fproducts\u002Fx3d-music\u002Fcover\u002Fce445e0d251f7540.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-music\u002Fcover\u002Fce445e0d251f7540.jpg",[166],[438,439,440,441,442,443,444,445,446,447,46,47,48,448,449,450,451,452,453],"boombox","ลำโพง","ลำโพงเปิดเพลง","เปิดเพลง youtube","music script","fivem music","xsound","youtube","คิวเพลง","ติดบนรถ","ลำโพงติดรถ","เปิดเพลงในรถ","ฟังเพลงด้วยกัน","เพลงร่วมกัน","ลำโพงวางพื้น","จำกัดลำโพง","2026-10-12T17:17:14.482272Z","2026-09-26T14:56:09.091062Z",{"id":457,"slug":458,"name":459,"summary":460,"price_thb":26,"license_mode":27,"cover_key":461,"cover_url":462,"category_slugs":463,"tags":464,"latest_version":55,"latest_released_at":479,"published_at":480,"has_docs":58,"config":59,"rent_price_satang":60},"6125d85f-eaff-45cb-90cd-9db4d66e7954","x3d-respawn","X3D Respawn","Free death screen: Call EMS button, wait for medics when they are online, respawn points, self-revive, a death summary and death kept across relogs.","public\u002Fproducts\u002Fx3d-respawn\u002Fcover\u002F1af99658aa5089b2.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-respawn\u002Fcover\u002F1af99658aa5089b2.jpg",[31],[465,466,467,52,468,469,470,471,472,40,473,46,47,48,474,475,476,477,478],"respawn","หน้าจอตาย","death screen","call ems","ambulance","esx_ambulancejob","ชุบตัวเอง","จุดเกิดใหม่","สรุปการตาย","รอหมอ","กันหนีตาย","ปุ่มเรียกหมอ","เกิดใหม่เมือง","ชุดปฐมพยาบาล","2026-10-12T17:17:26.33517Z","2026-09-25T16:14:21.42282Z",{"id":22,"slug":23,"name":24,"summary":25,"price_thb":26,"license_mode":27,"cover_key":28,"cover_url":29,"category_slugs":482,"tags":483,"latest_version":55,"latest_released_at":56,"published_at":57,"has_docs":58,"config":59,"rent_price_satang":60},[31],[33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54],{"id":485,"slug":486,"name":487,"summary":488,"price_thb":26,"license_mode":27,"cover_key":489,"cover_url":490,"category_slugs":491,"tags":492,"latest_version":55,"latest_released_at":505,"published_at":506,"has_docs":507,"config":27,"rent_price_satang":60},"6705aca9-39b7-48ad-a39b-0dc4a906dd70","x3d-safe","X3D Safe Cracking","A dial-cracking minigame: turn with A and D, press E on the notch. One export, no dependencies.","public\u002Fproducts\u002Fx3d-safe\u002Fcover\u002F410a110f32490438.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-safe\u002Fcover\u002F410a110f32490438.jpg",[243,192],[493,494,305,495,171,172,496,497,142,498,47,48,499,500,501,502,503,504],"safe cracking","เจาะตู้เซฟ","หมุนตู้เซฟ","มินิเกม fivem","export","crime","หมุนหน้าปัด","ตู้เซฟธนาคาร","ตู้เซฟร้าน","ตู้เซฟบ้าน","ไม่ต้องใช้ ESX","มินิเกม A\u002FD","2026-10-12T17:18:34.435941Z","2026-09-24T03:53:28.3285Z",false,{"id":509,"slug":510,"name":511,"summary":512,"price_thb":26,"license_mode":27,"cover_key":513,"cover_url":514,"category_slugs":515,"tags":516,"latest_version":85,"latest_released_at":525,"published_at":526,"has_docs":507,"config":27,"rent_price_satang":60},"d5bcab3a-9189-4813-9b17-6b34f3a16584","x3d-lockpick","X3D Lockpick","A lockpick minigame felt out with WASD, called with one export and usable from any script.","public\u002Fproducts\u002Fx3d-lockpick\u002Fcover\u002Fc36242cb20a32b3b.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-lockpick\u002Fcover\u002Fc36242cb20a32b3b.jpg",[243,192],[517,518,519,171,172,496,497,142,498,47,48,520,521,522,523,524],"lockpick","งัดล็อก","สะเดาะกุญแจ","งัดประตูบ้าน","งัดรถ","หมุดล็อก","มินิเกม WASD","ปรับความยาก","2026-10-12T17:18:46.115275Z","2026-09-24T03:53:14.231073Z",{"id":528,"slug":529,"name":530,"summary":531,"price_thb":26,"license_mode":27,"cover_key":532,"cover_url":533,"category_slugs":534,"tags":536,"latest_version":547,"latest_released_at":548,"published_at":549,"has_docs":58,"config":59,"rent_price_satang":60},"65d3b2da-6dba-4cd0-9907-06b8e6e54994","x3d-houserobbery","X3D House Robbery","Pick the door, search the floor, crack the safe, with a cooldown per house and both minigames in the same zip.","public\u002Fproducts\u002Fx3d-houserobbery\u002Fcover\u002F73f596dab6db196a.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-houserobbery\u002Fcover\u002F73f596dab6db196a.jpg",[535,243],"housing",[537,538,539,540,541,305,517,171,243,542,535,498,46,47,48,543,494,544,545,546],"งัดบ้าน","ปล้นบ้าน","house robbery","robbery","ปล้น","แก๊ง","คีย์การ์ด","เงินแดง","จุดค้นของ","ปล้นบ้านคูลดาวน์","1.2.4","2026-10-12T17:19:03.056031Z","2026-09-24T03:48:06.633278Z",{"id":551,"slug":552,"name":553,"summary":554,"price_thb":26,"license_mode":27,"cover_key":555,"cover_url":556,"category_slugs":557,"tags":558,"latest_version":574,"latest_released_at":575,"published_at":576,"has_docs":58,"config":59,"rent_price_satang":60},"5532c49c-d819-4dda-b8a0-71514a14df31","x3d-selldrug","X3D Sell Drug","Shady buyers appear around the map on a timer and pay in black money. Runs on ESX or standalone.","public\u002Fproducts\u002Fx3d-selldrug\u002Fcover\u002F38844a64037d78d6.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-selldrug\u002Fcover\u002F38844a64037d78d6.jpg",[243,165],[559,560,561,562,563,564,565,566,243,542,498,46,47,48,567,568,569,570,571,572,544,573],"ขายยา","งานขายยา","sell drug","drug selling","ของผิดกฎหมาย","เงินดำ","black money","ผู้รับซื้อ","จุด10","จุดสิบ","จุดขายยา","ขายของจุด10","ขายของลับ","ฟอกเงิน","ผู้รับซื้อรายใหญ่","1.2.6","2026-10-12T17:19:19.018788Z","2026-09-24T03:39:03.703963Z",{"id":578,"slug":579,"name":580,"summary":581,"price_thb":26,"license_mode":27,"cover_key":582,"cover_url":583,"category_slugs":584,"tags":585,"latest_version":232,"latest_released_at":605,"published_at":606,"has_docs":507,"config":59,"rent_price_satang":60},"8e4dcdf4-7c70-4185-a3c9-15bb5328c457","x3d-useitem","X3D Use Item","Painkillers, bandages, AED, armor, helmet, repair kits, ammo, loot boxes and buff food in one system that needs only ESX.","public\u002Fproducts\u002Fx3d-useitem\u002Fcover\u002Fe007251b171e6791.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-useitem\u002Fcover\u002Fe007251b171e6791.jpg",[214,192],[586,587,588,589,590,591,592,593,594,595,596,597,598,46,47,48,599,600,601,602,603,604],"use item","ไอเทมใช้ได้","usable items","ยา","ผ้าพันแผล","aed","ชุบคนล้ม","ซ่อมรถ","กระสุน","กล่องสุ่ม","อาหาร","เสื้อเกราะ","หมวกกันน็อค","บัฟอาหาร","ชุดซ่อมรถ","เติมกระสุน","ยืมเสื้อเกราะ","ใช้ไอเทม","ไอเทมเติมเลือด","2026-10-12T17:19:33.653792Z","2026-09-24T02:05:34.038449Z",{"id":608,"slug":609,"name":610,"summary":611,"price_thb":26,"license_mode":27,"cover_key":612,"cover_url":613,"category_slugs":614,"tags":615,"latest_version":55,"latest_released_at":630,"published_at":631,"has_docs":507,"config":27,"rent_price_satang":60},"8c823bc1-1de6-41b6-bf82-146d5a55eeb5","x3d-progressbar","X3D Progress Bar","A peach-themed progress bar with ESC to cancel, a countdown, an automatic hotkey lock, and a bundled Thai font.","public\u002Fproducts\u002Fx3d-progressbar\u002Fcover\u002Ff6830df60f656452.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-progressbar\u002Fcover\u002Ff6830df60f656452.jpg",[31],[616,617,618,619,620,621,622,31,623,46,47,48,624,625,626,627,628,629],"progressbar","progress bar","แถบโหลด","แถบความคืบหน้า","esx_progressbar","esx progressbar","ui","ยกเลิก esc","หลอดโหลด","ฟอนต์ไทย","นับเวลาถอยหลัง","ล็อกปุ่มลัด","โปรเกรสบาร์","แทน esx_progressbar","2026-10-12T17:19:45.934106Z","2026-09-24T01:22:17.768991Z",{"id":633,"slug":634,"name":635,"summary":636,"price_thb":26,"license_mode":27,"cover_key":637,"cover_url":638,"category_slugs":639,"tags":640,"latest_version":232,"latest_released_at":654,"published_at":655,"has_docs":58,"config":59,"rent_price_satang":60},"63ce5efe-2f18-499e-a52b-8155a6cebb84","x3d-slide","X3D Slide","A shooter-style forward slide on Shift plus one key, with a cooldown to stop spam. Fully configurable, nothing else needed.","public\u002Fproducts\u002Fx3d-slide\u002Fcover\u002F8c8383608791f58a.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-slide\u002Fcover\u002F8c8383608791f58a.jpg",[192],[641,642,643,644,645,646,647,648,142,46,47,48,649,650,651,652,653],"slide","สไลด์","slide fivem","ท่าสไลด์","หลบ","dodge","ท่าทาง","คูลดาวน์","สไลด์แบบเกมยิง","Shift สไลด์","ท่าหลบเกมยิง","ปุ่มสไลด์","ปรับแรงสไลด์","2026-10-12T17:20:03.227099Z","2026-09-24T01:21:56.84494Z",{"id":657,"slug":658,"name":659,"summary":660,"price_thb":26,"license_mode":27,"cover_key":661,"cover_url":662,"category_slugs":663,"tags":664,"latest_version":180,"latest_released_at":678,"published_at":679,"has_docs":58,"config":59,"rent_price_satang":60},"9b62b8ed-5911-47a8-b695-3320a6183758","x3d-notify","X3D Notify","Notification cards in nine positions, with item icons and rarity frames, and full Thai support.","public\u002Fproducts\u002Fx3d-notify\u002Fcover\u002F4a9cbdcedd86a149.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-notify\u002Fcover\u002F4a9cbdcedd86a149.jpg",[31],[665,666,667,668,669,670,622,31,625,671,46,47,48,672,673,674,675,676,677],"notify","notification","แจ้งเตือน","แจ้งเตือน fivem","esx_notify","esx notify","ไอคอนไอเทม","การ์ดแจ้งเตือน","กรอบความหายาก","แจ้งเตือน 9 ตำแหน่ง","สีในข้อความ","แทน esx_notify","แจ้งเตือนไอเทม","2026-10-12T17:20:21.047259Z","2026-09-24T01:21:40.547491Z",{"id":681,"slug":682,"name":683,"summary":684,"price_thb":26,"license_mode":27,"cover_key":685,"cover_url":686,"category_slugs":687,"tags":688,"latest_version":347,"latest_released_at":699,"published_at":700,"has_docs":58,"config":27,"rent_price_satang":60},"e6dc80f3-4f29-4d01-bffa-eba6829c6497","x3d-loadingscreen","X3D Loading Screen","A terminal-style loading screen with an ENTER WORLD button the player presses before spawning. One HTML file, no build step.","public\u002Fproducts\u002Fx3d-loadingscreen\u002Fcover\u002F32f1538b8e18f4db.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-loadingscreen\u002Fcover\u002F32f1538b8e18f4db.jpg",[31],[689,690,691,692,693,694,622,142,46,47,48,695,696,624,697,698],"loading screen","หน้าโหลด","หน้าโหลด fivem","loadingscreen","esx_loadingscreen","enter world","ปุ่มเข้าเมือง","หน้าโหลดเทอร์มินัล","พื้นหลังวิดีโอ","เพลงหน้าโหลด","2026-10-12T17:20:39.269405Z","2026-09-24T00:50:19.336351Z",{"id":702,"slug":703,"name":704,"summary":705,"price_thb":26,"license_mode":27,"cover_key":706,"cover_url":707,"category_slugs":708,"tags":710,"latest_version":726,"latest_released_at":727,"published_at":728,"has_docs":58,"config":27,"rent_price_satang":60},"37f7d9db-f90d-4eed-861b-922da1072932","es-extended","ESX Legacy Core — X3D Build","A faster es_extended that stops player saves going corrupt, autosaves every 10 minutes and freezes the economy before a restart. Drop-in, same resource name.","public\u002Fproducts\u002Fes-extended\u002Fcover\u002Fa0b783dc4bf383e9.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fes-extended\u002Fcover\u002Fa0b783dc4bf383e9.jpg",[709],"optimization",[46,711,712,713,714,715,716,717,718,719,47,48,720,721,722,723,724,725],"es_extended","esx legacy","esx core","esx_core","framework","core","esx ฟรี","ดาวน์โหลด esx","esx legacy 1.13","กันข้อมูลหาย","กันดูป","audit log","เซฟผู้เล่น","esx fork","กันตกทะลุแมพ","1.13.6","2026-10-12T17:20:52.726747Z","2026-09-23T13:28:50.819982Z",{"id":730,"slug":731,"name":732,"summary":733,"price_thb":26,"license_mode":27,"cover_key":734,"cover_url":735,"category_slugs":736,"tags":737,"latest_version":751,"latest_released_at":752,"published_at":753,"has_docs":58,"config":59,"rent_price_satang":60},"7c86bf83-0df0-4e59-ab59-461ac4a2bff8","x3d-skin","X3D Character Skin","A 77-slot character editor with an orbiting camera, poses and lighting. No skinchanger, no database, any framework.","public\u002Fproducts\u002Fx3d-skin\u002Fcover\u002Fdb520ac6e2e3d502.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-skin\u002Fcover\u002Fdb520ac6e2e3d502.jpg",[31],[46,142,738,739,740,741,742,743,744,47,48,745,746,747,748,749,750],"ตกแต่งตัวละคร","skin","character customization","skin creator","แต่งตัวละคร","ร้านเสื้อผ้า","ร้านตัดผม","ตู้เสื้อผ้า","ร้านเสริมสวย","ร้านหน้ากาก","ท่าโพส","แต่งหน้า","ไม่ต้องใช้ skinchanger","1.5.4","2026-10-12T17:21:14.159219Z","2026-09-22T04:02:41.988907Z",{"id":755,"slug":756,"name":757,"summary":758,"price_thb":26,"license_mode":27,"cover_key":759,"cover_url":760,"category_slugs":761,"tags":762,"latest_version":180,"latest_released_at":773,"published_at":774,"has_docs":58,"config":59,"rent_price_satang":60},"7337afbc-ca0d-4071-9de4-2cc04bd1b4e6","x3d-menu","X3D Main Menu","A server main menu: system cards, announcements, timed events, an in-game guidebook and per-player settings. No database, any framework.","public\u002Fproducts\u002Fx3d-menu\u002Fcover\u002F8a1dbb30861b0387.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-menu\u002Fcover\u002F8a1dbb30861b0387.jpg",[31],[46,142,763,764,765,766,194,767,47,48,768,769,770,771,772],"เมนูหลัก","main menu","menu","ประกาศ","คู่มือเมือง","เมนูเมือง","กฎเมือง","เมนู F4","ตั้งค่าผู้เล่น","แบนเนอร์อีเวนต์","2026-10-12T17:21:29.681926Z","2026-09-21T04:20:29.437521Z",{"id":776,"slug":777,"name":778,"summary":779,"price_thb":26,"license_mode":27,"cover_key":780,"cover_url":781,"category_slugs":782,"tags":783,"latest_version":796,"latest_released_at":797,"published_at":798,"has_docs":58,"config":59,"rent_price_satang":60},"7a9dd386-11c0-4f21-8c2e-cfa7dc24d15d","x3d-dailylogin","X3D Daily Login","Free daily check-in with streaks and a fully editable reward table, no database required, a full bag never costs the reward, works with any framework.","public\u002Fproducts\u002Fx3d-dailylogin\u002Fcover\u002Fffcad7901926aa67.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-dailylogin\u002Fcover\u002Fffcad7901926aa67.jpg",[192],[46,142,784,785,786,787,788,47,48,789,790,791,792,793,794,795],"เช็คอินรายวัน","daily login","daily reward","สตรีค","รางวัลรายวัน","ล็อคอินรายวัน","รางวัลค้างรับ","รับย้อนหลัง","โบนัสเวลาเล่น","รางวัลเข้าเกม","เช็คชื่อรายวัน","ไม่ต้องใช้ฐานข้อมูล","1.4.3","2026-10-12T17:21:47.885233Z","2026-09-20T10:37:48.155794Z",{"id":800,"slug":801,"name":802,"summary":803,"price_thb":26,"license_mode":27,"cover_key":804,"cover_url":805,"category_slugs":806,"tags":807,"latest_version":821,"latest_released_at":822,"published_at":823,"has_docs":58,"config":59,"rent_price_satang":60},"83c7d7cb-bde4-45e3-a552-d7e377e4dc5d","x3d-mailbox","X3D Mailbox","Free offline mailbox with item and money attachments plus \u002Fredeem codes, no database required — Mail and Safe tabs, any framework through adapter files.","public\u002Fproducts\u002Fx3d-mailbox\u002Fcover\u002F743a9e72c1ae8d6d.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-mailbox\u002Fcover\u002F743a9e72c1ae8d6d.jpg",[192],[46,48,808,809,142,810,811,47,812,813,814,815,816,817,818,819,820,795],"mailbox","redeem code","กล่องจดหมาย","ของแนบ","รีดีมโค้ด","ส่งของออฟไลน์","โค้ดรับของ","กรอกโค้ดรับของ","จดหมายออฟไลน์","ส่งของให้คนออฟไลน์","โค้ดแจกของ","แจกของกิจกรรม","ของชดเชย","1.7.2","2026-10-12T17:22:30.892527Z","2026-09-19T19:05:39.140076Z",{"id":825,"slug":826,"name":827,"summary":828,"price_thb":26,"license_mode":27,"cover_key":829,"cover_url":830,"category_slugs":831,"tags":832,"latest_version":55,"latest_released_at":843,"published_at":844,"has_docs":58,"config":59,"rent_price_satang":60},"fd28d581-12ee-43b8-9dfb-aa18defe53be","x3d-carry","X3D Carry","Free player carry script: carry and steal bodies, fireman carry and piggyback, consent before carrying the living, fully server authoritative, no dependencies.","public\u002Fproducts\u002Fx3d-carry\u002Fcover\u002F133f7c2c2d80c8a5.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-carry\u002Fcover\u002F133f7c2c2d80c8a5.jpg",[192],[46,142,833,834,835,47,48,836,837,838,839,840,841,842],"อุ้มศพ","carry","อุ้มผู้เล่น","แย่งศพ","แบกผู้เล่น","ขี่หลัง","อุ้มพาดบ่า","ลากศพ","เมืองแก๊ง","อุ้มเพื่อน","2026-10-12T17:22:50.777785Z","2026-09-16T13:52:19.956202Z",{"id":846,"slug":847,"name":848,"summary":849,"price_thb":26,"license_mode":27,"cover_key":850,"cover_url":851,"category_slugs":852,"tags":853,"latest_version":128,"latest_released_at":864,"published_at":865,"has_docs":58,"config":59,"rent_price_satang":60},"12cb8b4e-b8db-4ad1-a8a2-bd0679aabec5","x3d-environment","X3D Environment","Free one-file map cleaner: no NPCs, no AI traffic, no scenarios, no idle cam, and blood, tire marks and wounds wiped away.","public\u002Fproducts\u002Fx3d-environment\u002Fcover\u002F7aa9b73e2efb1416.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-environment\u002Fcover\u002F7aa9b73e2efb1416.jpg",[709],[46,142,854,709,855,856,857,47,48,858,859,860,861,862,863],"ล้างแมพ","ลดแลค","เพิ่ม FPS","ปิด NPC","ปิดรถ AI","ล้างคราบเลือด","ลบลอยยาง","ปิดกล้อง idle","ลบ NPC","แมพโล่ง","2026-10-12T17:23:03.418375Z","2026-09-16T09:49:13.991696Z",1,31,{"html":869,"headings":870},"\u003Ch2 id=\"installation\">Installation\u003C\u002Fh2>\n\u003Col>\n\u003Cli>Extract the zip and put the \u003Ccode>x3d_phone\u003C\u002Fcode> folder in \u003Ccode>resources\u002F\u003C\u002Fcode>. \u003Cstrong>Do not rename the folder\u003C\u002Fstrong>: every export and event uses this name.\u003C\u002Fli>\n\u003Cli>Run \u003Ccode>install.sql\u003C\u002Fcode> on your server database. It is safe to run again and keeps existing data.\u003C\u002Fli>\n\u003Cli>If your server has no \u003Ccode>phone\u003C\u002Fcode> item, run \u003Ccode>optional\u002Fphone_item.sql\u003C\u002Fcode>. With ox_inventory, add the item to \u003Ccode>ox_inventory\u002Fdata\u002Fitems.lua\u003C\u002Fcode> instead; the file has an example.\u003C\u002Fli>\n\u003Cli>If your server has no \u003Ccode>screenshot-basic\u003C\u002Fcode>, move \u003Ccode>optional\u002Fscreenshot-basic\u002F\u003C\u002Fcode> into \u003Ccode>resources\u002F\u003C\u002Fcode>. You can skip this; only the camera needs it.\u003C\u002Fli>\n\u003Cli>Add these lines to \u003Ccode>server.cfg\u003C\u002Fcode>, in this order:\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cpre>\u003Ccode>ensure oxmysql\nensure es_extended\nensure pma-voice\nensure screenshot-basic\nensure x3d_phone\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Players open the phone with \u003Cstrong>F1\u003C\u002Fstrong>, the \u003Ccode>\u002Fopenphone\u003C\u002Fcode> command, or by using the \u003Ccode>phone\u003C\u002Fcode> item. While the phone is open, \u003Cstrong>Alt\u003C\u002Fstrong> switches to game controls; press it again to get the cursor back.\u003C\u002Fp>\n\u003Ch2 id=\"requirements\">Requirements\u003C\u002Fh2>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Resource\u003C\u002Fth>\n\u003Cth>Required\u003C\u002Fth>\n\u003Cth>Used for\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>es_extended\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>ESX Legacy. Without it the script runs standalone and you wire banking and billing yourself in \u003Ccode>addons\u002F\u003C\u002Fcode> (see \u003Ccode>Config.Framework\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>oxmysql\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>yes\u003C\u002Ftd>\n\u003Ctd>database\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>pma-voice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>call audio; without it calls connect but carry no audio\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>screenshot-basic\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>the camera; a copy is bundled in \u003Ccode>optional\u002F\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>chat\u003C\u002Fcode> (FiveM)\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>post cards in chat\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>No image host, no API key, and no other software to install.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2 id=\"all-settings-config-config-lua\">All settings: \u003Ccode>config\u002Fconfig.lua\u003C\u002Fcode>\u003C\u002Fh2>\n\u003Ch3 id=\"general\">General\u003C\u002Fh3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Locale\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>'th'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Language of the phone and its messages: \u003Ccode>'th'\u003C\u002Fcode> or \u003Ccode>'en'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Framework\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>'auto'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>'auto'\u003C\u002Fcode> (ESX if present, else standalone) \u003Ccode>| 'esx' | 'standalone'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Debug\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode> prints logs to the server console\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.OpenKey\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>'F1'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Key that opens the phone. Players can rebind it in Settings &gt; Key Bindings &gt; FiveM. This value only applies to a player's first join.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.DefaultContacts\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>{}\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Contacts added to every new number, e.g. \u003Ccode>{ phone = '911', name = 'Police' }\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Ch3 id=\"phone-item\">Phone item\u003C\u002Fh3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.UseItem\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>The item must be in the inventory to open the phone, call, answer and get SMS alerts\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.PhoneItem\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>'phone'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Item name. You can use one your server already has, e.g. \u003Ccode>'iphone'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>With \u003Ccode>UseItem\u003C\u002Fcode> on:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>No item: the phone does not open, and every server callback refuses. Triggering events by hand does not get past this.\u003C\u002Fli>\n\u003Cli>A player without the item cannot be called. The caller sees &quot;unavailable&quot; and the call is logged as missed.\u003C\u002Fli>\n\u003Cli>SMS are still stored, but no alert shows until the player has the item.\u003C\u002Fli>\n\u003Cli>If the item leaves the inventory while the phone is open (dropped or taken), the phone closes and any call ends.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3 id=\"calls\">Calls\u003C\u002Fh3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.UseVoice\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Use pma-voice for call audio\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.CallChannelStart\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>1000\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>First pma-voice channel used for calls. Change it only if it collides with another script.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.CallTimeout\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>30\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Seconds before an unanswered call ends\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Ringtones\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>5 sounds\u003C\u002Ftd>\n\u003Ctd>Ringtones; each maps to a GTA V sound\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.NotificationSounds\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>3 sounds\u003C\u002Ftd>\n\u003Ctd>Message alert sounds\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.RingtonePreviewMs\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>3000\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Length of \u003Ccode>\u002Ftestringtone\u003C\u002Fcode> and \u003Ccode>\u002Ftestdialtone\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cblockquote>\n\u003Cp>\u003Ccode>Config.Ringtones\u003C\u002Fcode>, \u003Ccode>Config.NotificationSounds\u003C\u002Fcode> and \u003Ccode>Config.Wallpapers\u003C\u002Fcode> are what the server checks a player's choice against. You can remove an option in the config. Adding a new option also needs a change to the phone's web UI.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch3 id=\"messages\">Messages\u003C\u002Fh3>\n\u003Cp>Emoji work in every text box (SMS, Buzz, Dark Chat), with a picker holding all 3,600+ emoji in 9 groups plus search. Lengths are counted in real characters, so Thai text and emoji are not over-counted.\u003C\u002Fp>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.MaxMessageLength\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>500\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Maximum length of an SMS or a Dark Chat message\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Ch3 id=\"buzz-and-post-card-skins\">Buzz and post card skins\u003C\u002Fh3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Buzz.ToChat\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>New posts appear in everyone's in-game chat\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Buzz.Themes\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>all 5\u003C\u002Ftd>\n\u003Ctd>Skins on offer: \u003Ccode>default\u003C\u002Fcode>, \u003Ccode>halloween\u003C\u002Fcode>, \u003Ccode>christmas\u003C\u002Fcode>, \u003Ccode>songkran\u003C\u002Fcode>, \u003Ccode>night\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Buzz.DefaultTheme\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>'default'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Skin for players who have not picked one\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Buzz.PlayerTheme\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>: players pick their skin in Settings. \u003Ccode>false\u003C\u002Fcode>: everyone uses \u003Ccode>DefaultTheme\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>\u003Cstrong>Example:\u003C\u002Fstrong> lock the whole server to Halloween for the event:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-lua\">Config.Buzz = {\n    ToChat = true,\n    Themes = { 'halloween' },\n    DefaultTheme = 'halloween',\n    PlayerTheme = false,\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Post cards use FiveM's standard \u003Ccode>chat\u003C\u002Fcode> resource. x3d_phone adds its own styles through \u003Ccode>chat_theme\u003C\u002Fcode> and leaves your chat theme alone. Post text is always escaped, so players cannot inject HTML into chat.\u003C\u002Fp>\n\u003Ch3 id=\"service-numbers-police-ems-mechanic-and-job-scripts\">Service numbers (police \u002F EMS \u002F mechanic) and job scripts\u003C\u002Fh3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Dispatch.Numbers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>police, ambulance, mechanic\u003C\u002Ftd>\n\u003Ctd>Service numbers: \u003Ccode>number = { label = 'Shown name', jobs = { 'job' }, coords = true }\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Dispatch.OnDutyOnly\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode> delivers only to players on duty (ESX Legacy \u003Ccode>job.onDuty\u003C\u002Fcode>)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cul>\n\u003Cli>Service numbers appear as special contacts for everyone and cannot be edited or deleted.\u003C\u002Fli>\n\u003Cli>Texting \u003Ccode>police\u003C\u002Fcode> delivers \u003Ccode>[Police] ...\u003C\u002Fcode> to every online player with a job in \u003Ccode>jobs\u003C\u002Fcode> who has a phone. It arrives from the sender's own number with their location, so a tap sets a GPS waypoint and a reply goes straight back to the sender.\u003C\u002Fli>\n\u003Cli>The location comes from the character's position on the server, so it cannot be faked. One message per service every 20 seconds.\u003C\u002Fli>\n\u003Cli>If nobody from the service is online, the sender is told.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Hooking up job scripts:\u003C\u002Fstrong> the \u003Ccode>police\u003C\u002Fcode>, \u003Ccode>ambulance\u003C\u002Fcode> and \u003Ccode>mechanic\u003C\u002Fcode> numbers already ship in the config, and your job scripts can add or remove numbers with these events.\u003C\u002Fp>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Event\u003C\u002Fth>\n\u003Cth>What it does\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>TriggerEvent('x3d_phone:registerNumber', number, label, isDispatch, hasCoords)\u003C\u002Fcode> (server)\u003C\u002Ftd>\n\u003Ctd>Adds a service number from a job script (an existing number is left alone)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>TriggerEvent('x3d_phone:removeNumber', number)\u003C\u002Fcode> (server)\u003C\u002Ftd>\n\u003Ctd>Removes a registered number (numbers in the config stay)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>TriggerServerEvent('x3d_phone:send', number, message, anonymous)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Scripts that alert the police automatically (robberies etc.) send a message to a service number. With \u003Ccode>anonymous = true\u003C\u002Fcode> the message comes from the service number instead of the player's.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cblockquote>\n\u003Cp>Job scripts that call the old \u003Ccode>esx_phone:*\u003C\u002Fcode> event names do not work with x3d_phone; point them at the events above.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch4>Dispatch app\u003C\u002Fh4>\n\u003Cp>Responders (players with a job in \u003Ccode>jobs\u003C\u002Fcode>) get a \u003Cstrong>Dispatch\u003C\u002Fstrong> app. Each call shows a title, message, distance, age and the caller's number, plus a flashing map blip, a notification and a sound.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Respond\u003C\u002Fstrong> sets a GPS waypoint, tells the caller &quot;X accepted and is on the way&quot;, and shows the other responders that someone has it.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Close call\u003C\u002Fstrong> removes it from every phone and map. Calls nobody closes expire after \u003Ccode>AlertSeconds\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Calls come from texts to a service number, or from other scripts requesting a service.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Dispatch.AlertSeconds\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>600\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>How long a call stays in the app\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Dispatch.CallNeedsPhone\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Whether the caller needs the phone item (a &quot;call EMS&quot; button while downed should not)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Numbers.&lt;number&gt;.request\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003C\u002Ftd>\n\u003Ctd>Call title when someone requests the service, e.g. \u003Ccode>'Person injured, EMS needed'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Numbers.&lt;number&gt;.blip\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>{ sprite, color }\u003C\u002Fcode> of the responder's map blip\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>\u003Cstrong>Requesting a service from other scripts (e.g. a &quot;call EMS&quot; button on the death screen):\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-lua\">-- client\nexports['x3d_phone']:RequestService('ambulance', 'Unconscious in the street')\n-- or\nTriggerServerEvent('x3d_phone:requestService', 'ambulance', 'Unconscious in the street')\n\n-- server (set your own title \u002F coords)\nexports['x3d_phone']:SendAlert('police', { source = src, title = 'Bank robbery', message = 'Pacific Standard' })\nexports['x3d_phone']:SendAlert('police', { coords = vector3(x, y, z), title = 'Alarm triggered' })\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>RequestService\u003C\u002Fcode> reads the location from the caller's character on the server, so it cannot be faked, and a player can call the same service once every 60 seconds.\u003C\u002Fp>\n\u003Ch3 id=\"bills-app\">Bills app\u003C\u002Fh3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.Enabled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Shows the Bills app\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.AllowPersonal\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Allows personal bills. The money goes to the biller's bank account, even when they are offline.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.AllowDecline\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>The recipient can decline. With \u003Ccode>false\u003C\u002Fcode> they can only pay (the biller can still cancel).\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.MinAmount\u003C\u002Fcode> \u002F \u003Ccode>MaxAmount\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>1\u003C\u002Fcode> \u002F \u003Ccode>1000000\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Smallest \u002F largest bill\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.MaxOpenPerTarget\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>10\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Most unpaid bills one biller can have open to one number (anti-spam)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.PayFrom\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>'bank'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Which account the payer pays from: \u003Ccode>'bank'\u003C\u002Fcode> or \u003Ccode>'money'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.UsersTable\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>'users'\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>ESX players table, used to credit a biller who is offline\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.Jobs\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>police, ambulance, mechanic, taxi\u003C\u002Ftd>\n\u003Ctd>Jobs that can bill on behalf of the business: \u003Ccode>jobname = { label = 'Shown name', minGrade = 0, locked = true }\u003C\u002Fcode> · \u003Ccode>locked = true\u003C\u002Fcode> = the biller cannot cancel and the recipient cannot decline; it is paid or an admin cancels it in x3d_adminpanel (default: police, ambulance)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Billing.Admin\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>{ enabled = true, label = 'แอดมิน', groups = { 'admin', 'superadmin' }, locked = true }\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Admins can bill as &quot;Admin&quot; (e.g. fines); the money goes to \u003Ccode>Billing.PayAdmin\u003C\u002Fcode> at the end of \u003Ccode>addons\u002Fbilling\u002Fserver.lua\u003C\u002Fcode>, credited to nobody by default\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>Locked bills can only be cancelled in x3d_adminpanel → Phone → Unpaid bills (search by number or description, hold to cancel, with a cancel log).\u003C\u002Fp>\n\u003Cp>Business bills: by default there is no society account (\u003Ccode>Billing.PaySociety\u003C\u002Fcode> returns \u003Ccode>false\u003C\u002Fcode>), so the payer is not charged and the bill stays unpaid. Wire your server's society account (for example \u003Ccode>esx_addonaccount\u003C\u002Fcode>) in \u003Ccode>addons\u002Fbilling\u002Fserver.lua\u003C\u002Fcode> before you use business bills.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>The recipient gets an alert at once if online. If offline, the bill waits in the app.\u003C\u002Fli>\n\u003Cli>A bill can be paid once; tapping repeatedly never charges twice.\u003C\u002Fli>\n\u003Cli>One bill every 5 seconds per player, and descriptions go through \u003Ccode>FilterMessage\u003C\u002Fcode> like other messages.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Billing from other scripts (server):\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-lua\">local ok, idOrError = exports['x3d_phone']:CreateBill(source, '48213', 500, 'Parking fine', 'police')\n-- issuer: 'personal', a job name in Config.Billing.Jobs (the biller must actually have that job) or 'admin' (the biller must be in Config.Billing.Admin.groups)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3 id=\"images-camera-uploads-and-external-links\">Images: camera, uploads and external links\u003C\u002Fh3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Uploads.Enabled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Enables the camera and wallpaper uploads from the PC\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Uploads.BaseUrl\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>''\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Can stay empty; see below\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Uploads.MaxBytes\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>3 MB\u003C\u002Ftd>\n\u003Ctd>Maximum size per image (hard ceiling 8 MB)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Uploads.PerPlayerPerHour\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>30\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Uploads allowed per player per hour\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Uploads.Keep\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>1000\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>How many recent images to keep. After that the oldest is overwritten, and its link stops working.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Uploads.Quality\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>0.85\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>JPG quality of camera photos (0–1)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.ImageHosts\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>imgur, ibb\u003C\u002Ftd>\n\u003Ctd>External hosts players may paste image links from (chat, posts, wallpaper). \u003Ccode>{}\u003C\u002Fcode> turns external links off.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.AnyImageHost\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode> accepts https links from any site\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>\u003Cstrong>Where images are stored:\u003C\u002Fstrong> in \u003Ccode>x3d_phone\u002Fdata\u002Fuploads\u002F\u003C\u002Fcode> on your server. They are served through FXServer's own game port (30120), with no outside service. Worst-case disk use is \u003Ccode>Keep × MaxBytes\u003C\u002Fcode>, about 3 GB by default, but a camera photo is normally under 400 KB.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>\u003Ccode>BaseUrl\u003C\u002Fcode>:\u003C\u002Fstrong> when empty, image links are stored as \u003Ccode>\u002Fi\u002F&lt;token&gt;.jpg\u003C\u002Fcode>. Each player's client adds the address of the server it is connected to, so this works with no setup. Set \u003Ccode>BaseUrl\u003C\u002Fcode> only when:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>you have an https domain pointing at the server (for example through a reverse proxy), and you want photos to show inside post cards in chat.\u003C\u002Fli>\n\u003Cli>Example: \u003Ccode>BaseUrl = 'https:\u002F\u002Fimg.myserver.com\u002Fx3d_phone'\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Why \u003Ccode>cdn.discordapp.com\u003C\u002Fcode> is not a default host:\u003C\u002Fstrong> Discord file links expire after about 24 hours when opened outside Discord, so the image would be gone the next day.\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>⚠️ \u003Cstrong>\u003Ccode>AnyImageHost = true\u003C\u002Fcode>:\u003C\u002Fstrong> the image host sees the IP address of every player who views the image, and you do not control what the image shows. Prefer listing the hosts you trust in \u003Ccode>ImageHosts\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch3 id=\"mobile-banking\">Mobile banking\u003C\u002Fh3>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Setting\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003Cth>Meaning\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Banking.Enabled\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>true\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Shows the Banking app\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Banking.MinTransfer\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>1\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Smallest transfer\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Config.Banking.MaxTransfer\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>1000000\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Largest transfer\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>Transfers go to the phone number of an online player. They use the ESX \u003Ccode>bank\u003C\u002Fcode> account and are logged in the \u003Ccode>x3d_phone_bank_history\u003C\u002Fcode> table. A transfer cannot start while another one is still running, and a player can transfer once every 3 seconds.\u003C\u002Fp>\n\u003Chr>\n\u003Ch2 id=\"copies-to-discord\">Copies to Discord\u003C\u002Fh2>\n\u003Cp>Add these to \u003Ccode>server.cfg\u003C\u002Fcode>. The webhook URLs stay on the server; players never see them.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>set x3d_phone_upload_webhook &quot;https:\u002F\u002Fdiscord.com\u002Fapi\u002Fwebhooks\u002F...&quot;\nset x3d_phone_log_webhook    &quot;https:\u002F\u002Fdiscord.com\u002Fapi\u002Fwebhooks\u002F...&quot;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Convar\u003C\u002Fth>\n\u003Cth>What it sends\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>x3d_phone_upload_webhook\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>A copy of every photo a player takes or uploads, with name, server id, identifier and type (messages \u002F twitter \u002F wallpaper)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>x3d_phone_log_webhook\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Logs of SMS, posts, Dark Chat and transfers (optional)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cul>\n\u003Cli>Mentions are off in every post, so a player named \u003Ccode>@everyone\u003C\u002Fcode> pings nobody.\u003C\u002Fli>\n\u003Cli>Posts are queued, one every 1.5 seconds, to stay under Discord's rate limit. When more than 20 are waiting, new ones are skipped.\u003C\u002Fli>\n\u003Cli>The photo itself stays on your server, so in-game links never expire.\u003C\u002Fli>\n\u003Cli>Only URLs that look like real Discord webhooks are accepted.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Chr>\n\u003Ch2 id=\"fitting-your-server-addons\">Fitting your server: \u003Ccode>addons\u002F\u003C\u002Fcode>\u003C\u002Fh2>\n\u003Cp>Edit these files freely. Each one works out of the box.\u003C\u002Fp>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>File\u003C\u002Fth>\n\u003Cth>Functions\u003C\u002Fth>\n\u003Cth>Default\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Fnotify\u002Fclient.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>Notify(message, kind)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>esx_notify → ox_lib → \u003Ccode>ESX.ShowNotification\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Fvoice\u002Fclient.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>Voice.Enabled()\u003C\u002Fcode>, \u003Ccode>Voice.SetCallChannel(ch)\u003C\u002Fcode>, \u003Ccode>Voice.SetMuted(bool)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>pma-voice (mumble-voip example included)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Fupload\u002Fclient.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>Upload.Screenshot(kind, cb)\u003C\u002Fcode>, \u003Ccode>Upload.Target(kind, cb)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>screenshot-basic → stored on your server\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Fframework\u002Fserver.lua\u003C\u002Fcode> \u002F \u003Ccode>client.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>The framework bridge (\u003Ccode>Framework.*\u003C\u002Fcode>), identical across every X3D product\u003C\u002Ftd>\n\u003Ctd>ESX if present, else standalone\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Fbilling\u002Fserver.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>Billing.Charge\u003C\u002Fcode>, \u003Ccode>Billing.Refund\u003C\u002Fcode>, \u003Ccode>Billing.PaySociety\u003C\u002Fcode>, \u003Ccode>Billing.PayPerson\u003C\u002Fcode>, \u003Ccode>Billing.PayAdmin\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Charges \u002F refunds and pays the biller's bank through \u003Ccode>Framework.*\u003C\u002Fcode>; \u003Ccode>PaySociety\u003C\u002Fcode> returns \u003Ccode>false\u003C\u002Fcode>, wire it yourself\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Fbanking\u002Fserver.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>Banking.GetBalances\u003C\u002Fcode>, \u003Ccode>Banking.Transfer\u003C\u002Fcode>, \u003Ccode>Banking.History\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>ESX \u003Ccode>bank\u003C\u002Fcode> account\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Ffilter\u002Fserver.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>FilterMessage(src, kind, message)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>blocks words in \u003Ccode>Config.BannedWords\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Flog\u002Fserver.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>PhoneLog(src, kind, data)\u003C\u002Fcode>, \u003Ccode>UploadCopy(p, file)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Discord webhooks from convars\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>addons\u002Flocale\u002Fshared.lua\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>T(th, en)\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>follows \u003Ccode>Config.Locale\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>\u003Cstrong>Example:\u003C\u002Fstrong> to use your own banking system, change \u003Ccode>Banking.Transfer\u003C\u002Fcode> to call it and return \u003Ccode>true\u003C\u002Fcode>, or \u003Ccode>false, 'error message'\u003C\u002Fcode>. The server has already checked the amount, the recipient and the rate limit.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Example:\u003C\u002Fstrong> banned words:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-lua\">Config.BannedWords = { 'badword1', 'badword2' }\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Chr>\n\u003Ch2 id=\"exports-client\">Exports (client)\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-lua\">exports['x3d_phone']:OpenPhone()\nexports['x3d_phone']:ClosePhone()\nexports['x3d_phone']:IsPhoneOpen()     --&gt; boolean\nexports['x3d_phone']:GetPhoneNumber()  --&gt; string | nil\nexports['x3d_phone']:IsInCall()        --&gt; boolean\nexports['x3d_phone']:GetCallData()     --&gt; { phoneNumber, displayName, isOutgoing } | nil\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"commands\">Commands\u003C\u002Fh2>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Command\u003C\u002Fth>\n\u003Cth>What it does\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>\u002Fopenphone\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Open or close the phone\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>\u002Ftestringtone\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Play your selected ringtone\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>\u002Ftestnotification\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Play your selected alert sound\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>\u002Ftestdialtone\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Play the outgoing-call tone\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Ch2 id=\"troubleshooting\">Troubleshooting\u003C\u002Fh2>\n\u003Cdiv class=\"table-scroll\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Symptom\u003C\u002Fth>\n\u003Cth>Cause \u002F fix\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>F1 says &quot;You don't have a phone&quot;\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>Config.UseItem = true\u003C\u002Fcode> and the item is not in the inventory. Give the \u003Ccode>phone\u003C\u002Fcode> item, or set \u003Ccode>UseItem = false\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>No camera button\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>screenshot-basic\u003C\u002Fcode> is not ensured, or \u003Ccode>Config.Uploads.Enabled = false\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>A photo fails with \u003Ccode>upload_failed\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>Check the console. If it says \u003Ccode>cannot write data\u002Fuploads\u002F\u003C\u002Fcode>, create the \u003Ccode>data\u002Fuploads\u002F\u003C\u002Fcode> folder in the resource.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Calls connect but carry no audio\u003C\u002Ftd>\n\u003Ctd>pma-voice is not installed, or is ensured after x3d_phone\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Posts do not appear in chat\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>Config.Buzz.ToChat = false\u003C\u002Fcode>, or the server does not run FiveM's \u003Ccode>chat\u003C\u002Fcode> resource\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>A pasted image link will not send\u003C\u002Ftd>\n\u003Ctd>The host is not in \u003Ccode>Config.ImageHosts\u003C\u002Fcode>, or the link does not start with https\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n",[871,875,878,881,885,888,891,894,897,900,903,906,909,912,915,918,921],{"id":872,"text":873,"level":874},"installation","Installation",2,{"id":876,"text":877,"level":874},"requirements","Requirements",{"id":879,"text":880,"level":874},"all-settings-config-config-lua","All settings: config\u002Fconfig.lua",{"id":882,"text":883,"level":884},"general","General",3,{"id":886,"text":887,"level":884},"phone-item","Phone item",{"id":889,"text":890,"level":884},"calls","Calls",{"id":892,"text":893,"level":884},"messages","Messages",{"id":895,"text":896,"level":884},"buzz-and-post-card-skins","Buzz and post card skins",{"id":898,"text":899,"level":884},"service-numbers-police-ems-mechanic-and-job-scripts","Service numbers (police \u002F EMS \u002F mechanic) and job scripts",{"id":901,"text":902,"level":884},"bills-app","Bills app",{"id":904,"text":905,"level":884},"images-camera-uploads-and-external-links","Images: camera, uploads and external links",{"id":907,"text":908,"level":884},"mobile-banking","Mobile banking",{"id":910,"text":911,"level":874},"copies-to-discord","Copies to Discord",{"id":913,"text":914,"level":874},"fitting-your-server-addons","Fitting your server: addons\u002F",{"id":916,"text":917,"level":874},"exports-client","Exports (client)",{"id":919,"text":920,"level":874},"commands","Commands",{"id":922,"text":923,"level":874},"troubleshooting","Troubleshooting",1792316314194]