453 lines
15 KiB
Lua
453 lines
15 KiB
Lua
|
ESX = exports["es_extended"]:getSharedObject()
|
||
|
playerCache = {}
|
||
|
|
||
|
function GetPlayerFromCache(source)
|
||
|
if playerCache[tonumber(source)] == nil then
|
||
|
playerCache[tonumber(source)] = ESX.GetPlayerFromId(source)
|
||
|
end
|
||
|
return playerCache[tonumber(source)]
|
||
|
end
|
||
|
|
||
|
LR = {}
|
||
|
LR.__index = LR
|
||
|
local playerInZone = {}
|
||
|
local os_time = os.time
|
||
|
local coroutine_yield = coroutine.yield
|
||
|
function LR:Init()
|
||
|
local o = {}
|
||
|
setmetatable(o, LR)
|
||
|
o.LastCapture = 0
|
||
|
o.Zones = Config.Occ
|
||
|
o.ZoneData = {}
|
||
|
o.CurrentCapture = {}
|
||
|
o.IsOpen = false
|
||
|
GlobalState.LastCapture = 0
|
||
|
GlobalState.CurrentCapture = {}
|
||
|
GlobalState.Occ = o.Zones
|
||
|
o.OnDev = false
|
||
|
o.PressedPLayer = {}
|
||
|
o:EventHandler()
|
||
|
o:DelayThread()
|
||
|
o:SQL()
|
||
|
GlobalState.ostime = 0
|
||
|
GlobalState.GangBlips = {
|
||
|
['HM'] = {
|
||
|
sprite = 16,
|
||
|
color = 1
|
||
|
},
|
||
|
['LORD'] = {
|
||
|
sprite = 77,
|
||
|
color = 1
|
||
|
},
|
||
|
['HLG'] = {
|
||
|
sprite = 355,
|
||
|
color = 1
|
||
|
},
|
||
|
['ALS'] = {
|
||
|
sprite = 76,
|
||
|
color = 1
|
||
|
},
|
||
|
['AOE'] = {
|
||
|
sprite = 78,
|
||
|
color = 1
|
||
|
},
|
||
|
['GC'] = {
|
||
|
sprite = 80,
|
||
|
color = 1
|
||
|
},
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
GlobalState.OccOpen = o.IsOpen
|
||
|
return o
|
||
|
end
|
||
|
|
||
|
function LR:SQL()
|
||
|
MySQL.ready(function()
|
||
|
for k, v in pairs(self.Zones) do
|
||
|
local data = MySQL.Sync.fetchAll("SELECT * FROM occ_data WHERE `index` = @index", { ['@index'] = k })
|
||
|
if data[1] then
|
||
|
v.owner = data[1].owner
|
||
|
else
|
||
|
MySQL.Sync.execute("INSERT INTO occ_data (`index`, owner) VALUE (@index, @owner)",
|
||
|
{ ['@index'] = k, ['@owner'] = v.owner })
|
||
|
end
|
||
|
self.ZoneData[k] = {}
|
||
|
end
|
||
|
GlobalState.Occ = self.Zones
|
||
|
GlobalState.ZoneData = self.ZoneData
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function LR:DelayThread()
|
||
|
--GlobalState.OccDelay = 0
|
||
|
-- Citizen.CreateThread(function()
|
||
|
-- while true do
|
||
|
-- Wait(1000)
|
||
|
-- local d = os_time() - self.LastCapture
|
||
|
-- GlobalState.ostime = os_time()
|
||
|
-- end
|
||
|
-- end)
|
||
|
|
||
|
Citizen.CreateThread(function()
|
||
|
while true do
|
||
|
Wait(10 * 60 * 1000)
|
||
|
for k, v in pairs(self.Zones) do
|
||
|
if v.owner then
|
||
|
-- MySQL.Async.execute('UPDATE dh_rank SET scores = scores + @point WHERE name = @name', {
|
||
|
-- ['@name'] = v.owner,
|
||
|
-- ['@point'] = 5
|
||
|
-- })
|
||
|
|
||
|
MySQL.Async.execute('UPDATE jobs SET point = point + @point WHERE name = @name', {
|
||
|
['@name'] = v.owner,
|
||
|
['@point'] = 5
|
||
|
})
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function LR:EventHandler()
|
||
|
AddEventHandler("playerDropped", function(reason)
|
||
|
if playerCache[tonumber(source)] then
|
||
|
if playerInZone[source] then
|
||
|
local org = playerCache[tonumber(source)].job.name
|
||
|
for k, v in pairs(self.ZoneData) do
|
||
|
if v[org] then
|
||
|
v[org] = v[org] - 1
|
||
|
if v[org] == 0 then
|
||
|
v[org] = nil
|
||
|
end
|
||
|
GlobalState.ZoneData = self.ZoneData
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
playerInZone[source] = nil
|
||
|
end
|
||
|
playerCache[tonumber(source)] = nil
|
||
|
end
|
||
|
end)
|
||
|
AddEventHandler("esx:setJob", function(playerId, _org, lastorg)
|
||
|
if playerInZone[playerId] then
|
||
|
local org = lastorg.name
|
||
|
local neworg = _org.name
|
||
|
for k, v in pairs(self.ZoneData) do
|
||
|
if v[org] then
|
||
|
v[org] = v[org] - 1
|
||
|
if v[org] == 0 then
|
||
|
v[org] = nil
|
||
|
end
|
||
|
if v[neworg] then
|
||
|
v[neworg] = v[neworg] + 1
|
||
|
else
|
||
|
v[neworg] = 1
|
||
|
end
|
||
|
GlobalState.ZoneData = self.ZoneData
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
RegisterNetEvent("lr_occ2:server:join", function(index)
|
||
|
local src = source
|
||
|
print(src)
|
||
|
print(src)
|
||
|
local xPlayer = GetPlayerFromCache(source)
|
||
|
local org = xPlayer.job.name
|
||
|
if self.ZoneData[index][org] then
|
||
|
if self.ZoneData[index][org] == 30 then --so nguoi chiem dong
|
||
|
SetEntityCoords(GetPlayerPed(source), 236.00483703613, -876.13092041016, 30.031923294067, false, false,
|
||
|
false, false)
|
||
|
TriggerClientEvent("esx:showNotification", source, "Vượt quá số người cho phép")
|
||
|
else
|
||
|
playerInZone[source] = true
|
||
|
-- SetPlayerRoutingBucket(src, 10)
|
||
|
self.ZoneData[index][org] = self.ZoneData[index][org] + 1
|
||
|
end
|
||
|
else
|
||
|
playerInZone[source] = true
|
||
|
self.ZoneData[index][org] = 1
|
||
|
end
|
||
|
GlobalState.ZoneData = self.ZoneData
|
||
|
end)
|
||
|
RegisterNetEvent("lr_occ2:server:leave", function(index)
|
||
|
local src = source
|
||
|
-- print(src)
|
||
|
-- print(src)
|
||
|
local xPlayer = GetPlayerFromCache(source)
|
||
|
local org = xPlayer.job.name
|
||
|
if self.ZoneData[index][org] and playerInZone[source] then
|
||
|
self.ZoneData[index][org] = self.ZoneData[index][org] - 1
|
||
|
if self.ZoneData[index][org] == 0 then
|
||
|
self.ZoneData[index][org] = nil
|
||
|
end
|
||
|
GlobalState.ZoneData = self.ZoneData
|
||
|
playerInZone[source] = nil
|
||
|
-- SetPlayerRoutingBucket(src, 0)
|
||
|
end
|
||
|
end)
|
||
|
ESX.RegisterServerCallback('lr_occ2:callback:cC', function(source, cb, index)
|
||
|
if self.IsOpen then
|
||
|
if os_time() - self.LastCapture >= Config.Delay then
|
||
|
local crZone = self.Zones[index]
|
||
|
if crZone.lastCapture == nil or os_time() - crZone.lastCapture >= Config.DelayPoint then
|
||
|
if self.CurrentCapture[index] == nil then
|
||
|
if getLenght(self.CurrentCapture) < 1 then
|
||
|
local xPlayer = ESX.GetPlayerFromId(source)
|
||
|
if not self.PressedPLayer[xPlayer.identifier] then
|
||
|
if crZone.owner and crZone.owner == xPlayer.job.name then
|
||
|
self:TriggerClientEvent(source, ("Khu vực này đã thuộc về bạn"))
|
||
|
cb(false)
|
||
|
return
|
||
|
end
|
||
|
cb(true)
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Hiện có khu vực đang bị chiếm nên không thể chiếm khu vực này"))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Hiện có khu vực đang bị chiếm nên không thể chiếm khu vực này"))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Khu vực %s đang bị chiếm bởi %s"):format(crZone.Label, self.CurrentCapture[index].name))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Cần %s giây để có thể chiếm khu vực %s"):format(
|
||
|
Config.Delay - (os_time() - crZone.lastCapture), crZone.Label))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Cần %s giây để có thể chiếm"):format(Config.Delay - (os_time() - self.LastCapture)))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source, "Chưa đến thời gian chiếm đóng")
|
||
|
end
|
||
|
end)
|
||
|
ESX.RegisterServerCallback("lr_occ2:callback:CanCapture", function(source, cb, index, moves)
|
||
|
local xPlayer = ESX.GetPlayerFromId(source)
|
||
|
if self.OnDev then
|
||
|
if xPlayer.group ~= 'superadmin' then
|
||
|
cb(false)
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
if self.IsOpen then
|
||
|
print(os_time() - self.LastCapture)
|
||
|
if os_time() - self.LastCapture >= Config.Delay then
|
||
|
local crZone = self.Zones[index]
|
||
|
if crZone.lastCapture == nil or os_time() - crZone.lastCapture >= Config.DelayPoint then
|
||
|
if self.CurrentCapture[index] == nil then
|
||
|
if getLenght(self.CurrentCapture) < 1 then
|
||
|
local xPlayer = ESX.GetPlayerFromId(source)
|
||
|
if not self.PressedPLayer[xPlayer.identifier] then
|
||
|
if crZone.owner and crZone.owner == xPlayer.job.name then
|
||
|
self:TriggerClientEvent(source, ("Khu vực này đã thuộc về bạn"))
|
||
|
cb(false)
|
||
|
return
|
||
|
end
|
||
|
if not Config.ExceptJobs[xPlayer.job.name] then
|
||
|
self:TriggerClientEvent(source, ("Tổ chức của bạn không có quyền chiếm đóng"))
|
||
|
return
|
||
|
end
|
||
|
--self.PressedPLayer[xPlayer.identifier] = true
|
||
|
self.CurrentCapture[index] = {
|
||
|
name = xPlayer.name,
|
||
|
playerId = source,
|
||
|
startAt = os_time()
|
||
|
}
|
||
|
--self.LastCapture = os_time()
|
||
|
crZone.lastCapture = os_time()
|
||
|
GlobalState.Occ = self.Zones
|
||
|
GlobalState.CurrentCapture = self.CurrentCapture
|
||
|
GlobalState.LastCapture = os_time() - 480
|
||
|
TriggerClientEvent("lr_occ2:client:startCapture", -1, index, "[" .. xPlayer.job.name .. "] " .. xPlayer
|
||
|
.name)
|
||
|
self.crC = index
|
||
|
cb(true)
|
||
|
Citizen.CreateThread(function()
|
||
|
local time = crZone.time + os_time()
|
||
|
while true do
|
||
|
coroutine_yield(0)
|
||
|
if self.CurrentCapture[index] ~= nil then
|
||
|
Wait(1000)
|
||
|
if time <= os_time() then
|
||
|
if crZone.owner == nil then
|
||
|
|
||
|
else
|
||
|
self:RemovePoint(crZone.owner, crZone.point)
|
||
|
end
|
||
|
crZone.owner = xPlayer.job.name
|
||
|
crZone.lastCapture = os_time()
|
||
|
self.LastCapture = os_time()
|
||
|
self.CurrentCapture[index] = nil
|
||
|
GlobalState.Occ = self.Zones
|
||
|
GlobalState.CurrentCapture = self.CurrentCapture
|
||
|
GlobalState.LastCapture = os_time()
|
||
|
TriggerClientEvent("lr_occ:client:captured", -1, index, xPlayer.name,
|
||
|
xPlayer.job.name)
|
||
|
self:AddPoint(xPlayer.job.name, crZone.point, index)
|
||
|
break
|
||
|
end
|
||
|
else
|
||
|
self.CurrentCapture[index] = nil
|
||
|
GlobalState.CurrentCapture = self.CurrentCapture
|
||
|
print("Canceled")
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Hiện có khu vực đang bị chiếm nên không thể chiếm khu vực này"))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Hiện có khu vực đang bị chiếm nên không thể chiếm khu vực này"))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Khu vực %s đang bị chiếm bởi %s"):format(crZone.Label, self.CurrentCapture[index].name))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Cần %s giây để có thể chiếm khu vực %s"):format(
|
||
|
Config.Delay - (os_time() - crZone.lastCapture), crZone.Label))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source,
|
||
|
("Cần %s giây để có thể chiếm"):format(Config.Delay - (os_time() - self.LastCapture)))
|
||
|
end
|
||
|
else
|
||
|
cb(false)
|
||
|
self:TriggerClientEvent(source, "Chưa đến thời gian chiếm đóng")
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterCommand("chiemdong", function(source, args, rawCommand)
|
||
|
if self.IsOpen then
|
||
|
TriggerClientEvent("hm_hud:client:addCD", -1, 5 * 10, 'chiếm đóng', 'Kết thúc sau', 'warning',
|
||
|
'fas fa-skull-crossbones')
|
||
|
else
|
||
|
TriggerClientEvent("hm_hud:client:addCD", -1, 5 * 10, 'chiếm đóng', 'Bắt đầu sau', 'warning',
|
||
|
'fas fa-skull-crossbones')
|
||
|
end
|
||
|
Wait(10 * 1000)
|
||
|
self.IsOpen = not self.IsOpen
|
||
|
GlobalState.OccOpen = self.IsOpen
|
||
|
TriggerClientEvent("lr_occ2:client:openOcc", -1, self.IsOpen)
|
||
|
end, true)
|
||
|
|
||
|
-- RegisterCommand("vaochiemdong", function(source, args, rawCommand)
|
||
|
-- if self.IsOpen then
|
||
|
-- SetPlayerRoutingBucket(source, 10)
|
||
|
-- end
|
||
|
-- end, false)
|
||
|
|
||
|
RegisterCommand("thoatchiemdong", function(source, args, rawCommand)
|
||
|
SetPlayerRoutingBucket(source, 0)
|
||
|
end, false)
|
||
|
|
||
|
AddEventHandler("esx:playerDropped", function(playerId)
|
||
|
for k, v in pairs(self.CurrentCapture) do
|
||
|
if v.playerId == playerId then
|
||
|
self.CurrentCapture[k] = nil
|
||
|
self.LastCapture = os_time() - 480
|
||
|
--self.Zones[k].lastCapture = os_time()
|
||
|
TriggerClientEvent("lr_occ:client:cancelCapture", -1, k, "")
|
||
|
GlobalState.LastCapture = os_time() - 480
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent("lr_occ2:server:cancelCapture", function()
|
||
|
for k, v in pairs(self.CurrentCapture) do
|
||
|
if v.playerId == source then
|
||
|
local xPlayer = ESX.GetPlayerFromId(source)
|
||
|
self.LastCapture = os_time() - 480
|
||
|
GlobalState.LastCapture = os_time() - 480
|
||
|
self.CurrentCapture[k] = nil
|
||
|
--self.LastCapture = os_time()
|
||
|
self.Zones[k].lastCapture = os_time() - 1200
|
||
|
GlobalState.Occ = self.Zones
|
||
|
TriggerClientEvent("lr_occ:client:cancelCapture", -1, k, "[" .. xPlayer.job.name .. "] " .. xPlayer.name)
|
||
|
return
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
--[[RegisterNetEvent("lr_occ:server:addPoint", function(gang, point)
|
||
|
local data = MySQL.Sync.fetchAll("SELECT * FROM dh_rank WHERE `name` = @name", {['@name'] = gang})
|
||
|
if data[1] then
|
||
|
MySQL.Async.execute('UPDATE dh_rank SET scores = scores + @scores WHERE name = @name', {
|
||
|
['@name'] = gang,
|
||
|
['@scores'] = tonumber(point)
|
||
|
})
|
||
|
end
|
||
|
end)--]]
|
||
|
|
||
|
RegisterCommand("occdev", function(source, args, rawCommand)
|
||
|
self.OnDev = not self.OnDev
|
||
|
end)
|
||
|
lib.callback.register("lr_occ2:callback:getCurCapture", function(source)
|
||
|
return self.crC
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function LR:TriggerClientEvent(playerId, msg)
|
||
|
TriggerClientEvent("esx:showNotification", playerId, msg)
|
||
|
end
|
||
|
|
||
|
function LR:AddPoint(orgName, point, index)
|
||
|
MySQL.Async.execute('UPDATE jobs SET point = point + @point WHERE name = @name', {
|
||
|
['@name'] = orgName,
|
||
|
['@point'] = point
|
||
|
})
|
||
|
--[[MySQL.Async.execute('UPDATE dh_rank SET scores = scores + @point WHERE name = @name', {
|
||
|
['@name'] = orgName,
|
||
|
['@point'] = point
|
||
|
})--]]
|
||
|
MySQL.Async.execute("UPDATE occ_data SET owner = @owner WHERE `index` = @index", {
|
||
|
['@owner'] = orgName,
|
||
|
['@index'] = index
|
||
|
})
|
||
|
end
|
||
|
|
||
|
function LR:RemovePoint(orgName, point)
|
||
|
MySQL.Async.execute('UPDATE jobs SET point = point - @point WHERE name = @name', {
|
||
|
['@name'] = orgName,
|
||
|
['@point'] = point
|
||
|
})
|
||
|
--[[MySQL.Async.execute('UPDATE dh_rank SET scores = scores - @point WHERE name = @name', {
|
||
|
['@name'] = orgName,
|
||
|
['@point'] = point
|
||
|
})--]]
|
||
|
end
|
||
|
|
||
|
function getLenght(tb)
|
||
|
local c = 0
|
||
|
for k, v in pairs(tb) do
|
||
|
c = c + 1
|
||
|
end
|
||
|
return c
|
||
|
end
|
||
|
|
||
|
LR:Init()
|