Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #8

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions client/main.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
RegisterNetEvent('esx_service:notifyAllInService')
AddEventHandler('esx_service:notifyAllInService', function(notification, target)
target = GetPlayerFromServerId(target)
if target == PlayerId() then return end
RegisterNetEvent("esx_service:notifyAllInService", function(notifyMessage, src)
local targetPed = GetPlayerPed(GetPlayerFromServerId(src))
local mugshot, mugshotStr = ESX.Game.GetPedMugshot(targetPed)

local targetPed = GetPlayerPed(target)
local mugshot, mugshotStr = ESX.Game.GetPedMugshot(targetPed)

ESX.ShowAdvancedNotification(notification.title, notification.subject, notification.msg, mugshotStr, notification.iconType)
UnregisterPedheadshot(mugshot)
end)
ESX.ShowAdvancedNotification(notifyMessage.title, notifyMessage.subject, notifyMessage.msg, mugshotStr, notifyMessage.iconType)
UnregisterPedheadshot(mugshot)
end)
4 changes: 2 additions & 2 deletions fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ game 'gta5'
lua54 'yes'
description 'A basic duty system for Jobs'

version '1.0'
legacyversion '1.9.1'
version '1.1'
legacyversion '1.11.1'

shared_script '@es_extended/imports.lua'

Expand Down
314 changes: 252 additions & 62 deletions server/main.lua
Original file line number Diff line number Diff line change
@@ -1,86 +1,276 @@
local InService = {}
local MaxInService = {}
---@class ServiceNotification
---@field title string
---@field subject string
---@field msg string
---@field iconType number

function GetInServiceCount(name)
local count = 0
---@param serviceNotification unknown
local function isServiceNotification(serviceNotification)
if type(serviceNotification) ~= "table" then
return false
end
if type(serviceNotification.title) ~= "string" then
return false
end
if type(serviceNotification.subject) ~= "string" then
return false
end
if type(serviceNotification.msg) ~= "string" then
return false
end
if type(serviceNotification.iconType) ~= "number" then
return false
end

for k,v in pairs(InService[name]) do
if v == true then
count = count + 1
end
end
return true
end

---@param src number
---@param onDuty boolean
---@param serviceName string
---@return nil
local function setPlayerJobDuty(src, onDuty, serviceName)
local xPlayer = ESX.GetPlayerFromId(src)
if not xPlayer then
return
end

local currentJob = xPlayer.getJob()

if currentJob.name ~= serviceName then
return
end

xPlayer.setJob(currentJob.name, currentJob.grade, onDuty)
end


---@class Service
---@field serviceName string
---@field maxPlayers number
---@field players table<number, boolean>
---@field new fun(self:Service, serviceName: string, maxPlayers: number): Service
---@field getPlayerCount fun(self:Service): number
---@field getPlayers fun(self:Service): table<number, boolean>
---@field addPlayer fun(self:Service, src: number, force:boolean): boolean
---@field removePlayer fun(self:Service, src: number): nil
---@field hasPlayer fun(self:Service, src: number): boolean
---@field notifyAll fun(self:Service, serviceNotification: ServiceNotification, src: number): nil
local Service = {}
Service.__index = Service

---@type table<string, Service>
local services = {}

function Service:new(serviceName, maxPlayers)
if services[serviceName] then
return services[serviceName]
end

local obj = setmetatable({}, self)
obj.serviceName = serviceName
obj.maxPlayers = maxPlayers
obj.players = {}
GlobalState[serviceName] = 0

return obj
end

function Service:getPlayerCount()
return ESX.Table.SizeOf(self.players)
end

function Service:getPlayers()
return self.players
end

function Service:addPlayer(src, force)
if self:hasPlayer(src) then
return true
end

local servicePlayerCount = self:getPlayerCount()
if not force then
if servicePlayerCount >= self.maxPlayers then
return false
end
end

self.players[src] = true
GlobalState[self.serviceName] = servicePlayerCount + 1
setPlayerJobDuty(src, true, self.serviceName)

return count
return true
end

RegisterServerEvent('esx_service:activateService')
AddEventHandler('esx_service:activateService', function(name, max)
InService[name] = {}
MaxInService[name] = max
GlobalState[name] = GetInServiceCount(name)
function Service:removePlayer(src)
if self:hasPlayer(src) then
self.players[src] = nil
GlobalState[self.serviceName] = self:getPlayerCount()
setPlayerJobDuty(src, false, self.serviceName)
end
end

function Service:hasPlayer(src)
return self.players[src] or false
end

function Service:notifyAll(serviceNotification, src)
local targets = {}
for targetSrc, _ in pairs(self.players) do
if src ~= targetSrc then
table.insert(targets, targetSrc)
end
end

ESX.TriggerClientEvent("esx_service:notifyAllInService", targets, serviceNotification, src)
end

---@param serviceName string
---@param maxPlayers number
AddEventHandler("esx_service:activateService", function(serviceName, maxPlayers)
if type(serviceName) ~= "string" then
print(("[^3WARNING^7] Attempted To Activate Service With Invalid Name - ^5%s^7"):format(serviceName))
return
end
if services[serviceName] then
print(("[^3WARNING^7] Attempted To Activate Service That Is Already Active - ^5%s^7"):format(serviceName))
return
end
if type(maxPlayers) ~= "number" or maxPlayers <= 0 then
print(("[^3WARNING^7] Attempted To Activate Service With Invalid Max Players - ^5%s^7"):format(maxPlayers))
return
end

services[serviceName] = Service:new(serviceName, maxPlayers)
end)

RegisterServerEvent('esx_service:disableService')
AddEventHandler('esx_service:disableService', function(name)
InService[name][source] = nil
GlobalState[name] = GetInServiceCount(name)
---@param src number
---@param cb function
---@param serviceName string
ESX.RegisterServerCallback("esx_service:enableService", function(src, cb, serviceName)
local service = services[serviceName]
if not service then
print(("[^3WARNING^7] Attempted To Use Inactive Service - ^5%s^7"):format(serviceName))
return
end

local servicePlayerCount = service:getPlayerCount()
local success = service:addPlayer(src, false)

cb(success, service.maxPlayers, servicePlayerCount)
end)

RegisterServerEvent('esx_service:notifyAllInService')
AddEventHandler('esx_service:notifyAllInService', function(notification, name)
for k,v in pairs(InService[name]) do
if v == true then
TriggerClientEvent('esx_service:notifyAllInService', k, notification, source)
end
end
---@param serviceName string
RegisterNetEvent("esx_service:disableService", function(serviceName)
---@type number
local src <const> = source

local service = services[serviceName]
if not service then
print(("[^3WARNING^7] Attempted To Use Inactive Service - ^5%s^7"):format(serviceName))
return
end

service:removePlayer(src)
end)

ESX.RegisterServerCallback('esx_service:enableService', function(source, cb, name)
local inServiceCount = GetInServiceCount(name)

if inServiceCount >= MaxInService[name] then
cb(false, MaxInService[name], inServiceCount)
else
InService[name][source] = true
GlobalState[name] = GetInServiceCount(name)
cb(true, MaxInService[name], inServiceCount)
end
---@param src number
---@param cb function
---@param serviceName string
ESX.RegisterServerCallback("esx_service:isInService", function(src, cb, serviceName)
local service = services[serviceName]
if not service then
print(("[^3WARNING^7] Attempted To Use Inactive Service - ^5%s^7"):format(serviceName))
return
end

cb(service:hasPlayer(src))
end)

ESX.RegisterServerCallback('esx_service:isInService', function(source, cb, name)
local isInService = false
---@param src number
---@param cb function
---@param serviceName string
---@param targetSrc number
ESX.RegisterServerCallback("esx_service:isPlayerInService", function(src, cb, serviceName, targetSrc)
if type(targetSrc) ~= "number" then
print(("[^3WARNING^7] Attempted To Get Service With Invalid Target Source - ^5%s^7"):format(targetSrc))
return
end

local service = services[serviceName]
if not service then
print(("[^3WARNING^7] Attempted To Use Inactive Service - ^5%s^7"):format(serviceName))
return
end

cb(service:hasPlayer(targetSrc))
end)

if InService[name] ~= nil then
if InService[name][source] then
isInService = true
end
else
print(('[^3WARNING^7] Attempted To Use Inactive Service - ^5%s^7'):format(name))
end
---@param src number
---@param cb function
---@param serviceName string
ESX.RegisterServerCallback("esx_service:getInServiceList", function(src, cb, serviceName)
local service = services[serviceName]
if not service then
print(("[^3WARNING^7] Attempted To Use Inactive Service - ^5%s^7"):format(serviceName))
return
end

cb(isInService)
cb(service:getPlayers())
end)

ESX.RegisterServerCallback('esx_service:isPlayerInService', function(source, cb, name, target)
local isPlayerInService = false
local targetXPlayer = ESX.GetPlayerFromId(target)
---@param serviceNotification ServiceNotification
---@param serviceName string
---@param src number
AddEventHandler("esx_service:notifyAllInService", function(serviceNotification, serviceName, src)
if not isServiceNotification(serviceNotification) then
print(("[^3WARNING^7] Attempted To Notify Service With Invalid Notification - ^5%s^7"):format(json.encode(serviceNotification)))
return
end

if InService[name][targetXPlayer.source] then
isPlayerInService = true
end
local service = services[serviceName]
if not service then
print(("[^3WARNING^7] Attempted To Use Inactive Service - ^5%s^7"):format(serviceName))
return
end

cb(isPlayerInService)
service:notifyAll(serviceNotification, src)
end)

ESX.RegisterServerCallback('esx_service:getInServiceList', function(source, cb, name)
cb(InService[name])
---@param src number
---@param reason string
AddEventHandler("esx:playerDropped", function(src, reason)
for _, service in pairs(services) do
if service:hasPlayer(src) then
service:removePlayer(src)
end
end
end)

AddEventHandler('esx:playerDropped', function(playerId, reason)
for k,v in pairs(InService) do
if v[playerId] == true then
v[playerId] = nil
GlobalState[k] = GetInServiceCount(k)
end
end
---@param src number
---@param job table
---@param lastJob table
AddEventHandler("esx:setJob", function(src, job, lastJob)
local lastJobService = services[lastJob.name]
if lastJobService and lastJob.onDuty then
lastJobService:removePlayer(src)
end

local currentJobService = services[job.name]
if currentJobService and job.onDuty then
currentJobService:addPlayer(src, true)
end
end)

---@param src number
---@param xPlayer table
---@param isNew boolean
AddEventHandler("esx:playerLoaded", function(src, xPlayer, isNew)
local playerJob = xPlayer.getJob()
local jobService = services[playerJob.name]

if jobService and playerJob.onDuty then
jobService:addPlayer(src, true)
end
end)