Scripts/resources/[qb]/qb-core/server/events.lua

343 lines
14 KiB
Lua
Raw Normal View History

2024-12-29 20:06:22 +00:00
-- Event Handler
AddEventHandler('chatMessage', function(_, _, message)
if string.sub(message, 1, 1) == '/' then
CancelEvent()
return
end
end)
AddEventHandler('playerDropped', function(reason)
local src = source
if not QBCore.Players[src] then return end
local Player = QBCore.Players[src]
TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Dropped', 'red', '**' .. GetPlayerName(src) .. '** (' .. Player.PlayerData.license .. ') left..' ..'\n **Reason:** ' .. reason)
Player.Functions.Save()
local citizenid = Player.PlayerData.citizenid
local query = 'SELECT * FROM duty_logs WHERE citizenid = ? AND end_time IS NULL'
exports.oxmysql:execute(query, {citizenid}, function(result)
if result[1] then
local endTime = os.time()
local duration = endTime - result[1].start_time
exports.oxmysql:execute('UPDATE duty_logs SET end_time = ?, duration = ? WHERE citizenid = ? AND end_time IS NULL', {endTime, duration, citizenid})
end
end)
QBCore.Player_Buckets[Player.PlayerData.license] = nil
QBCore.Players[src] = nil
end)
-- Player Connecting
local function onPlayerConnecting(name, _, deferrals)
local src = source
local license
local identifiers = GetPlayerIdentifiers(src)
deferrals.defer()
-- Mandatory wait
Wait(0)
if QBCore.Config.Server.Closed then
if not IsPlayerAceAllowed(src, 'qbadmin.join') then
deferrals.done(QBCore.Config.Server.ClosedReason)
end
end
for _, v in pairs(identifiers) do
if string.find(v, 'license') then
license = v
break
end
end
if GetConvarInt("sv_fxdkMode", false) then
license = 'license:AAAAAAAAAAAAAAAA' -- Dummy License
end
if not license then
deferrals.done(Lang:t('error.no_valid_license'))
elseif QBCore.Config.Server.CheckDuplicateLicense and QBCore.Functions.IsLicenseInUse(license) then
deferrals.done(Lang:t('error.duplicate_license'))
end
local databaseTime = os.clock()
local databasePromise = promise.new()
-- conduct database-dependant checks
CreateThread(function()
deferrals.update(string.format(Lang:t('info.checking_ban'), name))
local databaseSuccess, databaseError = pcall(function()
local isBanned, Reason = QBCore.Functions.IsPlayerBanned(src)
if isBanned then
deferrals.done(Reason)
end
end)
if QBCore.Config.Server.Whitelist then
deferrals.update(string.format(Lang:t('info.checking_whitelisted'), name))
databaseSuccess, databaseError = pcall(function()
if not QBCore.Functions.IsWhitelisted(src) then
deferrals.done(Lang:t('error.not_whitelisted'))
end
end)
end
if not databaseSuccess then
databasePromise:reject(databaseError)
end
databasePromise:resolve()
end)
-- wait for database to finish
databasePromise:next(function()
deferrals.update(string.format(Lang:t('info.join_server'), name))
deferrals.done()
end, function (databaseError)
deferrals.done(Lang:t('error.connecting_database_error'))
print('^1' .. databaseError)
end)
-- if conducting checks for too long then raise error
while databasePromise.state == 0 do
if os.clock() - databaseTime > 30 then
deferrals.done(Lang:t('error.connecting_database_timeout'))
error(Lang:t('error.connecting_database_timeout'))
break
end
Wait(1000)
end
-- Add any additional defferals you may need!
end
AddEventHandler('playerConnecting', onPlayerConnecting)
-- Open & Close Server (prevents players from joining)
RegisterNetEvent('QBCore:Server:CloseServer', function(reason)
local src = source
if QBCore.Functions.HasPermission(src, 'admin') then
reason = reason or 'No reason specified'
QBCore.Config.Server.Closed = true
QBCore.Config.Server.ClosedReason = reason
for k in pairs(QBCore.Players) do
if not QBCore.Functions.HasPermission(k, QBCore.Config.Server.WhitelistPermission) then
QBCore.Functions.Kick(k, reason, nil, nil)
end
end
else
QBCore.Functions.Kick(src, Lang:t("error.no_permission"), nil, nil)
end
end)
RegisterNetEvent('QBCore:Server:OpenServer', function()
local src = source
if QBCore.Functions.HasPermission(src, 'admin') then
QBCore.Config.Server.Closed = false
else
QBCore.Functions.Kick(src, Lang:t("error.no_permission"), nil, nil)
end
end)
-- Callback Events --
-- Client Callback
RegisterNetEvent('QBCore:Server:TriggerClientCallback', function(name, ...)
if QBCore.ClientCallbacks[name] then
QBCore.ClientCallbacks[name](...)
QBCore.ClientCallbacks[name] = nil
end
end)
-- Server Callback
RegisterNetEvent('QBCore:Server:TriggerCallback', function(name, ...)
local src = source
QBCore.Functions.TriggerCallback(name, src, function(...)
TriggerClientEvent('QBCore:Client:TriggerCallback', src, name, ...)
end, ...)
end)
-- Player
RegisterNetEvent('QBCore:UpdatePlayer', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local newHunger = Player.PlayerData.metadata['hunger'] - QBCore.Config.Player.HungerRate
local newThirst = Player.PlayerData.metadata['thirst'] - QBCore.Config.Player.ThirstRate
if newHunger <= 0 then
newHunger = 0
end
if newThirst <= 0 then
newThirst = 0
end
Player.Functions.SetMetaData('thirst', newThirst)
Player.Functions.SetMetaData('hunger', newHunger)
TriggerClientEvent('hud:client:UpdateNeeds', src, newHunger, newThirst)
Player.Functions.Save()
end)
RegisterNetEvent('QBCore:ToggleDuty', function()
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local playerId = source
local player = QBCore.Functions.GetPlayer(playerId)
local citizenid = player.PlayerData.citizenid
local query = 'SELECT * FROM duty_logs WHERE citizenid = ? AND end_time IS NULL'
if not Player then return end
if Player.PlayerData.job.onduty then
Player.Functions.SetJobDuty(false)
local query = 'SELECT * FROM duty_logs WHERE citizenid = ? AND end_time IS NULL'
exports.oxmysql:execute(query, {citizenid}, function(result)
if result[1] then
local endTime = os.time()
local duration = endTime - result[1].start_time
exports.oxmysql:execute('UPDATE duty_logs SET end_time = ?, duration = ? WHERE citizenid = ? AND end_time IS NULL', {endTime, duration, citizenid})
TriggerClientEvent('chat:addMessage', playerId, { args = { '^1Duty Logs', '^7You are now off duty.' } })
-- TriggerClientEvent('chat:addMessage', -1, { args = { '^1Duty Logs', citizenid..' Just Clocked out' } })
else
TriggerClientEvent('chat:addMessage', playerId, { args = { '^1Duty Logs', '^7You are not on duty.' } })
end
end)
TriggerClientEvent('QBCore:Notify', src, Lang:t('info.off_duty'))
else
Player.Functions.SetJobDuty(true)
local query = 'SELECT * FROM duty_logs WHERE citizenid = ? AND end_time IS NULL'
exports.oxmysql:execute(query, {citizenid}, function(result)
if result[1] then
local startTime = os.time()
exports.oxmysql:execute('UPDATE duty_logs SET start_time = ? WHERE citizenid = ?', {startTime, citizenid})
TriggerClientEvent('chat:addMessage', playerId, { args = { '^1Duty Logs', '^7You are already on duty.' } })
else
local startTime = os.time()
exports.oxmysql:execute('INSERT INTO duty_logs (start_time, citizenid) VALUES (?, ?)', {startTime, citizenid})
TriggerClientEvent('chat:addMessage', playerId, { args = { '^1Duty Logs', '^7You are now on duty.' } })
-- TriggerClientEvent('chat:addMessage', -1, { args = { '^1Duty Logs', citizenid..' Just Clocked In' } })
end
end)
TriggerClientEvent('QBCore:Notify', src, Lang:t('info.on_duty'))
end
TriggerEvent('QBCore:Server:SetDuty', src, Player.PlayerData.job.onduty)
TriggerClientEvent('QBCore:Client:SetDuty', src, Player.PlayerData.job.onduty)
end)
-- BaseEvents
-- Vehicles
RegisterServerEvent('baseevents:enteringVehicle', function(veh,seat,modelName)
local src = source
local data = {
vehicle = veh,
seat = seat,
name = modelName,
event = 'Entering'
}
TriggerClientEvent('QBCore:Client:VehicleInfo', src, data)
end)
RegisterServerEvent('baseevents:enteredVehicle', function(veh,seat,modelName)
local src = source
local data = {
vehicle = veh,
seat = seat,
name = modelName,
event = 'Entered'
}
TriggerClientEvent('QBCore:Client:VehicleInfo', src, data)
end)
RegisterServerEvent('baseevents:enteringAborted', function()
local src = source
TriggerClientEvent('QBCore:Client:AbortVehicleEntering', src)
end)
RegisterServerEvent('baseevents:leftVehicle', function(veh,seat,modelName)
local src = source
local data = {
vehicle = veh,
seat = seat,
name = modelName,
event = 'Left'
}
TriggerClientEvent('QBCore:Client:VehicleInfo', src, data)
end)
-- Items
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon.
RegisterNetEvent('QBCore:Server:UseItem', function(item)
print(string.format("%s triggered QBCore:Server:UseItem by ID %s with the following data. This event is deprecated due to exploitation, and will be removed soon. Check ps-inventory for the right use on this event.", GetInvokingResource(), source))
QBCore.Debug(item)
end)
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon. function(itemName, amount, slot)
RegisterNetEvent('QBCore:Server:RemoveItem', function(itemName, amount)
local src = source
print(string.format("%s triggered QBCore:Server:RemoveItem by ID %s for %s %s. This event is deprecated due to exploitation, and will be removed soon. Adjust your events accordingly to do this server side with player functions.", GetInvokingResource(), src, amount, itemName))
end)
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon. function(itemName, amount, slot, info)
RegisterNetEvent('QBCore:Server:AddItem', function(itemName, amount)
local src = source
print(string.format("%s triggered QBCore:Server:AddItem by ID %s for %s %s. This event is deprecated due to exploitation, and will be removed soon. Adjust your events accordingly to do this server side with player functions.", GetInvokingResource(), src, amount, itemName))
end)
-- Non-Chat Command Calling (ex: qb-adminmenu)
RegisterNetEvent('QBCore:CallCommand', function(command, args)
local src = source
if not QBCore.Commands.List[command] then return end
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local hasPerm = QBCore.Functions.HasPermission(src, "command."..QBCore.Commands.List[command].name)
if hasPerm then
if QBCore.Commands.List[command].argsrequired and #QBCore.Commands.List[command].arguments ~= 0 and not args[#QBCore.Commands.List[command].arguments] then
TriggerClientEvent('QBCore:Notify', src, Lang:t('error.missing_args2'), 'error')
else
QBCore.Commands.List[command].callback(src, args)
end
else
TriggerClientEvent('QBCore:Notify', src, Lang:t('error.no_access'), 'error')
end
end)
-- Use this for player vehicle spawning
-- Vehicle server-side spawning callback (netId)
-- use the netid on the client with the NetworkGetEntityFromNetworkId native
-- convert it to a vehicle via the NetToVeh native
QBCore.Functions.CreateCallback('QBCore:Server:SpawnVehicle', function(source, cb, model, coords, warp)
local ped = GetPlayerPed(source)
model = type(model) == 'string' and joaat(model) or model
if not coords then coords = GetEntityCoords(ped) end
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, coords.w, true, true)
while not DoesEntityExist(veh) do Wait(0) end
if warp then
while GetVehiclePedIsIn(ped) ~= veh do
Wait(0)
TaskWarpPedIntoVehicle(ped, veh, -1)
end
end
while NetworkGetEntityOwner(veh) ~= source do Wait(0) end
cb(NetworkGetNetworkIdFromEntity(veh))
end)
-- Use this for long distance vehicle spawning
-- vehicle server-side spawning callback (netId)
-- use the netid on the client with the NetworkGetEntityFromNetworkId native
-- convert it to a vehicle via the NetToVeh native
QBCore.Functions.CreateCallback('QBCore:Server:CreateVehicle', function(source, cb, model, coords, warp)
model = type(model) == 'string' and GetHashKey(model) or model
if not coords then coords = GetEntityCoords(GetPlayerPed(source)) end
local CreateAutomobile = GetHashKey("CREATE_AUTOMOBILE")
local veh = Citizen.InvokeNative(CreateAutomobile, model, coords, coords.w, true, true)
while not DoesEntityExist(veh) do Wait(0) end
if warp then TaskWarpPedIntoVehicle(GetPlayerPed(source), veh, -1) end
cb(NetworkGetNetworkIdFromEntity(veh))
end)
--QBCore.Functions.CreateCallback('QBCore:HasItem', function(source, cb, items, amount)
-- https://github.com/qbcore-framework/ps-inventory/blob/e4ef156d93dd1727234d388c3f25110c350b3bcf/server/main.lua#L2066
--end)