Full View config.server.lua

Preview File Updated: v1.0.0 - 28.01.2024

SV = {}

SV.Database = {
    ['table:vehicles'] = 'vehicles',
    ['table:vehicle_categories'] = 'vehicle_categories',
}

SV.Webhooks = {
    ['PHOTOSTOOL'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",

    ['PURCHASE'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['PURCHASE_FROM_PLAYER'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['CREATE_ORDER'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['DELIVERY_ORDER'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['AUTO_DELIVERY_ORDER'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['EMPLOYEE_BONUS'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['EMPLOYEE_CHANGE_GRADE'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['EMPLOYEE_FIRE'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['EMPLOYEE_HIRE'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['WITHDRAW'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['DEPOSIT'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
    ['ANNOUNCEMENT'] = "https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXX",
}

SV.WebhookText = {
    ['TITLE.PURCHASE'] = "🧾 Purchased",
    ['DESCRIPTION.PURCHASE'] = [[
        Player %s [%s] purchased vehicle %s %s (%s) in the %s - %s (%s) for %s$ by %s.
        Selected colors - Primary: %s, Secondary: %s, Pearlescent: %s.
        Plate: %s
    ]],

    ['TITLE.PURCHASE_FROM_PLAYER'] = "🧾 Purchased from player",
    ['DESCRIPTION.PURCHASE_FROM_PLAYER'] = [[
        Player %s [%s][%s] purchased vehicle %s %s (%s) from %s [%s][%s] in the %s - %s (%s) for %s$ by %s.
        Selected colors - Primary: %s, Secondary: %s, Pearlescent: %s.
        Plate: %s
    ]],
    
    ['TITLE.CREATE_ORDER'] = "πŸ“¦ Create Order",
    ['DESCRIPTION.CREATE_ORDER'] = [[
        Player %s [%s] created an order for %s for %s$ in %s - %s (%s)
    ]],

    ['TITLE.DELIVERY_ORDER'] = "πŸͺ Delivery Order",
    ['DESCRIPTION.DELIVERY_ORDER'] = [[
        Player %s [%s] delivered order to %s - %s (%s) and recieved %s$ for deliver:
        %s
    ]],

    ['TITLE.AUTO_DELIVERY_ORDER'] = "πŸͺ Auto Delivery Order",
    ['DESCRIPTION.AUTO_DELIVERY_ORDER'] = [[
        Delivered order to %s - %s (%s):
        %s
    ]],

    ['TITLE.EMPLOYEE_BONUS'] = "πŸ’Έ Employee Bonus",
    ['DESCRIPTION.EMPLOYEE_BONUS'] = [[
        Player %s [%s] gave a bonus to employee %s of %s$ in store %s - %s (%s)
    ]],

    ['TITLE.EMPLOYEE_CHANGE_GRADE'] = "πŸ‘¨β€πŸ’Ό Employee Change Grade",
    ['DESCRIPTION.EMPLOYEE_CHANGE_GRADE'] = [[
        Player %s [%s] changed the job grade of player %s to %s in store %s - %s (%s)
    ]],

    ['TITLE.EMPLOYEE_FIRE'] = "❌ Employee Fire",
    ['DESCRIPTION.EMPLOYEE_FIRE'] = [[
        Player %s [%s] fired an employee %s to store %s - %s (%s)
    ]],

    ['TITLE.EMPLOYEE_HIRE'] = "βœ… Employee Hire",
    ['DESCRIPTION.EMPLOYEE_HIRE'] = [[
        Player %s [%s] hired an employee %s (%s) to store %s - %s (%s)
    ]],

    ['TITLE.WITHDRAW'] = "πŸ’² Withdraw",
    ['DESCRIPTION.WITHDRAW'] = [[
        Player %s [%s] withdrew $%s from store %s - %s (%s)
    ]],

    ['TITLE.DEPOSIT'] = "πŸ’² Deposit",
    ['DESCRIPTION.DEPOSIT'] = [[
        Player %s [%s] deposit $%s from store %s - %s (%s)
    ]],
    
    ['TITLE.ANNOUNCEMENT'] = "πŸ’² New Announcement",
    ['DESCRIPTION.ANNOUNCEMENT'] = [[
        Player %s [%s] wrote an announcement in store %s - %s (%s) with the content:
        ```%s```
    ]],
    
}

SV.Webhook = function(webhook_id, title, description, color, footer)
    local DiscordWebHook = SV.Webhooks[webhook_id]
    local embeds = {{
        ["title"] = title,
        ["type"] = "rich",
        ["description"] = description,
        ["color"] = color,
        ["footer"] = {
            ["text"] = footer..' - '..os.date(),
        },
    }}
    PerformHttpRequest(DiscordWebHook, function(err, text, headers) end, 'POST', json.encode({embeds = embeds}), {['Content-Type'] = 'application/json'})
end

SV.getIdentifier = function(xPlayer)
    if Config.Core == "ESX" then
        return xPlayer.identifier
    elseif Config.Core == "QB-Core" then
        return xPlayer.PlayerData.citizenid
    end
end

SV.getPlayerByIdentifier = function(identifier)
    if Config.Core == "ESX" then
        return Core.GetPlayerFromIdentifier(identifier)
    elseif Config.Core == "QB-Core" then
        return Core.Functions.GetPlayerByCitizenId(identifier)
    end
end

SV.getCharacterName = function(xPlayer)
    if Config.Core == "ESX" then
        return xPlayer.getName()
    elseif Config.Core == "QB-Core" then
        return xPlayer.PlayerData.charinfo.firstname..' '..xPlayer.PlayerData.charinfo.lastname
    end
end

SV.getPlayer = function(src)
    if Config.Core == "ESX" then
        return Core.GetPlayerFromId(src)
    elseif Config.Core == "QB-Core" then
        return Core.Functions.GetPlayer(src)
    end
end

SV.isPlayerEmployee = function(xPlayer, jobName)
    if Config.Core == "ESX" then
        return xPlayer.job.name == jobName
    elseif Config.Core == "QB-Core" then
        return xPlayer.PlayerData.job.name == jobName
    end
end

SV.isPlayerManager = function(xPlayer, jobName)
    if Config.Core == "ESX" then
        return (xPlayer.job.name == jobName and xPlayer.job.grade_name == 'manager')
    elseif Config.Core == "QB-Core" then
        return (xPlayer.PlayerData.job.name == jobName and xPlayer.PlayerData.job.grade.level == 1)
    end
end

SV.isPlayerBoss = function(xPlayer, jobName, storeId)
    if Config.Core == "ESX" then
        return (xPlayer.job.name == jobName and xPlayer.job.grade_name == 'boss')
    elseif Config.Core == "QB-Core" then
        return (xPlayer.PlayerData.job.name == jobName and xPlayer.PlayerData.job.grade.level == 2)
    end
end

SV.getPlayerJob = function(xPlayer)
    if Config.Core == "ESX" then
        return xPlayer.job.name
    elseif Config.Core == "QB-Core" then
        return xPlayer.PlayerData.job.name
    end
end

SV.setPlayerJob = function(src, xPlayer, jobName, grade, isOffline)
    if jobName then
        if Config.Core == "ESX" then
            xPlayer.setJob(jobName, grade)
        elseif Config.Core == "QB-Core" then
            xPlayer.Functions.SetJob(jobName, grade)
        end
    else
        if not isOffline then
            if Config.Core == "ESX" then
                xPlayer.setJob('unemployed', 0)
            elseif Config.Core == "QB-Core" then
                xPlayer.Functions.SetJob('unemployed')
            end
        else
            if Config.Core == "ESX" then
                MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade WHERE identifier = @identifier', {
                    ['@job'] = 'unemployed',
                    ['@job_grade'] = '0'
                })
            elseif Config.Core == "QB-Core" then
                TriggerClientEvent("vms_vehicleshopv2:notification", src, TRANSLATE('notify.employees:player_is_offline'), 4500, 'error')
            end
        end
    end
end

SV.getMoney = function(xPlayer, moneyType)
    if Config.Core == "ESX" then
        local moneyType = moneyType == 'cash' and 'money' or moneyType
        return xPlayer.getAccount(moneyType).money
    elseif Config.Core == "QB-Core" then
        return xPlayer.Functions.GetMoney(moneyType)
    end
end

SV.addMoney = function(xPlayer, moneyType, count)
    if Config.Core == "ESX" then
        local moneyType = moneyType == 'cash' and 'money' or moneyType == 'dirty' and 'black_money' or moneyType
        xPlayer.addAccountMoney(moneyType, count)
    elseif Config.Core == "QB-Core" then
        xPlayer.Functions.AddMoney(moneyType, count)
    end
end

SV.removeMoney = function(xPlayer, moneyType, count)
    if Config.Core == "ESX" then
        local moneyType = moneyType == 'cash' and 'money' or moneyType
        xPlayer.removeAccountMoney(moneyType, count)
    elseif Config.Core == "QB-Core" then
        xPlayer.Functions.RemoveMoney(moneyType, count)
    end
end

SV.getSocietyMoney = function(societyName, cb)
    if Config.Core == "ESX" then
        TriggerEvent('esx_addonaccount:getSharedAccount', "society_"..societyName, function(account)
            cb(account.money)
        end)
    elseif Config.Core == "QB-Core" then
        local society = exports['qb-banking']:GetAccountBalance(societyName)
        cb(society)
    end
end

SV.addSocietyMoney = function(societyName, amount)
    if Config.Core == "ESX" then
        TriggerEvent('esx_addonaccount:getSharedAccount', "society_"..societyName, function(account)
            account.addMoney(amount)
        end)
    elseif Config.Core == "QB-Core" then
        exports['qb-banking']:AddMoney(societyName, amount)
    end
end

SV.removeSocietyMoney = function(societyName, amount)
    if Config.Core == "ESX" then
        TriggerEvent('esx_addonaccount:getSharedAccount', "society_"..societyName, function(account)
            account.removeMoney(amount)
        end)
    elseif Config.Core == "QB-Core" then
        exports['qb-banking']:RemoveMoney(societyName, amount)
    end
end

SV.checkLicense = function(xPlayer, licenseName, cb)
    if Config.Core == "ESX" then
        TriggerEvent('esx_license:checkLicense', xPlayer.source, licenseName, function(hasLicense)
            if hasLicense then
                cb(true)
            else
                cb(false)
            end
        end)
    elseif Config.Core == "QB-Core" then
        local hasLicense = xPlayer.PlayerData.metadata['licences'][licenseName]
        cb(hasLicense)
    end
end

SV.verifyPlateNotExist = function(src, plate, cb)
    if Config.Core == "ESX" then
        MySQL.Async.fetchAll('SELECT plate FROM owned_vehicles WHERE @plate = plate', {
            ['@plate'] = plate
        }, function (result)
            cb(result[1] ~= nil)
        end)
    elseif Config.Core == "QB-Core" then
        MySQL.Async.fetchAll('SELECT plate FROM player_vehicles WHERE @plate = plate', {
            ['@plate'] = plate
        }, function(result)
            cb(result[1] ~= nil)
        end)
    end
end

---@param model: vehicle model name
---@param vehicleType: 'car' / 'plane' / 'boat'
---@param licensePlate: generated license plate
---@param primaryColor, secondaryColor, pearlescentColor: id of the selected color
SV.addPlayerVehicle = function(xPlayer, model, vehicleType, licensePlate, primaryColor, secondaryColor, pearlescentColor, spawnOnPurchase, cb)
    if Config.Core == "ESX" then
        local vehicleProperties = {
            ['color1'] = tonumber(primaryColor), 
            ['color2'] = tonumber(secondaryColor), 
            ['pearlescentColor'] = tonumber(pearlescentColor), 
            ['model'] = GetHashKey(model), 
            ['plate'] = licensePlate
        }
        MySQL.Async.execute('INSERT INTO owned_vehicles (`owner`, `plate`, `vehicle`, `type`, `stored`) VALUES (@owner, @plate, @vehicle, @type, @stored)', {
            ['@owner'] = xPlayer.identifier, 
            ['@plate'] = licensePlate, 
            ['@vehicle'] = json.encode(vehicleProperties), 
            ['@type'] = vehicleType,
            ['@stored'] = not spawnOnPurchase and 1 or 0
        })
        cb(vehicleProperties)
    elseif Config.Core == "QB-Core" then
        local vehicleProperties = {
            ['color1'] = tonumber(primaryColor), 
            ['color2'] = tonumber(secondaryColor), 
            ['pearlescentColor'] = tonumber(pearlescentColor), 
            ['model'] = GetHashKey(model), 
            ['plate'] = licensePlate,
            ['fuelLevel'] = 100.0,
        }
        MySQL.Async.execute('INSERT INTO player_vehicles (`license`, `citizenid`, `vehicle`, `hash`, `mods`, `plate`, `garage`, `state`) VALUES (@license, @citizenid, @vehicle, @hash, @mods, @plate, @garage, @state)', {
            ['@license'] = xPlayer.PlayerData.license,
            ['@citizenid'] = xPlayer.PlayerData.citizenid,
            ['@vehicle'] = model,
            ['@hash'] = vehicleProperties.model,
            ['@mods'] = json.encode(vehicleProperties),
            ['@plate'] = vehicleProperties.plate,
            ['@garage'] = 'OUT',
            ['@state'] = not spawnOnPurchase and 1 or 0
        })
        cb(vehicleProperties)
    end
end

SV.onVehicleSpawned = function(xPlayer, networkId)
    local networkId = networkId
    local vehicleId = NetworkGetEntityFromNetworkId(networkId)
    
end

SV.checkRequiredItem = function(xPlayer, name, count, removeOnUse) -- Soon this function will be useful, stay tuned
    if Config.Core == "ESX" then
        if xPlayer.getInventoryItem(name).count >= count then
            if removeOnUse then
                xPlayer.removeInventoryItem(name, count)
            end
            return true
        end
        return false
    elseif Config.Core == "QB-Core" then
        if xPlayer.Functions.GetItemByName(name) and xPlayer.Functions.GetItemByName(name).amount >= count then
            if removeOnUse then
                xPlayer.Functions.RemoveItem(name, count)
            end
            return true
        end
        return false
    end
end

SV.addAgreementItem = function(xPlayer, playerId, name, metadata) -- Soon this function will be useful, stay tuned
    if GetResourceState("qs-inventory") ~= "missing" then
        exports['qs-inventory']:AddItem(playerId, name, 1, nil, metadata)
        
    elseif GetResourceState("ox_inventory") ~= "missing" then
        exports['ox_inventory']:AddItem(playerId, name, 1, metadata, nil)
        
    elseif GetResourceState("qb-inventory") ~= "missing" then
        exports['qb-inventory']:AddItem(playerId, name, 1, nil, metadata)
        
    elseif GetResourceState("core_inventory") ~= "missing" then
        exports['core_inventory']:addItem(('primary-%s'):format((Config.Core == "ESX" and xPlayer.identifier or xPlayer.PlayerData.identifier):gsub(':','')), name, 1, metadata, 'content')
        
    end
end

SV.registerAgreementItem = function(cb) -- Soon this function will be useful, stay tuned
    if GetResourceState("qs-inventory") ~= "missing" then
        exports['qs-inventory']:CreateUsableItem(Config.AgreementItem, function(source, item)
            cb(item.info)
        end)
    elseif GetResourceState("ox_inventory") ~= "missing" then
        
    elseif GetResourceState("qb-inventory") ~= "missing" then
        QBCore.Functions.CreateUseableItem(Config.AgreementItem, function(source, item)
            local src = source
            local Player = QBCore.Functions.GetPlayer(src)
            if Player.Functions.GetItemByName(item.name) then
                cb(item.info)
            end
        end)
    elseif GetResourceState("core_inventory") ~= "missing" then
        
    else
        print("[^1INFORMATION^7] Your inventory is not supported to give agreement item, if you are using inventory with metadata, provide it in SV.addAgreementItem & SV.registerAgreementItem (config.server.lua).")
        print("If you use public paid or free inventory, we will be glad when you let us know so that we can add compatibility.")
    end
end

Citizen.CreateThread(function() -- Registration esx_society
    Citizen.Wait(1000)
    if not Config.UseBuildInCompanyBalance and not Config.RemoveBalanceFromMenu then
        for k, v in pairs(Config.Stores) do
            if v.jobName then
                TriggerEvent('esx_society:registerSociety', v.jobName, v.jobName, 'society_'..v.jobName, 'society_'..v.jobName, 'society_'..v.jobName, {type = 'public'})
            end
        end
    end
end)

Last updated