ed
This commit is contained in:
parent
19fb68f805
commit
01d047b3cc
53 changed files with 3222 additions and 5 deletions
136
resources/[housing]/ox_doorlock/server/convert.lua
Normal file
136
resources/[housing]/ox_doorlock/server/convert.lua
Normal file
|
@ -0,0 +1,136 @@
|
|||
---@diagnostic disable: inject-field
|
||||
---@type table?
|
||||
Config.DoorList = {}
|
||||
|
||||
local utils = require 'server.utils'
|
||||
|
||||
local function flattenTableToArray(tbl)
|
||||
if type(tbl) == 'table' then
|
||||
if table.type(tbl) == 'array' then return tbl end
|
||||
|
||||
local array = {}
|
||||
|
||||
for k in pairs(tbl) do
|
||||
array[#array + 1] = k
|
||||
end
|
||||
|
||||
return array
|
||||
end
|
||||
end
|
||||
|
||||
MySQL.ready(function()
|
||||
local files, fileCount = utils.getFilesInDirectory('convert', '%.lua')
|
||||
|
||||
if fileCount > 0 then
|
||||
print(('^3Found %d nui_doorlock config files.^0'):format(fileCount))
|
||||
end
|
||||
|
||||
local query =
|
||||
'INSERT INTO `ox_doorlock` (`name`, `data`) SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM `ox_doorlock` WHERE `name` = ?)'
|
||||
local queries = {}
|
||||
|
||||
for i = 1, fileCount do
|
||||
local fileName = files[i]
|
||||
local file = LoadResourceFile('ox_doorlock', ('convert/%s.lua'):format(fileName))
|
||||
|
||||
if file then
|
||||
load(file)()
|
||||
|
||||
if next(Config.DoorList) then
|
||||
local size = 0
|
||||
|
||||
for k, door in pairs(Config.DoorList) do
|
||||
size += 1
|
||||
local double = door.doors
|
||||
local qb = door.objName or (double and double[1].objName)
|
||||
|
||||
if qb then
|
||||
if double then
|
||||
for j = 1, 2 do
|
||||
double[j].objHash = double[j].objName
|
||||
double[j].objHeading = double[j].objYaw or 0
|
||||
end
|
||||
else
|
||||
door.objHash = door.objName
|
||||
door.objHeading = door.objYaw or 0
|
||||
end
|
||||
|
||||
local groups = door.authorizedJobs or {}
|
||||
|
||||
if door.authorizedGangs then
|
||||
for gang, grade in pairs(door.authorizedGangs) do
|
||||
groups[gang] = grade
|
||||
end
|
||||
end
|
||||
|
||||
door.authorizedJobs = next(groups) and groups
|
||||
door.lockpick = door.pickable
|
||||
door.showNUI = not door.hideLabel
|
||||
door.characters = flattenTableToArray(door.authorizedCitizenIDs)
|
||||
end
|
||||
|
||||
local data = {
|
||||
auto = door.slides or door.garage or door.sliding or door.doublesliding,
|
||||
autolock = (door.autolock and door.autolock / 1000) or (door.autoLock and door.autoLock / 1000),
|
||||
coords = door.objCoords,
|
||||
heading = door.objHeading and math.floor(door.objHeading + 0.5),
|
||||
model = door.objHash,
|
||||
characters = door.characters,
|
||||
groups = door.authorizedJobs,
|
||||
items = door.items,
|
||||
lockpick = door.lockpick,
|
||||
hideUi = door.showNUI ~= nil and not door.showNUI or false,
|
||||
lockSound = door.audioLock?.file and door.audioLock.file:gsub('%.ogg', ''),
|
||||
unlockSound = door.audioUnlock?.file and door.audioUnlock.file:gsub('%.ogg', ''),
|
||||
maxDistance = door.maxDistance or door.distance,
|
||||
doorRate = door.doorRate and door.doorRate + 0.0 or nil,
|
||||
state = door.locked and 1 or 0,
|
||||
passcode = door.passcode,
|
||||
doors = double and {
|
||||
{
|
||||
coords = double[1].objCoords,
|
||||
heading = math.floor(double[1].objHeading + 0.5),
|
||||
model = double[1].objHash,
|
||||
},
|
||||
{
|
||||
coords = double[2].objCoords,
|
||||
heading = math.floor(double[2].objHeading + 0.5),
|
||||
model = double[2].objHash,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if data.auto and not data.lockSound then
|
||||
if door.audioRemote then
|
||||
data.lockSound = 'button-remote'
|
||||
end
|
||||
end
|
||||
|
||||
if double and not data.coords then
|
||||
double = data.doors
|
||||
data.coords = double[1].coords - ((double[1].coords - double[2].coords) / 2)
|
||||
end
|
||||
|
||||
local name = ('%s %s'):format(fileName, k)
|
||||
|
||||
queries[size] = {
|
||||
query = query, values = { name, json.encode(data), name }
|
||||
}
|
||||
end
|
||||
|
||||
print(('^3Loaded %d doors from convert/%s.lua.^0'):format(size, fileName))
|
||||
|
||||
if MySQL.transaction.await(queries) then
|
||||
SaveResourceFile('ox_doorlock', ('convert/%s.lua'):format(fileName),
|
||||
'-- This file has already been converted for ox_doorlock and should be removed.\r\ndo return end\r\n\r\n' ..
|
||||
file, -1)
|
||||
end
|
||||
|
||||
table.wipe(Config.DoorList)
|
||||
table.wipe(queries)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Config.DoorList = nil
|
||||
end)
|
|
@ -0,0 +1,65 @@
|
|||
local resourceName = 'es_extended'
|
||||
|
||||
SetTimeout(0, function()
|
||||
local ESX = exports[resourceName]:getSharedObject()
|
||||
|
||||
GetPlayer = ESX.GetPlayerFromId
|
||||
|
||||
if not ESX.GetConfig().OxInventory then
|
||||
function RemoveItem(playerId, item)
|
||||
local player = GetPlayer(playerId)
|
||||
|
||||
if player then player.removeInventoryItem(item, 1) end
|
||||
end
|
||||
|
||||
---@param player table
|
||||
---@param items string[] | { name: string, remove?: boolean, metadata?: string }[]
|
||||
---@param removeItem? boolean
|
||||
---@return string?
|
||||
function DoesPlayerHaveItem(player, items, removeItem)
|
||||
for i = 1, #items do
|
||||
local item = items[i]
|
||||
local itemName = item.name or item
|
||||
local data = player.getInventoryItem(itemName)
|
||||
|
||||
if data?.count > 0 then
|
||||
if removeItem or item.remove then
|
||||
player.removeInventoryItem(itemName, 1)
|
||||
end
|
||||
|
||||
return itemName
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function GetCharacterId(player)
|
||||
return player.identifier
|
||||
end
|
||||
|
||||
function IsPlayerInGroup(player, filter)
|
||||
local type = type(filter)
|
||||
|
||||
if type == 'string' then
|
||||
if player.job.name == filter then
|
||||
return player.job.name, player.job.grade
|
||||
end
|
||||
else
|
||||
local tabletype = table.type(filter)
|
||||
|
||||
if tabletype == 'hash' then
|
||||
local grade = filter[player.job.name]
|
||||
|
||||
if grade and grade <= player.job.grade then
|
||||
return player.job.name, player.job.grade
|
||||
end
|
||||
elseif tabletype == 'array' then
|
||||
for i = 1, #filter do
|
||||
if player.job.name == filter[i] then
|
||||
return player.job.name, player.job.grade
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
36
resources/[housing]/ox_doorlock/server/framework/nd_core.lua
Normal file
36
resources/[housing]/ox_doorlock/server/framework/nd_core.lua
Normal file
|
@ -0,0 +1,36 @@
|
|||
local resourceName = 'ND_Core'
|
||||
local NDCore = exports[resourceName]
|
||||
|
||||
function GetPlayer(src)
|
||||
return NDCore:getPlayer(src)
|
||||
end
|
||||
|
||||
function GetCharacterId(player)
|
||||
return player.id
|
||||
end
|
||||
|
||||
function IsPlayerInGroup(player, groups)
|
||||
local type = type(groups)
|
||||
|
||||
if type == "string" then
|
||||
return player.getGroup(groups)
|
||||
end
|
||||
|
||||
if table.type(groups) == "array" then
|
||||
for i = 1, #groups do
|
||||
local groupName = groups[i]
|
||||
local groupInfo = player.getGroup(groupName)
|
||||
if groupInfo then
|
||||
return groupName, groupInfo.rank
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
for groupName, grade in pairs(groups) do
|
||||
local groupInfo = player.getGroup(groupName)
|
||||
if groupInfo and grade and grade <= groupInfo.rank then
|
||||
return groupName, groupInfo.rank
|
||||
end
|
||||
end
|
||||
end
|
16
resources/[housing]/ox_doorlock/server/framework/ox_core.lua
Normal file
16
resources/[housing]/ox_doorlock/server/framework/ox_core.lua
Normal file
|
@ -0,0 +1,16 @@
|
|||
if not lib.checkDependency('ox_core', '0.21.3', true) then return end
|
||||
|
||||
local Ox = require '@ox_core.lib.init' --[[@as OxServer]]
|
||||
|
||||
GetPlayer = Ox.GetPlayer
|
||||
|
||||
---@param player OxPlayerServer
|
||||
function GetCharacterId(player)
|
||||
return player.charId
|
||||
end
|
||||
|
||||
---@param player OxPlayerServer
|
||||
---@param groups string | string[] | table<string, number>
|
||||
function IsPlayerInGroup(player, groups)
|
||||
return player.getGroup(groups)
|
||||
end
|
97
resources/[housing]/ox_doorlock/server/framework/qb-core.lua
Normal file
97
resources/[housing]/ox_doorlock/server/framework/qb-core.lua
Normal file
|
@ -0,0 +1,97 @@
|
|||
local resourceName = 'qb-core'
|
||||
|
||||
SetTimeout(0, function()
|
||||
local QB = exports[resourceName]:GetCoreObject()
|
||||
|
||||
GetPlayer = QB.Functions.GetPlayer
|
||||
|
||||
if GetResourceState('ox_inventory') == 'missing' then
|
||||
function RemoveItem(playerId, item, slot)
|
||||
local player = GetPlayer(playerId)
|
||||
|
||||
if player then player.Functions.RemoveItem(item, 1, slot) end
|
||||
end
|
||||
|
||||
---@param player table
|
||||
---@param items string[] | { name: string, remove?: boolean, metadata?: string }[]
|
||||
---@param removeItem? boolean
|
||||
---@return string?
|
||||
function DoesPlayerHaveItem(player, items, removeItem)
|
||||
for i = 1, #items do
|
||||
local item = items[i]
|
||||
local itemName = item.name or item
|
||||
|
||||
if item.metadata then
|
||||
local playerItems = player.Functions.GetItemsByName(itemName)
|
||||
|
||||
for j = 1, #playerItems do
|
||||
local data = playerItems[j]
|
||||
|
||||
if data.info.type == item.metadata then
|
||||
if removeItem or item.remove then
|
||||
player.Functions.RemoveItem(itemName, 1, data.slot)
|
||||
end
|
||||
|
||||
return itemName
|
||||
end
|
||||
end
|
||||
else
|
||||
local data = player.Functions.GetItemByName(itemName)
|
||||
|
||||
if data then
|
||||
if item.remove then
|
||||
player.Functions.RemoveItem(itemName, 1, data.slot)
|
||||
end
|
||||
|
||||
return itemName
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function GetCharacterId(player)
|
||||
return player.PlayerData.citizenid
|
||||
end
|
||||
|
||||
local groups = { 'job', 'gang' }
|
||||
|
||||
function IsPlayerInGroup(player, filter)
|
||||
local type = type(filter)
|
||||
|
||||
if type == 'string' then
|
||||
for i = 1, #groups do
|
||||
local data = player.PlayerData[groups[i]]
|
||||
|
||||
if data.name == filter then
|
||||
return data.name, data.grade.level
|
||||
end
|
||||
end
|
||||
else
|
||||
local tabletype = table.type(filter)
|
||||
|
||||
if tabletype == 'hash' then
|
||||
for i = 1, #groups do
|
||||
local data = player.PlayerData[groups[i]]
|
||||
local grade = filter[data.name]
|
||||
|
||||
if grade and grade <= data.grade.level then
|
||||
return data.name, data.grade.level
|
||||
end
|
||||
end
|
||||
elseif tabletype == 'array' then
|
||||
for i = 1, #filter do
|
||||
local group = filter[i]
|
||||
|
||||
for j = 1, #groups do
|
||||
local data = player.PlayerData[groups[j]]
|
||||
|
||||
if data.name == group then
|
||||
return data.name, data.grade.level
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
377
resources/[housing]/ox_doorlock/server/main.lua
Normal file
377
resources/[housing]/ox_doorlock/server/main.lua
Normal file
|
@ -0,0 +1,377 @@
|
|||
if not LoadResourceFile(cache.resource, 'web/build/index.html') then
|
||||
error(
|
||||
'Unable to load UI. Build ox_doorlock or download the latest release.\n ^3https://github.com/overextended/ox_doorlock/releases/latest/download/ox_doorlock.zip^0')
|
||||
end
|
||||
|
||||
if not lib.checkDependency('oxmysql', '2.4.0') then return end
|
||||
if not lib.checkDependency('ox_lib', '3.14.0') then return end
|
||||
|
||||
lib.versionCheck('overextended/ox_doorlock')
|
||||
require 'server.convert'
|
||||
|
||||
local utils = require 'server.utils'
|
||||
local doors = {}
|
||||
|
||||
|
||||
local function encodeData(door)
|
||||
local double = door.doors
|
||||
|
||||
return json.encode({
|
||||
auto = door.auto,
|
||||
autolock = door.autolock,
|
||||
coords = door.coords,
|
||||
doors = double and {
|
||||
{
|
||||
coords = double[1].coords,
|
||||
heading = double[1].heading,
|
||||
model = double[1].model,
|
||||
},
|
||||
{
|
||||
coords = double[2].coords,
|
||||
heading = double[2].heading,
|
||||
model = double[2].model,
|
||||
},
|
||||
},
|
||||
characters = door.characters,
|
||||
groups = door.groups,
|
||||
heading = door.heading,
|
||||
items = door.items,
|
||||
lockpick = door.lockpick,
|
||||
hideUi = door.hideUi,
|
||||
holdOpen = door.holdOpen,
|
||||
lockSound = door.lockSound,
|
||||
maxDistance = door.maxDistance,
|
||||
doorRate = door.doorRate,
|
||||
model = door.model,
|
||||
state = door.state,
|
||||
unlockSound = door.unlockSound,
|
||||
passcode = door.passcode,
|
||||
lockpickDifficulty = door.lockpickDifficulty
|
||||
})
|
||||
end
|
||||
|
||||
local function getDoor(door)
|
||||
door = type(door) == 'table' and door or doors[door]
|
||||
if not door then return false end
|
||||
return {
|
||||
id = door.id,
|
||||
name = door.name,
|
||||
state = door.state,
|
||||
coords = door.coords,
|
||||
characters = door.characters,
|
||||
groups = door.groups,
|
||||
items = door.items,
|
||||
maxDistance = door.maxDistance,
|
||||
}
|
||||
end
|
||||
|
||||
exports('getDoor', getDoor)
|
||||
|
||||
exports('getAllDoors', function()
|
||||
local allDoors = {}
|
||||
|
||||
for _, door in pairs(doors) do
|
||||
allDoors[#allDoors+1] = getDoor(door)
|
||||
end
|
||||
|
||||
return allDoors
|
||||
end)
|
||||
|
||||
exports('getDoorFromName', function(name)
|
||||
for _, door in pairs(doors) do
|
||||
if door.name == name then
|
||||
return getDoor(door)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
exports('editDoor', function(id, data)
|
||||
local door = doors[id]
|
||||
|
||||
if door then
|
||||
for k, v in pairs(data) do
|
||||
if k ~= 'id' then
|
||||
local current = door[k]
|
||||
local t1 = type(current)
|
||||
local t2 = type(v)
|
||||
|
||||
if t1 ~= 'nil' and v ~= '' and t1 ~= t2 then
|
||||
error(("Expected '%s' for door.%s, received %s (%s)"):format(t1, k, t2, v))
|
||||
end
|
||||
|
||||
door[k] = v ~= '' and v or nil
|
||||
end
|
||||
end
|
||||
|
||||
MySQL.update('UPDATE ox_doorlock SET name = ?, data = ? WHERE id = ?', { door.name, encodeData(door), id })
|
||||
TriggerClientEvent('ox_doorlock:editDoorlock', -1, id, door)
|
||||
end
|
||||
end)
|
||||
|
||||
local soundDirectory = Config.NativeAudio and 'audio/dlc_oxdoorlock/oxdoorlock' or 'web/build/sounds'
|
||||
local fileFormat = Config.NativeAudio and '%.wav' or '%.ogg'
|
||||
local sounds = utils.getFilesInDirectory(soundDirectory, fileFormat)
|
||||
|
||||
lib.callback.register('ox_doorlock:getSounds', function()
|
||||
return sounds
|
||||
end)
|
||||
|
||||
local function createDoor(id, door, name)
|
||||
local double = door.doors
|
||||
door.id = id
|
||||
door.name = name
|
||||
|
||||
if double then
|
||||
for i = 1, 2 do
|
||||
double[i].hash = joaat(('ox_door_%s_%s'):format(id, i))
|
||||
|
||||
local coords = double[i].coords
|
||||
double[i].coords = vector3(coords.x, coords.y, coords.z)
|
||||
end
|
||||
|
||||
if not door.coords then
|
||||
door.coords = double[1].coords - ((double[1].coords - double[2].coords) / 2)
|
||||
end
|
||||
else
|
||||
door.hash = joaat(('ox_door_%s'):format(id))
|
||||
end
|
||||
|
||||
door.coords = vector3(door.coords.x, door.coords.y, door.coords.z)
|
||||
|
||||
if not door.state then
|
||||
door.state = 1
|
||||
end
|
||||
|
||||
if type(door.items?[1]) == 'string' then
|
||||
local items = {}
|
||||
|
||||
for i = 1, #door.items do
|
||||
items[i] = {
|
||||
name = door.items[i],
|
||||
remove = false,
|
||||
}
|
||||
end
|
||||
|
||||
door.items = items
|
||||
MySQL.update('UPDATE ox_doorlock SET data = ? WHERE id = ?', { encodeData(door), id })
|
||||
end
|
||||
|
||||
doors[id] = door
|
||||
return door
|
||||
end
|
||||
|
||||
local isLoaded = false
|
||||
local ox_inventory = exports.ox_inventory
|
||||
|
||||
SetTimeout(0, function()
|
||||
if GetPlayer then return end
|
||||
|
||||
function GetPlayer(_) end
|
||||
end)
|
||||
|
||||
function RemoveItem(playerId, item, slot)
|
||||
local player = GetPlayer(playerId)
|
||||
|
||||
if player then ox_inventory:RemoveItem(playerId, item, 1, nil, slot) end
|
||||
end
|
||||
|
||||
---@param player table
|
||||
---@param items string[] | { name: string, remove?: boolean, metadata?: string }[]
|
||||
---@param removeItem? boolean
|
||||
---@return string?
|
||||
function DoesPlayerHaveItem(player, items, removeItem)
|
||||
local playerId = player.source or player.PlayerData.source
|
||||
|
||||
for i = 1, #items do
|
||||
local item = items[i]
|
||||
local itemName = item.name or item
|
||||
local data = ox_inventory:Search(playerId, 'slots', itemName, item.metadata)[1]
|
||||
|
||||
if data and data.count > 0 then
|
||||
if removeItem or item.remove then
|
||||
ox_inventory:RemoveItem(playerId, itemName, 1, nil, data.slot)
|
||||
end
|
||||
|
||||
return itemName
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function isAuthorised(playerId, door, lockpick)
|
||||
if Config.PlayerAceAuthorised and IsPlayerAceAllowed(playerId, 'command.doorlock') then
|
||||
return true
|
||||
end
|
||||
|
||||
-- e.g. add_ace group.police "doorlock.mrpd locker rooms" allow
|
||||
-- add_principal fivem:123456 group.police
|
||||
-- or add_ace identifier.fivem:123456 "doorlock.mrpd locker rooms" allow
|
||||
if IsPlayerAceAllowed(playerId, ('doorlock.%s'):format(door.name)) then
|
||||
return true
|
||||
end
|
||||
|
||||
local player = GetPlayer(playerId)
|
||||
local authorised = door.passcode or false --[[@as boolean | string | nil]]
|
||||
|
||||
if player then
|
||||
if lockpick then
|
||||
return DoesPlayerHaveItem(player, Config.LockpickItems)
|
||||
end
|
||||
|
||||
if door.characters and table.contains(door.characters, GetCharacterId(player)) then
|
||||
return true
|
||||
end
|
||||
|
||||
if door.groups then
|
||||
authorised = IsPlayerInGroup(player, door.groups) and true or nil
|
||||
end
|
||||
|
||||
if not authorised and door.items then
|
||||
authorised = DoesPlayerHaveItem(player, door.items) or nil
|
||||
end
|
||||
|
||||
if authorised ~= nil and door.passcode then
|
||||
authorised = door.passcode == lib.callback.await('ox_doorlock:inputPassCode', playerId)
|
||||
end
|
||||
|
||||
------------------------------------
|
||||
------- Brutal Housing Editing -----
|
||||
------------------------------------
|
||||
|
||||
if GetResourceState("brutal_housing") == "started" then
|
||||
local propertyID = door.name:match("^(.-)_")
|
||||
if propertyID ~= nil then
|
||||
TriggerEvent('brutal_housing:server:hasKeyToHouse', playerId, propertyID, function(hasKey)
|
||||
authorised = hasKey
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------
|
||||
------- Brutal Housing Editing -----
|
||||
------------------------------------
|
||||
end
|
||||
|
||||
return authorised
|
||||
end
|
||||
|
||||
local sql = LoadResourceFile(cache.resource, 'sql/ox_doorlock.sql')
|
||||
|
||||
if sql then MySQL.query(sql) end
|
||||
|
||||
MySQL.ready(function()
|
||||
while Config.DoorList do Wait(100) end
|
||||
|
||||
local response = MySQL.query.await('SELECT `id`, `name`, `data` FROM `ox_doorlock`')
|
||||
|
||||
for i = 1, #response do
|
||||
local door = response[i]
|
||||
createDoor(door.id, json.decode(door.data), door.name)
|
||||
end
|
||||
|
||||
isLoaded = true
|
||||
|
||||
TriggerEvent('ox_doorlock:loaded')
|
||||
end)
|
||||
|
||||
---@param id number
|
||||
---@param state 0 | 1 | boolean
|
||||
---@param lockpick? boolean
|
||||
---@return boolean
|
||||
local function setDoorState(id, state, lockpick)
|
||||
local door = doors[id]
|
||||
|
||||
state = (state == 1 or state == 0) and state or (state and 1 or 0)
|
||||
|
||||
if door then
|
||||
local authorised = not source or source == '' or isAuthorised(source, door, lockpick)
|
||||
|
||||
if authorised then
|
||||
door.state = state
|
||||
TriggerClientEvent('ox_doorlock:setState', -1, id, state, source)
|
||||
|
||||
if door.autolock and state == 0 then
|
||||
SetTimeout(door.autolock * 1000, function()
|
||||
if door.state ~= 1 then
|
||||
door.state = 1
|
||||
|
||||
TriggerClientEvent('ox_doorlock:setState', -1, id, door.state)
|
||||
TriggerEvent('ox_doorlock:stateChanged', nil, door.id, door.state == 1)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
TriggerEvent('ox_doorlock:stateChanged', source, door.id, state == 1,
|
||||
type(authorised) == 'string' and authorised)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if source then
|
||||
lib.notify(source,
|
||||
{ type = 'error', icon = 'lock', description = state == 0 and 'cannot_unlock' or 'cannot_lock' })
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
RegisterNetEvent('ox_doorlock:setState', setDoorState)
|
||||
exports('setDoorState', setDoorState)
|
||||
|
||||
lib.callback.register('ox_doorlock:getDoors', function()
|
||||
while not isLoaded do Wait(100) end
|
||||
|
||||
return doors, sounds
|
||||
end)
|
||||
|
||||
RegisterNetEvent('ox_doorlock:editDoorlock', function(id, data)
|
||||
if IsPlayerAceAllowed(source, 'command.doorlock') then
|
||||
if data then
|
||||
if not data.coords then
|
||||
local double = data.doors
|
||||
data.coords = double[1].coords - ((double[1].coords - double[2].coords) / 2)
|
||||
end
|
||||
|
||||
if not data.name then
|
||||
data.name = tostring(data.coords)
|
||||
end
|
||||
end
|
||||
|
||||
if id then
|
||||
if data then
|
||||
MySQL.update('UPDATE ox_doorlock SET name = ?, data = ? WHERE id = ?',
|
||||
{ data.name, encodeData(data), id })
|
||||
else
|
||||
MySQL.update('DELETE FROM ox_doorlock WHERE id = ?', { id })
|
||||
end
|
||||
|
||||
doors[id] = data
|
||||
TriggerClientEvent('ox_doorlock:editDoorlock', -1, id, data)
|
||||
else
|
||||
local insertId = MySQL.insert.await('INSERT INTO ox_doorlock (name, data) VALUES (?, ?)',
|
||||
{ data.name, encodeData(data) })
|
||||
local door = createDoor(insertId, data, data.name)
|
||||
|
||||
TriggerClientEvent('ox_doorlock:setState', -1, door.id, door.state, false, door)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('ox_doorlock:breakLockpick', function()
|
||||
local player = GetPlayer(source)
|
||||
return player and DoesPlayerHaveItem(player, Config.LockpickItems, true)
|
||||
end)
|
||||
|
||||
lib.addCommand('doorlock', {
|
||||
help = locale('create_modify_lock'),
|
||||
params = {
|
||||
{
|
||||
name = 'closest',
|
||||
help = locale('command_closest'),
|
||||
optional = true,
|
||||
},
|
||||
},
|
||||
restricted = Config.CommandPrincipal
|
||||
}, function(source, args)
|
||||
TriggerClientEvent('ox_doorlock:triggeredCommand', source, args.closest)
|
||||
end)
|
44
resources/[housing]/ox_doorlock/server/utils.lua
Normal file
44
resources/[housing]/ox_doorlock/server/utils.lua
Normal file
|
@ -0,0 +1,44 @@
|
|||
local resourcePath = GetResourcePath(cache.resource):gsub('//', '/') .. '/'
|
||||
|
||||
local utils = {}
|
||||
|
||||
function utils.getFilesInDirectory(path, pattern)
|
||||
local files = {}
|
||||
local fileCount = 0
|
||||
local system = os.getenv('OS')
|
||||
local command = system and system:match('Windows') and 'dir "' or 'ls "'
|
||||
local suffix = command == 'dir "' and '/" /b' or '/"'
|
||||
local dir = io.popen(command .. resourcePath .. path .. suffix)
|
||||
|
||||
if dir then
|
||||
for line in dir:lines() do
|
||||
if line:match(pattern) then
|
||||
fileCount += 1
|
||||
files[fileCount] = line:gsub(pattern, '')
|
||||
end
|
||||
end
|
||||
|
||||
dir:close()
|
||||
end
|
||||
|
||||
return files, fileCount
|
||||
end
|
||||
|
||||
local frameworks = { 'es_extended', 'ND_Core', 'ox_core', 'qb-core' }
|
||||
local sucess = false
|
||||
|
||||
for i = 1, #frameworks do
|
||||
local framework = frameworks[i]
|
||||
|
||||
if GetResourceState(framework):find('start') then
|
||||
require(('server.framework.%s'):format(framework:lower()))
|
||||
sucess = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not sucess then
|
||||
warn('no compatible framework was loaded, most features will not work')
|
||||
end
|
||||
|
||||
return utils
|
Loading…
Add table
Add a link
Reference in a new issue