├── qb-phone
├── .gitattributes
├── html
│ ├── js
│ │ ├── camera.js
│ │ ├── config.js
│ │ ├── calculator.js
│ │ ├── ping.js
│ │ ├── jobcenter.js
│ │ ├── wenmo.js
│ │ ├── lsbn.js
│ │ ├── gopro.js
│ │ ├── details.js
│ │ ├── garage.js
│ │ ├── mail.js
│ │ ├── taxi.js
│ │ ├── gallery.js
│ │ ├── casino.js
│ │ └── debt.js
│ ├── img
│ │ ├── card.jpg
│ │ ├── taxi.png
│ │ ├── LSBNlogo.png
│ │ ├── apps
│ │ │ ├── RSL.png
│ │ │ ├── job.png
│ │ │ ├── clock.png
│ │ │ ├── debt.png
│ │ │ ├── house.png
│ │ │ ├── info.png
│ │ │ ├── lsbn.png
│ │ │ ├── mail.png
│ │ │ ├── notes.png
│ │ │ ├── phone.png
│ │ │ ├── ping.png
│ │ │ ├── wenmo.png
│ │ │ ├── camera.png
│ │ │ ├── contacts.png
│ │ │ ├── crypto.png
│ │ │ ├── details.png
│ │ │ ├── discord.png
│ │ │ ├── facetime.png
│ │ │ ├── gallery.png
│ │ │ ├── garage.png
│ │ │ ├── invoice.png
│ │ │ ├── messages.png
│ │ │ ├── politie.png
│ │ │ ├── racing.png
│ │ │ ├── safari.png
│ │ │ ├── services.png
│ │ │ ├── settings.png
│ │ │ ├── taxiapp.png
│ │ │ ├── twatter.png
│ │ │ ├── weather.png
│ │ │ ├── bank-logo.png
│ │ │ ├── calcilator.png
│ │ │ ├── calculator.png
│ │ │ ├── documents.png
│ │ │ ├── employment.png
│ │ │ ├── jobcenter.png
│ │ │ ├── details1213.png
│ │ │ ├── whatsapp-chat.png
│ │ │ ├── Advertisements.png
│ │ │ └── whatsapp-chatlight.png
│ │ ├── default.png
│ │ ├── erpinger.png
│ │ ├── nphone.png
│ │ ├── employment.png
│ │ ├── samsung-s10.png
│ │ ├── samsung-s102.png
│ │ ├── backgrounds
│ │ │ ├── bg.png
│ │ │ ├── yp.png
│ │ │ └── default-qbcore.png
│ │ ├── default-QBCore.jpg
│ │ └── map-photo-ping.png
│ └── css
│ │ ├── tooltip.css
│ │ ├── z-style.css
│ │ ├── camera.css
│ │ ├── lsbn.css
│ │ ├── taxi.css
│ │ ├── calculator.css
│ │ ├── ping.css
│ │ ├── casino.css
│ │ ├── gopro.css
│ │ ├── wenmo.css
│ │ ├── mail.css
│ │ ├── debt.css
│ │ ├── gallery.css
│ │ ├── details.css
│ │ └── jobcenter.css
├── assets
│ └── dialing.ogg
├── server
│ ├── versionchecker.lua
│ ├── cleanup.lua
│ ├── taxi.lua
│ ├── gallery.lua
│ ├── news.lua
│ ├── commands.lua
│ ├── pings.lua
│ ├── wenmo.lua
│ ├── advertisements.lua
│ ├── betting.lua
│ ├── whatsapp.lua
│ ├── twitter.lua
│ ├── invoices.lua
│ ├── mail.lua
│ ├── documents.lua
│ ├── garage.lua
│ └── crypto.lua
├── client
│ ├── trucker.lua
│ ├── taxi.lua
│ ├── gallery.lua
│ ├── news.lua
│ ├── wenmo.lua
│ ├── crypto.lua
│ ├── gopro.lua
│ ├── debt.lua
│ ├── betting.lua
│ ├── pings.lua
│ ├── houses.lua
│ ├── jobcenter.lua
│ ├── notification.lua
│ ├── mail.lua
│ ├── invoices.lua
│ ├── advertisements.lua
│ ├── documents.lua
│ ├── garage.lua
│ ├── twitter.lua
│ ├── groups.lua
│ ├── whatsapp.lua
│ ├── racing.lua
│ └── employment.lua
├── fxmanifest.lua
├── shared
│ └── shared.lua
├── Exports.MD
├── qb-phone.sql
└── README.md
└── README.md
/qb-phone/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/qb-phone/html/js/camera.js:
--------------------------------------------------------------------------------
1 | function setUpCameraApp(url){
2 | $('.phone-tab-button').click();
3 | }
--------------------------------------------------------------------------------
/qb-phone/assets/dialing.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/assets/dialing.ogg
--------------------------------------------------------------------------------
/qb-phone/html/img/card.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/card.jpg
--------------------------------------------------------------------------------
/qb-phone/html/img/taxi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/taxi.png
--------------------------------------------------------------------------------
/qb-phone/html/img/LSBNlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/LSBNlogo.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/RSL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/RSL.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/job.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/job.png
--------------------------------------------------------------------------------
/qb-phone/html/img/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/default.png
--------------------------------------------------------------------------------
/qb-phone/html/img/erpinger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/erpinger.png
--------------------------------------------------------------------------------
/qb-phone/html/img/nphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/nphone.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/clock.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/debt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/debt.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/house.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/house.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/info.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/lsbn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/lsbn.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/mail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/mail.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/notes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/notes.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/phone.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/ping.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/ping.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/wenmo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/wenmo.png
--------------------------------------------------------------------------------
/qb-phone/html/img/employment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/employment.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/camera.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/contacts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/contacts.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/crypto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/crypto.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/details.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/discord.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/discord.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/facetime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/facetime.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/gallery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/gallery.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/garage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/garage.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/invoice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/invoice.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/messages.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/messages.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/politie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/politie.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/racing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/racing.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/safari.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/safari.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/services.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/services.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/settings.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/taxiapp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/taxiapp.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/twatter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/twatter.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/weather.png
--------------------------------------------------------------------------------
/qb-phone/html/img/samsung-s10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/samsung-s10.png
--------------------------------------------------------------------------------
/qb-phone/html/img/samsung-s102.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/samsung-s102.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/bank-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/bank-logo.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/calcilator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/calcilator.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/calculator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/calculator.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/documents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/documents.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/employment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/employment.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/jobcenter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/jobcenter.png
--------------------------------------------------------------------------------
/qb-phone/html/img/backgrounds/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/backgrounds/bg.png
--------------------------------------------------------------------------------
/qb-phone/html/img/backgrounds/yp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/backgrounds/yp.png
--------------------------------------------------------------------------------
/qb-phone/html/img/default-QBCore.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/default-QBCore.jpg
--------------------------------------------------------------------------------
/qb-phone/html/img/map-photo-ping.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/map-photo-ping.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/details1213.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/details1213.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/whatsapp-chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/whatsapp-chat.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/Advertisements.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/Advertisements.png
--------------------------------------------------------------------------------
/qb-phone/html/img/apps/whatsapp-chatlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/apps/whatsapp-chatlight.png
--------------------------------------------------------------------------------
/qb-phone/html/img/backgrounds/default-qbcore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jnccloud/Renewed-Phone-Wahyu-Adi/HEAD/qb-phone/html/img/backgrounds/default-qbcore.png
--------------------------------------------------------------------------------
/qb-phone/server/versionchecker.lua:
--------------------------------------------------------------------------------
1 | if not lib.versionCheck('Renewed-Scripts/qb-phone') then print('Please update to latest qb-phone') end
2 | if not lib.checkDependency('ox_lib', '3.6.0') then print('Please update to ox_lib version 3.6.0') end
--------------------------------------------------------------------------------
/qb-phone/client/trucker.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 | RegisterNUICallback('GetTruckerData', function(_, cb)
3 | local TruckerMeta = PlayerData.metadata.jobrep.trucker
4 | local TierData = exports['qb-trucker']:GetTier(TruckerMeta)
5 | cb(TierData)
6 | end)
--------------------------------------------------------------------------------
/qb-phone/html/js/config.js:
--------------------------------------------------------------------------------
1 | Config = []
2 |
3 | Config.HeaderDisabledApps = [
4 | "bank",
5 | "whatsapp",
6 | "garage",
7 | "crypto",
8 | "racing",
9 | "houses",
10 | "services",
11 | "trucker",
12 | ]
13 |
14 | Config.DefaultCryptoPage = "general";
--------------------------------------------------------------------------------
/qb-phone/html/js/calculator.js:
--------------------------------------------------------------------------------
1 | function data(val){
2 | calc.display.value += val;
3 | }
4 | function ac(){
5 | calc.display.value = "";
6 | }
7 | function c(){
8 | calc.display.value = calc.display.value.slice(0, -1);
9 | }
10 | function equal(){
11 | calc.display.value = eval(calc.display.value);
12 | }
--------------------------------------------------------------------------------
/qb-phone/html/js/ping.js:
--------------------------------------------------------------------------------
1 | $(document).on('click', '#ping-send', function(e){
2 | e.preventDefault();
3 | var IDPlayer = $(".ierplol").val();
4 | if (IDPlayer >= 1){
5 | $.post('https://qb-phone/SendPingPlayer', JSON.stringify({
6 | id: IDPlayer
7 | }));
8 | $(".ierplol").val("");
9 | }
10 | });
--------------------------------------------------------------------------------
/qb-phone/html/css/tooltip.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .tooltip-inner {
4 | font-size: 11px;
5 | color: white;
6 | }
7 |
8 | .toggle.ios, .toggle-on.ios, .toggle-off.ios {
9 | border-radius: 20px;
10 | }
11 |
12 | .toggle.ios .toggle-handle {
13 | border-radius: 20px;
14 | }
15 |
16 | .custom-control, .custom-switch, .custom-control-input {
17 | color: white
18 | }
19 |
--------------------------------------------------------------------------------
/qb-phone/html/css/z-style.css:
--------------------------------------------------------------------------------
1 | #z-style-expert{
2 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
3 |
4 | background: #2c465f;
5 | background: #0d1218c0;
6 |
7 | background: #f5a15b;
8 | background: #c27e47;
9 |
10 | background: #8ee074;
11 | background: #6cac59;
12 |
13 | box-shadow: 0rem 0rem 0.2rem 0.02rem #000000a6;
14 |
15 | background: #227ea5;
16 |
17 | }
--------------------------------------------------------------------------------
/qb-phone/client/taxi.lua:
--------------------------------------------------------------------------------
1 | RegisterNUICallback('GetAvailableTaxiDrivers', function(_, cb)
2 | local drivers = lib.callback.await('qb-phone:server:GetAvailableTaxiDrivers', false)
3 | cb(drivers)
4 | end)
5 |
6 | RegisterNetEvent('qb-phone:OpenAvailableTaxi', function()
7 | local taxiMenu = {}
8 |
9 | -- TO BE WRITTEN
10 |
11 | lib.registerContext({
12 | id = 'taxi_call_menu',
13 | title = 'Available Taxis',
14 | options = taxiMenu
15 | })
16 | lib.showContext('taxi_call_menu')
17 | end)
--------------------------------------------------------------------------------
/qb-phone/client/gallery.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | RegisterNUICallback('GetGalleryData', function(_, cb)
4 | local data = PhoneData.Images
5 | cb(data)
6 | end)
7 |
8 | RegisterNUICallback('DeleteImage', function(image,cb)
9 | TriggerServerEvent('qb-phone:server:RemoveImageFromGallery',image)
10 | Wait(400)
11 | TriggerServerEvent('qb-phone:server:getImageFromGallery')
12 | cb(true)
13 | end)
14 |
15 | -- Events
16 |
17 | RegisterNetEvent('qb-phone:refreshImages', function(images)
18 | PhoneData.Images = images
19 | end)
--------------------------------------------------------------------------------
/qb-phone/server/cleanup.lua:
--------------------------------------------------------------------------------
1 | -- we only do this at the start of the server because its resource intensive and might lagg your database depending on the amount of data that needs to be dropped --
2 | AddEventHandler('onResourceStart', function(resource)
3 | if resource == GetCurrentResourceName() then
4 | Wait(100)
5 | MySQL.query.await('DELETE FROM phone_tweets WHERE `date` < NOW() - INTERVAL ? hour', {Config.TweetDuration})
6 | MySQL.query.await('DELETE FROM player_mails WHERE `date` < NOW() - INTERVAL ? hour', {Config.MailDuration})
7 | end
8 | end)
--------------------------------------------------------------------------------
/qb-phone/client/news.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | RegisterNUICallback('Send_lsbn_ToChat', function(data, cb)
4 | TriggerServerEvent('qb-phone:server:Send_lsbn_ToChat', data)
5 | cb("ok")
6 | end)
7 |
8 | RegisterNUICallback('GetLSBNchats', function(data, cb)
9 | TriggerServerEvent('qb-phone:server:GetLSBNchats', data)
10 | cb("ok")
11 | end)
12 |
13 | -- Events
14 |
15 | RegisterNetEvent('qb-phone:LSBN-reafy-for-add', function(data, toggle, text)
16 | if toggle then
17 | TriggerEvent('qb-phone:client:CustomNotification',
18 | "LSBN",
19 | text,
20 | "fas fa-bullhorn",
21 | "#d8e212",
22 | 1500
23 | )
24 | end
25 |
26 | SendNUIMessage({
27 | action = "AddNews",
28 | data = data,
29 | })
30 | end)
--------------------------------------------------------------------------------
/qb-phone/html/js/jobcenter.js:
--------------------------------------------------------------------------------
1 | function LoadJobCenter(){
2 | $.post('https://qb-phone/GetJobCentersJobs', JSON.stringify({}), function(Jobs){
3 | $(".job-list").html("");
4 | for (const [_, v] of Object.entries(Jobs)) {
5 | var AddOption =
6 | '
'
8 | $('.job-list').append(AddOption);
9 | }
10 | });
11 | };
12 |
13 | $(document).on('click', '#job-icon-class', function(e){
14 | e.preventDefault();
15 | var event = $(this).data('event')
16 | $.post('https://qb-phone/CasinoPhoneJobCenter', JSON.stringify({
17 | event: event,
18 | }));
19 | });
--------------------------------------------------------------------------------
/qb-phone/client/wenmo.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | RegisterNUICallback('wenmo_givemoney_toID', function(data)
4 | TriggerServerEvent('qb-phone:server:wenmo_givemoney_toID', data)
5 | end)
6 |
7 | RegisterNetEvent('QBCore:Client:OnMoneyChange', function(type, amount, changeType, reason)
8 | if type == "bank" then
9 | if changeType == 'remove' then
10 | SendNUIMessage({
11 | action = "ChangeMoney_Wenmo",
12 | Color = "#f5a15b",
13 | Amount = "-$"..amount,
14 | Reason = reason or "",
15 | })
16 | else
17 | SendNUIMessage({
18 | action = "ChangeMoney_Wenmo",
19 | Color = "#8ee074",
20 | Amount = "+$"..amount,
21 | Reason = reason or "",
22 | })
23 | end
24 | end
25 | end)
26 |
--------------------------------------------------------------------------------
/qb-phone/client/crypto.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | RegisterNUICallback('GetCryptosFromDegens', function(_, cb)
4 | cb(Config.CryptoCoins)
5 | end)
6 |
7 |
8 | RegisterNUICallback('BuyCrypto', function(data, cb)
9 | TriggerServerEvent('qb-phone:server:PurchaseCrypto', data.metadata, data.amount)
10 |
11 | cb("ok")
12 | end)
13 |
14 | RegisterNUICallback('SellCrypto', function(data, cb)
15 | TriggerServerEvent('qb-phone:server:SellCrypto', data.metadata, data.amount)
16 | cb("ok")
17 | end)
18 |
19 | RegisterNUICallback('ExchangeCrypto', function(data, cb)
20 | TriggerServerEvent('qb-phone:server:ExchangeCrypto', data.metadata, data.amount, data.stateid)
21 |
22 | cb("ok")
23 | end)
24 |
25 | RegisterNetEvent('qb-phone:client:UpdateCrypto', function()
26 | SendNUIMessage({
27 | action = "UpdateCrypto",
28 | PlayerData = PlayerData,
29 | })
30 | end)
31 |
--------------------------------------------------------------------------------
/qb-phone/client/gopro.lua:
--------------------------------------------------------------------------------
1 | if GetResourceState('brazzers-cameras') == 'started' then
2 | RegisterNUICallback('SetupGoPros', function(_, cb)
3 | local list = Config.BrazzersCameras and exports['brazzers-cameras']:GetMyCams() or {}
4 | cb(list)
5 | end)
6 |
7 | RegisterNUICallback('gopro-viewcam', function(data, cb)
8 | if not data then return end
9 | TriggerEvent('Renewed-Cameras:ViewCamera', tonumber(data.id))
10 | cb("ok")
11 | end)
12 |
13 | RegisterNUICallback('gopro-track', function(data, cb)
14 | TriggerEvent('Renewed-Cameras:client:TrackCam', data.id)
15 | if not data then return end
16 | cb("ok")
17 | end)
18 |
19 | RegisterNUICallback('gopro-transfer', function(data, cb)
20 | if not data then return end
21 | TriggerEvent("Renewed-Cameras:client:GrantAccess", tonumber(data.id), tonumber(data.stateid))
22 | cb("ok")
23 | end)
24 | end
--------------------------------------------------------------------------------
/qb-phone/server/taxi.lua:
--------------------------------------------------------------------------------
1 | lib.callback.register('qb-phone:server:GetAvailableTaxiDrivers', function(_)
2 | local TaxiDrivers = {}
3 |
4 | for i = 1, #Config.TaxiJob do
5 | local job = Config.TaxiJob[i]
6 | TaxiDrivers[job.Job] = {}
7 | TaxiDrivers[job.Job].Players = {}
8 | end
9 |
10 | for _, v in pairs(QBCore.Functions.GetPlayers()) do
11 | local Player = QBCore.Functions.GetPlayer(v)
12 | if Player then
13 | local job = Player.PlayerData.job.name
14 | if TaxiDrivers[job] and Player.PlayerData.job.onduty then
15 | TaxiDrivers[job].Players[#(TaxiDrivers[job].Players)+1] = {
16 | Name = Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname,
17 | Phone = Player.PlayerData.charinfo.phone,
18 | }
19 | end
20 | end
21 | end
22 | return TaxiDrivers
23 | end)
--------------------------------------------------------------------------------
/qb-phone/fxmanifest.lua:
--------------------------------------------------------------------------------
1 | fx_version 'cerulean'
2 | game 'gta5'
3 |
4 | author 'qb-phone Edit'
5 | description 'A NoPixel inspired edit of QBCore\'s Phone.'
6 | version '1.0.0'
7 |
8 | dependencies {
9 | 'ox_lib',
10 | }
11 |
12 | ui_page 'html/index.html'
13 |
14 | shared_scripts {
15 | 'config.lua',
16 | 'shared/shared.lua',
17 | '@qb-apartments/config.lua',
18 | '@qb-garages/config.lua',
19 | '@ox_lib/init.lua'
20 | }
21 |
22 | client_scripts {
23 | 'client/*.lua',
24 | }
25 |
26 | server_scripts {
27 | '@oxmysql/lib/MySQL.lua',
28 | 'server/*.lua',
29 | }
30 |
31 | files {
32 | 'html/*.html',
33 | 'html/js/*.js',
34 | 'html/img/*.png',
35 | 'html/css/*.css',
36 | 'html/img/backgrounds/*.png',
37 | 'html/img/apps/*.png',
38 | }
39 |
40 | lua54 'yes'
41 |
42 | dependency 'qb-target'
43 |
44 | escrow_ignore {
45 | 'config.lua',
46 | 'client/jobcenter.lua',
47 | 'server/employment.lua',
48 | }
--------------------------------------------------------------------------------
/qb-phone/html/css/camera.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Lato&display=swap');
2 |
3 | .camera-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
8 | overflow: hidden;
9 | }
10 |
11 |
12 | .camera-homescreen {
13 | position: absolute;
14 | height: 108%;
15 | width: 100%;
16 | left: 0vh;
17 | }
18 |
19 |
20 |
21 | .loader {
22 | z-index: 1000;
23 | border: 16px solid #f3f3f3;
24 | border-top: 16px solid #3498db;
25 | border-bottom: 16px solid #3498db;
26 | border-radius: 50%;
27 | animation: spin 2s linear infinite;
28 | position: absolute;
29 | top: 50%;
30 | left: 50%;
31 | margin-top: -50px;
32 | margin-left: -50px;
33 | width: 100px;
34 | height: 100px;
35 | }
36 |
37 | @keyframes spin {
38 | 0% { transform: rotate(0deg); }
39 | 100% { transform: rotate(360deg); }
40 | }
--------------------------------------------------------------------------------
/qb-phone/server/gallery.lua:
--------------------------------------------------------------------------------
1 | RegisterNetEvent('qb-phone:server:addImageToGallery', function(image)
2 | local src = source
3 | local Player = QBCore.Functions.GetPlayer(src)
4 | exports.oxmysql:insert('INSERT INTO phone_gallery (`citizenid`, `image`) VALUES (?, ?)',{Player.PlayerData.citizenid,image})
5 | end)
6 |
7 | RegisterNetEvent('qb-phone:server:getImageFromGallery', function()
8 | local src = source
9 | local Player = QBCore.Functions.GetPlayer(src)
10 | local images = exports.oxmysql:executeSync('SELECT * FROM phone_gallery WHERE citizenid = ? ORDER BY `date` DESC',{Player.PlayerData.citizenid})
11 | TriggerClientEvent('qb-phone:refreshImages', src, images)
12 | end)
13 |
14 | RegisterNetEvent('qb-phone:server:RemoveImageFromGallery', function(data)
15 | local src = source
16 | local Player = QBCore.Functions.GetPlayer(src)
17 | local image = data.image
18 | exports.oxmysql:execute('DELETE FROM phone_gallery WHERE citizenid = ? AND image = ?',{Player.PlayerData.citizenid,image})
19 | end)
--------------------------------------------------------------------------------
/qb-phone/server/news.lua:
--------------------------------------------------------------------------------
1 | local LSBNTable = {}
2 | local LSBNTableID = 0
3 |
4 | RegisterNetEvent('qb-phone:server:Send_lsbn_ToChat', function(data)
5 | LSBNTableID = LSBNTableID + 1
6 | if data.Type == "Text" then
7 | LSBNTable[LSBNTableID] = {['Text'] = data.Text, ['Image'] = "none", ['ID'] = LSBNTableID, ['Type'] = data.Type, ['Time'] = data.Time,}
8 | elseif data.Type == "Image" then
9 | LSBNTable[LSBNTableID] = {['Text'] = data.Text, ['Image'] = data.Image, ['ID'] = LSBNTableID, ['Type'] = data.Type, ['Time'] = data.Time,}
10 | end
11 | local Tables = {
12 | {
13 | ['Text'] = data.Text, ['Image'] = data.Image, ['ID'] = LSBNTableID, ['Type'] = data.Type, ['Time'] = data.Time,
14 | },
15 | }
16 | TriggerClientEvent('qb-phone:LSBN-reafy-for-add', -1, Tables, true, data.Text)
17 | end)
18 |
19 | RegisterNetEvent('qb-phone:server:GetLSBNchats', function()
20 | local src = source
21 | TriggerClientEvent('qb-phone:LSBN-reafy-for-add', src, LSBNTable, false, nil)
22 | end)
--------------------------------------------------------------------------------
/qb-phone/client/debt.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | -- Used for assts and to pay off the entire LOAN
4 | RegisterNUICallback('SendAllPayment', function(data, cb)
5 | -- All your cracked code here brains here
6 |
7 | TriggerServerEvent('Renewed-Debts:server:PayFull', tonumber(data.id))
8 |
9 | cb("ok")
10 | end)
11 |
12 | RegisterNUICallback('SendMinimumPayment', function(data, cb)
13 | -- All your cracked code here brains here
14 | TriggerServerEvent('Renewed-Debts:server:PayPartial', tonumber(data.id))
15 | cb("ok")
16 | end)
17 |
18 |
19 | RegisterNUICallback('GetPlayersDebt', function(_, cb)
20 | local debtData = Config.RenewedFinances and exports['qb-finances']:getDebt() or {}
21 | cb(debtData)
22 | end)
23 |
24 |
25 | -- refresh the shit
26 |
27 | RegisterNetEvent('qb-phone:client:refreshDebt', function()
28 | local debtData = Config.RenewedFinances and exports['qb-finances']:getDebt() or {}
29 | SendNUIMessage({
30 | action = "refreshDebt",
31 | debt = debtData,
32 | })
33 | end)
--------------------------------------------------------------------------------
/qb-phone/server/commands.lua:
--------------------------------------------------------------------------------
1 | QBCore.Commands.Add("setmetadata", "Set Player Metadata (God Only)", {}, false, function(source, args)
2 | local Player = QBCore.Functions.GetPlayer(source)
3 | if args[1] then
4 | if args[1] == "trucker" then
5 | if args[2] then
6 | local newrep = Player.PlayerData.metadata["jobrep"]
7 | newrep.trucker = tonumber(args[2])
8 | Player.Functions.SetMetaData("jobrep", newrep)
9 | end
10 | end
11 | end
12 | end, "god")
13 |
14 | QBCore.Commands.Add("p#", "Provide Phone Number", {}, false, function(source)
15 | local src = source
16 | local Player = QBCore.Functions.GetPlayer(src)
17 | local PlayerPed = GetPlayerPed(src)
18 | local number = Player.PlayerData.charinfo.phone
19 | local PlayerCoords = GetEntityCoords(PlayerPed)
20 | for _, v in pairs(QBCore.Functions.GetPlayers()) do
21 | local TargetPed = GetPlayerPed(v)
22 | local dist = #(PlayerCoords - GetEntityCoords(TargetPed))
23 |
24 | if dist < 3.0 then
25 | TriggerClientEvent('chat:addMessage', v, {
26 | color = { 255, 0, 0},
27 | multiline = true,
28 | args = {"Phone #", number}
29 | })
30 | end
31 | end
32 | end)
33 |
--------------------------------------------------------------------------------
/qb-phone/client/betting.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | RegisterNUICallback('CasinoAddBet', function(data, cb)
4 | TriggerServerEvent('qb-phone:server:CasinoAddBet', data)
5 | cb("ok")
6 | end)
7 |
8 | RegisterNetEvent('qb-phone:client:addbetForAll', function(data)
9 | SendNUIMessage({
10 | action = "BetAddToApp",
11 | datas = data,
12 | })
13 | end)
14 |
15 | RegisterNUICallback('BettingAddToTable', function(data, cb)
16 | TriggerServerEvent('qb-phone:server:BettingAddToTable', data)
17 | cb("ok")
18 | end)
19 |
20 | RegisterNUICallback('CasinoDeleteTable', function(_, cb)
21 | TriggerServerEvent('qb-phone:server:DeleteAndClearTable')
22 | cb("ok")
23 | end)
24 |
25 | RegisterNUICallback('CheckHasBetTable', function(_, cb)
26 | local HasTable = lib.callback.await('qb-phone:server:CheckHasBetTable', false)
27 | cb(HasTable)
28 | end)
29 |
30 | RegisterNUICallback('casino_status', function(_, cb)
31 | TriggerServerEvent('qb-phone:server:casino_status')
32 | cb("ok")
33 | end)
34 |
35 | RegisterNUICallback('CheckHasBetStatus', function(_, cb)
36 | local HasStatus = lib.callback.await('qb-phone:server:CheckHasBetStatus', false)
37 | cb(HasStatus)
38 | end)
39 |
40 | RegisterNUICallback('WineridCasino', function(data, cb)
41 | TriggerServerEvent('qb-phone:server:WineridCasino', data)
42 | cb("ok")
43 | end)
--------------------------------------------------------------------------------
/qb-phone/server/pings.lua:
--------------------------------------------------------------------------------
1 | RegisterNetEvent("qb-phone:server:sendPing", function(id)
2 | local src = source
3 | local Player = QBCore.Functions.GetPlayer(src)
4 | local Shitter = tonumber(id)
5 | local Other = QBCore.Functions.GetPlayer(Shitter)
6 | local HasVPN = Player.Functions.GetItemByName(Config.VPNItem)
7 | local name = HasVPN and 'Anonymous' or Player.PlayerData.charinfo.firstname
8 |
9 | if not Other then return TriggerClientEvent("QBCore:Notify", src, 'State ID does not exist!', "error") end
10 |
11 | local info = { type = 'ping', Other = Shitter, Player = src, Name = name, OtherName = Other.PlayerData.charinfo.firstname }
12 | if Player.PlayerData.citizenid ~= Other.PlayerData.citizenid then
13 | TriggerClientEvent("qb-phone:client:sendNotificationPing", Shitter, info)
14 | TriggerClientEvent("QBCore:Notify", src, 'Request Sent', "success")
15 | else
16 | TriggerClientEvent("QBCore:Notify", src, 'You cannot send a ping to yourself!', "error")
17 | end
18 | end)
19 |
20 | RegisterNetEvent("qb-phone:server:sendingPing", function(Other, Player, Name, OtherName)
21 | TriggerClientEvent('qb-phone:client:CustomNotification', Player, "PING", OtherName..' Accepted Your Ping!', 'fas fa-map-pin', '#b3e0f2', 7500)
22 | TriggerClientEvent("qb-phone:client:sendPing", Other, Name, GetEntityCoords(GetPlayerPed(Player)))
23 | end)
--------------------------------------------------------------------------------
/qb-phone/html/js/wenmo.js:
--------------------------------------------------------------------------------
1 | $(document).on('click', '.wenmo-send-money-btn', function(e){
2 | e.preventDefault();
3 | ClearInputNew()
4 | $('#wenmo-box-new-for-give').fadeIn(350);
5 | });
6 |
7 | $(document).on('click', '#wenmo-send-money-ended', function(e){
8 | e.preventDefault();
9 | var ID = $(".wenmo-input-one").val();
10 | var Amount = $(".wenmo-input-two").val();
11 | var Reason = $(".wenmo-input-three").val();
12 | if ((ID && Amount && Reason) != "" && (ID && Amount) >= 1){
13 | $.post('https://qb-phone/wenmo_givemoney_toID', JSON.stringify({
14 | ID: ID,
15 | Amount: Amount,
16 | Reason: Reason,
17 | }));
18 |
19 | ClearInputNew()
20 | $('#wenmo-box-new-for-give').fadeIn(350);
21 | }
22 | });
23 |
24 | $(document).ready(function(){
25 | window.addEventListener('message', function(event) {
26 | switch(event.data.action) {
27 | case "ChangeMoney_Wenmo":
28 | var date = new Date();
29 | var Times = date.getHours()+":"+date.getMinutes();
30 | var AddOption = ''+event.data.Amount+'
'+Times+'
'+
31 | '
'+event.data.Reason+'
'+
32 | '
'
33 |
34 | $('.wenmo-list').prepend(AddOption);
35 | break;
36 | }
37 | })
38 | });
--------------------------------------------------------------------------------
/qb-phone/server/wenmo.lua:
--------------------------------------------------------------------------------
1 | RegisterNetEvent('qb-phone:server:wenmo_givemoney_toID', function(data)
2 | local src = source
3 | local Ply = QBCore.Functions.GetPlayer(src)
4 | local OtherPly = QBCore.Functions.GetPlayer(tonumber(data.ID))
5 | local Amount = tonumber(data.Amount)
6 | local Reason = data.Reason
7 |
8 | if src == tonumber(data.ID) then return end
9 |
10 | if not OtherPly then return TriggerClientEvent('QBCore:Notify', src, 'Player not Online', "error") end
11 |
12 | local txt = "Wenmo: "..Reason
13 |
14 | if Ply.PlayerData.money.bank >= Amount then
15 | Ply.Functions.RemoveMoney('bank', Amount, txt)
16 | OtherPly.Functions.AddMoney('bank', Amount, txt)
17 |
18 | if Config.RenewedBanking then
19 | local cid = Ply.PlayerData.citizenid
20 | local name = ("%s %s"):format(Ply.PlayerData.charinfo.firstname, Ply.PlayerData.charinfo.lastname)
21 |
22 | local cid2 = OtherPly.PlayerData.citizenid
23 | local name2 = ("%s %s"):format(OtherPly.PlayerData.charinfo.firstname, OtherPly.PlayerData.charinfo.lastname)
24 |
25 | exports['Renewed-Banking']:handleTransaction(cid, "Wenmo Transaction", Amount, txt, name2, name, "withdraw")
26 | exports['Renewed-Banking']:handleTransaction(cid2, "Wenmo Transaction", Amount, txt, name, name2, "deposit")
27 | end
28 | else
29 | TriggerClientEvent("QBCore:Notify", src, 'You don\'t have enough money!', "error") -- replace this with Phone Notify
30 | end
31 | end)
32 |
--------------------------------------------------------------------------------
/qb-phone/client/pings.lua:
--------------------------------------------------------------------------------
1 | local Blip
2 |
3 | -- NUI Callback
4 |
5 | RegisterNetEvent("qb-phone:client:sendPing", function(Name, pos)
6 | if Blip then RemoveBlip(Blip) Blip = nil end
7 |
8 | Blip = AddBlipForCoord(pos.x, pos.y, pos.z)
9 | SetBlipSprite(Blip, 280)
10 | SetBlipDisplay(Blip, 4)
11 | SetBlipScale(Blip, 1.1)
12 | SetBlipAsShortRange(Blip, false)
13 | SetBlipColour(Blip, 0)
14 | BeginTextCommandSetBlipName("STRING")
15 | AddTextComponentSubstringPlayerName(Name..'\'s ping!')
16 | EndTextCommandSetBlipName(Blip)
17 |
18 | TriggerEvent('qb-phone:client:CustomNotification', Name..'\'s Location Marked', "Ping Available For 5 Minutes", 'fas fa-map-pin', '#b3e0f2', 7500)
19 | SetTimeout(60000*5, function()
20 | RemoveBlip(Blip)
21 | Blip = nil
22 | TriggerEvent('qb-phone:client:CustomNotification', Name..'\'s Location Removed', "Ping No Longer Available", 'fas fa-map-pin', '#b3e0f2', 7500)
23 | end)
24 | end)
25 |
26 | RegisterNUICallback('SendPingPlayer', function(data, cb)
27 | TriggerServerEvent('qb-phone:server:sendPing', data.id)
28 | cb('ok')
29 | end)
30 |
31 | -- Events
32 | RegisterNetEvent("qb-phone:client:sendNotificationPing", function(info)
33 | PlaySound(-1, "Click_Fail", "WEB_NAVIGATION_SOUNDS_PHONE", 0, 0, 1)
34 | local success = exports['qb-phone']:PhoneNotification("PING", info.Name..' Incoming Ping', 'fas fa-map-pin', '#b3e0f2', "NONE", 'fas fa-check-circle', 'fas fa-times-circle')
35 | if success then
36 | TriggerServerEvent("qb-phone:server:sendingPing", info.Other, info.Player, info.Name, info.OtherName)
37 | end
38 | end)
--------------------------------------------------------------------------------
/qb-phone/shared/shared.lua:
--------------------------------------------------------------------------------
1 | QBCore = exports['qb-core']:GetCoreObject()
2 |
3 | local phoneProp = 0
4 | local phoneModel = joaat("prop_npc_phone_02")
5 |
6 | function CheckAnimLoop()
7 | CreateThread(function()
8 | while PhoneData.AnimationData.lib and PhoneData.AnimationData.anim do
9 | if not IsEntityPlayingAnim(cache.ped, PhoneData.AnimationData.lib, PhoneData.AnimationData.anim, 3) then
10 | lib.requestAnimDict(PhoneData.AnimationData.lib)
11 | TaskPlayAnim(cache.ped, PhoneData.AnimationData.lib, PhoneData.AnimationData.anim, 3.0, 3.0, -1, 50, 0, false, false, false)
12 | end
13 | Wait(500)
14 | end
15 | end)
16 | end
17 |
18 | function newPhoneProp()
19 | deletePhone()
20 | lib.requestModel(phoneModel)
21 | phoneProp = CreateObject(phoneModel, 1.0, 1.0, 1.0, true, true, false)
22 | local bone = GetPedBoneIndex(cache.ped, 28422)
23 | if phoneModel == joaat("prop_cs_phone_01") then
24 | AttachEntityToEntity(phoneProp, cache.ped, bone, 0.0, 0.0, 0.0, 50.0, 320.0, 50.0, true, true, false, false, 2, true)
25 | else
26 | AttachEntityToEntity(phoneProp, cache.ped, bone, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true, false, false, 2, true)
27 | end
28 | end
29 |
30 | function deletePhone()
31 | if phoneProp then
32 | DeleteObject(phoneProp)
33 | phoneProp = 0
34 | end
35 | end
36 |
37 | function DoPhoneAnimation(anim)
38 | local AnimationLib = 'cellphone@'
39 | local AnimationStatus = anim
40 | if cache.vehicle then
41 | AnimationLib = 'anim@cellphone@in_car@ps'
42 | end
43 | lib.requestAnimDict(AnimationLib)
44 | TaskPlayAnim(cache.ped, AnimationLib, AnimationStatus, 3.0, 3.0, -1, 50, 0, false, false, false)
45 | PhoneData.AnimationData.lib = AnimationLib
46 | PhoneData.AnimationData.anim = AnimationStatus
47 | CheckAnimLoop()
48 | end
--------------------------------------------------------------------------------
/qb-phone/server/advertisements.lua:
--------------------------------------------------------------------------------
1 | Adverts = {}
2 |
3 | local function GetAdvertFromNumb(src)
4 | for k, v in pairs(Adverts) do
5 | if v.source == src then
6 | return k
7 | end
8 | end
9 | end
10 |
11 | RegisterNetEvent('qb-phone:server:AddAdvert', function(msg, url)
12 | local src = source
13 | local Player = QBCore.Functions.GetPlayer(src)
14 | local name = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)
15 | local table = GetAdvertFromNumb(src)
16 | if not url then url = "" else url = url:gsub("[%<>\"()\'$]","") end
17 |
18 | if table then
19 | Adverts[table] = {
20 | message = msg:gsub("[%<>\"()\'$]",""),
21 | name = name,
22 | number = Player.PlayerData.charinfo.phone,
23 | url = url,
24 | source = src,
25 | }
26 | else
27 | Adverts[#Adverts+1] = {
28 | message = msg:gsub("[%<>\"()\'$]",""),
29 | name = name,
30 | number = Player.PlayerData.charinfo.phone,
31 | url = url,
32 | source = src,
33 | }
34 | end
35 |
36 | TriggerClientEvent('qb-phone:client:UpdateAdverts', -1, Adverts, name, src)
37 | end)
38 |
39 | RegisterNetEvent('qb-phone:server:DeleteAdvert', function()
40 | local k = GetAdvertFromNumb(source)
41 | if not k then return end
42 | table.remove(Adverts, k)
43 | TriggerClientEvent('qb-phone:client:UpdateAdverts', -1, Adverts)
44 | end)
45 |
46 | RegisterNetEvent('qb-phone:server:flagAdvert', function(number)
47 | local src = source
48 | local Player = QBCore.Functions.GetPlayerByPhone(number)
49 | local citizenid = Player.PlayerData.citizenid
50 | local name = Player.PlayerData.charinfo.firstname..' '..Player.PlayerData.charinfo.lastname
51 | -- Add some type of log here for admins to keep track of flagged posts
52 | TriggerClientEvent('QBCore:Notify', src, 'Post by '..name.. ' ['..citizenid..'] has been flagged', 'error')
53 | end)
54 |
--------------------------------------------------------------------------------
/qb-phone/html/css/lsbn.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .lsbn-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | overflow: hidden;
8 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
9 | }
10 |
11 | .lsbn-header {
12 | position: absolute;
13 | width: 86%;
14 | height: 10%;
15 | left: 6.5%;
16 | right: 0;
17 | color: white;
18 | /* font-family: 'Gilroy'; */
19 | font-size: 1.8vh;
20 | /* margin: 0 auto; */
21 | }
22 |
23 | .lsbn-header > p {
24 | line-height: 12vh;
25 | text-indent: 2vh;
26 | margin: 0 0 0 9vh;
27 | }
28 |
29 | .lsbn-header > span {
30 | position: absolute;
31 | top: 8vh;
32 | left: 9vh;
33 | font-size: 1.2vh;
34 | height: 2vh;
35 | color: white;
36 | }
37 |
38 | .lsbn-list {
39 | position: absolute;
40 | width: 90%;
41 | height: 74%;
42 | margin: 0 auto;
43 | left: 0;
44 | right: 0;
45 | bottom: 3%;
46 | border-radius: .5vh;
47 | overflow-y: scroll;
48 | }
49 |
50 | .lsbn-list::-webkit-scrollbar {
51 | display: none;
52 | }
53 |
54 |
55 |
56 |
57 |
58 | .lsbn-send-news-for-chat{
59 | position: absolute;
60 | color: whitesmoke;
61 | transition: all 0.2s ease 0s;
62 | display: inline;
63 | border-radius: 4px;
64 | top: 77%;
65 | left: 91%;
66 | z-index: 1;
67 | }
68 | .lsbn-send-news-for-chat:hover{
69 | color: rgb(187, 187, 187);
70 | }
71 |
72 | .lsbn-logo-style{
73 | width: 90%;
74 | position: relative;
75 | top: 70%;
76 | margin-left: 5%;
77 | }
78 |
79 | .lsbn-chat-style-main{
80 | width: 90%;
81 | margin-left: 4%;
82 | margin-bottom: 2%;
83 | padding: 2%;
84 | color: whitesmoke;
85 | background: #2c465f;
86 | border-bottom: 0.1vh solid rgba(245, 245, 245, 0.68);
87 | border-radius: 2px;
88 | }
89 |
90 | .lsbn-chat-time-style{
91 | text-align: right;
92 | color: #adadad;
93 | }
94 |
95 | .lsbn-chat-to-image-style{
96 | width: 100%;
97 | }
--------------------------------------------------------------------------------
/qb-phone/html/css/taxi.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .taxi-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | overflow: hidden;
8 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
9 | }
10 |
11 | .taxi-header {
12 | position: absolute;
13 | width: 100%;
14 | height: 12vh;
15 | top: 0;
16 | color: white;
17 | font-size: 1.8vh;
18 | }
19 |
20 | .taxi-taxi-image {
21 | position: absolute;
22 | width: 27vh;
23 | margin: 0 auto;
24 | left: 0;
25 | right: 0;
26 | top: 6vh;
27 | }
28 |
29 | .taxis-list {
30 | position: absolute;
31 | width: 100%;
32 | height: 71%;
33 | margin: 0 auto;
34 | text-align: center;
35 | bottom: 3%;
36 | }
37 |
38 | .taxis-list::-webkit-scrollbar {
39 | display: none;
40 | }
41 |
42 | .taxi-list {
43 | position: relative;
44 | width: 90.0%;
45 | height: 6vh;
46 | margin: auto;
47 | border-bottom: .1vh solid #fff;
48 | }
49 |
50 | .taxi-list-fullname {
51 | position: absolute;
52 | top: 10%;
53 | font-size: 1.3vh;
54 | max-width: 14vh;
55 | white-space: nowrap;
56 | overflow: hidden !important;
57 | text-overflow: ellipsis;
58 | color: white;
59 | }
60 |
61 | .taxi-list-phone {
62 | position: absolute;
63 | top: 50%;
64 | font-size: 1.3vh;
65 | max-width: 14vh;
66 | color: white;
67 | }
68 |
69 | .taxi-list-call {
70 | color: white;
71 | position: absolute;
72 | top: 25%;
73 | transform: rotate(0deg);
74 | right: 0;
75 | font-size: 2vh;
76 | }
77 |
78 | .taxi-list-call:hover i {
79 | color: rgb(179, 179, 179);
80 | }
81 |
82 | .notaxidrivers {
83 | width: 100%;
84 | text-align: center;
85 | font-family: 'Gilroy';
86 | font-size: 1.7vh;
87 | font-weight: bold;
88 | color: #FFFFFF;
89 | line-height: 20vh;
90 | }
91 |
92 | #taxi-frown {
93 | position: absolute;
94 | top: 15.5%;
95 | left: 41.5%;
96 | font-size: 275%;
97 | color: #FFFFFF;
98 | }
99 |
--------------------------------------------------------------------------------
/qb-phone/client/houses.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | RegisterNUICallback('GetPlayerHouses', function(_, cb)
4 | QBCore.Functions.TriggerCallback('qb-phone:server:GetPlayerHouses', function(Houses)
5 | cb(Houses)
6 | end)
7 | end)
8 |
9 | RegisterNUICallback('GetPlayerKeys', function(_, cb)
10 | QBCore.Functions.TriggerCallback('qb-phone:server:GetHouseKeys', function(Keys)
11 | cb(Keys)
12 | end)
13 | end)
14 |
15 | RegisterNUICallback('SetHouseLocation', function(data, cb)
16 | SetNewWaypoint(data.HouseData.HouseData.coords.enter.x, data.HouseData.HouseData.coords.enter.y)
17 | QBCore.Functions.Notify("GPS set to " .. data.HouseData.HouseData.adress .. "!", "success")
18 | cb("ok")
19 | end)
20 |
21 | RegisterNUICallback('RemoveKeyholder', function(data, cb)
22 | TriggerServerEvent('qb-houses:server:removeHouseKey', data.HouseData.name, {
23 | citizenid = data.HolderData.citizenid,
24 | firstname = data.HolderData.charinfo.firstname,
25 | lastname = data.HolderData.charinfo.lastname,
26 | })
27 |
28 | cb("ok")
29 | end)
30 |
31 | RegisterNUICallback('TransferCid', function(data, cb)
32 | local TransferedCid = data.newBsn
33 |
34 | QBCore.Functions.TriggerCallback('qb-phone:server:TransferCid', function(CanTransfer)
35 | cb(CanTransfer)
36 | end, TransferedCid, data.HouseData)
37 | end)
38 |
39 | RegisterNUICallback('FetchPlayerHouses', function(data, cb)
40 | QBCore.Functions.TriggerCallback('qb-phone:server:MeosGetPlayerHouses', function(result)
41 | cb(result)
42 | end, data.input)
43 | end)
44 |
45 | RegisterNUICallback('SetGPSLocation', function(data, cb)
46 | SetNewWaypoint(data.coords.x, data.coords.y)
47 | QBCore.Functions.Notify('GPS set!', "success")
48 |
49 | cb("ok")
50 | end)
51 |
52 | RegisterNUICallback('SetApartmentLocation', function(data, cb)
53 | local ApartmentData = data.data.appartmentdata
54 | local TypeData = Apartments.Locations[ApartmentData.type]
55 |
56 | SetNewWaypoint(TypeData.coords.enter.x, TypeData.coords.enter.y)
57 | QBCore.Functions.Notify('GPS set!', "success")
58 |
59 | cb("ok")
60 | end)
--------------------------------------------------------------------------------
/qb-phone/client/jobcenter.lua:
--------------------------------------------------------------------------------
1 | NoVPN = {}
2 | CreateThread(function ()
3 | for _, v in pairs(Config.JobCenter) do
4 | if v.vpn == false then
5 | NoVPN[#NoVPN+1] = v
6 | end
7 | end
8 | end)
9 |
10 | RegisterNUICallback('GetJobCentersJobs', function(data, cb)
11 | local result = QBCore.Functions.HasItem("vpn", 1)
12 | if result then
13 | cb(Config.JobCenter)
14 | else
15 | cb(NoVPN)
16 | end
17 | end)
18 |
19 | RegisterNUICallback('CasinoPhoneJobCenter', function(data)
20 | TriggerEvent(data.event)
21 | end)
22 |
23 | RegisterNetEvent('qb-phone:jobcenter:tow', function()
24 | TriggerEvent('qb-phone:client:CustomNotification',
25 | 'JOB CENTER',
26 | 'GPS Waypoint Set',
27 | 'fas fa-briefcase',
28 | '#2496f2',
29 | 5000
30 | )
31 | SetNewWaypoint(-191.48, -1158.67)
32 | end)
33 |
34 | RegisterNetEvent('qb-phone:jobcenter:fish', function()
35 | TriggerEvent('qb-phone:client:CustomNotification',
36 | 'JOB CENTER',
37 | 'GPS Waypoint Set',
38 | 'fas fa-briefcase',
39 | '#2496f2',
40 | 5000
41 | )
42 | SetNewWaypoint(-335.15, 6105.79)
43 | end)
44 |
45 | RegisterNetEvent('qb-phone:jobcenter:postop', function()
46 | TriggerEvent('qb-phone:client:CustomNotification',
47 | 'JOB CENTER',
48 | 'GPS Waypoint Set',
49 | 'fas fa-briefcase',
50 | '#2496f2',
51 | 5000
52 | )
53 | SetNewWaypoint(-427.78, -2774.04)
54 | end)
55 |
56 | RegisterNetEvent('qb-phone:jobcenter:sanitation', function()
57 | TriggerEvent('qb-phone:client:CustomNotification',
58 | 'JOB CENTER',
59 | 'GPS Waypoint Set',
60 | 'fas fa-briefcase',
61 | '#2496f2',
62 | 5000
63 | )
64 | SetNewWaypoint(-321.83, -1545.94)
65 | end)
66 |
67 | RegisterNetEvent('qb-phone:jobcenter:pdimpound', function()
68 | TriggerEvent('qb-phone:client:CustomNotification',
69 | 'JOB CENTER',
70 | 'GPS Waypoint Set',
71 | 'fas fa-briefcase',
72 | '#2496f2',
73 | 5000
74 | )
75 | SetNewWaypoint(442.05, -1013.97)
76 | end)
--------------------------------------------------------------------------------
/qb-phone/client/notification.lua:
--------------------------------------------------------------------------------
1 | local Result = nil
2 | local test = false
3 |
4 | -- NUI Callbacks
5 |
6 | RegisterNUICallback('AcceptNotification', function()
7 | Result = true
8 | Wait(100)
9 | test = false
10 | return Result
11 | end)
12 |
13 | RegisterNUICallback('DenyNotification', function()
14 | Result = false
15 | Wait(100)
16 | test = false
17 | return Result
18 | end)
19 |
20 | -- Events
21 |
22 | RegisterNetEvent("qb-phone:client:CustomNotification", function(title, text, icon, color, timeout) -- Send a PhoneNotification to the phone from anywhere
23 | SendNUIMessage({
24 | action = "PhoneNotification",
25 | PhoneNotify = {
26 | title = title,
27 | text = text,
28 | icon = icon,
29 | color = color,
30 | timeout = timeout,
31 | },
32 | })
33 | end)
34 |
35 | -- ex. local success = exports['qb-phone']:PhoneNotification("PING", info.Name..' Incoming Ping', 'fas fa-map-pin', '#b3e0f2', "NONE", 'fas fa-check-circle', 'fas fa-times-circle')
36 |
37 | RegisterNetEvent("qb-phone:client:CustomNotification2", function(title, text, icon, color, timeout, accept, deny) -- Send a PhoneNotification to the phone from anywhere
38 | SendNUIMessage({
39 | action = "PhoneNotificationCustom",
40 | PhoneNotify = {
41 | title = title,
42 | text = text,
43 | icon = icon,
44 | color = color,
45 | timeout = timeout,
46 | accept = accept,
47 | deny = deny,
48 | },
49 | })
50 | end)
51 | -- Functions
52 |
53 | local function PhoneNotification(title, text, icon, color, timeout, accept, deny)
54 | Result = nil
55 | test = true
56 | SendNUIMessage({
57 | action = "PhoneNotificationCustom",
58 | PhoneNotify = {
59 | title = title,
60 | text = text,
61 | icon = icon,
62 | color = color,
63 | timeout = timeout,
64 | accept = accept,
65 | deny = deny,
66 | },
67 | })
68 | while test do
69 | Wait(5)
70 | end
71 | Wait(100)
72 | return Result
73 | end exports("PhoneNotification", PhoneNotification)
74 |
--------------------------------------------------------------------------------
/qb-phone/Exports.MD:
--------------------------------------------------------------------------------
1 | qb-phone exports
2 |
3 | # Crypto (Server side)
4 |
5 | ```
6 |
7 | exports['qb-phone']:RemoveCrypto(src, type, amount)
8 |
9 | exports['qb-phone']:hasEnough(src, type, amount)
10 |
11 | exports['qb-phone']:AddCrypto(src, type, amount)
12 |
13 | ```
14 |
15 | # Employment (Server side)
16 |
17 | ```
18 |
19 | exports['qb-phone']:hireUser(Job, CID, grade)
20 |
21 | exports['qb-phone']:fireUser(Job, CID)
22 |
23 | ```
24 |
25 | # Groups (Server Side)
26 | ```
27 |
28 | exports['qb-phone']:NotifyGroup(group, msg, type)
29 |
30 | exports['qb-phone']:pNotifyGroup(group, header, msg, icon, colour, length)
31 |
32 | exports['qb-phone']:CreateBlipForGroup(groupID, name, data)
33 |
34 | exports['qb-phone']:RemoveBlipForGroup(groupID, name)
35 |
36 | exports['qb-phone']:GetGroupByMembers(src)
37 |
38 | exports['qb-phone']:getGroupMembers(groupID)
39 |
40 | exports['qb-phone']:getGroupSize(groupID)
41 |
42 | exports['qb-phone']:GetGroupLeader(groupID)
43 |
44 | exports['qb-phone']:DestroyGroup(groupID)
45 |
46 | exports['qb-phone']:isGroupLeader(src, groupID)
47 |
48 | --------------------------------------------------
49 |
50 | exports['qb-phone']:setJobStatus(groupID, status, stages)
51 |
52 | exports['qb-phone']:getJobStatus(groupID)
53 |
54 | exports['qb-phone']:resetJobStatus(groupID)
55 |
56 | --------------------------------------------------
57 |
58 | exports['qb-phone']:isGroupTemp(groupID)
59 |
60 | exports['qb-phone']:CreateGroup(src, name, password)
61 |
62 | ```
63 |
64 | # Notifications (Client side)
65 |
66 | ```
67 |
68 | exports['qb-phone']:PhoneNotification(title, text, icon, color, timeout, accept, deny)
69 |
70 | ```
71 |
72 | # Twitter (Server side)
73 |
74 | ```
75 |
76 | local function escape_str(s)
77 | return s
78 | end
79 |
80 | local TweetData = {
81 | firstName = PhoneData.PlayerData.charinfo.firstname,
82 | lastName = PhoneData.PlayerData.charinfo.lastname,
83 | citizenid = PhoneData.PlayerData.citizenid,
84 | message = escape_str(data.Message):gsub("[%<>\"()\'$]",""),
85 | time = data.Date,
86 | tweetId = "TWEET-"..math.random(11111111, 99999999),
87 | type = data.type,
88 | url = URL
89 | }
90 |
91 | exports['qb-phone']:AddNewTweet(TweetData)
92 |
93 | ```
94 |
--------------------------------------------------------------------------------
/qb-phone/client/mail.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | RegisterNUICallback('AcceptMailButton', function(data, cb)
4 | if data.buttonEvent or data.buttonData then
5 | if data.isServer then
6 | TriggerServerEvent(data.buttonEvent, data.buttonData)
7 | else
8 | TriggerEvent(data.buttonEvent, data.buttonData)
9 | end
10 | end
11 |
12 | TriggerServerEvent('qb-phone:server:ClearButtonData', data.mailId)
13 | cb('ok')
14 | end)
15 |
16 | RegisterNUICallback('GetMails', function(_, cb)
17 | cb(PhoneData.Mails)
18 | end)
19 |
20 | RegisterNUICallback('RemoveMail', function(data, cb)
21 | local MailId = data.mailId
22 | TriggerServerEvent('qb-phone:server:RemoveMail', MailId)
23 | cb('ok')
24 | end)
25 |
26 | -- Events
27 |
28 | RegisterNetEvent('qb-phone:client:NewMailNotify', function(MailData)
29 | TriggerEvent('qb-phone:client:CustomNotification',
30 | "Mail",
31 | "New E-Mail from: "..MailData.sender,
32 | "fas fa-envelope",
33 | "ff002f",
34 | 1500
35 | )
36 |
37 | Config.PhoneApplications['mail'].Alerts = Config.PhoneApplications['mail'].Alerts + 1
38 | end)
39 |
40 | RegisterNetEvent('qb-phone:client:UpdateMails', function(NewMails)
41 |
42 | PhoneData.Mails = {}
43 |
44 | for _, v in pairs(NewMails) do
45 | PhoneData.Mails[#PhoneData.Mails+1] = {
46 | citizenid = v.citizenid,
47 | sender = v.sender,
48 | subject = v.subject,
49 | message = v.message,
50 | read = v.read,
51 | mailid = v.mailId,
52 | date = v.date,
53 | button = type(v.button) == "string" and json.decode(v.button) or v.button
54 | }
55 | end
56 |
57 | PhoneData.Mails = NewMails
58 |
59 | SendNUIMessage({
60 | action = "UpdateMails",
61 | Mails = NewMails
62 | })
63 | end)
64 |
65 | RegisterCommand("testmail", function(source)
66 | TriggerServerEvent('qb-phone:server:sendNewMail', {
67 | sender = "MV-SCRIPT",
68 | subject = "Test Mail",
69 | message = "Hello,
The vehicle you need to collect is a
" ..
70 | ".
The approximate position of the vehicle and the scrapyard you need to bring it to are marked on your GPS.",
71 | })
72 | end, false)
--------------------------------------------------------------------------------
/qb-phone/client/invoices.lua:
--------------------------------------------------------------------------------
1 | local function GetInvoiceFromID(id)
2 | for k, v in pairs(PhoneData.Invoices) do
3 | if v.id == id then
4 | return k
5 | end
6 | end
7 | end
8 |
9 | -- NUI Callback
10 |
11 | RegisterNUICallback('GetInvoices', function(_, cb)
12 | cb(PhoneData.Invoices)
13 | end)
14 |
15 | RegisterNUICallback('PayInvoice', function(data, cb)
16 | local senderCitizenId = data.senderCitizenId
17 | local society = data.society
18 | local amount = data.amount
19 | local invoiceId = data.invoiceId
20 |
21 | TriggerServerEvent('qb-phone:server:PayMyInvoice', society, amount, invoiceId, senderCitizenId)
22 | cb("ok")
23 | end)
24 |
25 | RegisterNUICallback('DeclineInvoice', function(data, cb)
26 | local amount = data.amount
27 | local invoiceId = data.invoiceId
28 | TriggerServerEvent('qb-phone:server:DeclineMyInvoice', amount, invoiceId)
29 | cb("ok")
30 | end)
31 |
32 | -- Events
33 |
34 | RegisterNetEvent('qb-phone:client:AcceptorDenyInvoice', function(id, name, job, senderCID, amount, resource)
35 | PhoneData.Invoices[#PhoneData.Invoices+1] = {
36 | id = id,
37 | citizenid = QBCore.Functions.GetPlayerData().citizenid,
38 | sender = name,
39 | society = job,
40 | sendercitizenid = senderCID,
41 | amount = amount
42 | }
43 |
44 | local success = exports['qb-phone']:PhoneNotification("Invoice", 'Invoice of $'..amount.." Sent from "..name, 'fas fa-file-invoice-dollar', '#b3e0f2', "NONE", 'fas fa-check-circle', 'fas fa-times-circle')
45 | if success then
46 | local table = GetInvoiceFromID(id)
47 | if table then
48 | TriggerServerEvent('qb-phone:server:PayMyInvoice', job, amount, id, senderCID, resource)
49 | end
50 | else
51 | local table = GetInvoiceFromID(id)
52 | if table then
53 | TriggerServerEvent('qb-phone:server:DeclineMyInvoice', amount, id, senderCID, resource)
54 | end
55 | end
56 | end)
57 |
58 | RegisterNetEvent('qb-phone:client:RemoveInvoiceFromTable', function(id)
59 | local table = GetInvoiceFromID(id)
60 | if table then
61 | PhoneData.Invoices[table] = nil
62 |
63 | SendNUIMessage({
64 | action = "refreshInvoice",
65 | invoices = PhoneData.Invoices,
66 | })
67 | end
68 | end)
--------------------------------------------------------------------------------
/qb-phone/client/advertisements.lua:
--------------------------------------------------------------------------------
1 | -- Functions
2 |
3 | local function GetKeyByNumber(Number)
4 | if PhoneData.Chats then
5 | for k, v in pairs(PhoneData.Chats) do
6 | if v.number == Number then
7 | return k
8 | end
9 | end
10 | end
11 | end
12 |
13 | -- NUI Callback
14 |
15 | RegisterNUICallback('PostAdvert', function(data, cb)
16 | local url
17 |
18 | if data.url and string.match(data.url, '[a-z]*://[^ >,;]*') then
19 | url = data.url
20 | end
21 |
22 | TriggerServerEvent('qb-phone:server:AddAdvert', data.message, url)
23 | cb("ok")
24 | end)
25 |
26 |
27 | RegisterNUICallback('FlagAdvert', function(data, cb)
28 | TriggerServerEvent('qb-phone:server:flagAdvert', data.number)
29 | cb("ok")
30 | end)
31 |
32 | RegisterNUICallback("DeleteAdvert", function(_, cb)
33 | TriggerServerEvent("qb-phone:server:DeleteAdvert")
34 | cb("ok")
35 | end)
36 |
37 | RegisterNUICallback('LoadAdverts', function(_, cb)
38 | cb(PhoneData.Adverts)
39 | end)
40 |
41 | RegisterNUICallback('ClearAlerts', function(data, cb)
42 | local chat = data.number
43 | local ChatKey = GetKeyByNumber(chat)
44 |
45 | if PhoneData.Chats[ChatKey].Unread then
46 | local newAlerts = (Config.PhoneApplications['whatsapp'].Alerts - PhoneData.Chats[ChatKey].Unread)
47 | Config.PhoneApplications['whatsapp'].Alerts = newAlerts
48 |
49 | PhoneData.Chats[ChatKey].Unread = 0
50 |
51 | SendNUIMessage({
52 | action = "RefreshWhatsappAlerts",
53 | Chats = PhoneData.Chats,
54 | })
55 | SendNUIMessage({ action = "RefreshAppAlerts", AppData = Config.PhoneApplications })
56 | end
57 |
58 | cb("ok")
59 | end)
60 |
61 | -- Events
62 |
63 | RegisterNetEvent('qb-phone:client:UpdateAdverts', function(Adverts, LastAd, src)
64 | if not FullyLoaded or not Adverts then return end
65 | PhoneData.Adverts = Adverts
66 |
67 | SendNUIMessage({
68 | action = "RefreshAdverts",
69 | Adverts = PhoneData.Adverts
70 | })
71 |
72 | if not LastAd or not src then return end
73 | if GetPlayerServerId(cache.ped) == src then return end
74 |
75 | TriggerEvent('qb-phone:client:CustomNotification',
76 | "Advertisement",
77 | "New Ad Posted: "..LastAd,
78 | "fas fa-ad",
79 | "#ff8f1a",
80 | 4500
81 | )
82 | end)
--------------------------------------------------------------------------------
/qb-phone/client/documents.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | -- WORK IN PROGRESS
4 | --[[
5 | RegisterNUICallback('SetupHousingDocuments', function(_, cb)
6 | QBCore.Functions.TriggerCallback('qb-phone:server:GetHousingLocations', function(houses)
7 | cb(houses)
8 | end)
9 | end)
10 | ]]
11 |
12 | RegisterNUICallback('documents_Save_Note_As', function(data, cb)
13 | TriggerServerEvent('qb-phone:server:documents_Save_Note_As', data)
14 | cb("ok")
15 | end)
16 |
17 | RegisterNUICallback('document_Send_Note', function(data, cb)
18 | if data.Type == 'LocalSend' then
19 | local pID, playerPed, coords = lib.getClosestPlayer(GetEntityCoords(cache.ped), 2.5)
20 | if pID ~= -1 then
21 | local PlayerId = GetPlayerServerId(pID)
22 | TriggerServerEvent("qb-phone:server:sendDocumentLocal", data, PlayerId)
23 | else
24 | TriggerEvent("DoShortHudText", "No one around!", 2)
25 | end
26 | elseif data.Type == 'PermSend' then
27 | TriggerServerEvent('qb-phone:server:sendDocument', data)
28 | end
29 | cb("ok")
30 | end)
31 |
32 | RegisterNetEvent("qb-phone:client:sendingDocumentRequest", function(data, Receiver, Ply, SenderName)
33 | local success = exports['qb-phone']:PhoneNotification("DOCUMENTS", SenderName..' Incoming Document', 'fas fa-folder', '#b3e0f2', "NONE", 'fas fa-check-circle', 'fas fa-times-circle')
34 | if success then
35 | if data.Type == 'PermSend' then
36 | TriggerServerEvent("qb-phone:server:documents_Save_Note_As", data, Receiver, Ply, SenderName)
37 | elseif data.Type == 'LocalSend' then
38 | TriggerEvent('qb-phone:client:CustomNotification',
39 | 'DOCUMENTS',
40 | 'New Document',
41 | 'fas fa-folder',
42 | '#d9d9d9',
43 | 5000
44 | )
45 |
46 | SendNUIMessage({
47 | action = "DocumentSent",
48 | DocumentSend = {
49 | title = data.Title,
50 | text = data.Text,
51 | },
52 | })
53 | end
54 | end
55 | end)
56 |
57 | RegisterNUICallback('GetNote_for_Documents_app', function(_, cb)
58 | cb(PhoneData.Documents)
59 | end)
60 |
61 | RegisterNetEvent('qb-phone:RefReshNotes_Free_Documents', function(notes)
62 | PhoneData.Documents = notes
63 | SendNUIMessage({
64 | action = "DocumentRefresh",
65 | })
66 | end)
--------------------------------------------------------------------------------
/qb-phone/server/betting.lua:
--------------------------------------------------------------------------------
1 | local CasinoTable = {}
2 | local BetNumber = 0
3 |
4 | RegisterNetEvent('qb-phone:server:CasinoAddBet', function(data)
5 | BetNumber += 1
6 | CasinoTable[BetNumber] = {['Name'] = data.name, ['chanse'] = data.chanse, ['id'] = BetNumber}
7 | TriggerClientEvent('qb-phone:client:addbetForAll', -1, CasinoTable)
8 | end)
9 |
10 | local CasinoBetList = {}
11 | local casino_status = true
12 |
13 | RegisterNetEvent('qb-phone:server:BettingAddToTable', function(data)
14 | local src = source
15 | local Player = QBCore.Functions.GetPlayer(src)
16 | local amount = tonumber(data.amount)
17 | local CSN = Player.PlayerData.citizenid
18 | if casino_status then
19 | if Player.PlayerData.money.bank >= amount then
20 | if not CasinoBetList[CSN] then
21 | Player.Functions.RemoveMoney('bank', amount, "casino betting")
22 | CasinoBetList[CSN] = {['csn'] = CSN, ['amount'] = amount, ['player'] = data.player, ['chanse'] = data.chanse, ['id'] = data.id}
23 | else
24 | TriggerClientEvent('QBCore:Notify', src, "You are already betting...", "error")
25 | end
26 | else
27 | TriggerClientEvent('QBCore:Notify', src, "You do not have enough money!", "error")
28 | end
29 | else
30 | TriggerClientEvent('QBCore:Notify', src, "Betting is not active...", "error")
31 | end
32 | end)
33 |
34 | RegisterNetEvent('qb-phone:server:DeleteAndClearTable', function()
35 | local src = source
36 | CasinoTable = {}
37 | CasinoBetList = {}
38 | BetNumber = 0
39 | TriggerClientEvent('qb-phone:client:addbetForAll', -1, CasinoTable)
40 | TriggerClientEvent('QBCore:Notify', src, "Done", "primary")
41 | end)
42 |
43 | lib.callback.register('qb-phone:server:CheckHasBetTable', function(_)
44 | return CasinoTable
45 | end)
46 |
47 |
48 | RegisterNetEvent('qb-phone:server:casino_status', function()
49 | casino_status = not casino_status
50 | end)
51 |
52 | lib.callback.register('qb-phone:server:CheckHasBetStatus', function(_)
53 | return casino_status
54 | end)
55 |
56 | RegisterNetEvent('qb-phone:server:WineridCasino', function(data)
57 | local Winer = data.id
58 | for _, v in pairs(CasinoBetList) do
59 | if v.id == Winer then
60 | local OtherPly = QBCore.Functions.GetPlayerByCitizenId(v.csn)
61 | if OtherPly then
62 | local amount = v.amount * v.chanse
63 | OtherPly.Functions.AddMoney('bank', tonumber(amount), "Casino Winner")
64 | end
65 | end
66 | end
67 | end)
--------------------------------------------------------------------------------
/qb-phone/client/garage.lua:
--------------------------------------------------------------------------------
1 | -- Functions
2 |
3 | local function findVehFromPlateAndLocate(plate)
4 | local gameVehicles = QBCore.Functions.GetVehicles()
5 | for i = 1, #gameVehicles do
6 | local vehicle = gameVehicles[i]
7 | if DoesEntityExist(vehicle) then
8 | if QBCore.Functions.GetPlate(vehicle) == plate then
9 | local vehCoords = GetEntityCoords(vehicle)
10 | SetNewWaypoint(vehCoords.x, vehCoords.y)
11 | return true
12 | end
13 | end
14 | end
15 | end
16 |
17 | -- NUI Callback
18 |
19 | RegisterNUICallback('SetupGarageVehicles', function(_, cb)
20 | local vehicles = lib.callback.await('qb-phone:server:GetGarageVehicles', false)
21 | cb(vehicles)
22 | cb(PhoneData.GarageVehicles)
23 | end)
24 |
25 | RegisterNUICallback('gps-vehicle-garage', function(data, cb)
26 | local veh = data.veh
27 | if Config.Garage == 'jdev' then
28 | exports['qb-garages']:TrackVehicleByPlate(veh.plate)
29 | TriggerEvent('qb-phone:client:CustomNotification',
30 | "GARAGE",
31 | "GPS Marker Set!",
32 | "fas fa-car",
33 | "#e84118",
34 | 5000
35 | )
36 | cb("ok")
37 | elseif Config.Garage == 'qbcore' then
38 | --Deprecated
39 | if veh.state == 'In' then
40 | if veh.parkingspot then
41 | SetNewWaypoint(veh.parkingspot.x, veh.parkingspot.y)
42 | QBCore.Functions.Notify("Your vehicle has been marked", "success")
43 | end
44 | elseif veh.state == 'Out' and findVehFromPlateAndLocate(veh.plate) then
45 | QBCore.Functions.Notify("Your vehicle has been marked", "success")
46 | else
47 | QBCore.Functions.Notify("This vehicle cannot be located", "error")
48 | end
49 | cb("ok")
50 | end
51 | end)
52 |
53 | RegisterNUICallback('sellVehicle', function(data, cb)
54 | TriggerServerEvent('qb-phone:server:sendVehicleRequest', data)
55 | cb("ok")
56 | end)
57 |
58 | -- Events
59 |
60 | RegisterNetEvent('qb-phone:client:sendVehicleRequest', function(data, seller)
61 | local success = exports['qb-phone']:PhoneNotification("VEHICLE SALE", 'Purchase '..data.plate..' for $'..data.price, 'fas fa-map-pin', '#b3e0f2', "NONE", 'fas fa-check-circle', 'fas fa-times-circle')
62 | if success then
63 | TriggerServerEvent("qb-phone:server:sellVehicle", data, seller, 'accepted')
64 | else
65 | TriggerServerEvent("qb-phone:server:sellVehicle", data, seller, 'denied')
66 | end
67 | end)
68 |
69 | RegisterNetEvent('qb-phone:client:updateGarages', function()
70 | SendNUIMessage({
71 | action = "UpdateGarages",
72 | })
73 | end)
74 |
--------------------------------------------------------------------------------
/qb-phone/html/js/lsbn.js:
--------------------------------------------------------------------------------
1 |
2 | LoadLSBNEvent = function() {
3 | var PlayerJob = QB.Phone.Data.PlayerData.job.name;
4 | if (PlayerJob == "reporter"){
5 | $(".lsbn-send-news-for-chat").css({"display":"block"});
6 | } else {
7 | $(".lsbn-send-news-for-chat").css({"display":"none"});
8 | }
9 |
10 | $(".lsbn-list").html("");
11 | $.post('https://qb-phone/GetLSBNchats', JSON.stringify({}));
12 | }
13 |
14 | $(document).on('click', '.lsbn-send-news-for-chat', function(e){
15 | e.preventDefault();
16 | ClearInputNew()
17 | $('#lsbn-box-new-add-text').fadeIn(350);
18 | });
19 |
20 | $(document).on('click', '#lsbn-submit-to-send-text', function(e){
21 | e.preventDefault();
22 |
23 | var Text = $(".lsbn-input-yek").val();
24 | var Image = $(".lsbn-input-doo").val();
25 | var date = new Date();
26 | var Times = date.getDay()+" "+MonthFormatting[date.getMonth()]+" "+date.getHours()+":"+date.getMinutes();
27 |
28 | if((Text && Image) != ""){
29 | $.post('https://qb-phone/Send_lsbn_ToChat', JSON.stringify({
30 | Type: "Image",
31 | Text: Text,
32 | Image: Image,
33 | Time: Times,
34 | }));
35 | ClearInputNew()
36 | $('#lsbn-box-new-add-text').fadeOut(350);
37 | }else if (Text != ""){
38 | $.post('https://qb-phone/Send_lsbn_ToChat', JSON.stringify({
39 | Type: "Text",
40 | Text: Text,
41 | Time: Times,
42 | }));
43 | ClearInputNew()
44 | $('#lsbn-box-new-add-text').fadeOut(350);
45 | }
46 | });
47 |
48 | $(document).ready(function(){
49 | window.addEventListener('message', function(event) {
50 | switch(event.data.action) {
51 | case "AddNews":
52 | AddNewsLSBN(event.data.data)
53 | break;
54 | }
55 | })
56 | });
57 |
58 |
59 | AddNewsLSBN = function(data) {
60 | for (const [k, v] of Object.entries(data)) {
61 | if(v.Type == "Text"){
62 | var AddOption = ''+v.Text+
63 | '
'+v.Time+'
'
64 | '
';
65 |
66 | $('.lsbn-list').prepend(AddOption);
67 | }else if(v.Type == "Image"){
68 | var AddOption = ''+
69 | '

'+
70 | '
'+v.Text+'
'+
71 | '
'+v.Time+'
'+
72 | '
';
73 |
74 | $('.lsbn-list').prepend(AddOption);
75 | }
76 | }
77 | }
78 |
79 | $(document).on('click','.lsbn-chat-to-image-style', function (){
80 | let source = $(this).attr('src')
81 | QB.Screen.popUp(source);
82 | });
--------------------------------------------------------------------------------
/qb-phone/html/js/gopro.js:
--------------------------------------------------------------------------------
1 | let cam
2 |
3 | // Functions
4 |
5 | function ConfirmationFrame() {
6 | $('.spinner-input-frame').css("display", "flex");
7 | setTimeout(function () {
8 | $('.spinner-input-frame').css("display", "none");
9 | $('.checkmark-input-frame').css("display", "flex");
10 | setTimeout(function () {
11 | $('.checkmark-input-frame').css("display", "none");
12 | }, 2000)
13 | }, 1000)
14 | }
15 |
16 | SetupGoPros = function(cams) {
17 | $(".gopro-lists").html("");
18 | if (JSON.stringify(cams) != "[]"){
19 | $.each(cams, function(i, cams){
20 | var Element = '';
21 | $(".gopro-lists").append(Element);
22 | });
23 | }else{
24 | $(".gopro-lists").html('Nothing Here!
');
25 | }
26 | }
27 |
28 | // Search Bar Filter
29 |
30 | $(document).ready(function(){
31 | $("#gopro-search").on("keyup", function() {
32 | var value = $(this).val().toLowerCase();
33 | $(".gopro-list").filter(function() {
34 | $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
35 | });
36 | });
37 | });
38 |
39 | // On Clicks
40 |
41 | $(document).on('click', '#gopro-view-camera', function(e){
42 | e.preventDefault();
43 | cam = $(this).data('id')
44 | $.post("https://qb-phone/gopro-viewcam", JSON.stringify({
45 | id: cam,
46 | }));
47 | });
48 |
49 | $(document).on('click', '#gopro-track-camera', function(e){
50 | e.preventDefault();
51 | cam = $(this).data('id')
52 | $.post("https://qb-phone/gopro-track", JSON.stringify({
53 | id: cam,
54 | }));
55 | });
56 |
57 | $(document).on('click', '#gopro-addto-camera', function(e){
58 | e.preventDefault();
59 | ClearInputNew()
60 | cam = $(this).data('id')
61 | $('#gopro-access-menu').fadeIn(350);
62 | });
63 |
64 | $(document).on('click', '#gopro-send-access', function(e){
65 | e.preventDefault();
66 | var stateid = $(".gopro-stateid-access").val();
67 | if(stateid != ""){
68 | setTimeout(function(){
69 | ConfirmationFrame()
70 | }, 150);
71 | $.post("https://qb-phone/gopro-transfer", JSON.stringify({
72 | id: cam,
73 | stateid: stateid,
74 | }));
75 | }
76 | ClearInputNew()
77 | $('#gopro-access-menu').fadeOut(350);
78 | });
79 |
--------------------------------------------------------------------------------
/qb-phone/html/js/details.js:
--------------------------------------------------------------------------------
1 | function numberWithCommas(num) {
2 | return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
3 | }
4 |
5 | function LoadPlayerMoneys(){
6 | var PlayerPhoneNumber = QB.Phone.Data.PlayerData.charinfo.phone;
7 | var PlayerBankAcc = QB.Phone.Data.PlayerData.charinfo.account;
8 | var PlayerBankMoney = QB.Phone.Data.PlayerData.money.bank;
9 | var PlayerCashMoney = QB.Phone.Data.PlayerData.money.cash;
10 | var PlayerCasinoMoney = QB.Phone.Data.PlayerData.money.casino;
11 | var PlayerStateID = QB.Phone.Data.PlayerData.citizenid;
12 |
13 | // $(".details-phone").html(formatPhoneNumber(PlayerPhoneNumber))
14 | // $(".details-bankserial").html(PlayerBankAcc)
15 | // $(".details-bankmoney").html("$"+numberWithCommas(PlayerBankMoney))
16 | // $(".details-cashmoney").html("$"+numberWithCommas(PlayerCashMoney))
17 | // $(".details-casinomoney").html("$"+numberWithCommas(PlayerCasinoMoney))
18 | // $(".details-stateid").html(PlayerStateID)
19 | $(".details-phone").html(formatPhoneNumber(PlayerPhoneNumber))
20 | $(".details-bankserial").html(PlayerBankAcc)
21 | $(".details-bankmoney").html("$"+(PlayerBankMoney))
22 | $(".details-cashmoney").html("$"+(PlayerCashMoney))
23 | $(".details-casinomoney").html("$"+(PlayerCasinoMoney))
24 | $(".details-stateid").html(PlayerStateID)
25 |
26 | var PlayerLicenses = QB.Phone.Data.PlayerData.metadata.licences;
27 |
28 | $(".details-license-body-main").html("");
29 | // var AddOption0 = 'Licenses
'
30 | // $('.details-list').append(AddOption0);
31 | for (const [k, v] of Object.entries(PlayerLicenses)) {
32 | if (v){
33 | var firstLetter = k.substring(0, 1);
34 | var Fulltext = firstLetter.toUpperCase()+k.replace(firstLetter,'')+" License"
35 |
36 | var AddOption = ''+
37 | '
'+Fulltext+'
'+
38 | '
Valid
'+
39 | '
'
40 | $('.details-license-body-main').append(AddOption);
41 | }
42 | }
43 | }
44 |
45 |
46 | function formatPhoneNumber(phoneNumber) {
47 | // Remove any non-numeric characters from the phone number
48 | var cleaned = ('' + phoneNumber).replace(/\D/g, '');
49 |
50 | // Check if the number is empty
51 | if (cleaned === '') {
52 | return '';
53 | }
54 |
55 | // Format the number as (XXX)-XXX-XXXX
56 | var formatted = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
57 |
58 | // If the format doesn't match, return the original number
59 | if (formatted === null) {
60 | return phoneNumber;
61 | }
62 |
63 | // Otherwise, return the formatted number
64 | return '(' + formatted[1] + ')-' + formatted[2] + '-' + formatted[3];
65 | }
--------------------------------------------------------------------------------
/qb-phone/server/whatsapp.lua:
--------------------------------------------------------------------------------
1 | RegisterNetEvent('qb-phone:server:UpdateMessages', function(ChatMessages, ChatNumber)
2 | if not ChatNumber or not ChatMessages then return end
3 |
4 | local src = source
5 | local SenderData = QBCore.Functions.GetPlayer(src)
6 | local TargetData = QBCore.Functions.GetPlayerByPhone(ChatNumber)
7 |
8 | if TargetData then
9 | local Chat = MySQL.query.await('SELECT * FROM phone_messages WHERE citizenid = ? AND number = ?', {SenderData.PlayerData.citizenid, ChatNumber})
10 | if Chat[1] then
11 | MySQL.update('UPDATE phone_messages SET messages = ? WHERE citizenid = ? AND number = ?', {json.encode(ChatMessages), TargetData.PlayerData.citizenid, SenderData.PlayerData.charinfo.phone})
12 | MySQL.update('UPDATE phone_messages SET messages = ? WHERE citizenid = ? AND number = ?', {json.encode(ChatMessages), SenderData.PlayerData.citizenid, TargetData.PlayerData.charinfo.phone})
13 | TriggerClientEvent('qb-phone:client:UpdateMessages', TargetData.PlayerData.source, ChatMessages, SenderData.PlayerData.charinfo.phone, false)
14 | else
15 | MySQL.insert('INSERT INTO phone_messages (citizenid, number, messages) VALUES (?, ?, ?)', {TargetData.PlayerData.citizenid, SenderData.PlayerData.charinfo.phone, json.encode(ChatMessages)})
16 | MySQL.insert('INSERT INTO phone_messages (citizenid, number, messages) VALUES (?, ?, ?)', {SenderData.PlayerData.citizenid, TargetData.PlayerData.charinfo.phone, json.encode(ChatMessages)})
17 | TriggerClientEvent('qb-phone:client:UpdateMessages', TargetData.PlayerData.source, ChatMessages, SenderData.PlayerData.charinfo.phone, true)
18 | end
19 | else
20 | local query = '%' .. ChatNumber .. '%'
21 | local Player = MySQL.query.await('SELECT * FROM players WHERE charinfo LIKE ?', {query})
22 | local Chat = MySQL.query.await('SELECT * FROM phone_messages WHERE citizenid = ? AND number = ?', {SenderData.PlayerData.citizenid, ChatNumber})
23 | if Chat[1] and Player[1] then
24 | MySQL.update('UPDATE phone_messages SET messages = ? WHERE citizenid = ? AND number = ?', {json.encode(ChatMessages), Player[1].citizenid, SenderData.PlayerData.charinfo.phone})
25 | Player[1].charinfo = json.decode(Player[1].charinfo)
26 | MySQL.update('UPDATE phone_messages SET messages = ? WHERE citizenid = ? AND number = ?', {json.encode(ChatMessages), SenderData.PlayerData.citizenid, Player[1].charinfo.phone})
27 | elseif Player[1] then
28 | MySQL.insert('INSERT INTO phone_messages (citizenid, number, messages) VALUES (?, ?, ?)', {Player[1].citizenid, SenderData.PlayerData.charinfo.phone, json.encode(ChatMessages)})
29 | Player[1].charinfo = json.decode(Player[1].charinfo)
30 | MySQL.insert('INSERT INTO phone_messages (citizenid, number, messages) VALUES (?, ?, ?)', {SenderData.PlayerData.citizenid, Player[1].charinfo.phone, json.encode(ChatMessages)})
31 | end
32 | end
33 | end)
--------------------------------------------------------------------------------
/qb-phone/html/css/calculator.css:
--------------------------------------------------------------------------------
1 | .calculator-app {
2 | display: none;
3 | height: 108%;
4 | width: 100%;
5 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
6 | overflow: hidden;
7 | }
8 |
9 | .calculator-header {
10 | position: absolute;
11 | width: 100%;
12 | height: 8vh;
13 | background-color: transparent;
14 | top: 0;
15 | color: white;
16 | font-family: 'Gilroy';
17 | font-size: 1.8vh;
18 | }
19 |
20 | .calculator-header > p {
21 | line-height: 12vh;
22 | text-indent: 2vh;
23 | }
24 |
25 |
26 | .calculator-list {
27 | position: absolute;
28 | background-color: transparent;
29 | width: 100%;
30 | height: 85%;
31 |
32 | margin: 0 auto;
33 | left: 0;
34 | right: 0;
35 | bottom: 0;
36 |
37 | border-radius: .5vh;
38 |
39 | overflow-y: scroll;
40 | }
41 |
42 | .calculator-list::-webkit-scrollbar {
43 | display: none;
44 | }
45 |
46 |
47 |
48 | form{
49 | width: 92%;
50 | position: relative;
51 | top: 45%;
52 | left: 5%;
53 | transform: translate(-1%, -50%);
54 | }
55 | input[name="display"]{
56 | background: rgb(39, 39, 39);
57 | color: #fff;
58 | font-size: 4.5vh;
59 | height: 10vh;
60 | text-align: left;
61 | margin: 4vh 0.5vh;
62 | width: calc(100% - 10px);
63 | border: none;
64 | padding: 0 1vh;
65 | }
66 | input[type="button"]{
67 | font-size: 2vh;
68 | float: left;
69 | width: calc(100% / 4 - 0.6vh);
70 | background: #fff;
71 | background-image: linear-gradient(#fff, rgb(189, 189, 189));
72 | text-align: center;
73 | padding: 1vh;
74 | margin: 0 0 0.45vh 0.45vh;
75 | border: none;
76 | transition: 0.25s;
77 | border-radius: 5px;
78 | }
79 | input[type="button"]:hover{
80 | background: rgb(121, 121, 121);
81 | background-image: linear-gradient(rgb(121, 121, 121), rgb(87, 87, 87));
82 | }
83 | input[type="button"]:nth-last-of-type(1){
84 | background: yellow;
85 | background-image: linear-gradient(yellow, rgb(163, 163, 2));
86 | width: calc(50% - 0.7vh);
87 | transition: 0.25s;
88 | }
89 | input[type="button"]:nth-last-of-type(1):hover{
90 | background: rgb(204, 204, 4);
91 | background-image: linear-gradient(rgb(204, 204, 4), rgb(167, 167, 1));
92 | }
93 |
94 | #minishalhcalc{
95 | background: rgb(241, 126, 18);
96 | background-image: linear-gradient(rgb(241, 126, 18), rgb(202, 106, 16));
97 | color: #fff;
98 | transition: 0.25s;
99 | }
100 | #minishalhcalc:hover{
101 | background: rgb(204, 102, 6);
102 | background-image: linear-gradient(rgb(204, 102, 6), rgb(174, 86, 4));
103 | }
104 | #shakhescalc{
105 | background: rgb(191, 191, 191);
106 | background-image: linear-gradient(rgb(191, 191, 191), rgb(153, 153, 153));
107 | transition: 0.25s;
108 | }
109 | #shakhescalc:hover{
110 | background: rgb(121, 121, 121);
111 | background-image: linear-gradient(rgb(121, 121, 121), rgb(90, 90, 90));
112 | }
113 |
114 | .calc-icon{
115 | margin-left: -0.1vh;
116 | width: 4.8vh;
117 | }
--------------------------------------------------------------------------------
/qb-phone/html/css/ping.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .ping-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | overflow: hidden;
8 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
9 | }
10 |
11 | .ping-header {
12 | position: absolute;
13 | width: 90%;
14 | height: 35%;
15 | top: 8%;
16 | left: 0;
17 | right: 0;
18 | color: white;
19 | font-size: 1.8vh;
20 | margin: 0 auto;
21 | }
22 |
23 | .erpinger {
24 | position: absolute;
25 | width: 175%;
26 | margin: 0 auto;
27 | left: -9.7vh;
28 | right: 6vh;
29 | top: -6.5vh;
30 | }
31 |
32 | .ping-header > p {
33 | line-height: 12vh;
34 | text-indent: 2vh;
35 | margin: 0 0 0 9vh;
36 | }
37 |
38 | .ping-header > span {
39 | position: absolute;
40 | top: 8vh;
41 | left: 9vh;
42 | font-size: 1.2vh;
43 | height: 2vh;
44 | color: white;
45 | }
46 |
47 | .ping-list {
48 | position: absolute;
49 | width: 98%;
50 | height: 100%;
51 | margin: 0 auto;
52 | left: 0;
53 | right: 0;
54 | /* bottom: 3%; */
55 | border-radius: .5vh;
56 | overflow-y: scroll;
57 | }
58 |
59 | .ping-list::-webkit-scrollbar {
60 | display: none;
61 | }
62 |
63 |
64 | .imagepingapp{
65 | width: 100%;
66 | height: 100%;
67 | }
68 |
69 | .channel {
70 | position: absolute;
71 | width: 100%;
72 | top: 20%;
73 | font-size: 2vh;
74 | background: none;
75 | -moz-user-select: -moz-none;
76 | -khtml-user-select: none;
77 | -webkit-user-select: none;
78 | -o-user-select: none;
79 | user-select: none;
80 | z-index: 1;
81 | color: whitesmoke;
82 | }
83 |
84 |
85 | .ping-sender-piinger{
86 | display: block;
87 | height: 4.5vh;
88 | width: 80%;
89 | top: 1.5vh;
90 | text-align: center;
91 | margin-left: 10%;
92 | background: rgb(49,71,94);
93 | border-radius: 4px;
94 | box-shadow: 1px 1px 6px rgb(5, 5, 5);
95 | text-shadow: 1px 1px 3px rgb(5, 5, 5);
96 | transition: 0.3s;
97 | padding: 8px;
98 | }
99 |
100 | .ping-sender-piinger > i{
101 | margin-right: 2.5vh;
102 | }
103 |
104 | .ping-sender-piinger:hover{
105 | background: rgb(37, 68, 111);
106 | }
107 |
108 | .ping-menu-text{
109 | position: relative;
110 | top: 2.2vh;
111 | margin-left: 20%;
112 | margin-bottom: 20%;
113 | width: 55%;
114 | border: none;
115 | background: none;
116 | outline: none;
117 | text-indent: 3vh;
118 | text-align: left;
119 | line-height: 3.0vh;
120 | font-size: 1.45vh;
121 | overflow: hidden;
122 | color: white;
123 | border-bottom: .1vh solid #fff;
124 | transition: 0.25s;
125 | }
126 |
127 | #ping-menu-icon{
128 | position: relative;
129 | top: 2.2vh;
130 | right: 13.7vh;
131 | font-size: 1.4vh;
132 | color: white;
133 | }
134 |
135 | .ping-menu-title{
136 | position: relative;
137 | bottom: 0.2vh;
138 | right: 15.4vh;
139 | font-size: 1.1vh;
140 | color: white;
141 | }
--------------------------------------------------------------------------------
/qb-phone/html/js/garage.js:
--------------------------------------------------------------------------------
1 | let veh
2 | let plate
3 |
4 | $(document).ready(function(){
5 | $("#garage-search").on("keyup", function() {
6 | var value = $(this).val().toLowerCase();
7 | $(".garage-vehicle").filter(function() {
8 | $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
9 | });
10 | });
11 | });
12 |
13 | $(document).on('click', '.garage-vehicle', function(e){
14 | e.preventDefault();
15 |
16 | $(this).find(".garage-block").toggle();
17 | var Id = $(this).attr('id');
18 | var VehData = $("#"+Id).data('VehicleData');
19 | veh = VehData
20 | });
21 |
22 |
23 | $(document).on('click', '.box-track', function(e){
24 | e.preventDefault()
25 | $.post("https://qb-phone/gps-vehicle-garage", JSON.stringify({
26 | veh: veh,
27 | }));
28 | });
29 |
30 | $(document).on('click', '.box-sellvehicle', function(e){
31 | e.preventDefault()
32 | plate = $(this).parent().attr('id');
33 | $('#garage-sellvehicle-menu').fadeIn(350);
34 | });
35 |
36 | $(document).on('click', '#garage-sellvehicle', function(e){
37 | e.preventDefault();
38 | var stateid = $(".garage-sellvehicle-stateid").val();
39 | var price = $(".garage-sellvehicle-price").val();
40 | if(price != "" && stateid != ""){
41 | $.post("https://qb-phone/sellVehicle", JSON.stringify({
42 | plate: plate,
43 | id: stateid,
44 | price: price
45 | }));
46 | }
47 | ClearInputNew()
48 | $('#garage-sellvehicle-menu').fadeOut(350);
49 | });
50 |
51 | SetupGarageVehicles = function(Vehicles) {
52 | $(".garage-vehicles").html("");
53 | if (Vehicles != null) {
54 | $.each(Vehicles, function(i, vehicle){
55 | var Element =
56 | ' '+vehicle.fullname+' '+vehicle.plate+' '+vehicle.state+'' +
57 | '
' +
58 | '
'+vehicle.garage+'
' +
59 | '
'+vehicle.plate+'
' +
60 | '
'+vehicle.fuel+'
' +
61 | '
'+vehicle.engine + " %"+'
' +
62 | '
'+vehicle.body+ " %"+'
' +
63 | '
'+vehicle.paymentsleft+' Payments Left
' +
64 | '
TRACKSELL
' +
65 | '
' +
66 | '
';
67 |
68 | $(".garage-vehicles").append(Element);
69 | $("#vehicle-"+i).data('VehicleData', vehicle);
70 | });
71 | }
72 | }
--------------------------------------------------------------------------------
/qb-phone/html/css/casino.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .casino-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | overflow: hidden;
8 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
9 | }
10 |
11 | .casino-header {
12 | position: absolute;
13 | width: 90%;
14 | height: 10%;
15 | top: 8%;
16 | left: 0;
17 | right: 0;
18 | color: white;
19 | font-size: 1.8vh;
20 | margin: 0 auto;
21 | }
22 |
23 | .casino-header > p {
24 | line-height: 12vh;
25 | text-indent: 2vh;
26 | margin: 0 0 0 9vh;
27 | }
28 |
29 | .casino-header > span {
30 | position: absolute;
31 | top: 8vh;
32 | left: 9vh;
33 | font-size: 1.2vh;
34 | height: 2vh;
35 | color: white;
36 | }
37 |
38 | .casino-list {
39 | position: absolute;
40 | width: 90%;
41 | height: 80%;
42 | margin: 0 auto;
43 | left: 0;
44 | right: 0;
45 | bottom: 3%;
46 | border-radius: .5vh;
47 | overflow-y: scroll;
48 | }
49 |
50 | .casino-list::-webkit-scrollbar {
51 | display: none;
52 | }
53 |
54 | .casino-dashboard-boss{
55 | display: none;
56 | position: relative;
57 | left: 80%;
58 | width: 15%;
59 | background: #2c465f;
60 | color: whitesmoke;
61 | text-align: center;
62 | border-radius: 4px;
63 | box-shadow: 0rem 0rem 0.2rem 0.02rem #000000a6;
64 | transition: 0.2s;
65 | }
66 | .casino-dashboard-boss:hover{
67 | background: #0d1218c0;
68 | }
69 |
70 | .casino-dashboard-btn{
71 | width: 86%;
72 | margin-left: 6.5%;
73 | margin-bottom: 3%;
74 | color: whitesmoke;
75 | background: #0d1218c0;
76 | text-align: center;
77 | border-radius: 4px;
78 | transition: 0.2s;
79 | }
80 | .casino-dashboard-btn:hover{
81 | background: #0d1218;
82 | }
83 |
84 |
85 |
86 | .casino-license-body-main{
87 | display: block;
88 | width: 95%;
89 | margin-left: 1.8%;
90 | padding-left: 2%;
91 | margin-bottom: 2%;
92 | color: whitesmoke;
93 | border-radius: 4px;
94 | background: #2c465f;
95 | transition: 0.2s;
96 | font-size: 130%;
97 | }
98 | .casino-license-body-main:hover{
99 | background: #0d1218c0;
100 | }
101 |
102 | .casino-license-icon-class{
103 | display: inline;
104 | text-align: right;
105 | width: 10%;
106 | }
107 | .casino-license-text-class{
108 | display: inline-block;
109 | width: 85%;
110 | }
111 |
112 | #casino-click-beting{
113 | color: #8ee074;
114 | transition: 0.2s;
115 | }
116 | #casino-click-beting:hover{
117 | color: #6cac59;
118 | }
119 |
120 | .casino-info-player{
121 | width: 86%;
122 | color: whitesmoke;
123 | margin-left: 10%;
124 | margin-bottom: 2%;
125 | }
126 |
127 | #casino-Winer-this{
128 | background: #8ee074;
129 | transition: 0.2s;
130 | width: 72%;
131 | border-radius: 4px;
132 | color: black;
133 | text-align: center;
134 | }
135 | #casino-Winer-this:hover{
136 | background: #6cac59;
137 | }
138 |
139 | .casino-text-clear{
140 | text-align: center;
141 | color: whitesmoke;
142 | }
--------------------------------------------------------------------------------
/qb-phone/client/twitter.lua:
--------------------------------------------------------------------------------
1 | -- Functions
2 |
3 | local function escape_str(s)
4 | return s
5 | end
6 |
7 | local function GenerateTweetId()
8 | local tweetId = "TWEET-"..math.random(11111111, 99999999)
9 | return tweetId
10 | end
11 |
12 | -- NUI Callback
13 |
14 | RegisterNUICallback('GetTweets', function(_, cb)
15 | local hasVPN = QBCore.Functions.HasItem(Config.VPNItem)
16 |
17 | cb({
18 | TweetData = PhoneData.Tweets,
19 | hasVPN = hasVPN,
20 | })
21 | end)
22 |
23 | RegisterNUICallback('PostNewTweet', function(data, cb)
24 |
25 | local URL
26 |
27 | if data.url ~= "" and string.match(data.url, '[a-z]*://[^ >,;]*') then
28 | URL = data.url
29 | else
30 | URL = ""
31 | end
32 |
33 | local TweetMessage = {
34 | firstName = PhoneData.PlayerData.charinfo.firstname,
35 | lastName = PhoneData.PlayerData.charinfo.lastname,
36 | citizenid = PhoneData.PlayerData.citizenid,
37 | message = escape_str(data.Message):gsub("[%<>\"()\'$]",""),
38 | time = data.Date,
39 | tweetId = GenerateTweetId(),
40 | type = data.type,
41 | url = URL,
42 | showAnonymous = data.anonymous
43 | }
44 |
45 | TriggerServerEvent('qb-phone:server:UpdateTweets', TweetMessage)
46 | cb("ok")
47 | end)
48 |
49 | RegisterNUICallback('DeleteTweet',function(data)
50 | TriggerServerEvent('qb-phone:server:DeleteTweet', data.id)
51 | end)
52 |
53 | RegisterNUICallback('FlagTweet',function(data, cb)
54 | QBCore.Functions.Notify(data.name..' was reported for saying '..data.message, "error")
55 | cb('ok')
56 | end)
57 |
58 | -- Events
59 |
60 | RegisterNetEvent('qb-phone:client:UpdateTweets', function(src, Tweets, delete)
61 | if not PhoneData or not FullyLoaded then return end
62 | PhoneData.Tweets = Tweets
63 | local MyPlayerId = PlayerData.source or -1
64 |
65 |
66 | if delete and src == MyPlayerId then
67 | SendNUIMessage({
68 | action = "PhoneNotification",
69 | PhoneNotify = {
70 | title = "Twitter",
71 | text = "Tweet deleted!",
72 | icon = "fab fa-twitter",
73 | color = "#1DA1F2",
74 | timeout = 1000,
75 | },
76 | })
77 | end
78 |
79 | local hasVPN = QBCore.Functions.HasItem(Config.VPNItem)
80 |
81 | SendNUIMessage({
82 | action = "UpdateTweets",
83 | Tweets = PhoneData.Tweets,
84 | hasVPN = hasVPN,
85 | })
86 |
87 | if delete then return end
88 |
89 | local NewTweetData = Tweets[#Tweets]
90 | local newFirst, newLast = NewTweetData.firstName:gsub("[%<>\"()\'$]",""), NewTweetData.lastName:gsub("[%<>\"()\' $]","")
91 |
92 |
93 | if not delete and src == MyPlayerId then return end
94 |
95 | if not delete then
96 | SendNUIMessage({
97 | action = "PhoneNotification",
98 | PhoneNotify = {
99 | title = "@"..newFirst.." "..newLast,
100 | text = NewTweetData.message:gsub("[%<>\"()\'$]",""),
101 | icon = "fab fa-twitter",
102 | color = "#1DA1F2",
103 | },
104 | })
105 | end
106 | end)
--------------------------------------------------------------------------------
/qb-phone/html/css/gopro.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Lato&display=swap');
2 |
3 | .gopro-icon {
4 | margin-top: .5vh;
5 | width: 3.4vh;
6 | }
7 |
8 | .gopro-app {
9 | display: none;
10 | height: 108%;
11 | width: 100%;
12 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
13 | overflow: hidden;
14 | }
15 |
16 | .gopro-app-header {
17 | position: absolute;
18 | height: 9vh;
19 | width: 100%;
20 | text-align: center;
21 | line-height: 13.5vh;
22 | color: white;
23 | font-size: 1.5vh;
24 | }
25 |
26 | .gopro-homescreen {
27 | position: absolute;
28 | height: 108%;
29 | width: 100%;
30 | left: 0vh;
31 | }
32 |
33 | .gopro-lists::-webkit-scrollbar {
34 | display: none;
35 | }
36 |
37 | .gopro-lists {
38 | position: absolute;
39 | width: 90%;
40 | height: 45vh;
41 | margin: 0 auto;
42 | left: 0;
43 | right: 0.0vh;
44 | top: 12vh;
45 | overflow-x: hidden;
46 | overflow-y: scroll;
47 | }
48 |
49 | .gopro-list {
50 | position: relative;
51 | width: 90%;
52 | color: white;
53 | left: 15px;
54 | height: 5.5vh;
55 | margin-bottom: 8px;
56 | background-color: rgb(44, 70, 95);
57 | box-shadow: rgba(0, 0, 0, 0.557) 0rem 0rem 0.1rem 0.01rem;
58 | border-radius: 0.15rem;
59 | border-bottom: 0.1vh solid rgba(245, 245, 245, 0.68);
60 | }
61 |
62 | .gopro-list:hover {
63 | background-color: #15222e;
64 | }
65 |
66 | .gopro-list-icon {
67 | position: absolute;
68 | margin: .7vh;
69 | margin-left: 1.0vh;
70 | text-align: center;
71 | line-height: 3.5vh;
72 | color: white;
73 | font-size: 4.0vh;
74 | }
75 |
76 | .gopro-list-name {
77 | position: absolute;
78 | left: 6.8vh;
79 | color: white;
80 | line-height: 2.7vh;
81 | font-size: 1.35vh;
82 | }
83 |
84 | /* Action Buttons */
85 |
86 | .gopro-action-buttons {
87 | visibility: hidden;
88 | position: absolute;
89 | height: 108%;
90 | width: 100%;
91 | padding-bottom: 5.1vh;
92 | left: 0;
93 | right: 0;
94 | }
95 |
96 | .gopro-action-buttons > i {
97 | position: relative;
98 | float: left;
99 | margin-left: 1.8vh;
100 | left: 5.5vh;
101 | top: 1.7vh;
102 | font-size: 1.8vh;
103 | color: rgb(255, 255, 255);
104 | text-align: center;
105 | }
106 |
107 | .gopro-action-buttons > i:hover {
108 | color: #2c465f;
109 | }
110 |
111 | .gopro-list:hover .gopro-action-buttons {
112 | background: #0d1218c0;
113 | visibility: visible;
114 | }
115 |
116 | /* Search Bar / Icon */
117 |
118 | #gopro-search {
119 | display: block;
120 | position: absolute;
121 | background: none;
122 | border: none;
123 | background: none;
124 | top: 6.9vh;
125 | width: 79%;
126 | margin: 0 auto;
127 | left: 0%;
128 | right: 0;
129 | opacity: 1;
130 | height: 2.5vh;
131 | /* border-radius: 1vh; */
132 | border-bottom: .1vh solid #f5f5f5ad;
133 | /* box-shadow: 0 0 .2vh 0 rgba(0, 0, 0, 0.281); */
134 | /* font-family: 'Gilroy'; */
135 | outline: none;
136 | text-indent: 2.5vh;
137 | z-index: 100;
138 | color: whitesmoke;
139 | }
140 | #gopro-search-icon {
141 | position: absolute;
142 | top: 7.5vh;
143 | left: 3.5vh;
144 | font-size: 1.4vh;
145 | color: #FFFFFF;
146 | }
--------------------------------------------------------------------------------
/qb-phone/html/css/wenmo.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .wenmo-app {
4 | display: none;
5 | height: 100%;
6 | width: 100%;
7 | overflow: hidden;
8 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
9 | }
10 |
11 | .wenmo-header {
12 | position: absolute;
13 | width: 90%;
14 | height: 10%;
15 | left: 6.5%;
16 | right: 0;
17 | color: white;
18 | font-size: 1.8vh;
19 | }
20 |
21 | .wenmo-header > p {
22 | line-height: 12vh;
23 | text-indent: 2vh;
24 | margin: 0 0 0 9vh;
25 | }
26 |
27 | .wenmo-header > span {
28 | position: absolute;
29 | top: 8vh;
30 | left: 9vh;
31 | font-size: 1.2vh;
32 | height: 2vh;
33 | color: white;
34 | }
35 |
36 | .wenmo-list {
37 | position: absolute;
38 | width: 90%;
39 | height: 84%;
40 | margin: 0 auto;
41 | left: 0;
42 | right: 0;
43 | bottom: 3%;
44 | border-radius: .5vh;
45 | overflow-y: scroll;
46 | }
47 |
48 | .wenmo-list::-webkit-scrollbar {
49 | display: none;
50 | }
51 |
52 |
53 | .wenmo-send-money-btn{
54 | position: absolute;
55 | bottom: 0;
56 | top: 2vh;
57 | right: -1.5vh;
58 | width: 3.5vh;
59 | height: 3.5vh;
60 | margin: 2.2vh;
61 | z-index: 101;
62 | border-radius: 0.5vh;
63 | text-align: center;
64 | transition: .2s;
65 | background: linear-gradient(180deg, rgba(67,120,204,1) 0%, rgba(124,166,241,1) 100%);
66 | }
67 |
68 | .wenmo-send-money-btn:hover{
69 | color: rgb(187, 187, 187);
70 | }
71 |
72 | .wenmo-send-money-btn > i {
73 | line-height: 3.5vh;
74 | font-size: 2vh;
75 | color: white;
76 | }
77 |
78 | .wenmo-form-style-body{
79 | margin-bottom: 0.5vh;
80 | padding: 0.8vh 1.5vh;
81 | /* Adjust the padding here */
82 | border-radius: 0.463vh;
83 | background: rgb(11, 14, 21);
84 | overflow: hidden;
85 | }
86 |
87 | .wenmo-time-class-body{
88 | display: inline;
89 | float: right;
90 | color: whitesmoke;
91 | }
92 |
93 | .wenmo-input-one{
94 | display: block;
95 | position: absolute;
96 | background: rgb(11, 14, 21);
97 | border: none;
98 | width: 90%;
99 | margin: 0 auto;
100 | left: -2%;
101 | right: 0;
102 | opacity: 1;
103 | height: auto;
104 | border-radius: 0.5vh;
105 | outline: none;
106 | text-indent: .5vh;
107 | z-index: 100;
108 | color: #FFFFFF;
109 | height: 4vh;
110 | }
111 | .wenmo-input-two{
112 | display: block;
113 | position: absolute;
114 | background: rgb(11, 14, 21);
115 | border: none;
116 | width: 90%;
117 | margin: 0 auto;
118 | left: -2%;
119 | right: 0;
120 | opacity: 1;
121 | height: auto;
122 | border-radius: 0.5vh;
123 | outline: none;
124 | text-indent: .5vh;
125 | z-index: 100;
126 | color: #FFFFFF;
127 | height: 4vh;
128 | top:8vh;
129 | }
130 | .wenmo-input-three{
131 | display: block;
132 | position: absolute;
133 | background: rgb(11, 14, 21);
134 | border: none;
135 | width: 90%;
136 | margin: 0 auto;
137 | left: -2%;
138 | right: 0;
139 | opacity: 1;
140 | height: auto;
141 | border-radius: 0.5vh;
142 | outline: none;
143 | text-indent: .5vh;
144 | z-index: 100;
145 | color: #FFFFFF;
146 | height: 4vh;
147 | top:13vh;
148 | }
--------------------------------------------------------------------------------
/qb-phone/html/css/mail.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .mail-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
8 | overflow: hidden;
9 | }
10 |
11 | .mail-home {
12 | position: relative;
13 | left: 0;
14 | }
15 |
16 | .mail-header {
17 | display: block;
18 | width: 100%;
19 | }
20 |
21 | .mail-list {
22 | position: absolute;
23 | width: 86.0%;
24 | height: 46.5vh;
25 | top: 13vh;
26 | margin: 0 auto;
27 | left: 0;
28 | right: 0;
29 | overflow-y: scroll;
30 | }
31 |
32 | .mail-list::-webkit-scrollbar {
33 | display: none;
34 | }
35 |
36 | .mail {
37 | color: white;
38 | margin-bottom: 0.5vh;
39 | padding: 0.8vh 1.5vh;
40 | /* Adjust the padding here */
41 | border-radius: 0.463vh;
42 | background: rgb(11, 14, 21);
43 | overflow: hidden;
44 | font-size:1.3vh;
45 | font-family:'Gilroy';
46 | }
47 |
48 | .mail-sender {
49 | padding-top: 1.8vh;
50 | padding-left: 0.5vh;
51 | font-size: 1.1vh;
52 | color: white;
53 | left: 0.8vh;
54 | }
55 |
56 | .mail-subject {
57 | padding-left: 0.5vh;
58 | font-size: 1.1vh;
59 | color: white;
60 | max-width: 21vh;
61 | width: 21vh;
62 | }
63 |
64 | .mail-message {
65 | padding-left: 0.5vh;
66 | font-size: 1.1vh;
67 | color: white;
68 | max-width: 21vh;
69 | margin-bottom: 7%;
70 | }
71 |
72 | .mail-line {
73 | margin-left: 1.5vh;
74 | margin-right: 1.5vh;
75 | border-bottom: .1vh solid #fff;
76 | }
77 |
78 | .mail-time {
79 | margin-top: 0.7vh;
80 | font-size: 1.15vh;
81 | color: white;
82 | width: 100%;
83 | text-align: center;
84 | }
85 |
86 | #mail-search {
87 | display: block;
88 | position: absolute;
89 | background: rgb(11, 14, 21);
90 | border: 2px solid #34373e;
91 | top: 8vh;
92 | width: 86%;
93 | margin: 0 auto;
94 | left: -2%;
95 | right: 0;
96 | opacity: 1;
97 | height: 4vh;
98 | border-radius: 0.5vh;
99 | outline: none;
100 | text-indent: .8vh;
101 | z-index: 0;
102 | color: #FFFFFF;
103 | }
104 | #mail-search-icon {
105 | float: right;
106 | color: #34373e;
107 | position: absolute;
108 | right: 3.5vh;
109 | top: 8.7vh;
110 | z-index: 1;
111 | background: #1c1f26;
112 | padding: 0.5vh;
113 | border-radius: 0.3vh;
114 | }
115 |
116 | .nomails {
117 | text-align: center;
118 | font-family: 'Gilroy';
119 | font-size: 1.7vh;
120 | font-weight: bold;
121 | color: #FFFFFF;
122 | line-height: 20vh;
123 | }
124 |
125 | #mail-frown {
126 | position: absolute;
127 | top: 3.5%;
128 | left: 41.5%;
129 | font-size: 275%;
130 | color: #FFFFFF;
131 | }
132 |
133 | .mail-block {
134 | padding: 0 0.3vh;
135 | /*line-height: 5vh;*/
136 | display: none;
137 | overflow: hidden;
138 | }
139 |
140 | .mail-box {
141 | transition: 0.25s;
142 | border-radius: 0.5vh;
143 | color: white;
144 | font-family: 'Gilroy';
145 | font-size: 1.1vh;
146 | margin-bottom: 4%;
147 | width:85%;
148 | text-align:center;
149 | }
150 |
151 | .mail-delete{
152 | background: linear-gradient(0deg, rgb(141, 23, 23) 0%, rgb(155, 19, 19) 50%, rgb(141, 23, 23) 100%);
153 | padding: 4.0%;
154 | }
155 |
156 | .mail-accept{
157 | background: linear-gradient(0deg, rgba(18,115,92,1) 0%, rgba(15,133,105,1) 50%, rgba(18,115,92,1) 100%);
158 | padding: 4.0%;
159 | }
--------------------------------------------------------------------------------
/qb-phone/server/twitter.lua:
--------------------------------------------------------------------------------
1 | Tweets = {}
2 |
3 | -- Events
4 |
5 | CreateThread(function()
6 | local tweetsSelected = MySQL.query.await('SELECT * FROM phone_tweets WHERE `date` > NOW() - INTERVAL ? hour', {Config.TweetDuration})
7 | Tweets = tweetsSelected
8 | end)
9 |
10 | RegisterNetEvent('qb-phone:server:DeleteTweet', function(tweetId)
11 | local src = source
12 | local CID = QBCore.Functions.GetPlayer(src).PlayerData.citizenid
13 | local delete = false
14 | for i = 1, #Tweets do
15 | if Tweets[i].tweetId == tweetId and Tweets[i].citizenid == CID then
16 | table.remove(Tweets, i)
17 | delete = true
18 | break
19 | end
20 | end
21 | if not delete then return end
22 | TriggerClientEvent('qb-phone:client:UpdateTweets', -1, src, Tweets, true)
23 | end)
24 |
25 | RegisterNetEvent('qb-phone:server:UpdateTweets', function(TweetData)
26 | local src = source
27 | local Player = QBCore.Functions.GetPlayer(src)
28 | local HasVPN = Player.Functions.GetItemByName(Config.VPNItem)
29 |
30 | if (TweetData.showAnonymous and HasVPN) then
31 | TweetData.firstName = "Anonymous"
32 | TweetData.lastName = ""
33 | end
34 |
35 | print(json.encode(TweetData.url))
36 | MySQL.insert('INSERT INTO phone_tweets (citizenid, firstName, lastName, message, url, tweetid, type) VALUES (?, ?, ?, ?, ?, ?, ?)', {
37 | TweetData.citizenid,
38 | TweetData.firstName:gsub("[%<>\"()\'$]",""),
39 | TweetData.lastName:gsub("[%<>\"()\'$]",""),
40 | TweetData.message:gsub("[%<>\"()\'$]",""),
41 | TweetData.url,
42 | TweetData.tweetId,
43 | TweetData.type,
44 | }, function(id)
45 | if id then
46 | Tweets[#Tweets+1] = {
47 | id = id,
48 | citizenid = TweetData.citizenid,
49 | firstName = TweetData.firstName:gsub("[%<>\"()\'$]",""),
50 | lastName = TweetData.lastName:gsub("[%<>\"()\'$]",""),
51 | message = TweetData.message:gsub("[%<>\"()\'$]",""),
52 | url = TweetData.url,
53 | tweetId =TweetData.tweetId,
54 | type = TweetData.type,
55 | date = os.date('%Y-%m-%d %H:%M:%S')
56 | }
57 |
58 | TriggerClientEvent('qb-phone:client:UpdateTweets', -1, src, Tweets, false)
59 | end
60 | end)
61 | end)
62 |
63 | -- Use this tweet function in different resources I used it in Renewed Fishing script to make the ped tweet close to start of tournaments --
64 | local function AddNewTweet(TweetData)
65 | local tweetID = TweetData and TweetData.tweetId or "TWEET-"..math.random(11111111, 99999999)
66 |
67 | MySQL.insert('INSERT INTO phone_tweets (citizenid, firstName, lastName, message, url, tweetid, type) VALUES (?, ?, ?, ?, ?, ?, ?)', {
68 | TweetData.citizenid,
69 | TweetData.firstName:gsub("[%<>\"()\'$]",""),
70 | TweetData.lastName:gsub("[%<>\"()\'$]",""),
71 | TweetData.message:gsub("[%<>\"()\'$]",""),
72 | TweetData.url,
73 | tweetID,
74 | TweetData.type or "tweet",
75 | }, function(id)
76 | if id then
77 | Tweets[#Tweets+1] = {
78 | id = id,
79 | citizenid = TweetData.citizenid or "TEMP332",
80 | firstName = TweetData.firstName:gsub("[%<>\"()\'$]",""),
81 | lastName = TweetData.lastName:gsub("[%<>\"()\'$]",""),
82 | message = TweetData.message:gsub("[%<>\"()\'$]",""),
83 | url = TweetData.url or "",
84 | tweetId = tweetID,
85 | type = TweetData.type or "tweet",
86 | date = os.date('%Y-%m-%d %H:%M:%S')
87 | }
88 |
89 | TriggerClientEvent('qb-phone:client:UpdateTweets', -1, 0, Tweets, false)
90 | end
91 | end)
92 | end exports("AddNewTweet", AddNewTweet)
--------------------------------------------------------------------------------
/qb-phone/html/js/mail.js:
--------------------------------------------------------------------------------
1 | var OpenedMail = null;
2 |
3 | // Mail APP
4 |
5 | // Search
6 |
7 | $(document).ready(function(){
8 | $("#mail-search").on("keyup", function() {
9 | var value = $(this).val().toLowerCase();
10 | $(".mail").filter(function() {
11 | $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
12 | });
13 | });
14 | });
15 |
16 | // Functions
17 |
18 | QB.Phone.Functions.SetupMails = function(Mails) {
19 | if (Mails !== null && Mails !== undefined) {
20 | Mails = Mails.reverse();
21 | if (Mails.length > 0) {
22 | $(".mail-list").html("");
23 | $.each(Mails, function(i, mail){
24 | var TimeAgo = moment(mail.date).format('MM/DD/YYYY hh:mm');
25 |
26 | if (JSON.stringify(mail.button) != "[]"){
27 | var element =
28 | ''+
29 | '
From: '+mail.sender+'' +
30 | '
Subject: '+mail.subject+'
' +
31 | '
' +
32 | '
'+mail.message+'
' +
33 | '
ACCEPTDELETE
' +
34 | '
' +
35 | '
' +
36 | '
'+TimeAgo+'
' +
37 | '
';
38 | $(".mail-list").append(element);
39 | $("#mail-"+mail.mailid).data('MailData', mail);
40 | }else{
41 | var element =
42 | ''+
43 | '
From: '+mail.sender+'' +
44 | '
Subject: '+mail.subject+'
' +
45 | '
' +
46 | '
'+mail.message+'
' +
47 | '
DELETE
' +
48 | '
' +
49 | '
' +
50 | '
'+TimeAgo+'
' +
51 | '
';
52 | $(".mail-list").append(element);
53 | $("#mail-"+mail.mailid).data('MailData', mail);
54 | }
55 | });
56 | } else {
57 | $(".mail-list").html('Nothing Here!
');
58 | }
59 |
60 | }
61 | }
62 |
63 | // Clicks
64 |
65 | $(document).on('click', '.mail-accept', function(e){
66 | e.preventDefault();
67 | var mailId = $(this).parent().parent().parent().data('mailid');
68 | var MailData = $("#"+OpenedMail).data('MailData');
69 | $.post('https://qb-phone/AcceptMailButton', JSON.stringify({
70 | buttonEvent: MailData.button.buttonEvent,
71 | buttonData: MailData.button.buttonData,
72 | isServer: MailData.button.isServer,
73 | mailId: mailId,
74 | }));
75 | });
76 |
77 | $(document).on('click', '.mail-delete', function(e){
78 | e.preventDefault();
79 | var mailId = $(this).parent().parent().parent().data('mailid');
80 | $.post('https://qb-phone/RemoveMail', JSON.stringify({
81 | mailId: mailId
82 | }));
83 | });
84 |
85 | $(document).on('click', '.mail', function(e){
86 | e.preventDefault();
87 | $(this).find(".mail-block").toggle();
88 | OpenedMail = $(this).attr('id');
89 | });
--------------------------------------------------------------------------------
/qb-phone/html/css/debt.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .debt-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | overflow: hidden;
8 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
9 | }
10 |
11 | .debts-header {
12 | position: absolute;
13 | width: 100%;
14 | height: 12vh;
15 | top: 0;
16 | color: white;
17 | /* font-family: 'Gilroy'; */
18 | font-size: 1.8vh;
19 | }
20 |
21 | .debts-list {
22 | position: absolute;
23 | width: 80.0%;
24 | height: 46.5vh;
25 | top: 10.8vh;
26 | margin: 0 auto;
27 | left: 0;
28 | right: 0;
29 | overflow-y: scroll;
30 | }
31 |
32 | .debts-list::-webkit-scrollbar {
33 | display: none;
34 | }
35 |
36 | .debt-list {
37 | padding: 4px;
38 | width: 100%;
39 | background-color: rgb(44, 70, 95);
40 | border-radius: 4px 4px 0px 0px;
41 | border-bottom: .1vh solid #fff;
42 | margin-bottom: 3.5%;
43 | }
44 |
45 | /* ASSET FEES */
46 |
47 | .debt-icon {
48 | position: relative;
49 | line-height: 6vh;
50 | left: 0vh;
51 | padding-top: 1.1vh;
52 | padding-bottom: 1.1vh;
53 | padding-left: 1.3vh;
54 | padding-right: 2.6vh;
55 | color: white;
56 | font-size: 4.0vh;
57 | transition: .05s linear;
58 | }
59 |
60 | .debt-main-title {
61 | position: absolute;
62 | left: 6.8vh;
63 | color: white;
64 | line-height: 8.5vh;
65 | font-size: 1.2vh;
66 | }
67 |
68 | .debt-main-fee {
69 | position: absolute;
70 | left: 6.8vh;
71 | color: white;
72 | line-height: 3vh;
73 | font-size: 1.2vh;
74 | }
75 |
76 | .debt-remaining-payments {
77 | position: absolute;
78 | right: 1.0vh;
79 | color: white;
80 | line-height: 8.5vh;
81 | font-size: 1.3vh;
82 | }
83 |
84 | /* Click Block CSS */
85 |
86 | .debt-block {
87 | padding: 0 18px;
88 | /*line-height: 5vh;*/
89 | display: none;
90 | overflow: hidden;
91 | background-color: rgb(44, 70, 95);
92 | margin-bottom: 1.4vh;
93 | }
94 |
95 | .debt-title {
96 | padding: 3px 18px;
97 | padding-top: 0.5vh;
98 | padding-left: 0vh;
99 | color: white;
100 | font-size: 1.3vh;
101 | border-bottom: .1vh solid #fff;
102 | }
103 |
104 | .debt-title > i {
105 | padding-right: 0.8vh;
106 | font-size: 1.3vh;
107 | color: white;
108 | }
109 |
110 | .debt-extrainfo {
111 | padding: 3px 18px;
112 | padding-top: 0.5vh;
113 | padding-left: 0vh;
114 | color: white;
115 | font-size: 1.3vh;
116 | border-bottom: .1vh solid #fff;
117 | }
118 |
119 | .debt-extrainfo > i {
120 | padding-right: 0.8vh;
121 | font-size: 1.3vh;
122 | color: white;
123 | }
124 |
125 | .debt-due {
126 | padding: 3px 18px;
127 | padding-top: 0.5vh;
128 | padding-left: 0vh;
129 | color: white;
130 | font-size: 1.3vh;
131 | border-bottom: .1vh solid #fff;
132 | margin-bottom: 7%;
133 | }
134 |
135 | .debt-due > i {
136 | padding-right: 0.8vh;
137 | font-size: 1.3vh;
138 | color: white;
139 | }
140 |
141 | .debt-box {
142 | transition: 0.25s;
143 | border-radius: 5px;
144 | color: black;
145 | font-family: 'Gilroy';
146 | font-size: 1.1vh;
147 | margin-bottom: 4%;
148 | }
149 |
150 | .send-all-box{
151 | background:#90e278;
152 | padding: 4.0%;
153 | }
154 |
155 | .send-minimum-box{
156 | background:#f6a167;
157 | padding: 4.0%;
158 | }
159 |
160 | /* SEARCH SHIT */
161 |
162 | #debt-search {
163 | display: block;
164 | position: absolute;
165 | background: none;
166 | border: none;
167 | background: none;
168 | top: 6.9vh;
169 | width: 77%;
170 | margin: 0 auto;
171 | left: -2%;
172 | right: 0;
173 | opacity: 1;
174 | height: 2.5vh;
175 | border-bottom: .1vh solid #f5f5f5ad;
176 | outline: none;
177 | text-indent: 2.5vh;
178 | z-index: 100;
179 | color: whitesmoke;
180 | }
181 | #debt-search-icon {
182 | position: absolute;
183 | top: 7.5vh;
184 | left: 3.5vh;
185 | font-size: 1.4vh;
186 | color: #FFFFFF;
187 | }
--------------------------------------------------------------------------------
/qb-phone/html/js/taxi.js:
--------------------------------------------------------------------------------
1 | // Functions
2 |
3 | function formatPhoneNumber(phoneNumberString) {
4 | var cleaned = ('' + phoneNumberString).replace(/\D/g, '');
5 | var match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
6 | if (match) {
7 | return '(' + match[1] + ') ' + match[2] + '-' + match[3];
8 | }
9 | return phoneNumberString;
10 | }
11 |
12 | SetupTaxiDrivers = function(data) {
13 | $(".taxis-list").html("");
14 | $.each(data, function(job, jobData) {
15 | $(".taxis-list").append(`Available Drivers
`);
16 | $.each(jobData.Players, function(i, player) {
17 | $(".taxis-list").append(` ${player.Name}
${formatPhoneNumber(player.Phone)}
`);
18 | });
19 |
20 | if (jobData.Players.length === 0) {
21 | $(".taxis-list").append('None Available!
');
22 | }
23 | $(".taxis-list").append("
");
24 | });
25 | }
26 |
27 | // On Click
28 |
29 | $(document).on('click', '.taxi-list-call', function(e){
30 | e.preventDefault();
31 | var Number = $(this).parent().attr('id');
32 | if (Number != undefined){
33 | var InputNum = Number;
34 |
35 | if (InputNum != ""){
36 | cData = {
37 | number: InputNum,
38 | name: InputNum,
39 | }
40 | $.post('https://qb-phone/CallContact', JSON.stringify({
41 | ContactData: cData,
42 | Anonymous: QB.Phone.Data.AnonymousCall,
43 | }), function(status){
44 | if (cData.number !== QB.Phone.Data.PlayerData.charinfo.phone) {
45 | if (status.IsOnline) {
46 | if (status.CanCall) {
47 | if (!status.InCall) {
48 | $('.phone-new-box-body').fadeOut(350);
49 | ClearInputNew()
50 | $(".phone-call-outgoing").css({"display":"none"});
51 | $(".phone-call-incoming").css({"display":"none"});
52 | $(".phone-call-ongoing").css({"display":"none"});
53 | $(".phone-call-outgoing-caller").html(cData.name);
54 | QB.Phone.Functions.HeaderTextColor("white", 400);
55 | QB.Phone.Animations.TopSlideUp('.phone-application-container', 400, -160);
56 | setTimeout(function(){
57 | $(".phone-app").css({"display":"none"});
58 | QB.Phone.Animations.TopSlideDown('.phone-application-container', 400, -160);
59 | QB.Phone.Functions.ToggleApp("phone-call", "block");
60 | $(".phone-currentcall-container").css({"display":"block"});
61 | $("#incoming-answer").css({"display":"none"});
62 | }, 450);
63 |
64 | CallData.name = cData.name;
65 | CallData.number = cData.number;
66 |
67 | QB.Phone.Data.currentApplication = "phone-call";
68 | } else {
69 | QB.Phone.Notifications.Add("fas fa-phone", "Phone", "You're already in a call!");
70 | }
71 | } else {
72 | QB.Phone.Notifications.Add("fas fa-phone", "Phone", "This person is busy!");
73 | }
74 | } else {
75 | QB.Phone.Notifications.Add("fas fa-phone", "Phone", "This person is not available!");
76 | }
77 | } else {
78 | QB.Phone.Notifications.Add("fas fa-phone", "Phone", "You can't call yourself!");
79 | }
80 | });
81 | }
82 | }
83 | })
84 |
--------------------------------------------------------------------------------
/qb-phone/client/groups.lua:
--------------------------------------------------------------------------------
1 | local inJob = false
2 | local GroupBlips = {}
3 |
4 | local function FindBlipByName(name)
5 | for i=1, #GroupBlips do
6 | if GroupBlips[i] and GroupBlips[i].name == name then
7 | return i
8 | end
9 | end
10 | end
11 |
12 | RegisterNetEvent("groups:removeBlip", function(name)
13 | local i = FindBlipByName(name)
14 | if i then
15 | local blip = GroupBlips[i]["blip"]
16 | SetBlipRoute(blip, false)
17 | RemoveBlip(blip)
18 | GroupBlips[i] = nil
19 | end
20 | end)
21 |
22 | RegisterNetEvent('groups:phoneNotification', function(data)
23 | SendNUIMessage({
24 | action = "PhoneNotification",
25 | PhoneNotify = {
26 | title = data.title,
27 | text = data.text,
28 | icon = data.icon,
29 | color = data.color,
30 | timeout = data.timeout,
31 | },
32 | })
33 | end)
34 |
35 | RegisterNetEvent("groups:createBlip", function(name, data)
36 | if not data then return print("Invalid Data was passed to the create blip event") end
37 |
38 | if FindBlipByName(name) then
39 | TriggerEvent("groups:removeBlip", name)
40 | end
41 |
42 | local blip
43 | if data.entity then
44 | blip = AddBlipForEntity(data.entity)
45 | elseif data.netId then
46 | blip = AddBlipForEntity(NetworkGetEntityFromNetworkId(data.netId))
47 | elseif data.radius then
48 | blip = AddBlipForRadius(data.coords.x, data.coords.y, data.coords.z, data.radius)
49 | else
50 | blip = AddBlipForCoord(data.coords)
51 | end
52 |
53 | if not data.color then data.color = 1 end
54 | if not data.alpha then data.alpha = 255 end
55 |
56 | if not data.radius then
57 | if not data.sprite then data.sprite = 1 end
58 | if not data.scale then data.scale = 0.7 end
59 | if not data.label then data.label = "NO LABEL FOUND" end
60 |
61 | SetBlipSprite(blip, data.sprite)
62 | SetBlipScale(blip, data.scale)
63 | BeginTextCommandSetBlipName("STRING")
64 | AddTextComponentSubstringPlayerName(data.label)
65 | EndTextCommandSetBlipName(blip)
66 | end
67 |
68 | SetBlipColour(blip, data.color)
69 | SetBlipAlpha(blip, data.alpha)
70 |
71 | if data.route then
72 | SetBlipRoute(blip, true)
73 | SetBlipRouteColour(blip, data.routeColor)
74 | end
75 | GroupBlips[#GroupBlips+1] = {name = name, blip = blip}
76 | end)
77 |
78 | RegisterNUICallback('GetGroupsApp', function (_, cb)
79 | local getGroups = lib.callback.await('qb-phone:server:getAllGroups', false)
80 | cb(getGroups)
81 | end)
82 |
83 | RegisterNetEvent('qb-phone:client:RefreshGroupsApp', function(Groups, finish)
84 | if finish then inJob = false end
85 | if inJob then return end
86 | SendNUIMessage({
87 | action = "refreshApp",
88 | data = Groups,
89 | })
90 | end)
91 |
92 |
93 | RegisterNetEvent('qb-phone:client:AddGroupStage', function(_, stage)
94 | inJob = true
95 | SendNUIMessage({
96 | action = "addGroupStage",
97 | status = stage
98 | })
99 | end)
100 |
101 |
102 | RegisterNUICallback('jobcenter_CreateJobGroup', function(data, cb) --employment
103 | TriggerServerEvent('qb-phone:server:jobcenter_CreateJobGroup', data)
104 | cb("ok")
105 | end)
106 |
107 | RegisterNUICallback('jobcenter_JoinTheGroup', function(data, cb) --employment
108 | TriggerServerEvent('qb-phone:server:jobcenter_JoinTheGroup', data)
109 | cb("ok")
110 | end)
111 |
112 | RegisterNUICallback('jobcenter_leave_grouped', function(data, cb) --employment
113 | if not data then return end
114 | local success = exports['qb-phone']:PhoneNotification("Job Center", 'Are you sure you want to leave the group?', 'fas fa-users', '#FFBF00', "NONE", 'fas fa-check-circle', 'fas fa-times-circle')
115 | if success then
116 | TriggerServerEvent('qb-phone:server:jobcenter_leave_grouped', data)
117 | end
118 | cb("ok")
119 | end)
120 |
121 | RegisterNUICallback('jobcenter_DeleteGroup', function(data, cb) --employment
122 | TriggerServerEvent('qb-phone:server:jobcenter_DeleteGroup', data)
123 | cb("ok")
124 | end)
125 |
126 |
127 | RegisterNUICallback('jobcenter_CheckPlayerNames', function(data, cb) --employment
128 | local HasName = lib.callback.await('qb-phone:server:jobcenter_CheckPlayerNames', false, data.id)
129 | cb(HasName)
130 | end)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### README.md for Renewed Phone customized by Wahyu Adi ("4.0 INSPIRED")
2 |
3 | #### GPL v3 Compliant Distribution Notification
4 |
5 | Welcome to the repository for Renewed-Phone customized by Wahyu Adi, originally customized by [FjamZoo](https://github.com/Renewed-Scripts/qb-phone). This document serves as an official notification and overview of the distribution of this software, which includes modifications made by the previous owner from whom I acquired it. The software is governed under the GNU General Public License version 3 (GPLv3), which is dedicated to protecting the freedoms to use, study, modify, and share software.
6 |
7 | #### Background
8 |
9 | The decision to acquire and subsequently distribute this script was informed by the discovery that the original seller was engaging in the practice of reselling free software at a significant markup, with only minimal changes to the user interface. In response to this, and in keeping with the spirit and legal requirements of the GPLv3, I have taken the initiative to ensure that these modifications, along with the original script, are made freely available. This repository embodies a commitment to the open-source community's principles of transparency, collaboration, and the free distribution of software.
10 |
11 | #### Repository Contents
12 |
13 | Contained within this repository is the complete source code of the script as it was received by me, unaltered from its modified state. This includes both the original code and the modifications introduced by the previous owner.
14 |
15 | #### Our Commitment to Open Source
16 |
17 | By making this modified script accessible on GitHub, we are adhering to the stipulations set forth by the GPLv3, thus ensuring that everyone is granted the freedom to use, modify, and distribute the software. This action is a reflection of our dedication to supporting the open-source ecosystem, fostering a culture of free knowledge exchange, and advancing technology in a manner that is inclusive and equitable.
18 |
19 | #### Reason for Distribution
20 |
21 | It is important to highlight that the catalyst for this distribution was the realization that the original seller was capitalizing on the open-source nature of the software by reselling it at a high price with only minimal user interface enhancements. This practice not only contravenes the ethos of the open-source movement but also undermines the fundamental rights afforded by the GPLv3. By making this software freely available, we aim to rectify this situation and ensure that the software remains accessible to all, in line with the original intentions of its licensing.
22 |
23 | #### Access and Use
24 |
25 | We invite all interested parties to explore, utilize, and contribute to this project. In accordance with the GPLv3, you are empowered to:
26 |
27 | - **Run** the software for any purpose.
28 | - **Study** the source code and modify it according to your needs.
29 | - **Distribute** copies of the original or modified software, thus enabling others to benefit from the same freedoms.
30 |
31 | #### Conclusion
32 |
33 | This README stands as a declaration of our compliance with GPLv3 licensing requirements and our unwavering commitment to the principles of open-source software distribution. Through initiatives like this, we collectively contribute towards a technological future that is open, collaborative, and innovative.
34 |
35 | For detailed information on the GNU General Public License version 3 (GPLv3), please visit [GNU's Official Website](https://www.gnu.org/licenses/gpl-3.0.en.html).
36 |
37 | Your contributions, feedback, and participation in this project are warmly welcomed. Together, we can guarantee that the benefits of technology remain freely accessible to everyone.
38 |
39 | # Keep FiveM Free and Open Source
40 | # Obey the GPL
41 |
42 | **Proof of purchase:**
43 |
44 | 
45 | 
46 | 
47 | 
48 | 
49 | 
50 |
51 |
52 | **CFX, if you ever look at this, here's a prime example of someone selling FiveM content outside of Tebex.**
53 |
--------------------------------------------------------------------------------
/qb-phone/html/css/gallery.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Lato&display=swap');
2 |
3 | .gallery-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
8 | overflow: hidden;
9 | }
10 |
11 | .gallery-app-header {
12 | position: absolute;
13 | height: 9vh;
14 | width: 100%;
15 | text-align: center;
16 | line-height: 12.5vh;
17 | color: white;
18 | font-size: 1.5vh;
19 | }
20 |
21 | .gallery-homescreen {
22 | position: absolute;
23 | height: 108%;
24 | width: 100%;
25 | left: 0vh;
26 | }
27 |
28 | .gallery-detailscreen {
29 | position: absolute;
30 | height: 108%;
31 | width: 100%;
32 | left: -30vh;
33 | }
34 | .gallery-postscreen {
35 | position: absolute;
36 | height: 108%;
37 | width: 100%;
38 | left: -30vh;
39 | }
40 |
41 | .gallery-images {
42 | position: absolute;
43 | width: 85%;
44 | height: 44.5vh;
45 | top: 10.5vh;
46 | margin: 0 auto;
47 | left: 0;
48 | right: 0;
49 | overflow-y: scroll;
50 | }
51 |
52 | .gallery-images::-webkit-scrollbar {
53 | display: none;
54 | }
55 |
56 | .tumbnail{
57 | width: 100%;
58 | border-radius: 0.3vh;
59 | }
60 |
61 | .gallery-image {
62 | display: inline-block;
63 | width: 50%;
64 | padding: 0.2vh;
65 | height: 7.1vh;
66 |
67 | }
68 | .gallery-details {
69 | position: absolute;
70 | height: 76%;
71 | width: 84%;
72 | margin: 0 auto;
73 | left: 0vh;
74 | right: 0;
75 | top: 11vh;
76 | }
77 |
78 |
79 |
80 | .return-button {
81 | display: flex;
82 | flex-direction: row;
83 | justify-content: space-between;
84 | }
85 |
86 | .return-button > div {
87 | margin: 2px;
88 | width: 100%;
89 | height: 5vh;
90 | background-color: rgb(233, 233, 233);
91 | border-radius: .3vh;
92 | transition: .05s linear;
93 | text-align: center;
94 | line-height: 5vh;
95 | font-size: 1.4vh;
96 | }
97 |
98 | .return-button > div:hover {
99 | background-color: rgb(212, 212, 212);
100 | }
101 |
102 | .make-post-button {
103 | display: flex;
104 | flex-direction: row;
105 | }
106 |
107 | .make-post-button > div {
108 | margin: 2px;
109 | width: 40%;
110 | height: 5vh;
111 | background-color: #8ee074;
112 | border-radius: .3vh;
113 | transition: .05s linear;
114 | text-align: center;
115 | line-height: 5vh;
116 | font-size: 1.4vh;
117 | }
118 |
119 | .make-post-button > div:hover {
120 | background-color: #6cac59;
121 | }
122 |
123 | #delete-button {
124 | margin: 2px;
125 | width: 20%;
126 | height: 5vh;
127 | background-color: #f5a15b;
128 | border-radius: .3vh;
129 | transition: .05s linear;
130 | text-align: center;
131 | line-height: 5vh;
132 | font-size: 1.4vh;
133 | }
134 | #delete-button:hover {
135 | background-color: #c27e47;
136 | }
137 |
138 | #gallery-coppy-button{
139 | background: rgb(187, 187, 81);
140 | }
141 | #gallery-coppy-button:hover{
142 | background: rgb(145, 145, 63);
143 | }
144 |
145 | .posts-button {
146 | display: flex;
147 | flex-direction: row;
148 | justify-content: space-between;
149 | }
150 |
151 | #tweet-button {
152 | margin: 2px;
153 | width: 50%;
154 | height: 5vh;
155 |
156 | color: #151515;
157 | border-radius: .3vh;
158 | transition: .2s linear;
159 | text-align: center;
160 | line-height: 5vh;
161 | font-size: 1.4vh;
162 | background-color: #08a0e9;
163 |
164 | }
165 | #tweet-button:hover {
166 | background-color: #0078a3;
167 | }
168 |
169 | #advert-button {
170 | margin: 2px;
171 | width: 50%;
172 | height: 5vh;
173 | color: #fff;
174 | border-radius: .3vh;
175 | transition: .2s linear;
176 | text-align: center;
177 | line-height: 5vh;
178 | font-size: 1.4vh;
179 | background-color: #ff8f1a;
180 | }
181 | #advert-button:hover {
182 | background-color: #bd7528;
183 | }
184 |
185 |
186 |
187 | #new-textarea {
188 | border: none;
189 | height: 15vh;
190 | margin: 0 auto;
191 | left: 0;
192 | right: 0;
193 | background: none;
194 | outline: none;
195 | border: .1vh solid #f5f5f5ad;
196 | color: whitesmoke;
197 | resize: none;
198 | transition: border-bottom 0.1s ease-in-out;
199 | padding: 0.87vh;
200 | font-size: 1.4vh;
201 | top: 12vh;
202 | width: 100%;
203 | border-radius: 4px;
204 | }
--------------------------------------------------------------------------------
/qb-phone/server/invoices.lua:
--------------------------------------------------------------------------------
1 | -- Events
2 |
3 | RegisterNetEvent('qb-phone:server:InvoiceHandler')
4 |
5 | -- EVENT HANDLER(S) --
6 |
7 | -- Has player paid something this --
8 | --[[AddEventHandler('qb-phone:server:InvoiceHandler', function(paid, amount, source, resource)
9 |
10 | if paid and resource == GetCurrentResourceName() then
11 | if amount >= config.minPayment then
12 | if Config.RenewedBanking then
13 | local cid = Player.PlayerData.citizenid
14 | local name = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)
15 | exports['Renewed-Banking']:handleTransaction(cid, "Phone Invoice", amount, "Paid off phone invoice of $"..amount, name, name, "withdraw")
16 | end
17 | -- Do shit
18 | end
19 | end
20 | end)]]
21 |
22 | RegisterNetEvent('qb-phone:server:PayMyInvoice', function(society, amount, invoiceId, sendercitizenid, resource)
23 | local src = source
24 | local Player = QBCore.Functions.GetPlayer(src)
25 | local SenderPly = QBCore.Functions.GetPlayerByCitizenId(sendercitizenid)
26 | if Player.PlayerData.money.bank >= amount then
27 | Player.Functions.RemoveMoney('bank', amount, "Paid Mobile Invoice")
28 | if SenderPly and Config.BillingCommissions and Config.BillingCommissions[society] then
29 | local commission = math.ceil(amount * Config.BillingCommissions[society])
30 | SenderPly.Functions.AddMoney('bank', commission, "Invoice Paid")
31 | end
32 |
33 | if SenderPly then
34 | TriggerClientEvent('qb-phone:client:CustomNotification', SenderPly.PlayerData.source,
35 | "Invoice Paid off by " .. SenderPly.PlayerData.charinfo.firstname .. ".",
36 | "Recent Invoice of $" .. amount .. " has been paid.",
37 | "fas fa-file-invoice-dollar",
38 | "#1DA1F2",
39 | 7500
40 | )
41 | end
42 |
43 | TriggerClientEvent('qb-phone:client:RemoveInvoiceFromTable', src, invoiceId)
44 | TriggerEvent("qb-phone:server:InvoiceHandler", true, amount, src, resource)
45 |
46 | exports.oxmysql:execute('DELETE FROM phone_invoices WHERE id = ?', {invoiceId})
47 | end
48 | end)
49 |
50 | RegisterNetEvent('qb-phone:server:DeclineMyInvoice', function(amount, invoiceId, sendercitizenid, resource)
51 | local Ply = QBCore.Functions.GetPlayer(source)
52 | local SenderPly = QBCore.Functions.GetPlayerByCitizenId(sendercitizenid)
53 | if not Ply then return end
54 |
55 | exports.oxmysql:execute('DELETE FROM phone_invoices WHERE id = ?', {invoiceId})
56 | if SenderPly then
57 | TriggerClientEvent('qb-phone:client:CustomNotification', SenderPly.PlayerData.source,
58 | "Invoice Declined by " .. SenderPly.PlayerData.charinfo.firstname .. ".",
59 | "Recent invoice of $" .. amount .. " has been declined.",
60 | "fas fa-file-invoice-dollar",
61 | "#1DA1F2",
62 | 7500
63 | )
64 | end
65 |
66 | TriggerClientEvent('qb-phone:client:RemoveInvoiceFromTable', source, invoiceId)
67 | TriggerEvent("qb-phone:server:InvoiceHandler", false, amount, source, resource)
68 | end)
69 |
70 |
71 | RegisterNetEvent('qb-phone:server:CreateInvoice', function(billed, biller, amount)
72 | local billedID = tonumber(billed)
73 | local cash = tonumber(amount)
74 | local billedCID = QBCore.Functions.GetPlayer(billedID)
75 | local billerInfo = QBCore.Functions.GetPlayer(biller)
76 |
77 | local resource = GetInvokingResource()
78 |
79 | if not billedID or not cash or not billedCID or not billerInfo then return end
80 | MySQL.Async.insert('INSERT INTO phone_invoices (citizenid, amount, society, sender, sendercitizenid) VALUES (?, ?, ?, ?, ?)',{
81 | billedCID.PlayerData.citizenid,
82 | cash,
83 | billerInfo.PlayerData.job.name,
84 | billerInfo.PlayerData.charinfo.firstname,
85 | billerInfo.PlayerData.citizenid
86 | }, function(id)
87 | if id then
88 | TriggerClientEvent('qb-phone:client:AcceptorDenyInvoice', billedCID.PlayerData.source, id, billerInfo.PlayerData.charinfo.firstname, billerInfo.PlayerData.job.name, billerInfo.PlayerData.citizenid, cash, resource)
89 | end
90 | end)
91 | end)
92 |
93 | lib.callback.register('qb-phone:server:GetInvoices', function(source)
94 | local Player = QBCore.Functions.GetPlayer(source)
95 | local invoices = exports.oxmysql:executeSync('SELECT * FROM phone_invoices WHERE citizenid = ?', {Player.PlayerData.citizenid})
96 | return invoices
97 | end)
98 |
--------------------------------------------------------------------------------
/qb-phone/client/whatsapp.lua:
--------------------------------------------------------------------------------
1 | -- Functions
2 |
3 | local function IsNumberInContacts(num)
4 | for _, v in pairs(PhoneData.Contacts) do
5 | if num == v.number then
6 | return v.name
7 | end
8 | end
9 | end
10 |
11 | local function GetKeyByDate(Number, Date)
12 | if PhoneData.Chats[Number] and PhoneData.Chats[Number].messages then
13 | for key, chat in pairs(PhoneData.Chats[Number].messages) do
14 | if chat.date == Date then
15 | return key
16 | end
17 | end
18 | end
19 | end
20 |
21 | -- NUI Callback
22 |
23 | RegisterNUICallback('GetWhatsappChat', function(data, cb)
24 | if PhoneData.Chats[data.phone] then
25 | cb(PhoneData.Chats[data.phone])
26 | else
27 | cb(false)
28 | end
29 | end)
30 |
31 | RegisterNUICallback('GetWhatsappChats', function(_, cb)
32 | cb(PhoneData.Chats)
33 | end)
34 |
35 | RegisterNUICallback('SendMessage', function(data, cb)
36 | local ChatMessage = data.ChatMessage
37 | local ChatDate = data.ChatDate
38 | local ChatNumber = data.ChatNumber
39 | local ChatTime = data.ChatTime
40 | local ChatType = data.ChatType
41 | local ChatKey = GetKeyByDate(ChatNumber, ChatDate)
42 |
43 | if PhoneData.Chats[ChatNumber] then
44 | if not PhoneData.Chats[ChatNumber].messages then
45 | PhoneData.Chats[ChatNumber].messages = {}
46 | end
47 | else
48 | PhoneData.Chats[ChatNumber] = {
49 | name = IsNumberInContacts(ChatNumber),
50 | number = ChatNumber,
51 | messages = {},
52 | }
53 | end
54 |
55 | if not ChatKey or (ChatKey and not PhoneData.Chats[ChatNumber].messages[ChatKey]) then
56 | local temp = #PhoneData.Chats[ChatNumber].messages+1
57 | PhoneData.Chats[ChatNumber].messages[temp] = {
58 | date = ChatDate,
59 | messages = {},
60 | }
61 |
62 | ChatKey = temp
63 | end
64 |
65 | if ChatMessage then
66 | PhoneData.Chats[ChatNumber].messages[ChatKey].messages[#PhoneData.Chats[ChatNumber].messages[ChatKey].messages+1] = {
67 | message = ChatMessage,
68 | time = ChatTime,
69 | sender = PhoneData.PlayerData.citizenid,
70 | type = ChatType,
71 | data = {},
72 | }
73 | else
74 | PhoneData.Chats[ChatNumber].messages[ChatKey].messages[#PhoneData.Chats[ChatNumber].messages[ChatKey].messages+1] = {
75 | message = "Photo",
76 | time = ChatTime,
77 | sender = PhoneData.PlayerData.citizenid,
78 | type = ChatType,
79 | data = {
80 | url = data.url
81 | },
82 | }
83 | end
84 |
85 | TriggerServerEvent('qb-phone:server:UpdateMessages', PhoneData.Chats[ChatNumber].messages, ChatNumber)
86 | SendNUIMessage({
87 | action = "UpdateChat",
88 | chatData = PhoneData.Chats[ChatNumber],
89 | chatNumber = ChatNumber,
90 | })
91 |
92 |
93 | cb("ok")
94 | end)
95 |
96 | -- Events
97 |
98 | RegisterNetEvent('qb-phone:client:UpdateMessages', function(ChatMessages, SenderNumber, New)
99 | if not ChatMessages or not SenderNumber then return end
100 |
101 | local NumberKey = type(SenderNumber) ~= "string" and tostring(SenderNumber) or SenderNumber
102 | local name = IsNumberInContacts(SenderNumber) or SenderNumber
103 |
104 | if SenderNumber == PhoneData.PlayerData.charinfo.phone then return end
105 |
106 | if New then
107 | PhoneData.Chats[NumberKey] = {
108 | name = name,
109 | number = SenderNumber,
110 | messages = ChatMessages
111 | }
112 | else
113 | PhoneData.Chats[NumberKey].messages = ChatMessages
114 | end
115 |
116 | SendNUIMessage({
117 | action = "PhoneNotification",
118 | PhoneNotify = {
119 | title = "Messages",
120 | text = "New Message From: "..name,
121 | icon = "fas fa-comment",
122 | color = "#25D366",
123 | timeout = math.random(4000, 7500),
124 | },
125 | })
126 |
127 | if PhoneData.isOpen then
128 | SendNUIMessage({
129 | action = "UpdateChat",
130 | chatData = PhoneData.Chats[NumberKey],
131 | chatNumber = NumberKey,
132 | })
133 | else
134 | Config.PhoneApplications['whatsapp'].Alerts = Config.PhoneApplications['whatsapp'].Alerts + 1
135 | end
136 |
137 | if not PhoneData.Chats[NumberKey].Unread then PhoneData.Chats[NumberKey].Unread = 1 else PhoneData.Chats[NumberKey].Unread += 1 end
138 | end)
--------------------------------------------------------------------------------
/qb-phone/qb-phone.sql:
--------------------------------------------------------------------------------
1 |
2 | DROP TABLE IF EXISTS `phone_gallery`;
3 | CREATE TABLE IF NOT EXISTS `phone_gallery` (
4 | `citizenid` varchar(255) NOT NULL,
5 | `image` varchar(255) NOT NULL,
6 | `date` timestamp NULL DEFAULT current_timestamp()
7 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
8 |
9 | DROP TABLE IF EXISTS `phone_invoices`;
10 | CREATE TABLE IF NOT EXISTS `phone_invoices` (
11 | `id` int(10) NOT NULL AUTO_INCREMENT,
12 | `citizenid` varchar(50) DEFAULT NULL,
13 | `amount` int(11) NOT NULL DEFAULT 0,
14 | `society` tinytext DEFAULT NULL,
15 | `sender` varchar(50) DEFAULT NULL,
16 | `sendercitizenid` varchar(50) DEFAULT NULL,
17 | `time` int(11) DEFAULT NULL,
18 | PRIMARY KEY (`id`),
19 | KEY `citizenid` (`citizenid`)
20 | ) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=utf8;
21 |
22 | DROP TABLE IF EXISTS `phone_messages`;
23 | CREATE TABLE IF NOT EXISTS `phone_messages` (
24 | `id` int(11) NOT NULL AUTO_INCREMENT,
25 | `citizenid` varchar(50) DEFAULT NULL,
26 | `number` varchar(50) DEFAULT NULL,
27 | `messages` text DEFAULT NULL,
28 | `time` int(11) DEFAULT NULL,
29 | PRIMARY KEY (`id`),
30 | KEY `citizenid` (`citizenid`),
31 | KEY `number` (`number`)
32 | ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
33 |
34 | DROP TABLE IF EXISTS `phone_note`;
35 | CREATE TABLE IF NOT EXISTS `phone_note` (
36 | `id` int(10) NOT NULL AUTO_INCREMENT,
37 | `citizenid` varchar(50) DEFAULT NULL,
38 | `title` text DEFAULT NULL,
39 | `text` text DEFAULT NULL,
40 | `lastupdate` varchar(50) DEFAULT NULL,
41 | PRIMARY KEY (`id`),
42 | KEY `citizenid` (`citizenid`)
43 | ) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8;
44 |
45 | DROP TABLE IF EXISTS `phone_tweets`;
46 | CREATE TABLE IF NOT EXISTS `phone_tweets` (
47 | `id` int(11) NOT NULL AUTO_INCREMENT,
48 | `citizenid` varchar(50) DEFAULT NULL,
49 | `firstName` varchar(25) DEFAULT NULL,
50 | `lastName` varchar(25) DEFAULT NULL,
51 | `type` varchar(25) DEFAULT NULL,
52 | `message` text DEFAULT NULL,
53 | `url` text DEFAULT NULL,
54 | `tweetId` varchar(25) NOT NULL,
55 | `date` datetime DEFAULT current_timestamp(),
56 | PRIMARY KEY (`id`),
57 | KEY `citizenid` (`citizenid`)
58 | ) ENGINE=InnoDB AUTO_INCREMENT=289 DEFAULT CHARSET=UTF8;
59 |
60 | DROP TABLE IF EXISTS `player_contacts`;
61 | CREATE TABLE IF NOT EXISTS `player_contacts` (
62 | `id` int(11) NOT NULL AUTO_INCREMENT,
63 | `citizenid` varchar(50) DEFAULT NULL,
64 | `name` varchar(50) DEFAULT NULL,
65 | `number` varchar(50) DEFAULT NULL,
66 | PRIMARY KEY (`id`),
67 | KEY `citizenid` (`citizenid`)
68 | ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
69 |
70 | DROP TABLE IF EXISTS `player_mails`;
71 | CREATE TABLE IF NOT EXISTS `player_mails` (
72 | `id` int(11) NOT NULL AUTO_INCREMENT,
73 | `citizenid` varchar(50) DEFAULT NULL,
74 | `sender` varchar(50) DEFAULT NULL,
75 | `subject` varchar(50) DEFAULT NULL,
76 | `message` text DEFAULT NULL,
77 | `read` tinyint(4) DEFAULT 0,
78 | `mailid` int(11) DEFAULT NULL,
79 | `date` timestamp NULL DEFAULT current_timestamp(),
80 | `button` text DEFAULT NULL,
81 | PRIMARY KEY (`id`),
82 | KEY `citizenid` (`citizenid`)
83 | ) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8;
84 |
85 |
86 | DROP TABLE IF EXISTS `phone_chatrooms`;
87 | CREATE TABLE `phone_chatrooms` (
88 | `id` INT unsigned NOT NULL AUTO_INCREMENT,
89 | `room_code` VARCHAR(10) NOT NULL UNIQUE,
90 | `room_name` VARCHAR(15) NOT NULL,
91 | `room_owner_id` VARCHAR(20),
92 | `room_owner_name` VARCHAR(60),
93 | `room_members` TEXT DEFAULT '{}',
94 | `room_pin` VARCHAR(50),
95 | `unpaid_balance` DECIMAL(10,2) DEFAULT 0,
96 | `is_pinned` BOOLEAN DEFAULT 0,
97 | `created` DATETIME DEFAULT NOW(),
98 | PRIMARY KEY (`id`)
99 | );
100 |
101 | INSERT INTO `phone_chatrooms` (`room_code`, `room_name`, `room_owner_id`, `room_owner_name`, `is_pinned`) VALUES
102 | ('411', '411', 'official', 'Government', 1),
103 | ('lounge', 'The Lounge', 'official', 'Government', 1),
104 | ('events', 'Events', 'official', 'Government', 1);
105 |
106 | DROP TABLE IF EXISTS `phone_chatroom_messages`;
107 | CREATE TABLE `phone_chatroom_messages` (
108 | `id` INT unsigned NOT NULL AUTO_INCREMENT,
109 | `room_id` INT unsigned,
110 | `member_id` VARCHAR(20),
111 | `member_name` VARCHAR(50),
112 | `message` TEXT NOT NULL,
113 | `is_pinned` BOOLEAN DEFAULT FALSE,
114 | `created` DATETIME DEFAULT NOW(),
115 | PRIMARY KEY (`id`)
116 | );
117 |
118 | DROP TABLE IF EXISTS `player_jobs`;
119 | CREATE TABLE IF NOT EXISTS `player_jobs` (
120 | `id` int(11) NOT NULL AUTO_INCREMENT,
121 | `jobname` varchar(50) DEFAULT NULL,
122 | `employees` text DEFAULT NULL,
123 | `maxEmployee` tinyint(11) DEFAULT 15,
124 | PRIMARY KEY (`id`)
125 | ) ENGINE=InnoDB AUTO_INCREMENT=106 DEFAULT CHARSET=utf8;
--------------------------------------------------------------------------------
/qb-phone/html/css/details.css:
--------------------------------------------------------------------------------
1 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
2 |
3 | .details-app {
4 | display: none;
5 | height: 108%;
6 | width: 100%;
7 | overflow: hidden;
8 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
9 | -moz-user-select: -moz-text;
10 | -khtml-user-select: text;
11 | -webkit-user-select: text;
12 | -o-user-select: text;
13 | user-select: text;
14 | }
15 |
16 |
17 |
18 | .details-header {
19 | position: absolute;
20 | width: 90%;
21 | height: 20%;
22 | top: 8%;
23 | left: 0;
24 | right: 0;
25 | color: white;
26 | font-size: 1.3vh;
27 | margin: 0 auto;
28 | }
29 |
30 |
31 | .details-header-main {
32 | position: absolute;
33 | width: 90%;
34 | top: 0%;
35 | left: 0;
36 | right: 7%;
37 | color: white;
38 | font-size: 2.4vh;
39 | margin: 0 auto;
40 | font-family: 'Gilroy';
41 | }
42 |
43 | .details-header-secondary {
44 | position: absolute;
45 | width: 90%;
46 | top: 40%;
47 | left: 0;
48 | right: 7%;
49 | color: white;
50 | font-size: 1.5vh;
51 | margin: 0 auto;
52 | font-family: 'Gilroy';
53 | }
54 |
55 | .details-header-license {
56 | position: absolute;
57 | width: 90%;
58 | height: 30%;
59 | top: 27vh;
60 | right: 7%;
61 | color: white;
62 | font-size: 1.5vh;
63 | margin: 0 auto;
64 | font-family: 'Gilroy';
65 | }
66 |
67 | .details-header>p {
68 | line-height: 12vh;
69 | text-indent: 2vh;
70 | margin: 0 0 0 9vh;
71 | font-family: 'Gilroy';
72 | }
73 |
74 | .details-header>span {
75 | position: absolute;
76 | top: 8vh;
77 | left: 9vh;
78 | font-size: 1.2vh;
79 | height: 2vh;
80 | color: white;
81 | font-family: 'Gilroy';
82 | }
83 |
84 | .details-list {
85 | margin-bottom: 0.5vh;
86 | padding: 0.8vh 1.5vh;
87 | /* Adjust the padding here */
88 | border-radius: 0.463vh;
89 | background: rgb(11, 14, 21);
90 | overflow: hidden;
91 | /* Ensures the box expands to contain floated elements */
92 | }
93 |
94 | .details-list::-webkit-scrollbar {
95 | display: none;
96 | }
97 |
98 |
99 | .details-money-types {
100 | position: absolute;
101 | width: 110%;
102 | top: 17vh;
103 | /* Adjust the percentage to move it down */
104 | left: 52%;
105 | transform: translate(-50%, -50%);
106 | }
107 |
108 | .details-license-types {
109 | position: absolute;
110 | width: 110%;
111 | height:200%;
112 | top: 42vh;
113 | /* Adjust the percentage to move it down */
114 | left: 52%;
115 | transform: translate(-50%, -50%);
116 | overflow-y: scroll;
117 | }
118 |
119 | .details-value {
120 | float: right;
121 | clear: right;
122 | font-family: 'Gilroy';
123 | }
124 |
125 | .details-label {
126 | float: left;
127 | font-family: 'Gilroy';
128 | }
129 |
130 | .details-box {
131 | margin-bottom: 0.5vh;
132 | padding: 0.8vh 1.5vh;
133 | /* Adjust the padding here */
134 | border-radius: 0.463vh;
135 | background: rgb(11, 14, 21);
136 | overflow: hidden;
137 | /* Ensures the box expands to contain floated elements */
138 | }
139 |
140 |
141 | .details-moneys-body-main {
142 | display: block;
143 | width: 100%;
144 | margin-left: 3%;
145 | margin-bottom: 2%;
146 | max-width: 90%;
147 | white-space: nowrap;
148 | overflow: hidden !important;
149 | text-overflow: ellipsis;
150 | }
151 |
152 | .details-icon-class {
153 | display: inline-block;
154 | text-align: center;
155 | width: 10%;
156 | }
157 |
158 | .details-text-class {
159 | display: inline;
160 | width: 90%;
161 | }
162 |
163 | .details-license-body-main {
164 | display: block;
165 | width: 100%;
166 | margin-left: 3%;
167 | margin-bottom: 3vh;
168 | max-width: 90%;
169 | white-space: nowrap;
170 | overflow: hidden !important;
171 | text-overflow: ellipsis;
172 | }
173 |
174 | .details-license-icon-class {
175 | display: inline;
176 | text-align: right;
177 | width: 10%;
178 | }
179 |
180 | .details-license-text-class {
181 | display: inline-block;
182 | width: 85%;
183 | }
184 |
185 | .details-text-license {
186 | width: 100%;
187 | color: whitesmoke;
188 | text-align: center;
189 | }
190 |
191 | .details-section {
192 | margin-bottom: 1.8519vh;
193 | /* Adjust spacing between sections */
194 | }
195 |
196 | .details-section h2 {
197 | color: white;
198 | font-size: 1.2vh;
199 | /* Adjust font size */
200 | margin-bottom: 0.9259vh;
201 | font-family: 'Gilroy';
202 | /* Adjust spacing between header and content */
203 | }
204 |
205 | .valid-text {
206 | background: #15661b;
207 | border-radius: 0.3vh;
208 | padding: 0.4vh;
209 | font-family: 'Gilroy';
210 | font-size: 1.3vh;
211 | }
--------------------------------------------------------------------------------
/qb-phone/client/racing.lua:
--------------------------------------------------------------------------------
1 | -- NUI Callback
2 |
3 | RegisterNUICallback('GetAvailableRaces', function(_, cb)
4 | QBCore.Functions.TriggerCallback('qb-lapraces:server:GetRaces', function(Races)
5 | cb(Races)
6 | end)
7 | end)
8 |
9 | RegisterNUICallback('JoinRace', function(data, cb)
10 | TriggerServerEvent('qb-lapraces:server:JoinRace', data.RaceData)
11 | cb("ok")
12 | end)
13 |
14 | RegisterNUICallback('LeaveRace', function(data, cb)
15 | TriggerServerEvent('qb-lapraces:server:LeaveRace', data.RaceData)
16 | cb("ok")
17 | end)
18 |
19 | RegisterNUICallback('StartRace', function(data, cb)
20 | TriggerServerEvent('qb-lapraces:server:StartRace', data.RaceData.RaceId)
21 | cb("ok")
22 | end)
23 |
24 | RegisterNUICallback('SetAlertWaypoint', function(data, cb)
25 | local coords = data.alert.coords
26 | QBCore.Functions.Notify('GPS set: '..data.alert.title, "primary")
27 | SetNewWaypoint(coords.x, coords.y)
28 | cb("ok")
29 | end)
30 |
31 | RegisterNUICallback('GetRaces', function(_, cb)
32 | QBCore.Functions.TriggerCallback('qb-lapraces:server:GetListedRaces', function(Races)
33 | cb(Races)
34 | end)
35 | end)
36 |
37 | RegisterNUICallback('GetTrackData', function(data, cb)
38 | QBCore.Functions.TriggerCallback('qb-lapraces:server:GetTrackData', function(TrackData, CreatorData)
39 | TrackData.CreatorData = CreatorData
40 | cb(TrackData)
41 | end, data.RaceId)
42 | end)
43 |
44 | RegisterNUICallback('SetupRace', function(data, cb)
45 | -- local hasDongle = exports.ox_inventory:Search('count', 'phone_dongle')
46 | local hasDongle = QBCore.Functions.HasItem('phone_dongle', 'count')
47 | TriggerServerEvent('qb-lapraces:server:SetupRace', data.RaceId, tonumber(data.AmountOfLaps))
48 | if hasDongle >= 1 then
49 | SendNUIMessage({
50 | action = "PhoneNotification",
51 | PhoneNotify = {
52 | title = "FROM THE PM",
53 | text = "New Race Has Started!",
54 | icon = "fas fa-flag-checkered",
55 | color = "#167869"
56 | },
57 | })
58 | end
59 | cb("ok")
60 | end)
61 |
62 | RegisterNUICallback('HasCreatedRace', function(_, cb)
63 | QBCore.Functions.TriggerCallback('qb-lapraces:server:HasCreatedRace', function(HasCreated)
64 | cb(HasCreated)
65 | end)
66 | end)
67 |
68 | RegisterNUICallback('IsInRace', function(_, cb)
69 | local InRace = exports['qb-lapraces']:IsInRace()
70 | cb(InRace)
71 | end)
72 |
73 | RegisterNUICallback('IsAuthorizedToCreateRaces', function(data, cb)
74 | QBCore.Functions.TriggerCallback('qb-lapraces:server:IsAuthorizedToCreateRaces', function(IsAuthorized, NameAvailable)
75 | local sendData = {
76 | IsAuthorized = IsAuthorized,
77 | IsBusy = exports['qb-lapraces']:IsInEditor(),
78 | IsNameAvailable = NameAvailable,
79 | }
80 | cb(sendData)
81 | end, data.TrackName)
82 | end)
83 |
84 | RegisterNUICallback('StartTrackEditor', function(data, cb)
85 | TriggerServerEvent('qb-lapraces:server:CreateLapRace', data.TrackName)
86 | cb("ok")
87 | end)
88 |
89 | RegisterNUICallback('GetRacingLeaderboards', function(_, cb)
90 | QBCore.Functions.TriggerCallback('qb-lapraces:server:GetRacingLeaderboards', function(Races)
91 | cb(Races)
92 | end)
93 | end)
94 |
95 | RegisterNUICallback('RaceDistanceCheck', function(data, cb)
96 | QBCore.Functions.TriggerCallback('qb-lapraces:server:GetRacingData', function(RaceData)
97 | local coords = GetEntityCoords(cache.ped)
98 | local checkpointcoords = RaceData.Checkpoints[1].coords
99 | local dist = #(coords - vector3(checkpointcoords.x, checkpointcoords.y, checkpointcoords.z))
100 | if dist <= 115.0 then
101 | if data.Joined then
102 | TriggerEvent('qb-lapraces:client:WaitingDistanceCheck')
103 | end
104 | cb(true)
105 | else
106 | QBCore.Functions.Notify('You\'re too far away from the race. GPS set.', "error", 5000)
107 | SetNewWaypoint(checkpointcoords.x, checkpointcoords.y)
108 | cb(false)
109 | end
110 | end, data.RaceId)
111 | end)
112 |
113 | RegisterNUICallback('IsBusyCheck', function(data, cb)
114 | if data.check == "editor" then
115 | cb(exports['qb-lapraces']:IsInEditor())
116 | else
117 | cb(exports['qb-lapraces']:IsInRace())
118 | end
119 | end)
120 |
121 | RegisterNUICallback('CanRaceSetup', function(_, cb)
122 | QBCore.Functions.TriggerCallback('qb-lapraces:server:CanRaceSetup', function(CanSetup)
123 | cb(CanSetup)
124 | end)
125 | end)
126 |
127 | -- Events
128 |
129 | RegisterNetEvent('qb-phone:client:RaceNotify', function(message)
130 | TriggerEvent('qb-phone:client:CustomNotification',
131 | "Racing",
132 | message,
133 | "fas fa-flag-checkered",
134 | "#353b48",
135 | 3500
136 | )
137 | end)
138 |
139 | RegisterNetEvent('qb-phone:client:UpdateLapraces', function()
140 | SendNUIMessage({
141 | action = "UpdateRacingApp",
142 | })
143 | end)
--------------------------------------------------------------------------------
/qb-phone/server/mail.lua:
--------------------------------------------------------------------------------
1 | -- Functions
2 |
3 | local function GenerateMailId()
4 | return math.random(111111, 999999)
5 | end
6 |
7 |
8 |
9 | RegisterNetEvent('qb-phone:server:RemoveMail', function(MailId)
10 | local src = source
11 | local Player = QBCore.Functions.GetPlayer(src)
12 | if not MailId or not Player then return end
13 |
14 | local CID = Player.PlayerData.citizenid
15 |
16 |
17 | MySQL.query('DELETE FROM player_mails WHERE mailid = ? AND citizenid = ?', {MailId, CID})
18 | SetTimeout(100, function()
19 | local mails = MySQL.query.await('SELECT * FROM player_mails WHERE citizenid = ? ORDER BY `date` ASC', {CID})
20 | TriggerClientEvent('qb-phone:client:UpdateMails', src, mails)
21 | end)
22 | end)
23 |
24 |
25 | RegisterNetEvent('qb-phone:server:sendNewMail', function(mailData, citizenID)
26 |
27 | if not mailData or not mailData.sender or not mailData.subject or not mailData.message then return end
28 | local Player
29 |
30 | if citizenID then
31 | Player = QBCore.Functions.GetPlayerByCitizenId(citizenID)
32 | else
33 | Player = QBCore.Functions.GetPlayer(source)
34 | end
35 |
36 | if Player then
37 | local CID = Player.PlayerData.citizenid
38 | if mailData.button then
39 | MySQL.insert('INSERT INTO player_mails (`citizenid`, `sender`, `subject`, `message`, `mailid`, `read`, `button`) VALUES (?, ?, ?, ?, ?, ?, ?)', {CID, mailData.sender, mailData.subject, mailData.message, GenerateMailId(), 0, json.encode(mailData.button)})
40 | else
41 | MySQL.insert('INSERT INTO player_mails (`citizenid`, `sender`, `subject`, `message`, `mailid`, `read`) VALUES (?, ?, ?, ?, ?, ?)', {CID, mailData.sender, mailData.subject, mailData.message, GenerateMailId(), 0})
42 | end
43 |
44 | TriggerClientEvent('qb-phone:client:NewMailNotify', Player.PlayerData.source, mailData)
45 |
46 | SetTimeout(200, function()
47 | local mails = MySQL.query.await('SELECT * FROM player_mails WHERE citizenid = ? ORDER BY `date` ASC', {CID})
48 | if mails[1] then
49 | for _, v in pairs(mails) do
50 | if v.button then
51 | v.button = json.decode(v.button)
52 | end
53 | end
54 | end
55 |
56 | TriggerClientEvent('qb-phone:client:UpdateMails', Player.PlayerData.source, mails)
57 | end)
58 | elseif citizenID then
59 | if mailData.button then
60 | MySQL.insert('INSERT INTO player_mails (`citizenid`, `sender`, `subject`, `message`, `mailid`, `read`, `button`) VALUES (?, ?, ?, ?, ?, ?, ?)', {citizenID, mailData.sender, mailData.subject, mailData.message, GenerateMailId(), 0, json.encode(mailData.button)})
61 | else
62 | MySQL.insert('INSERT INTO player_mails (`citizenid`, `sender`, `subject`, `message`, `mailid`, `read`) VALUES (?, ?, ?, ?, ?, ?)', {citizenID, mailData.sender, mailData.subject, mailData.message, GenerateMailId(), 0})
63 | end
64 | end
65 | end)
66 |
67 | function sendNewMailToOffline(citizenid, mailData)
68 | local Player = QBCore.Functions.GetPlayerByCitizenId(citizenid)
69 | if Player then
70 | local src = Player.PlayerData.source
71 | if mailData.button == nil then
72 | MySQL.insert('INSERT INTO player_mails (`citizenid`, `sender`, `subject`, `message`, `mailid`, `read`) VALUES (?, ?, ?, ?, ?, ?)', {Player.PlayerData.citizenid, mailData.sender, mailData.subject, mailData.message, GenerateMailId(), 0})
73 | TriggerClientEvent('qb-phone:client:NewMailNotify', src, mailData)
74 | else
75 | MySQL.insert('INSERT INTO player_mails (`citizenid`, `sender`, `subject`, `message`, `mailid`, `read`, `button`) VALUES (?, ?, ?, ?, ?, ?, ?)', {Player.PlayerData.citizenid, mailData.sender, mailData.subject, mailData.message, GenerateMailId(), 0, json.encode(mailData.button)})
76 | TriggerClientEvent('qb-phone:client:NewMailNotify', src, mailData)
77 | end
78 | SetTimeout(200, function()
79 | local mails = MySQL.query.await(
80 | 'SELECT * FROM player_mails WHERE citizenid = ? ORDER BY `date` ASC', {Player.PlayerData.citizenid})
81 | if mails[1] ~= nil then
82 | for k, _ in pairs(mails) do
83 | if mails[k].button ~= nil then
84 | mails[k].button = json.decode(mails[k].button)
85 | end
86 | end
87 | end
88 |
89 | TriggerClientEvent('qb-phone:client:UpdateMails', src, mails)
90 | end)
91 | else
92 | if mailData.button == nil then
93 | MySQL.insert('INSERT INTO player_mails (`citizenid`, `sender`, `subject`, `message`, `mailid`, `read`) VALUES (?, ?, ?, ?, ?, ?)', {citizenid, mailData.sender, mailData.subject, mailData.message, GenerateMailId(), 0})
94 | else
95 | MySQL.insert('INSERT INTO player_mails (`citizenid`, `sender`, `subject`, `message`, `mailid`, `read`, `button`) VALUES (?, ?, ?, ?, ?, ?, ?)', {citizenid, mailData.sender, mailData.subject, mailData.message, GenerateMailId(), 0, json.encode(mailData.button)})
96 | end
97 | end
98 | end
99 | exports("sendNewMailToOffline",sendNewMailToOffline)
--------------------------------------------------------------------------------
/qb-phone/server/documents.lua:
--------------------------------------------------------------------------------
1 | RegisterNetEvent("qb-phone:server:sendDocument", function(data)
2 | local src = source
3 | local Ply = QBCore.Functions.GetPlayer(src)
4 | local Receiver = QBCore.Functions.GetPlayer(tonumber(data.StateID))
5 | local SenderName = Ply.PlayerData.charinfo.firstname..' '..Ply.PlayerData.charinfo.lastname
6 | if not Receiver then
7 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
8 | "Documents",
9 | "Invalid State ID",
10 | "fas fa-folder",
11 | "#d9d9d9",
12 | 5000
13 | )
14 | return
15 | end
16 |
17 | if Ply.PlayerData.citizenid ~= Receiver.PlayerData.citizenid then
18 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
19 | "Documents",
20 | "Document Sent",
21 | "fas fa-folder",
22 | "#d9d9d9",
23 | 5000
24 | )
25 | TriggerClientEvent("qb-phone:client:sendingDocumentRequest", data.StateID, data, Receiver, Ply, SenderName)
26 | else
27 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
28 | "Documents",
29 | "You can't send a document to yourself!",
30 | "fas fa-folder",
31 | "#d9d9d9",
32 | 5000
33 | )
34 | end
35 | end)
36 |
37 | RegisterNetEvent("qb-phone:server:sendDocumentLocal", function(data, playerId)
38 | local src = source
39 | local Ply = QBCore.Functions.GetPlayer(src)
40 | local Receiver = QBCore.Functions.GetPlayer(playerId)
41 | local SenderName = Ply.PlayerData.charinfo.firstname..' '..Ply.PlayerData.charinfo.lastname
42 |
43 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
44 | "Documents",
45 | "Document Sent",
46 | "fas fa-folder",
47 | "#d9d9d9",
48 | 5000
49 | )
50 | TriggerClientEvent("qb-phone:client:sendingDocumentRequest", playerId, data, Receiver, Ply, SenderName)
51 | end)
52 |
53 | local function saveNote(data, CID, src)
54 | if not data or not data.Title or not data.Text or not data.Time or not CID or not src then return end
55 |
56 | exports.oxmysql:insert('INSERT INTO phone_note (citizenid, title, text, lastupdate) VALUES (?, ?, ?, ?)',{CID, data.Title, data.Text, data.Time})
57 |
58 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
59 | "Documents",
60 | "Created new Document",
61 | "fas fa-folder",
62 | "#d9d9d9",
63 | 5000
64 | )
65 | end
66 |
67 | local function updateNote(data, ID, src)
68 | if not data or not data.Title or not data.Text or not data.Time or not ID or not src then return end
69 | MySQL.Sync.execute('UPDATE phone_note SET title = @title, text = @text, lastupdate = @lastupdate WHERE id = @id', {
70 | ["@id"] = ID,
71 | ["@title"] = data.Title,
72 | ["@text"] = data.Text,
73 | ["@lastupdate"] = data.Time
74 | })
75 |
76 |
77 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
78 | "Documents",
79 | "Document Saved",
80 | "fas fa-folder",
81 | "#d9d9d9",
82 | 5000
83 | )
84 | end
85 |
86 | local function deleteNote(ID, src)
87 | if not ID or not src then return end
88 |
89 | exports.oxmysql:execute('DELETE FROM phone_note WHERE id = ?', {ID})
90 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
91 | "Documents",
92 | "Document Deleted",
93 | "fas fa-folder",
94 | "#d9d9d9",
95 | 5000
96 | )
97 | end
98 |
99 | RegisterNetEvent('qb-phone:server:documents_Save_Note_As', function(data, Receiver)
100 | local src = source
101 | local Player = QBCore.Functions.GetPlayer(src)
102 | if not data or not Player then return end
103 | if data.Type ~= 'Delete' then
104 | if not data.Title or not data.Text or not data.Time then return end
105 | end
106 |
107 | local CID = Player.PlayerData.citizenid
108 | local ID
109 |
110 | if data.Type ~= "New" and not data.ID then return else ID = tonumber(data.ID) end
111 |
112 | if data.Type == "New" then
113 | saveNote(data, CID, src)
114 | elseif data.Type == "Update" then
115 | local Note = exports.oxmysql:executeSync('SELECT * FROM phone_note WHERE id = ?', {ID})
116 | if Note[1] then
117 | updateNote(data, ID, src)
118 | end
119 | elseif data.Type == "Delete" then
120 | deleteNote(ID, src)
121 | elseif data.Type == "PermSend" then
122 | local Note = exports.oxmysql:executeSync('SELECT * FROM phone_note WHERE id = ?', {ID})
123 | if Note[1] then
124 | Wait(400)
125 | exports.oxmysql:insert('INSERT INTO phone_note (citizenid, title, text, lastupdate) VALUES (?, ?, ?, ?)',{Receiver.PlayerData.citizenid, data.Title, data.Text, data.Time})
126 | TriggerClientEvent('qb-phone:client:CustomNotification', tonumber(data.StateID), 'DOCUMENTS', 'New Document', 'fas fa-folder', '#d9d9d9', 5000)
127 | end
128 | end
129 |
130 | Wait(250)
131 | local Notes = exports.oxmysql:executeSync('SELECT * FROM phone_note WHERE citizenid = ?', {CID})
132 | Wait(100)
133 | TriggerClientEvent('qb-phone:RefReshNotes_Free_Documents', src, Notes)
134 | end)
135 |
--------------------------------------------------------------------------------
/qb-phone/server/garage.lua:
--------------------------------------------------------------------------------
1 | RegisterNetEvent('qb-phone:server:sendVehicleRequest', function(data)
2 | local src = source
3 | local Player = QBCore.Functions.GetPlayer(src)
4 | local Asshole = tonumber(data.id)
5 | local OtherAsshole = QBCore.Functions.GetPlayer(Asshole)
6 |
7 | if not OtherAsshole then return TriggerClientEvent("QBCore:Notify", src, 'State ID does not exist!', "error") end
8 | if not data.price or not data.plate then return end
9 | if Player.PlayerData.citizenid == OtherAsshole.PlayerData.citizenid then return TriggerClientEvent("QBCore:Notify", src, 'You cannot sell a vehicle to yourself!', "error") end
10 |
11 | TriggerClientEvent('qb-phone:client:sendVehicleRequest', Asshole, data, Player)
12 | end)
13 |
14 | RegisterNetEvent('qb-phone:server:sellVehicle', function(data, Seller, type)
15 | local src = source
16 | local Player = QBCore.Functions.GetPlayer(src)
17 | local SellerData = QBCore.Functions.GetPlayerByCitizenId(Seller.PlayerData.citizenid)
18 |
19 | if type == 'accepted' then
20 | if Player.PlayerData.money.bank and Player.PlayerData.money.bank >= tonumber(data.price) then
21 | Player.Functions.RemoveMoney('bank', data.price, "Bought Used Vehicle")
22 | SellerData.Functions.AddMoney('bank', data.price, "Sold Used Vehicle")
23 | TriggerClientEvent('qb-phone:client:CustomNotification', src, "VEHICLE SALE", "You purchased the vehicle for $"..data.price, "fas fa-chart-line", "#D3B300", 5500)
24 | TriggerClientEvent('qb-phone:client:CustomNotification', Seller.PlayerData.source, "VEHICLE SALE", "Your vehicle was successfully purchased!", "fas fa-chart-line", "#D3B300", 5500)
25 | MySQL.update('UPDATE player_vehicles SET citizenid = ?, garage = ?, state = ? WHERE plate = ?',{Player.PlayerData.citizenid, Config.SellGarage, 1, data.plate})
26 | -- Update Garages
27 | TriggerClientEvent('qb-phone:client:updateGarages', src)
28 | TriggerClientEvent('qb-phone:client:updateGarages', Seller.PlayerData.source)
29 | else
30 | TriggerClientEvent('qb-phone:client:CustomNotification', src, "VEHICLE SALE", "Insufficient Funds", "fas fa-chart-line", "#D3B300", 5500)
31 | TriggerClientEvent('qb-phone:client:CustomNotification', Seller.PlayerData.source, "VEHICLE SALE", "Your vehicle was not purchased!", "fas fa-chart-line", "#D3B300", 5500)
32 | end
33 | elseif type == 'denied' then
34 | TriggerClientEvent('qb-phone:client:CustomNotification', src, "VEHICLE SALE", "Request denied", "fas fa-chart-line", "#D3B300", 5500)
35 | TriggerClientEvent('qb-phone:client:CustomNotification', Seller.PlayerData.source, "VEHICLE SALE", "Your sale request was denied!", "fas fa-chart-line", "#D3B300", 5500)
36 | end
37 | end)
38 |
39 | local function round(num, numDecimalPlaces)
40 | return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
41 | end
42 |
43 | lib.callback.register('qb-phone:server:GetGarageVehicles', function(source)
44 | local src = source
45 | local Player = QBCore.Functions.GetPlayer(src)
46 | local Vehicles = {}
47 | local vehdata
48 | local result = exports.oxmysql:executeSync('SELECT * FROM player_vehicles WHERE citizenid = ?', {Player.PlayerData.citizenid})
49 | if result[1] then
50 | for _, v in pairs(result) do
51 | local VehicleData = QBCore.Shared.Vehicles[v.vehicle]
52 | local VehicleGarage = "None"
53 | local enginePercent = round(v.engine / 10, 0)
54 | local bodyPercent = round(v.body / 10, 0)
55 | -- if v.garage then
56 | -- if Config.Garages[v.garage] then
57 | -- VehicleGarage = Config.Garages[v.garage]["label"]
58 | -- else
59 | -- VehicleGarage = v.garage
60 | -- end
61 | -- end
62 |
63 | local VehicleState = "In"
64 | if v.state == 0 then
65 | VehicleState = "Out"
66 | elseif v.state == 2 then
67 | VehicleState = "Impounded"
68 | end
69 |
70 | if VehicleData["brand"] then
71 | vehdata = {
72 | fullname = VehicleData["brand"] .. " " .. VehicleData["name"],
73 | brand = VehicleData["brand"],
74 | model = VehicleData["name"],
75 | plate = v.plate,
76 | garage = VehicleGarage,
77 | state = VehicleState,
78 | fuel = v.fuel,
79 | engine = enginePercent,
80 | body = bodyPercent,
81 | paymentsleft = v.paymentsleft
82 | }
83 | else
84 | vehdata = {
85 | fullname = VehicleData["name"],
86 | brand = VehicleData["name"],
87 | model = VehicleData["name"],
88 | plate = v.plate,
89 | garage = VehicleGarage,
90 | state = VehicleState,
91 | fuel = v.fuel,
92 | engine = enginePercent,
93 | body = bodyPercent,
94 | paymentsleft = v.paymentsleft
95 | }
96 | end
97 | Vehicles[#Vehicles+1] = vehdata
98 | end
99 | return Vehicles
100 | else
101 | return nil
102 | end
103 | end)
104 |
--------------------------------------------------------------------------------
/qb-phone/html/js/gallery.js:
--------------------------------------------------------------------------------
1 | function setUpGalleryData(Images){
2 | $(".gallery-images").html("");
3 | if (Images != null) {
4 | $.each(Images, function(i, image){
5 | var Element = '';
6 |
7 | $(".gallery-images").append(Element);
8 | $("#image-"+i).data('ImageData', image);
9 | });
10 | }
11 | }
12 |
13 | $(document).on('click', '.tumbnail', function(e){
14 | e.preventDefault();
15 | let source = $(this).attr('src')
16 | $(".gallery-homescreen").animate({
17 | left: 30+"vh"
18 | }, 200);
19 | $(".gallery-detailscreen").animate({
20 | left: 0+"vh"
21 | }, 200);
22 | SetupImageDetails(source);
23 | });
24 |
25 | $(document).on('click', '.image', function(e){
26 | e.preventDefault();
27 | let source = $(this).attr('src')
28 | QB.Screen.popUp(source)
29 | });
30 |
31 |
32 | $(document).on('click', '#delete-button', function(e){
33 | e.preventDefault();
34 | let source = $('.image').attr('src')
35 |
36 | setTimeout(() => {
37 | $.post('https://qb-phone/DeleteImage', JSON.stringify({image:source}), function(Hashtags){
38 | setTimeout(()=>{
39 | $('#return-button').click()
40 | $.post('https://qb-phone/GetGalleryData', JSON.stringify({}), function(data){
41 | setTimeout(()=>{
42 | setUpGalleryData(data);
43 |
44 | },200)
45 | });
46 | },200)
47 | })
48 |
49 | }, 200);
50 | });
51 |
52 |
53 | function SetupImageDetails(Image){
54 | $('#imagedata').attr("src", Image);
55 | }
56 | let postImageUrl="";
57 | function SetupPostDetails(){
58 | }
59 |
60 |
61 | $(document).on('click', '#make-post-button', function(e){
62 | e.preventDefault();
63 | let source = $('#imagedata').attr('src')
64 | postImageUrl=source
65 |
66 | $(".gallery-detailscreen").animate({
67 | left: 30+"vh"
68 | }, 200);
69 | $(".gallery-postscreen").animate({
70 | left: 0+"vh"
71 | }, 200);
72 | SetupPostDetails();
73 | });
74 |
75 | $(document).on('click', '#gallery-coppy-button', function(e){
76 | e.preventDefault();
77 | let source = $('#imagedata').attr('src')
78 | copyToClipboard(source)
79 | });
80 |
81 | const copyToClipboard = str => {
82 | const el = document.createElement('textarea');
83 | el.value = str;
84 | document.body.appendChild(el);
85 | el.select();
86 | document.execCommand('copy');
87 | document.body.removeChild(el);
88 | };
89 |
90 | $(document).on('click', '#return-button', function(e){
91 | e.preventDefault();
92 |
93 | $(".gallery-homescreen").animate({
94 | left: 00+"vh"
95 | }, 200);
96 | $(".gallery-detailscreen").animate({
97 | left: -30+"vh"
98 | }, 200);
99 | });
100 |
101 | $(document).on('click', '#returndetail-button', function(e){
102 | e.preventDefault();
103 | returnDetail();
104 |
105 | });
106 |
107 | function returnDetail(){
108 | $(".gallery-detailscreen").animate({
109 | left: 00+"vh"
110 | }, 200);
111 | $(".gallery-postscreen").animate({
112 | left: -30+"vh"
113 | }, 200);
114 | }
115 |
116 |
117 | $(document).on('click', '#tweet-button', function(e){
118 | e.preventDefault();
119 | var TweetMessage = $("#new-textarea").val();
120 | var imageURL = postImageUrl
121 | if (TweetMessage != "") {
122 | var CurrentDate = new Date();
123 | $.post('https://qb-phone/PostNewTweet', JSON.stringify({
124 | Message: TweetMessage,
125 | Date: CurrentDate,
126 | Picture: QB.Phone.Data.MetaData.profilepicture,
127 | url: imageURL
128 | }), function(Tweets){
129 | QB.Phone.Notifications.LoadTweets(Tweets);
130 | });
131 | var TweetMessage = $("#new-textarea").val(' ');
132 | $.post('https://qb-phone/GetHashtags', JSON.stringify({}), function(Hashtags){
133 | QB.Phone.Notifications.LoadHashtags(Hashtags)
134 | })
135 | returnDetail()
136 | } else {
137 | QB.Phone.Notifications.Add("fab fa-twitter", "Twitter", "Fill a message!", "#1DA1F2");
138 | };
139 | $('#tweet-new-url').val("");
140 | $("#tweet-new-message").val("");
141 | });
142 |
143 |
144 | $(document).on('click', '#advert-button', function(e){
145 | e.preventDefault();
146 | var Advert = $("#new-textarea").val();
147 | let picture = postImageUrl;
148 |
149 | if (Advert !== "") {
150 | $(".advert-home").animate({
151 | left: 0+"vh"
152 | });
153 | $(".new-advert").animate({
154 | left: -30+"vh"
155 | });
156 | if (!picture){
157 | $.post('https://qb-phone/PostAdvert', JSON.stringify({
158 | message: Advert,
159 | url: null
160 | }));
161 | returnDetail()
162 | }else {
163 | $.post('https://qb-phone/PostAdvert', JSON.stringify({
164 | message: Advert,
165 | url: picture
166 | }));
167 | returnDetail()
168 | }
169 | $("#new-textarea").val(' ');
170 | } else {
171 | QB.Phone.Notifications.Add("fas fa-ad", "Advertisement", "You can\'t post an empty ad!", "#ff8f1a", 2000);
172 | }
173 | });
174 |
175 |
--------------------------------------------------------------------------------
/qb-phone/html/css/jobcenter.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap');
2 | @import "https://assets.nopixel.net/web/fonts/gilroy/stylesheet.css";
3 | .job-app {
4 | display: none;
5 | height: 100%;
6 | width: 100%;
7 | overflow: hidden;
8 | background-image: url("../img/backgrounds/bg.png");
9 | background-position: center;
10 | background-repeat: no-repeat;
11 | background-size: cover;
12 | /* background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%); */
13 | }
14 |
15 | .job-header {
16 | position: absolute;
17 | width: 90%;
18 | height: 10%;
19 | /* top: 8%; */
20 | left: 0;
21 | right: 0;
22 | color: white;
23 | /* font-family: 'Gilroy'; */
24 | font-size: 1.5vh;
25 | /* margin: 0 auto; */
26 | }
27 |
28 | .job-header > p {
29 | text-align: center;
30 | line-height: 12vh;
31 | text-indent: 2vh;
32 | font-family: 'Gilroy';
33 | font-size: 2vh;
34 | /* margin: 0 0 0 9vh; */
35 | }
36 |
37 | .job-header > span {
38 | position: absolute;
39 | top: 8vh;
40 | left: 5vh;
41 | font-size: 1.2vh;
42 | height: 2vh;
43 | color: white;
44 | }
45 |
46 | .job-list {
47 | position: absolute;
48 | width: 90%;
49 | height: 80%;
50 | margin: 0 auto;
51 | left: 0;
52 | right: 0;
53 | bottom: 3%;
54 | border-radius: .5vh;
55 | overflow-y: scroll;
56 | }
57 |
58 | .job-list::-webkit-scrollbar {
59 | display: none;
60 | }
61 |
62 | .job-class-body-job{
63 | color: #ffffff;
64 | margin-bottom: 0.5vh;
65 | padding: 1vh 1.5vh;
66 | /* Adjust the padding here */
67 | border-radius: 0.463vh;
68 | background: rgb(25,103,117);
69 | background: linear-gradient(101deg, rgba(25,103,117,1) 0%, rgba(26,137,149,0.26094187675070024) 85%);
70 | overflow: hidden;
71 | /* box-shadow: 0rem 0rem 0.2rem 0.02rem #000000a6; */
72 | }
73 | .job-class-body-job:hover{
74 | background: rgb(28,136,148);
75 | background: radial-gradient(circle, rgba(28,136,148,1) 0%, rgba(8,203,215,1) 100%);
76 | }
77 |
78 | .job-showitems-other{
79 | margin-left: 35%;
80 | position: absolute;
81 | display: initial;
82 | visibility: hidden;
83 | }
84 |
85 | .job-title {
86 | font-size: 14px;
87 | }
88 |
89 | #job-icon-class2{
90 | margin-left: 30%;
91 | font-size: 275%;
92 | }
93 |
94 | #job-icon-class{
95 | float: inline-end;
96 | font-size: 1.8vh;
97 | padding: 0.8vh;
98 | border-radius: 0.3vh;
99 | width: 4vh;
100 | height: auto;
101 | }
102 | #job-icon-left-class{
103 | text-align: center;
104 | font-size: 1.8vh;
105 | background: #15586D;
106 | padding: 0.8vh;
107 | border-radius: 0.3vh;
108 | width: 4vh;
109 | height: auto;
110 | }
111 | .job-class-body-job:hover .job-showitems-other{
112 | visibility: visible;
113 | }
114 |
115 | #job-icon-class:hover{
116 | color: #8ee074;
117 | }
118 |
119 | .jobcenter-input-group-name{
120 | display: block;
121 | position: absolute;
122 | background: rgb(11, 14, 21);
123 | border: none;
124 | width: 90%;
125 | margin: 0 auto;
126 | left: -2%;
127 | right: 0;
128 | opacity: 1;
129 | height: auto;
130 | border-radius: 0.5vh;
131 | outline: none;
132 | text-indent: .5vh;
133 | z-index: 100;
134 | color: #FFFFFF;
135 | height: 4vh;
136 | top:2vh;
137 | }
138 |
139 | .jobcenter-input-password {
140 | display: block;
141 | position: absolute;
142 | background: rgb(11, 14, 21);
143 | border: none;
144 | width: 90%;
145 | margin: 0 auto;
146 | left: -2%;
147 | right: 0;
148 | opacity: 1;
149 | height: auto;
150 | border-radius: 0.5vh;
151 | outline: none;
152 | text-indent: .5vh;
153 | z-index: 100;
154 | color: #FFFFFF;
155 | height: 4vh;
156 | top:7vh;
157 | }
158 | .jobcenter-input-join-password {
159 | display: block;
160 | position: absolute;
161 | background: rgb(11, 14, 21);
162 | border: none;
163 | width: 90%;
164 | margin: 0 auto;
165 | left: -2%;
166 | right: 0;
167 | opacity: 1;
168 | height: auto;
169 | border-radius: 0.5vh;
170 | outline: none;
171 | text-indent: .5vh;
172 | z-index: 100;
173 | color: #FFFFFF;
174 | height: 4vh;
175 | }
176 |
177 | .jobcenter-input-password2 {
178 | display: block;
179 | position: absolute;
180 | background: rgb(11, 14, 21);
181 | border: none;
182 | width: 90%;
183 | margin: 0 auto;
184 | left: -2%;
185 | right: 0;
186 | opacity: 1;
187 | height: auto;
188 | border-radius: 0.5vh;
189 | outline: none;
190 | text-indent: .5vh;
191 | z-index: 100;
192 | color: #FFFFFF;
193 | height: 4vh;
194 | top:12vh;
195 | }
196 | .groups-menu-body {
197 | display: none;
198 | position: absolute;
199 | height: 40%;
200 | width: 90%;
201 | background: linear-gradient(158deg, rgba(24,25,46,1) 0%, rgba(15,18,27,1) 32%, rgba(24,25,46,1) 68%, rgba(15,18,27,1) 100%);
202 | box-shadow: inset 0px 0px 5px 0px rgba(0, 0, 0, 0.247);
203 | margin: 0 auto;
204 | left: 0;
205 | right: 0;
206 | top: 8.5vh;
207 | border-radius: 0.5vh;
208 | overflow: hidden;
209 | z-index: 700;
210 | border: 1px solid rgba(123,171,248,1);
211 | }
212 | .groups-menu-main {
213 | position: absolute;
214 | transform: translate(-50%, -50%);
215 | top: 1vh;
216 | left: 50%;
217 | padding-top: 10%;
218 | padding-bottom: 5%;
219 | width: 100%;
220 | border-radius: .5vh;
221 | }
--------------------------------------------------------------------------------
/qb-phone/client/employment.lua:
--------------------------------------------------------------------------------
1 | -- Use This Callback Whenever You Need To Get A the information --
2 | local cachedEmployees = {}
3 | local myJobs = {}
4 |
5 | -- NUI Callbacks
6 |
7 | RegisterNUICallback('GetJobs', function(_, cb)
8 | cb(myJobs)
9 | end)
10 |
11 | RegisterNUICallback('dutyStatus', function(_, cb)
12 | cb({
13 | job = QBCore.Functions.GetPlayerData().job.name,
14 | duty = QBCore.Functions.GetPlayerData().job.onduty
15 | })
16 | end)
17 |
18 |
19 | RegisterNUICallback('GetEmployees', function(data, cb)
20 | if not data.job then return end
21 |
22 | local employees = cachedEmployees[data.job] or {}
23 |
24 | cb(employees)
25 | end)
26 |
27 | RegisterNUICallback('SendEmployeePayment', function(data, cb)
28 | if not data.job or not data.cid or not data.amount then return end
29 |
30 | TriggerServerEvent('qb-phone:server:SendEmploymentPayment', data.job, data.cid, data.amount)
31 | cb("ok")
32 | end)
33 |
34 | RegisterNUICallback('RemoveEmployee', function(data, cb)
35 | if not data or not data.job or not data.cid then return end
36 |
37 | TriggerServerEvent('qb-phone:server:fireUser', data.job, data.cid)
38 |
39 | cb("ok")
40 | end)
41 |
42 | RegisterNUICallback('ChangeRole', function(data, cb)
43 | if not data then return end
44 |
45 | TriggerServerEvent('qb-phone:server:gradesHandler', data.job, tostring(data.cid), data.grade)
46 | cb("ok")
47 | end)
48 |
49 | RegisterNUICallback('ClockIn', function(data, cb)
50 | if not data or not data.job then return end
51 |
52 | TriggerServerEvent('qb-phone:server:clockOnDuty', data.job)
53 | cb("ok")
54 | end)
55 |
56 | RegisterNUICallback('HireFucker', function(data, cb)
57 | if not data then return end
58 | if not data.job or not data.stateid or not data.grade then return end
59 |
60 | TriggerServerEvent('qb-phone:server:hireUser', data.job, data.stateid, data.grade)
61 | cb("ok")
62 | end)
63 |
64 | RegisterNUICallback('ChargeMF', function(data, cb)
65 | if not data or not data.stateid or not data.amount or not data.job then return end
66 |
67 | TriggerServerEvent('qb-phone:server:ChargeCustomer', data.stateid, data.amount, data.note, data.job)
68 | cb("ok")
69 | end)
70 |
71 | RegisterNetEvent('qb-phone:client:JobsHandler', function(job, employees)
72 | if not job or not employees then return end
73 | if not cachedEmployees[job] then return end
74 |
75 | cachedEmployees[job] = {}
76 | for _, v in pairs(employees) do
77 | cachedEmployees[job][#cachedEmployees[job]+1] = {
78 | cid = v.cid,
79 | name = v.name,
80 | grade = tonumber(v.grade),
81 | }
82 | table.sort(cachedEmployees[job], function(a, b)
83 | return a.grade > b.grade
84 | end)
85 | end
86 | end)
87 |
88 |
89 | RegisterNetEvent('qb-phone:client:MyJobsHandler', function(job, jobTable, employees)
90 | if not QBCore.Shared.Jobs[job] then return end
91 |
92 | myJobs[job] = jobTable
93 |
94 | if employees then
95 | cachedEmployees[job] = {}
96 | for _, v in pairs(employees) do
97 | cachedEmployees[job][#cachedEmployees[job]+1] = {
98 | cid = v.cid,
99 | name = v.name,
100 | grade = tonumber(v.grade),
101 | }
102 | table.sort(cachedEmployees[job], function(a, b)
103 | return a.grade > b.grade
104 | end)
105 | end
106 | else
107 | cachedEmployees[job] = nil
108 | end
109 | end)
110 |
111 | AddEventHandler('onResourceStart', function(resource)
112 | if resource == GetCurrentResourceName() then
113 | Wait(300)
114 |
115 | local employees, myShit = lib.callback.await('qb-phone:server:GetMyJobs', false)
116 | if not employees then print('qb-phone first start might be enabled on the server, disable it!') return end
117 |
118 | for k, _ in pairs(employees) do
119 | for _, v in pairs(employees[k]) do
120 | if not cachedEmployees[k] then cachedEmployees[k] = {} end
121 | cachedEmployees[k][#cachedEmployees[k]+1] = {
122 | cid = v.cid,
123 | name = v.name,
124 | grade = tonumber(v.grade),
125 | }
126 | end
127 | table.sort(cachedEmployees[k], function(a, b)
128 | return a.grade > b.grade
129 | end)
130 | end
131 |
132 | if myShit then
133 | for k, v in pairs(myShit) do
134 | if QBCore.Shared.Jobs[k] and not myJobs[k] then myJobs[k] = v end
135 | end
136 | end
137 | end
138 | end)
139 |
140 | RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
141 | local employees, myShit = lib.callback.await('qb-phone:server:GetMyJobs', false)
142 | for k, _ in pairs(employees) do
143 | for _, v in pairs(employees[k]) do
144 | if not cachedEmployees[k] then cachedEmployees[k] = {} end
145 | cachedEmployees[k][#cachedEmployees[k]+1] = {
146 | cid = v.cid,
147 | name = v.name,
148 | grade = tonumber(v.grade),
149 | }
150 | end
151 | table.sort(cachedEmployees[k], function(a, b)
152 | return a.grade > b.grade
153 | end)
154 | end
155 |
156 |
157 | if myShit then
158 | for k, v in pairs(myShit) do
159 | if QBCore.Shared.Jobs[k] and not myJobs[k] then myJobs[k] = v end
160 | end
161 | end
162 | end)
163 |
164 | RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() -- Reset all variables
165 | myJobs = {}
166 | cachedEmployees = {}
167 | end)
168 |
--------------------------------------------------------------------------------
/qb-phone/README.md:
--------------------------------------------------------------------------------
1 | # Installation steps
2 |
3 | ## General Setup
4 | General setup is quite easy, delete your OLD qb-phone
5 | if you server havent been running previously then go ahead and run the provided SQL file in your database.
6 |
7 | If your server has been running qb-phone previously please update your sql while being carefull and take a backup so you have no data lost.
8 |
9 | After the SQL setup you can now drop the resource into your server and start it up while you conduct the next steps.
10 |
11 | ## Employment setup
12 | Setting up employment and multijob can be quite tricky so make sure to reread this if you have any issues...
13 | If you already have a multijob system and you do not wish to use this then you can skip this step.
14 |
15 |
16 | 1. Head over to qb-phone/server/employment.lua and change local FirstStart from false to true like shown below
17 |
18 | ```lua
19 | local FirstStart = true
20 | ```
21 |
22 | 2. Start the script and make sure it's fully done, it can take a while depending on your current playerbase (ensure qb-phone in console or f8)
23 |
24 | 3. Head over to qb-phone/server/employment.lua again and change the FirstStart to false
25 |
26 | Like so:
27 | ```lua
28 | local FirstStart = false
29 | ```
30 |
31 | 4. Headover to your qb-core/server/commands.lua and find the follow command 'setjob'
32 |
33 | replace the commands with the code below:
34 | ```lua
35 | QBCore.Commands.Add('setjob', 'Set A Players Job (Admin Only)', { { name = 'id', help = 'Player ID' }, { name = 'job', help = 'Job name' }, { name = 'grade', help = 'Grade' } }, true, function(source, args)
36 | local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
37 | if Player then
38 | local job = tostring(args[2])
39 | local grade = tonumber(args[3])
40 | local sgrade = tostring(args[3])
41 | local jobInfo = QBCore.Shared.Jobs[job]
42 | if jobInfo then
43 | if jobInfo["grades"][sgrade] then
44 | Player.Functions.SetJob(job, grade)
45 | exports['qb-phone']:hireUser(job, Player.PlayerData.citizenid, grade)
46 | else
47 | TriggerClientEvent('QBCore:Notify', source, "Not a valid grade", 'error')
48 | end
49 | else
50 | TriggerClientEvent('QBCore:Notify', source, "Not a valid job", 'error')
51 | end
52 | else
53 | TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
54 | end
55 | end, 'admin')
56 | ```
57 |
58 | 5. Now below that add the new command called 'removejob' like shown below
59 |
60 | ```lua
61 | QBCore.Commands.Add('removejob', 'Removes A Players Job (Admin Only)', { { name = 'id', help = 'Player ID' }, { name = 'job', help = 'Job name' } }, true, function(source, args)
62 | local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
63 | if Player then
64 | if Player.PlayerData.job.name == tostring(args[2]) then
65 | Player.Functions.SetJob("unemployed", 0)
66 | end
67 | exports['qb-phone']:fireUser(tostring(args[2]), Player.PlayerData.citizenid)
68 | else
69 | TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
70 | end
71 | end, 'admin')
72 | ```
73 |
74 | 6. If you use qb-cityhall then u have to Find ApplyJob in qb-cityhall/server/main.lua and replace with this one
75 |
76 | ```lua
77 | RegisterNetEvent('qb-cityhall:server:ApplyJob', function(job, cityhallCoords)
78 | local src = source
79 | local Player = QBCore.Functions.GetPlayer(src)
80 | if not Player then return end
81 | local ped = GetPlayerPed(src)
82 | local pedCoords = GetEntityCoords(ped)
83 | local JobInfo = QBCore.Shared.Jobs[job]
84 | if #(pedCoords - cityhallCoords) >= 20.0 or not availableJobs[job] then
85 | return DropPlayer(source, "Attempted exploit abuse")
86 | end
87 | Player.Functions.SetJob(job, 0)
88 | exports['qb-phone']:hireUser(job, Player.PlayerData.citizenid, 0)
89 | TriggerClientEvent('QBCore:Notify', src, Lang:t('info.new_job', {job = JobInfo.label}))
90 | end)
91 | ```
92 |
93 | 7. Throw the `dialing.ogg` into your interact-sound/client/html/sounds file, if you don't already have it
94 |
95 | 8. Restart your server fully to get the new commands working and also to get the phone fully working.
96 |
97 |
98 | It should now look like this
99 |
100 | 
101 |
102 |
103 | ## Casino Setup
104 |
105 | 1. Head over to your qb-core/config.lua
106 | 2. Replace the following code with below code
107 | ```lua
108 | -- Old
109 | QBConfig.Money.MoneyTypes = { cash = 500, bank = 5000, crypto = 0 } -- type = startamount - Add or remove money types for your server (for ex. blackmoney = 0), remember once added it will not be removed from the database!
110 | QBConfig.Money.DontAllowMinus = { 'cash', 'crypto' } -- Money that is not allowed going in minus
111 | ```
112 | ```lua
113 | -- NEW
114 | QBConfig.Money.MoneyTypes = { cash = 500, bank = 5000, casino = 0 } -- type = startamount - Add or remove money types for your server (for ex. blackmoney = 0), remember once added it will not be removed from the database!
115 | QBConfig.Money.DontAllowMinus = { 'cash', 'casino' } -- Money that is not allowed going in minus
116 | ```
117 |
118 | ## Crypto Setup
119 |
120 | 1. Head over to your qb-core/server/Player.lua
121 | 2. Paste the below code into your metadata if you dont know what is metadata it looks something like this: PlayerData.metadata['inside']
122 |
123 | Code to be pasted
124 | ```lua
125 | PlayerData.metadata['crypto'] = PlayerData.metadata['crypto'] or {
126 | ["shung"] = 0,
127 | ["gne"] = 0,
128 | ["xcoin"] = 0,
129 | ["lme"] = 0
130 | }
131 | ```
132 |
133 | It should now all look like this:
134 |
135 | 
136 |
--------------------------------------------------------------------------------
/qb-phone/html/js/casino.js:
--------------------------------------------------------------------------------
1 | var PlayerNameOf = null
2 | var PlayerChanseOf = null
3 | var PlayerIDOf = null
4 |
5 | function LoadCasinoJob(){
6 | var PlayerJob = QB.Phone.Data.PlayerData.job.name;
7 | if (PlayerJob == "pilot"){
8 | $(".casino-dashboard-boss").css({"display":"block"});
9 | $("#casino-Winer-this").css({"display":"block"});
10 | } else {
11 | $(".casino-dashboard-boss").css({"display":"none"});
12 | $("#casino-Winer-this").css({"display":"none"});
13 | }
14 |
15 | CheckStatus();
16 |
17 | $.post('https://qb-phone/CheckHasBetTable', JSON.stringify({}), function(HasTable){
18 | if(JSON.stringify(HasTable) != "[]"){
19 | AddToChat(HasTable)
20 | }else{
21 | $(".casino-list").html("");
22 | var AddOption = 'No Event
'+
23 | '
'+
24 | '
'+
25 | '
'+
26 | '
'
27 | $('.casino-list').append(AddOption);
28 | }
29 | });
30 | }
31 |
32 | $(document).on('click', '.casino-dashboard-boss', function(e){
33 | e.preventDefault();
34 | ClearInputNew()
35 | $('#casino-dashboard-box').fadeIn(350);
36 | });
37 |
38 | $(document).on('click', '#casino_create_bet', function(e){
39 | e.preventDefault();
40 | ClearInputNew()
41 | $('#casino-dashboard-box').fadeOut(350);
42 | $('#casino-dashboard-box-create-bet').fadeIn(350);
43 | });
44 |
45 | $(document).on('click', '#casino_delete', function(e){
46 | e.preventDefault();
47 | $.post('https://qb-phone/CasinoDeleteTable', JSON.stringify({}));
48 | });
49 |
50 | $(document).on('click', '#casino_status', function(e){
51 | e.preventDefault();
52 | $.post('https://qb-phone/casino_status', JSON.stringify({}));
53 | CheckStatus();
54 | });
55 |
56 | $(document).on('click', '#casino-submit-bet', function(e){
57 | e.preventDefault();
58 | var InName = $(".casino_input_name").val();
59 | var InChanse = $(".casino_input_Chanse").val();
60 | if (InName != "" && InChanse != "" && InChanse >= 1.0){
61 | $.post('https://qb-phone/CasinoAddBet', JSON.stringify({
62 | name: InName,
63 | chanse: InChanse,
64 | }));
65 | ClearInputNew();
66 | } else {
67 | QB.Phone.Notifications.Add("fas fa-exclamation-circle", "System", "Fields are incorrect")
68 | }
69 | });
70 |
71 | $(document).ready(function(){
72 | window.addEventListener('message', function(event) {
73 | switch(event.data.action) {
74 | case "BetAddToApp":
75 | AddToChat(event.data.datas)
76 | break;
77 | }
78 | })
79 | });
80 |
81 | function AddToChat(data){
82 | $(".casino-list").html("");
83 | if(JSON.stringify(data) != "[]"){
84 | for (const [k, v] of Object.entries(data)) {
85 | var firstLetter = v.Name.substring(0, 1);
86 | var Fulltext = firstLetter.toUpperCase()+(v.Name).replace(firstLetter,'')
87 |
88 | var AddOption = ''+
89 | '
'+Fulltext+'
'+
90 | '
'+
91 | '
'
92 | $('.casino-list').append(AddOption);
93 | }
94 | }else{
95 | $(".casino-list").html("");
96 | var AddOption = 'No Event
'+
97 | '
'+
98 | '
'+
99 | '
'+
100 | '
'
101 | $('.casino-list').append(AddOption);
102 | }
103 | }
104 |
105 | function CheckStatus(){
106 | $.post('https://qb-phone/CheckHasBetStatus', JSON.stringify({}), function(HasStatus){
107 | if (HasStatus){
108 | $("#casino_status").html("Status: Betting Enabled");
109 | }else{
110 | $("#casino_status").html("Status: Betting Disabled");
111 | }
112 | });
113 | }
114 |
115 |
116 | $(document).on('click', '#casino-click-beting', function(e){
117 | e.preventDefault();
118 | PlayerNameOf = $(this).data('name')
119 | PlayerChanseOf = $(this).data('chanse')
120 | PlayerIDOf = $(this).data('id')
121 | $("#casino-info-player").html(PlayerNameOf);
122 | $("#casino-info-total").html("0 Dollars");
123 | $("#casino-info-chanse").html("x"+PlayerChanseOf);
124 | $('#casin-bet-boxing-player').fadeIn(350);
125 | });
126 |
127 | $(".casino-amount-for-bet-player").keyup(function(){
128 | var input = this.value
129 | var MoneyAmount = input * PlayerChanseOf
130 |
131 | $("#casino-info-total").html(MoneyAmount+" Dollars");
132 | });
133 |
134 | $(document).on('click', '#casino-end-task-accept', function(e){
135 | e.preventDefault();
136 | var Amount = $(".casino-amount-for-bet-player").val();
137 | if (Amount != "" && Amount >= 1.0){
138 | $.post('https://qb-phone/BettingAddToTable', JSON.stringify({
139 | amount: Amount,
140 | chanse: PlayerChanseOf,
141 | player: PlayerNameOf,
142 | id: PlayerIDOf,
143 | }));
144 | ClearInputNew();
145 | } else {
146 | QB.Phone.Notifications.Add("fas fa-exclamation-circle", "System", "Fields are incorrect")
147 | }
148 | });
149 |
150 | $(document).on('click', '#casino-Winer-this', function(e){
151 | e.preventDefault();
152 | $.post('https://qb-phone/WineridCasino', JSON.stringify({
153 | id: PlayerIDOf,
154 | }));
155 | });
--------------------------------------------------------------------------------
/qb-phone/html/js/debt.js:
--------------------------------------------------------------------------------
1 | let debt
2 |
3 | // Search
4 |
5 | $(document).ready(function(){
6 | $("#debt-search").on("keyup", function() {
7 | var value = $(this).val().toLowerCase();
8 | $(".debt-list").filter(function() {
9 | $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1);
10 | });
11 | });
12 | });
13 |
14 | // Functions
15 |
16 | var formatter = new Intl.NumberFormat('en-US', {
17 | style: 'currency',
18 | currency: 'USD',
19 | });
20 |
21 | function ConfirmationFrame() {
22 | $('.spinner-input-frame').css("display", "flex");
23 | setTimeout(function () {
24 | $('.spinner-input-frame').css("display", "none");
25 | $('.checkmark-input-frame').css("display", "flex");
26 | setTimeout(function () {
27 | $('.checkmark-input-frame').css("display", "none");
28 | }, 2000)
29 | }, 1000)
30 | }
31 |
32 | // Debt Shit
33 |
34 | // Block
35 | $(document).on('click', '.debt-list', function(e){
36 | e.preventDefault();
37 |
38 | $(this).find(".debt-block").toggle();
39 | var Id = $(this).attr('id');
40 | debt = Id
41 | });
42 |
43 | // Pay All Tab
44 | $(document).on('click', '.send-all-box', function(e){
45 | e.preventDefault();
46 |
47 | var Id = $(this).parent().parent().parent().attr('id');
48 | debt = Id
49 | setTimeout(function(){
50 | ConfirmationFrame()
51 | }, 150);
52 | $.post('https://qb-phone/SendAllPayment', JSON.stringify({
53 | id: Id,
54 | }));
55 | });
56 |
57 | // Pay Minimum
58 | $(document).on('click', '.send-minimum-box', function(e){
59 | e.preventDefault();
60 |
61 | var Id = $(this).parent().parent().parent().attr('id');
62 | debt = Id
63 | setTimeout(function(){
64 | ConfirmationFrame()
65 | }, 150);
66 | $.post('https://qb-phone/SendMinimumPayment', JSON.stringify({
67 | id: Id,
68 | }));
69 | });
70 |
71 | function LoadDebtJob(data){
72 | $(".debts-list").html("");
73 | if(data) {
74 | Object.keys(data).map(function(element, index){
75 | if (element === 'assets'){
76 | $(".debts-list").append(`Asset Fees
`);
77 | }else if (element === 'loan'){
78 | $(".debts-list").append(`Loan Payment
`);
79 | }else if (element === 'fine'){
80 | $(".debts-list").append(`Bill Payments
`);
81 | }
82 | Object.keys(data[element]).map(function(element2, _){
83 | if (element === 'assets'){
84 | $(".debts-list").append(' '+data[element][element2].car+' '+formatter.format(data[element][element2].totalamount)+'' +
85 | '
' +
86 | '
'+data[element][element2].sender+'
' +
87 | '' +
88 | '
in '+data[element][element2].display+'
' +
89 | '
PAY
' +
90 | '
' +
91 | '
');
92 |
93 | } else if (element === 'loan'){
94 | $(".debts-list").append(' '+data[element][element2].car+' '+formatter.format(data[element][element2].totalamount)+'' +
95 | '
' +
96 | '
'+data[element][element2].sender+'
' +
97 | '' +
98 | '
in '+data[element][element2].display+'
' +
99 | '
PAY MINIMUMPAY ALL
' +
100 | '
' +
101 | '
');
102 | } else if (element === 'fine'){
103 | $(".debts-list").append(' '+data[element][element2].name+' '+formatter.format(data[element][element2].totalamount)+' '+data[element][element2].paybacks+"/"+data[element][element2].totalPays+'' +
104 | '
' +
105 | '
'+data[element][element2].sender+'
' +
106 | '' +
107 | '
in '+data[element][element2].display+'
' +
108 | '
PAY MINIMUMPAY ALL
' +
109 | '
' +
110 | '
');
111 | }
112 | $("#debt-"+data[element][element2].id).data('debtId', element2);
113 | })
114 | })
115 | }
116 | }
--------------------------------------------------------------------------------
/qb-phone/server/crypto.lua:
--------------------------------------------------------------------------------
1 | -- exports['qb-phone']:RemoveCrypto(Player, type, amount)
2 | local function RemoveCrypto(src, type, amount)
3 | if not src then return end
4 | local Player = QBCore.Functions.GetPlayer(src)
5 | if not Player or not type or not amount then return end
6 |
7 | local Crypto = Player.PlayerData.metadata.crypto
8 | if not Crypto then return end
9 | amount = tonumber(amount)
10 | if amount < 1 then return false end
11 |
12 | if (Crypto[type] - amount) >= 0 then
13 | Crypto[type] -= amount
14 | Player.Functions.SetMetaData("crypto", Crypto)
15 | TriggerClientEvent('qb-phone:client:UpdateCrypto', src)
16 | return true
17 | else
18 | return false
19 | end
20 | end exports("RemoveCrypto", RemoveCrypto)
21 |
22 |
23 | -- exports['qb-phone']:hasEnough(Player, type, amount)
24 | local function hasEnough(src, type, amount)
25 | if not src then return end
26 | local Player = QBCore.Functions.GetPlayer(src)
27 |
28 | if not Player or not type or not amount then return end
29 |
30 | local Crypto = Player.PlayerData.metadata.crypto
31 |
32 | if not Crypto then return end
33 | if Crypto[type] - tonumber(amount) >= 0 then
34 | return true
35 | else
36 | return false
37 | end
38 | end exports("hasEnough", hasEnough)
39 |
40 |
41 | -- exports['qb-phone']:AddCrypto(Player, type, amount)
42 | local function AddCrypto(src, type, amount)
43 | if not src then return end
44 | local Player = QBCore.Functions.GetPlayer(src)
45 |
46 | if not Player or not type or not amount then return false end
47 |
48 | local Crypto = Player.PlayerData.metadata.crypto
49 |
50 | if not Crypto then return false end
51 | Crypto[type] = Crypto[type] + tonumber(amount)
52 | Player.Functions.SetMetaData("crypto", Crypto)
53 | TriggerClientEvent('qb-phone:client:UpdateCrypto', src)
54 |
55 | return true
56 | end exports("AddCrypto", AddCrypto)
57 |
58 | local function GetConfig(metadata)
59 | for k, v in pairs(Config.CryptoCoins) do
60 | if v.metadata == metadata then
61 | return k
62 | end
63 | end
64 | end
65 |
66 | RegisterNetEvent('qb-phone:server:PurchaseCrypto', function(type, amount)
67 | local src = source
68 | local Player = QBCore.Functions.GetPlayer(src)
69 | if not Player or not Player.PlayerData.metadata.crypto[type] then return end -- if the crypto dosnt exist
70 | local v = Config.CryptoCoins[GetConfig(type)]
71 | local cashAmount = tonumber(amount) * v.value
72 |
73 | if not v.purchase then return end -- Only modders should be only to do this so no need to send a message to client
74 |
75 | local txt = "Purchased " .. amount .. "x " .. v.abbrev
76 |
77 | if Player.PlayerData.money.bank >= cashAmount then
78 | Player.Functions.RemoveMoney('bank', cashAmount, txt)
79 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
80 | "WALLET",
81 | "You Purchased "..amount.." "..type.."!",
82 | "fas fa-chart-line",
83 | "#D3B300",
84 | 7500
85 | )
86 |
87 | if Config.RenewedBanking then
88 | local cid = Player.PlayerData.citizenid
89 | local name = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)
90 | exports['Renewed-Banking']:handleTransaction(cid, "Crypto Purchase", cashAmount, txt, "Los Santos Crypto", name, "withdraw")
91 | end
92 |
93 | AddCrypto(src, type, amount)
94 | else
95 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
96 | "WALLET",
97 | "Not Enough Money",
98 | "fas fa-chart-line",
99 | "#D3B300",
100 | 7500
101 | )
102 | end
103 | end)
104 |
105 | RegisterNetEvent('qb-phone:server:SellCrypto', function(type, amount)
106 | local src = source
107 | local Player = QBCore.Functions.GetPlayer(src)
108 | if not Player or not Player.PlayerData.metadata.crypto[type] then return end -- if the crypto dosnt exist
109 | local v = Config.CryptoCoins[GetConfig(type)]
110 | local cryptoAmount = tonumber(amount) * v.value
111 |
112 | if not v.sell then return end -- Only modders should be only to do this so no need to send a message to client
113 |
114 | local txt = "Sold " .. amount .. "x " .. v.abbrev
115 |
116 | if not RemoveCrypto(src, type, amount) then return end
117 |
118 | Player.Functions.AddMoney('bank', cryptoAmount, txt)
119 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
120 | "WALLET",
121 | "You Sold "..amount.." "..type.."!",
122 | "fas fa-chart-line",
123 | "#D3B300",
124 | 7500
125 | )
126 |
127 | if Config.RenewedBanking then
128 | local cid = Player.PlayerData.citizenid
129 | local name = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)
130 | exports['Renewed-Banking']:handleTransaction(cid, "Sold Crypto", cryptoAmount, txt, "Los Santos Crypto", name, "deposit")
131 | end
132 | end)
133 |
134 | RegisterNetEvent('qb-phone:server:ExchangeCrypto', function(type, amount, stateid)
135 | local src = source
136 | local Player = QBCore.Functions.GetPlayer(src)
137 | local Receiver = QBCore.Functions.GetPlayer(tonumber(stateid))
138 | if not Player or not Player.PlayerData.metadata.crypto[type] then return end -- if the crypto dosnt exist
139 | if not Receiver then return TriggerClientEvent("QBCore:Notify", src, 'This state id does not exists!', "error") end
140 |
141 | if Player.PlayerData.citizenid ~= Receiver.PlayerData.citizenid then
142 | if RemoveCrypto(src, type, amount) then
143 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
144 | "WALLET",
145 | "You sent "..amount.." "..type.."!",
146 | "fas fa-chart-line",
147 | "#D3B300",
148 | 7500
149 | )
150 |
151 | AddCrypto(Receiver.PlayerData.source, type, amount)
152 | TriggerClientEvent('qb-phone:client:CustomNotification', Receiver.PlayerData.source,
153 | "WALLET",
154 | "You received "..amount.." "..type.."!",
155 | "fas fa-chart-line",
156 | "#D3B300",
157 | 7500
158 | )
159 | else
160 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
161 | "WALLET",
162 | "Cannot transfer crypto!",
163 | "fas fa-chart-line",
164 | "#D3B300",
165 | 7500
166 | )
167 |
168 | end
169 | else
170 | TriggerClientEvent('qb-phone:client:CustomNotification', src,
171 | "WALLET",
172 | "Cannot send crypto to yourself!",
173 | "fas fa-chart-line",
174 | "#D3B300",
175 | 7500
176 | )
177 | end
178 | end)
179 |
--------------------------------------------------------------------------------