Architecture
System Overview
wtf_group is a FiveM resource built on a client-server architecture with a React-based NUI (tablet UI) that communicates through a Lua bridge layer.
┌─────────────────────────────────────────────────────────────────┐
│ FiveM Client │
│ │
│ ┌──────────┐ ┌──────────────────┐ ┌────────────────────────┐ │
│ │ Bridge │ │ Client Lua │ │ NUI (React UI) │ │
│ │ │ │ │ │ │ │
│ │ QBX │◄─┤ tablet.lua │◄─┤ TabletShell │ │
│ │ QBCore │ │ sync.lua │ │ ├── Desktop │ │
│ │ ESX │ │ nui.lua │ │ ├── Taskbar │ │
│ │ Stand │ │ blips.lua │ │ ├── Windows │ │
│ │ │ │ vpn.lua │ │ ├── StartMenu │ │
│ │ │ │ auction.lua │ │ ├── SystemTray │ │
│ │ │ │ contracts.lua │ │ └── 18 Apps │ │
│ └──────────┘ └────────┬─────────┘ └────────────────────────┘ │
│ │ │
├──────────────────────────┼────────────────────────────────────────┤
│ FiveM Server │
│ │ │
│ ┌──────────┐ ┌────────┴─────────┐ ┌────────────────────────┐ │
│ │ Bridge │ │ Server Lua │ │ MySQL (oxmysql) │ │
│ │ │◄─┤ │◄─┤ │ │
│ │ │ │ database.lua │ │ 32 tables │ │
│ │ │ │ group.lua │ │ │ │
│ │ │ │ tablet.lua │ │ │ │
│ │ │ │ vpn.lua │ │ │ │
│ │ │ │ auction.lua │ │ │ │
│ │ │ │ contracts.lua │ │ │ │
│ │ │ │ weather.lua │ │ │ │
│ │ │ │ sync.lua │ │ │ │
│ └──────────┘ └──────────────────┘ └────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘Data Flow
NUI → Server
React Component
→ nuiFetch(callbackName, data) -- ui/src/nui.js
→ RegisterNUICallback() -- client/*.lua
→ TriggerServerEvent() -- client → server
→ MySQL.query/insert/update -- oxmysql
→ TriggerClientEvent() -- server → client
→ SendNUIMessage() -- client → React
→ window.addEventListener('message') -- ui/src/nui.jsSettings & App Data
React UI ←→ useTablet() hook ←→ localStorage (instant)
↓
dbStorage.js → NUI callback → Client → Server → MySQLSettings are written to both localStorage (instant UI response) and MySQL (durable persistence). On mount, MySQL values override localStorage.
Key Components
Bridge Layer (bridge/)
Framework abstraction that provides a unified API across Qbox, QBCore, ESX, and standalone:
lua
Bridge.GetPlayerData(source)
Bridge.GetMoney(source, 'bank')
Bridge.AddMoney(source, 'bank', amount, reason)
Bridge.RemoveMoney(source, 'bank', amount, reason)
Bridge.GetPlayerJob(source)
Bridge.GetPlayerGang(source)See Bridge Overview for details.
Client Lua (client/)
| File | Purpose |
|---|---|
main.lua | Resource init, command registration, keybinds |
tablet.lua | Tablet open/close, NUI bridge, app messaging |
sync.lua | Real-time group state synchronization |
nui.lua | NUI callback handlers for group operations |
blips.lua | GPS blip system, vehicle detection |
vpn.lua | VPN NUI callbacks + event listeners |
auction.lua | Auction NUI callbacks + event listeners |
contracts.lua | Contract NUI callbacks + event listeners |
Server Lua (server/)
| File | Purpose |
|---|---|
database.lua | Schema (32 tables), all DB functions |
group.lua | Core group logic, create/disband/leave |
tablet.lua | Server-side tablet handlers, data API |
sync.lua | Server→client state broadcasting |
task.lua | Task creation, activation, completion |
reputation.lua | XP, levels, perks |
roles.lua | Role assignment, permissions |
alliance.lua | Alliance/war system |
turfs.lua | Territory claiming, challenges |
bounty.lua | Bounty board, claiming |
mailbox.lua | Internal mail system |
garage.lua | Vehicle storage, spawning |
dashboard.lua | Dashboard data aggregation |
cooldown.lua | Global and per-activity cooldowns |
vpn.lua | VPN proxy management, license keys |
auction.lua | Auction server logic, bidding, wallet |
contracts.lua | Contract buying, starting, stock, queue |
weather_control.lua | Renewed-Weathersync admin controls |
React UI (ui/src/)
| Directory | Purpose |
|---|---|
apps/ | 18 tablet apps (VPN, Auction, Weather, etc.) |
components/ | 26+ shared UI components |
context/ | React contexts (Group, Tablet, App) |
shell/ | Tablet OS shell (Desktop, Taskbar, Window, etc.) |
lib/ | Utilities (settings, icons, sounds, DB storage) |
styles/ | CSS (tablet theme, animations) |
Database Schema
32 MySQL tables organized by feature:
| Group | Tables |
|---|---|
| Group Core | wtf_groups, wtf_group_members, wtf_group_roles, wtf_group_activity_log, wtf_group_reputation, wtf_group_spawns |
| Features | wtf_tasks, wtf_global_cooldowns, wtf_group_alliances, wtf_turfs, wtf_turf_challenges, wtf_bounties, wtf_mailbox, wtf_garage |
| Tablet | wtf_tablet_app_data, wtf_tablet_notifications, wtf_tablet_settings, wtf_tablet_installed_apps |
| VPN | wtf_vpn_proxies, wtf_vpn_license_keys |
| Auction | auction_listings, auction_bids, auction_watchlist, auction_balances, auction_accounts, auction_sessions, auction_settings |
| Contracts | wtf_contract_stock, wtf_contract_active, wtf_contract_inventory, wtf_contract_start_queue, wtf_contract_history |
See Database Reference for full schema.
NUI Message Protocol
All React ↔ Lua communication uses SendNUIMessage with action strings:
| Action | Direction | Description |
|---|---|---|
groupSync | Server→React | Group state update |
vpnData | Server→React | VPN connection status |
auctionResponse | Server→React | Auction action result |
contractsResponse | Server→React | Contract action result |
tablet:settingsLoaded | Server→React | Settings loaded from DB |
tablet:appDataLoaded | Server→React | App data loaded from DB |
See Events Reference for the complete list.