forked from Simnation/Main
ed
This commit is contained in:
parent
6d22d5f77c
commit
63fbc60a00
86 changed files with 8352 additions and 3428 deletions
954
resources/[Developer]/sn_vehicleKey/client.lua
Normal file
954
resources/[Developer]/sn_vehicleKey/client.lua
Normal file
|
@ -0,0 +1,954 @@
|
|||
-- error when both menus are enabled
|
||||
if (Config.useContextMenu and Config.useNativeUI) then
|
||||
print("^1[ERROR] You can use only one menu or no menu at all. You cannot use both menus."
|
||||
.. "\nMake sure to set at least one to false in the config and to edit the fxmanifest accordingly!")
|
||||
end
|
||||
|
||||
local keymakers = {}
|
||||
|
||||
local lockNotif = nil
|
||||
local createNewKeyNotif = nil
|
||||
|
||||
local LockStatus = {
|
||||
Unlocked = 1,
|
||||
Locked = 2
|
||||
}
|
||||
|
||||
local CB = exports["kimi_callbacks"]
|
||||
|
||||
local menuPoolNativeUI
|
||||
local keymakerMenuNativeUI
|
||||
local keyInvMenuNativeUI
|
||||
if (Config.useNativeUI) then
|
||||
if (NativeUI == nil) then
|
||||
print("^1[ERROR] NativeUI was not properly initialized! Make sure to install NativeUI and start it before this resource!")
|
||||
end
|
||||
|
||||
menuPoolNativeUI = NativeUI.CreatePool()
|
||||
keymakerMenuNativeUI = NativeUI.CreateMenu(Config.Strings.keymakerTitle, Config.Strings.keymakerSub)
|
||||
keyInvMenuNativeUI = NativeUI.CreateMenu(Config.Strings.keyInvTitle, Config.Strings.keyInvSub)
|
||||
end
|
||||
|
||||
local isAtKeymaker = false
|
||||
local menuOpen = false
|
||||
|
||||
-- create client side peds
|
||||
Citizen.CreateThread(function()
|
||||
for i, keymaker in ipairs(Config.Keymakers) do
|
||||
RequestModel(keymaker.model)
|
||||
while not HasModelLoaded(keymaker.model) do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
local ped = CreatePed(0, keymaker.model, keymaker.pos.x, keymaker.pos.y, keymaker.pos.z, keymaker.pos.w, false, true)
|
||||
|
||||
SetBlockingOfNonTemporaryEvents(ped, true)
|
||||
FreezeEntityPosition(ped, true)
|
||||
SetEntityInvincible(ped, true)
|
||||
|
||||
table.insert(keymakers, ped)
|
||||
|
||||
-- add blip
|
||||
local blip = AddBlipForCoord(keymaker.pos.x, keymaker.pos.y, keymaker.pos.z)
|
||||
|
||||
SetBlipSprite(blip, 134)
|
||||
SetBlipColour(blip, 0)
|
||||
|
||||
SetBlipScale(blip, 1.0)
|
||||
SetBlipDisplay(blip, 2)
|
||||
SetBlipAsShortRange(blip, true)
|
||||
|
||||
BeginTextCommandSetBlipName('STRING')
|
||||
AddTextComponentSubstringPlayerName(Config.Strings.keymaker)
|
||||
EndTextCommandSetBlipName(blip)
|
||||
end
|
||||
end)
|
||||
|
||||
-- main loop
|
||||
Citizen.CreateThread(function()
|
||||
while (true) do
|
||||
Citizen.Wait(0)
|
||||
|
||||
if (Config.useNativeUI) then
|
||||
if (menuOpen) then
|
||||
menuPoolNativeUI:ProcessMenus()
|
||||
end
|
||||
|
||||
if (isAtKeymaker) then
|
||||
if (not menuOpen) then
|
||||
ShowHelpText(Config.Strings.helpText)
|
||||
end
|
||||
|
||||
if (IsControlJustPressed(0, 51)) then
|
||||
if (menuPoolNativeUI:IsAnyMenuOpen()) then
|
||||
menuPoolNativeUI:CloseAllMenus()
|
||||
menuOpen = false
|
||||
else
|
||||
GenerateKeymakerMenuNativeUI()
|
||||
keymakerMenuNativeUI:Visible(true)
|
||||
menuOpen = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (IsControlJustPressed(0, Config.keyMenuKey)) then
|
||||
if (menuPoolNativeUI:IsAnyMenuOpen()) then
|
||||
menuPoolNativeUI:CloseAllMenus()
|
||||
menuOpen = false
|
||||
else
|
||||
GenerateKeyInventoryNativeUI()
|
||||
keyInvMenuNativeUI:Visible(true)
|
||||
menuOpen = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- lock vehicle with key
|
||||
--[[ if (Config.lockKey and IsControlJustPressed(0, Config.lockKey)) then
|
||||
local vehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0)
|
||||
if (DoesEntityExist(vehicle) and IsVehicleOrKeyOwner(vehicle)) then
|
||||
ToggleLock(vehicle, GetVehicleDoorLockStatus(vehicle) ~= LockStatus.Locked)
|
||||
end
|
||||
end ]]
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
-- ContextMenu
|
||||
if (Config.useContextMenu) then
|
||||
local menuPool = MenuPool()
|
||||
menuPool.OnOpenMenu = function(screenPosition, hitSomething, worldPosition, hitEntity, normalDirection)
|
||||
local playerPos = GetEntityCoords(PlayerPedId())
|
||||
if (Vdist(worldPosition.x, worldPosition.y, worldPosition.z, playerPos.x, playerPos.y, playerPos.z) < Config.maxDistance) then
|
||||
CreateMenu(screenPosition, hitEntity)
|
||||
end
|
||||
end
|
||||
|
||||
function CreateMenu(screenPosition, hitEntity)
|
||||
menuPool:Reset()
|
||||
|
||||
if (hitEntity) then
|
||||
if (hitEntity == PlayerPedId()) then
|
||||
local vehicleData = CB:Trigger("VKC:getPlayerVehicleData")
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
menuPool:Reset()
|
||||
|
||||
local playerMenu = menuPool:AddMenu()
|
||||
|
||||
local ownVehMenu, ownVehMenuItem = menuPool:AddSubmenu(playerMenu, Config.Strings.CM.masterKeysTitle)
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local item = ownVehMenu:AddItem(model .. " " .. plate)
|
||||
end
|
||||
|
||||
local ownKeyMenu, ownKeyMenuItem = menuPool:AddSubmenu(playerMenu, Config.Strings.CM.keysTitle)
|
||||
for i, key in ipairs(ownedKeys) do
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(key.model))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(key.model)
|
||||
end
|
||||
|
||||
local item = ownKeyMenu:AddItem(model .. " " .. key.plate)
|
||||
item.rightText = Text("x" .. key.count)
|
||||
end
|
||||
|
||||
-- Fahrzeugübergabe-Menü hinzufügen
|
||||
local transferVehMenu, transferVehMenuItem = menuPool:AddSubmenu(playerMenu, "Fahrzeug übergeben")
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local item = transferVehMenu:AddItem(model .. " " .. plate)
|
||||
item.closeMenuOnClick = true
|
||||
item.OnClick = function()
|
||||
-- Finde den nächsten Spieler
|
||||
local player = GetClosestPlayer(5.0)
|
||||
|
||||
if player then
|
||||
local targetPlayerId = GetPlayerServerId(player)
|
||||
local playerName = GetPlayerName(player)
|
||||
|
||||
local success = CB:Trigger("VKC:transferVehicleOwnership", plate, targetPlayerId)
|
||||
|
||||
if success then
|
||||
Notification(string.format("Du hast dein %s an %s übergeben", model, playerName))
|
||||
else
|
||||
Notification("Übergabe fehlgeschlagen")
|
||||
end
|
||||
else
|
||||
Notification("Kein Spieler in der Nähe gefunden")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
playerMenu:SetPosition(screenPosition)
|
||||
playerMenu:Visible(true)
|
||||
elseif (IsEntityAKeymaker(hitEntity)) then
|
||||
local vehicleData = GetPlayerVehicleData()
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
menuPool:Reset()
|
||||
|
||||
local keymakerMenu = menuPool:AddMenu()
|
||||
|
||||
local createKeyMenu, createKeyMenuItem = menuPool:AddSubmenu(keymakerMenu, Config.Strings.CM.createKeyTitle)
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
local keyCount = GetKeyCount(plate, ownedKeys)
|
||||
|
||||
local keyItem = createKeyMenu:AddItem(model .. " " .. plate)
|
||||
keyItem.rightText = Text("x" .. tostring(keyCount))
|
||||
keyItem.OnClick = function()
|
||||
local result = CB:Trigger("VKC:createNewKey", plate, 1)
|
||||
if (type(result) == "boolean" and result == true) then
|
||||
Notification(string.format(Config.Strings.createSuccess, model))
|
||||
|
||||
local oldCount = keyItem.rightText.title:gsub("x", "")
|
||||
keyItem.rightText.title = "x" .. tostring(tonumber(oldCount) + 1)
|
||||
elseif (type(result) == "string" and result == "noMoney") then
|
||||
Notification(string.format(Config.Strings.createNoMoney, model))
|
||||
else
|
||||
Notification(string.format(Config.Strings.createFailed, model))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local invalidateKeyMenu, invalidateKeyMenuItem = menuPool:AddSubmenu(keymakerMenu, Config.Strings.CM.invalKeyTitle)
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local item = invalidateKeyMenu:AddItem(model .. " " .. plate)
|
||||
item.closeMenuOnClick = true
|
||||
item.OnClick = function()
|
||||
local result = CB:Trigger("VKC:removeAllKeys", plate)
|
||||
if (type(result) == "boolean" and result == true) then
|
||||
Notification(string.format(Config.Strings.deleteKeys, model))
|
||||
elseif (type(result) == "string" and result == "noMoney") then
|
||||
Notification(string.format(Config.Strings.removeNoMoney, vehName))
|
||||
else
|
||||
Notification(string.format(Config.Strings.removeFailed, vehName))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
keymakerMenu:SetPosition(screenPosition)
|
||||
keymakerMenu:Visible(true)
|
||||
elseif (IsEntityAPed(hitEntity) and IsPedAPlayer(hitEntity)) then
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
menuPool:Reset()
|
||||
|
||||
local interactMenu = menuPool:AddMenu()
|
||||
|
||||
local giveKeyMenu, giveKeyMenuItem = menuPool:AddSubmenu(interactMenu, Config.Strings.CM.giveKey)
|
||||
for i, key in ipairs(ownedKeys) do
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(key.model))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(key.model)
|
||||
end
|
||||
|
||||
local keyItem = giveKeyMenu:AddItem(model .. " " .. key.plate)
|
||||
keyItem.rightText = Text("x" .. key.count)
|
||||
keyItem.closeMenuOnClick = true
|
||||
keyItem.OnClick = function()
|
||||
local players = GetActivePlayers()
|
||||
for i, player in ipairs(players) do
|
||||
if (GetPlayerPed(player) == hitEntity) then
|
||||
local success = CB:Trigger("VKC:giveKeyToPlayer", key.plate, GetPlayerServerId(player))
|
||||
if (success) then
|
||||
Notification(string.format(Config.Strings.giveSuccess, model))
|
||||
else
|
||||
Notification(string.format(Config.Strings.giveFailed, model))
|
||||
end
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
interactMenu:SetPosition(screenPosition)
|
||||
interactMenu:Visible(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function IsEntityAKeymaker(entity)
|
||||
for i, keymaker in ipairs(keymakers) do
|
||||
if (entity == keymaker) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- NativeUI
|
||||
function GenerateKeymakerMenuNativeUI()
|
||||
keymakerMenuNativeUI:Clear()
|
||||
|
||||
local vehicleData = GetPlayerVehicleData()
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
keymakerMenuNativeUI = NativeUI.CreateMenu(Config.Strings.NUI.keymakerMenuTitle, Config.Strings.NUI.keymakerMenuSub)
|
||||
menuPoolNativeUI:Add(keymakerMenuNativeUI)
|
||||
|
||||
local submenuCreateKey = menuPoolNativeUI:AddSubMenu(keymakerMenuNativeUI, Config.Strings.NUI.createKeyTitle, Config.Strings.NUI.createKeyDesc)
|
||||
submenuCreateKey.ParentItem:RightLabel(">")
|
||||
submenuCreateKey.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.createKeyTitle
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
local keyCount = GetKeyCount(plate, ownedKeys)
|
||||
|
||||
local vehItem = NativeUI.CreateItem(model .. " " .. plate, string.format(Config.Strings.NUI.createVehicleKey, model, plate))
|
||||
vehItem:RightLabel("x" .. tostring(keyCount))
|
||||
|
||||
submenuCreateKey:AddItem(vehItem)
|
||||
end
|
||||
submenuCreateKey.OnItemSelect = function(menu, item, index)
|
||||
Citizen.CreateThread(function()
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicleData[index][2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicleData[index][2])
|
||||
end
|
||||
|
||||
local result = CB:Trigger("VKC:createNewKey", vehicleData[index][1], 1)
|
||||
if (type(result) == "boolean" and result == true) then
|
||||
Notification(string.format(Config.Strings.createSuccess, model))
|
||||
|
||||
if (submenuCreateKey:Visible()) then
|
||||
local oldCount = item.Label.Text._Text:gsub("x", "")
|
||||
item:RightLabel("x" .. tostring(tonumber(oldCount) + 1))
|
||||
end
|
||||
elseif (type(result) == "string" and result == "noMoney") then
|
||||
Notification(string.format(Config.Strings.createNoMoney, model))
|
||||
else
|
||||
Notification(string.format(Config.Strings.createFailed, model))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local submenuInvalidateKey = menuPoolNativeUI:AddSubMenu(keymakerMenuNativeUI, Config.Strings.NUI.invalKeyTitle, Config.Strings.NUI.invalKeyDesc)
|
||||
submenuInvalidateKey.ParentItem:RightLabel(">")
|
||||
submenuInvalidateKey.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.invalKeyTitle
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local keyItem = NativeUI.CreateItem(model .. " " .. plate, string.format(Config.Strings.NUI.invalVehicleKey, model, plate))
|
||||
submenuInvalidateKey:AddItem(keyItem)
|
||||
end
|
||||
submenuInvalidateKey.OnItemSelect = function(menu, item, index)
|
||||
Citizen.CreateThread(function()
|
||||
local result = CB:Trigger("VKC:removeAllKeys", vehicleData[index][1])
|
||||
|
||||
if (type(result) == "boolean" and result == true) then
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicleData[index][2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicleData[index][2])
|
||||
end
|
||||
Notification(string.format(Config.Strings.deleteKeys, model))
|
||||
elseif (type(result) == "string" and result == "noMoney") then
|
||||
Notification(string.format(Config.Strings.removeNoMoney, vehName))
|
||||
else
|
||||
Notification(string.format(Config.Strings.removeFailed, vehName))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
keymakerMenuNativeUI.OnMenuClosed = function(menu)
|
||||
menuOpen = false
|
||||
end
|
||||
|
||||
menuPoolNativeUI:ControlDisablingEnabled(false)
|
||||
menuPoolNativeUI:MouseControlsEnabled(false)
|
||||
|
||||
menuPoolNativeUI:RefreshIndex()
|
||||
end
|
||||
|
||||
function GenerateKeyInventoryNativeUI()
|
||||
keyInvMenuNativeUI:Clear()
|
||||
|
||||
local vehicleData = GetPlayerVehicleData()
|
||||
local ownedKeys = GetPlayerKeys()
|
||||
|
||||
keyInvMenuNativeUI = NativeUI.CreateMenu(Config.Strings.NUI.keyInventoryTitle, Config.Strings.NUI.keyInventorySub)
|
||||
menuPoolNativeUI:Add(keyInvMenuNativeUI)
|
||||
|
||||
local submenuShowMasterKeys = menuPoolNativeUI:AddSubMenu(keyInvMenuNativeUI, Config.Strings.NUI.masterKeysTitle, Config.Strings.NUI.masterKeysDesc)
|
||||
submenuShowMasterKeys.ParentItem:RightLabel(">")
|
||||
submenuShowMasterKeys.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.masterKeysTitle
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
--local keyCount = GetKeyCount(plate, ownedKeys)
|
||||
|
||||
local vehItem = NativeUI.CreateItem(model .. " " .. plate, "")
|
||||
--vehItem:RightLabel("x" .. tostring(keyCount))
|
||||
submenuShowMasterKeys:AddItem(vehItem)
|
||||
end
|
||||
|
||||
-- Fahrzeugübergabe-Untermenü hinzufügen
|
||||
local submenuTransferVehicle = menuPoolNativeUI:AddSubMenu(keyInvMenuNativeUI, "Fahrzeug übergeben", "Übertrage ein Fahrzeug an einen Spieler in der Nähe")
|
||||
submenuTransferVehicle.ParentItem:RightLabel(">")
|
||||
submenuTransferVehicle.Subtitle.Text._Text = "~b~Fahrzeug übergeben"
|
||||
for i, vehicle in ipairs(vehicleData) do
|
||||
local plate = vehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(vehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(vehicle[2])
|
||||
end
|
||||
|
||||
local vehItem = NativeUI.CreateItem(model .. " " .. plate, "Wähle dieses Fahrzeug zum Übergeben")
|
||||
submenuTransferVehicle:AddItem(vehItem)
|
||||
end
|
||||
|
||||
submenuTransferVehicle.OnItemSelect = function(menu, item, index)
|
||||
local selectedVehicle = vehicleData[index]
|
||||
local plate = selectedVehicle[1]
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(selectedVehicle[2]))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(selectedVehicle[2])
|
||||
end
|
||||
|
||||
-- Finde den nächsten Spieler
|
||||
local player = GetClosestPlayer(5.0)
|
||||
|
||||
if player then
|
||||
local targetPlayerId = GetPlayerServerId(player)
|
||||
local playerName = GetPlayerName(player)
|
||||
|
||||
local success = CB:Trigger("VKC:transferVehicleOwnership", plate, targetPlayerId)
|
||||
|
||||
if success then
|
||||
lib.notify({
|
||||
title = "Fahrzeug übergeben",
|
||||
description = "Du hast dein " .. model .. " an " .. playerName .. " übergeben",
|
||||
position = "top",
|
||||
type = "success",
|
||||
icon = "car"
|
||||
})
|
||||
else
|
||||
lib.notify({
|
||||
title = "Fahrzeug übergeben",
|
||||
description = "Übergabe fehlgeschlagen",
|
||||
position = "top",
|
||||
type = "error",
|
||||
icon = "car"
|
||||
})
|
||||
end
|
||||
else
|
||||
lib.notify({
|
||||
title = "Fahrzeug übergeben",
|
||||
description = "Kein Spieler in der Nähe gefunden",
|
||||
position = "top",
|
||||
type = "error",
|
||||
icon = "car"
|
||||
})
|
||||
end
|
||||
|
||||
menuPoolNativeUI:CloseAllMenus()
|
||||
menuOpen = false
|
||||
end
|
||||
|
||||
local submenuShowKeys = menuPoolNativeUI:AddSubMenu(keyInvMenuNativeUI, Config.Strings.NUI.keysTitle, Config.Strings.NUI.keysDesc)
|
||||
submenuShowKeys.ParentItem:RightLabel(">")
|
||||
submenuShowKeys.Subtitle.Text._Text = "~b~" .. Config.Strings.NUI.keysTitle
|
||||
for i, key in ipairs(ownedKeys) do
|
||||
local model = GetLabelText(GetDisplayNameFromVehicleModel(key.model))
|
||||
if (model == "NULL") then
|
||||
model = GetDisplayNameFromVehicleModel(key.model)
|
||||
end
|
||||
|
||||
local submenuKey = menuPoolNativeUI:AddSubMenu(submenuShowKeys, model .. " " .. key.plate, "")
|
||||
submenuKey.ParentItem:RightLabel("x" .. tostring(key.count) .. " >")
|
||||
submenuKey.Subtitle.Text._Text = "~b~" .. model .. " " .. key.plate
|
||||
|
||||
local giveItem = NativeUI.CreateItem(Config.Strings.NUI.giveKeyTitle, Config.Strings.NUI.giveKeyDesc)
|
||||
submenuKey:AddItem(giveItem)
|
||||
|
||||
local removeItem = NativeUI.CreateItem(Config.Strings.NUI.removeKeyTitle, Config.Strings.NUI.removeKeyDesc)
|
||||
submenuKey:AddItem(removeItem)
|
||||
|
||||
submenuKey.OnItemSelect = function(menu, item, index)
|
||||
if (item == giveItem) then
|
||||
Citizen.CreateThread(function()
|
||||
local player = GetClosestPlayer(2.0)
|
||||
if (player) then
|
||||
local success = CB:Trigger("VKC:giveKeyToPlayer", key.plate, GetPlayerServerId(player))
|
||||
if (success) then
|
||||
Notification(string.format(Config.Strings.giveSuccess, key.plate))
|
||||
else
|
||||
Notification(string.format(Config.Strings.giveFailed, key.plate))
|
||||
end
|
||||
else
|
||||
Notification(string.format(Config.Strings.giveFailed, key.plate))
|
||||
end
|
||||
end)
|
||||
elseif (item == removeItem) then
|
||||
Citizen.CreateThread(function()
|
||||
local success = CB:Trigger("VKC:removeKey", key.plate, 1)
|
||||
if (success) then
|
||||
Notification(string.format(Config.Strings.removeSuccess, key.plate))
|
||||
|
||||
if (submenuShowKeys:Visible() or submenuKey:Visible()) then
|
||||
local oldCount = submenuKey.ParentItem.Label.Text._Text:gsub("x", "")
|
||||
oldCount = oldCount:gsub(" >", "")
|
||||
submenuKey.ParentItem:RightLabel("x" .. tostring(tonumber(oldCount) - 1) .. " >")
|
||||
end
|
||||
else
|
||||
Notification(string.format(Config.Strings.removeFailed, key.plate))
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
keyInvMenuNativeUI.OnMenuClosed = function(menu)
|
||||
menuOpen = false
|
||||
end
|
||||
|
||||
menuPoolNativeUI:ControlDisablingEnabled(false)
|
||||
menuPoolNativeUI:MouseControlsEnabled(false)
|
||||
|
||||
menuPoolNativeUI:RefreshIndex()
|
||||
end
|
||||
|
||||
if (Config.useNativeUI) then
|
||||
Citizen.CreateThread(function()
|
||||
while (true) do
|
||||
Citizen.Wait(250)
|
||||
|
||||
isAtKeymaker = false
|
||||
|
||||
local pos = GetEntityCoords(PlayerPedId())
|
||||
for i, keymaker in ipairs(Config.Keymakers) do
|
||||
if (Vdist(pos.x, pos.y, pos.z, keymaker.pos.x, keymaker.pos.y, keymaker.pos.z) < 2.0) then
|
||||
isAtKeymaker = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if (Config.keyMenuCommand) then
|
||||
RegisterCommand(Config.keyMenuCommand, function(source, args, raw)
|
||||
if (menuPoolNativeUI:IsAnyMenuOpen()) then
|
||||
menuPoolNativeUI:CloseAllMenus()
|
||||
end
|
||||
|
||||
GenerateKeyInventoryNativeUI()
|
||||
keyInvMenuNativeUI:Visible(true)
|
||||
menuOpen = true
|
||||
end, false)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- lock vehicle
|
||||
if (Config.lockCommand) then
|
||||
RegisterCommand(Config.lockCommand, function(source, args, raw)
|
||||
local vehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0)
|
||||
if (DoesEntityExist(vehicle) and IsVehicleOrKeyOwner(vehicle)) then
|
||||
ToggleLock(vehicle, GetVehicleDoorLockStatus(vehicle) ~= LockStatus.Locked)
|
||||
end
|
||||
end, false)
|
||||
end
|
||||
|
||||
function ToggleLock(vehicle, lock)
|
||||
local lockStatus = GetVehicleDoorLockStatus(vehicle)
|
||||
|
||||
if (NetworkHasControlOfEntity(vehicle)) then
|
||||
ToggleLockOnVehicle(vehicle, lock)
|
||||
else
|
||||
TriggerServerEvent("VKC:toggleLockNet", NetworkGetNetworkIdFromEntity(vehicle), lock)
|
||||
end
|
||||
|
||||
-- play sound
|
||||
TriggerServerEvent("VKC:playDoorLockSoundNet", NetworkGetNetworkIdFromEntity(vehicle), lock)
|
||||
|
||||
-- play remote animation
|
||||
if (not IsPedInAnyVehicle(PlayerPedId(), false)) then
|
||||
PlayRemoteAnimation()
|
||||
end
|
||||
|
||||
-- show notification
|
||||
--[[
|
||||
if (lockNotif) then
|
||||
RemoveNotification(lockNotif)
|
||||
end
|
||||
lockNotif = Notification(lockStatus == LockStatus.Locked and Config.Strings.unlockNotif or Config.Strings.lockNotif)
|
||||
]]
|
||||
end
|
||||
|
||||
function ToggleLockOnVehicle(vehicle, lock)
|
||||
if (lock) then
|
||||
SetVehicleDoorsShut(vehicle, false)
|
||||
SetVehicleDoorsLocked(vehicle, LockStatus.Locked)
|
||||
--exports['okokNotify']:Alert("Fahrzeug", "Du hast dein Fahrzeug Abgeschlossen", 3000, 'error')
|
||||
lib.notify({
|
||||
title = "Fahrzeug",
|
||||
description = "Du hast dein Fahrzeug Abgeschlossen",
|
||||
position = "top",
|
||||
type = "error",
|
||||
icon = "car"
|
||||
})
|
||||
|
||||
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
else
|
||||
SetVehicleDoorsLocked(vehicle, LockStatus.Unlocked)
|
||||
--exports['okokNotify']:Alert("Fahrzeug", "Du hast dein Fahrzeug Aufgeschlossen", 3000, 'success')
|
||||
lib.notify({
|
||||
title = "Fahrzeug",
|
||||
description = "Du hast dein Fahrzeug Aufgeschlossen",
|
||||
position = "top",
|
||||
type = "success",
|
||||
icon = "car"
|
||||
})
|
||||
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 2)
|
||||
Citizen.Wait(150)
|
||||
SetVehicleLights(vehicle, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function PlayDoorLockSound(vehicle, lock)
|
||||
if (lock) then
|
||||
PlayVehicleDoorCloseSound(vehicle, 0)
|
||||
else
|
||||
PlayVehicleDoorOpenSound(vehicle, 0)
|
||||
end
|
||||
end
|
||||
|
||||
if (Config.lockCommand or Config.lockKey) then
|
||||
RegisterNetEvent("VKC:toggleLockOnPlayer")
|
||||
AddEventHandler("VKC:toggleLockOnPlayer", function(vehicleNetId, unlocked)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehicleNetId)
|
||||
if (DoesEntityExist(vehicle) and NetworkHasControlOfEntity(vehicle)) then
|
||||
local lockStatus = GetVehicleDoorLockStatus(vehicle)
|
||||
ToggleLockOnVehicle(vehicle, unlocked)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("VKC:playDoorLockSound")
|
||||
AddEventHandler("VKC:playDoorLockSound", function(vehicleNetId, lock)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehicleNetId)
|
||||
if (DoesEntityExist(vehicle)) then
|
||||
PlayDoorLockSound(vehicle, lock)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
|
||||
RegisterNetEvent("VKC:giveKeyNotif")
|
||||
AddEventHandler("VKC:giveKeyNotif", function(plate)
|
||||
Notification(string.format(Config.Strings.giveSuccessPly, plate))
|
||||
end)
|
||||
|
||||
-- Ereignis für Fahrzeugübergabe-Benachrichtigung
|
||||
RegisterNetEvent("VKC:vehicleTransferNotif")
|
||||
AddEventHandler("VKC:vehicleTransferNotif", function(plate, model)
|
||||
lib.notify({
|
||||
title = "Fahrzeug erhalten",
|
||||
description = "Du hast ein " .. model .. " mit dem Kennzeichen " .. plate .. " erhalten",
|
||||
position = "top",
|
||||
type = "success",
|
||||
icon = "car"
|
||||
})
|
||||
end)
|
||||
|
||||
|
||||
function IsVehicleOwner(vehicle)
|
||||
if (not DoesEntityExist(vehicle)) then
|
||||
print("^1[ERROR] Parameter \"vehicle\" was nil or vehicle did not exist while triggering export \"IsVehicleOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
return CB:Trigger("VKC:isVehicleOwner", GetVehicleNumberPlateText(vehicle))
|
||||
end
|
||||
|
||||
function IsKeyOwner(vehicle)
|
||||
if (not DoesEntityExist(vehicle)) then
|
||||
print("^1[ERROR] Parameter \"vehicle\" was nil or vehicle did not exist while triggering export \"IsKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
return CB:Trigger("VKC:isKeyOwner", GetVehicleNumberPlateText(vehicle), GetEntityModel(vehicle))
|
||||
end
|
||||
|
||||
function IsVehicleOrKeyOwner(vehicle)
|
||||
if (not DoesEntityExist(vehicle)) then
|
||||
print("^1[ERROR] Parameter \"vehicle\" was nil or vehicle did not exist while triggering export \"IsVehicleOrKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
return CB:Trigger("VKC:isVehicleOrKeyOwner", GetVehicleNumberPlateText(vehicle), GetEntityModel(vehicle))
|
||||
end
|
||||
|
||||
function GetPlayerKeys()
|
||||
return CB:Trigger("VKC:getPlayerKeys")
|
||||
end
|
||||
|
||||
function GetPlayerVehicleData()
|
||||
return CB:Trigger("VKC:getPlayerVehicleData")
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- play lock animation
|
||||
function PlayRemoteAnimation()
|
||||
Citizen.CreateThread(function()
|
||||
RequestModel(keyPropHash)
|
||||
RequestAnimDict("anim@mp_player_intmenu@key_fob@")
|
||||
while (not HasModelLoaded(keyPropHash) and not HasAnimDictLoaded("anim@mp_player_intmenu@key_fob@")) do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
local playerPed = PlayerPedId()
|
||||
local playerPos = GetEntityCoords(playerPed)
|
||||
|
||||
local keyObj = CreateObjectNoOffset(keyPropHash, playerPos.x, playerPos.y, playerPos.z, true, true, false)
|
||||
SetModelAsNoLongerNeeded(keyPropHash)
|
||||
|
||||
local boneIndex = GetEntityBoneIndexByName(playerPed, "IK_R_Hand")
|
||||
local offset = vector3(0.08, 0.025, -0.01)
|
||||
local rotOffset = vector3(0, 70, 140)
|
||||
AttachEntityToEntity(keyObj, playerPed, boneIndex, offset.x, offset.y, offset.z, rotOffset.x, rotOffset.y, rotOffset.z, false, false, true, false, 2, true)
|
||||
|
||||
TaskPlayAnim(playerPed, "anim@mp_player_intmenu@key_fob@", "fob_click_fp", 8.0, 8.0, -1, 48, 1, false, false, false)
|
||||
RemoveAnimDict("anim@mp_player_intmenu@key_fob@")
|
||||
|
||||
Citizen.Wait(1500)
|
||||
|
||||
DeleteEntity(keyObj)
|
||||
end)
|
||||
end
|
||||
|
||||
-- show text in upper left corner
|
||||
function ShowHelpText(text)
|
||||
BeginTextCommandDisplayHelp('STRING')
|
||||
AddTextComponentSubstringPlayerName(text)
|
||||
EndTextCommandDisplayHelp(0, false, true, -1)
|
||||
end
|
||||
|
||||
-- displays a notification and returns its handle
|
||||
function Notification(text)
|
||||
SetNotificationTextEntry('STRING')
|
||||
AddTextComponentSubstringPlayerName(text)
|
||||
return DrawNotification(false, true)
|
||||
end
|
||||
|
||||
-- get key count
|
||||
function GetKeyCount(plate, keyArray)
|
||||
for i, key in ipairs(keyArray) do
|
||||
if (plate == key.plate) then
|
||||
return key.count
|
||||
end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
-- get all players
|
||||
function GetAllPlayers()
|
||||
local players = {}
|
||||
|
||||
for k, v in ipairs(GetActivePlayers()) do
|
||||
table.insert(players, v)
|
||||
end
|
||||
|
||||
return players
|
||||
end
|
||||
|
||||
-- get the closest player
|
||||
function GetClosestPlayer(maxRange)
|
||||
local playerPed = PlayerPedId()
|
||||
local players = GetAllPlayers()
|
||||
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
local closestDistance = maxRange
|
||||
local closestPlayer = nil
|
||||
|
||||
for i=1, #players, 1 do
|
||||
local coords = GetEntityCoords(GetPlayerPed(players[i]))
|
||||
local dist = Vdist(playerCoords.x, playerCoords.y, playerCoords.z, coords.x, coords.y, coords.z)
|
||||
if (dist < closestDistance and players[i] ~= PlayerId()) then
|
||||
closestDistance = dist
|
||||
closestPlayer = players[i]
|
||||
end
|
||||
end
|
||||
|
||||
if (closestPlayer ~= nil and DoesEntityExist(GetPlayerPed(closestPlayer))) then
|
||||
return closestPlayer
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Return closest loaded vehicle entity or nil if no vehicle is found
|
||||
function GetClosestVehicle(position, maxRadius)
|
||||
local vehicles = GetAllVehicles()
|
||||
local dist = maxRadius
|
||||
local closestVehicle = nil
|
||||
|
||||
for i=1, #vehicles, 1 do
|
||||
local vehicleCoords = GetEntityCoords(vehicles[i])
|
||||
local tempDist = Vdist(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, position.x, position.y, position.z)
|
||||
if (tempDist < dist) then
|
||||
dist = tempDist
|
||||
closestVehicle = vehicles[i]
|
||||
end
|
||||
end
|
||||
|
||||
if (closestVehicle ~= nil and DoesEntityExist(closestVehicle)) then
|
||||
return closestVehicle
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns all loaded vehicles on client side
|
||||
function GetAllVehicles()
|
||||
local vehicles = {}
|
||||
|
||||
for vehicle in EnumerateVehicles() do
|
||||
table.insert(vehicles, vehicle)
|
||||
end
|
||||
|
||||
return vehicles
|
||||
end
|
||||
|
||||
-- getting all vehicles
|
||||
function EnumerateVehicles()
|
||||
return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle)
|
||||
end
|
||||
function EnumerateEntities(initFunc, moveFunc, disposeFunc)
|
||||
return coroutine.wrap(function()
|
||||
local iter, id = initFunc()
|
||||
if not id or id == 0 then
|
||||
disposeFunc(iter)
|
||||
return
|
||||
end
|
||||
|
||||
local enum = {handle = iter, destructor = disposeFunc}
|
||||
setmetatable(enum, entityEnumerator)
|
||||
|
||||
local next = true
|
||||
repeat
|
||||
coroutine.yield(id)
|
||||
next, id = moveFunc(iter)
|
||||
until not next
|
||||
|
||||
enum.destructor, enum.handle = nil, nil
|
||||
disposeFunc(iter)
|
||||
end)
|
||||
end
|
||||
local entityEnumerator = {
|
||||
__gc = function(enum)
|
||||
if enum.destructor and enum.handle then
|
||||
enum.destructor(enum.handle)
|
||||
end
|
||||
enum.destructor = nil
|
||||
enum.handle = nil
|
||||
end
|
||||
}
|
||||
|
||||
--[[
|
||||
RegisterCommand("plate", function(source, args, raw)
|
||||
local vehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0)
|
||||
if (DoesEntityExist(vehicle)) then
|
||||
SetVehicleNumberPlateText(vehicle, args[1])
|
||||
end
|
||||
end, false)
|
||||
]]
|
||||
|
||||
|
||||
RegisterKeyMapping("vehicleLock", "Vehicle Lock", "keyboard", "PAGEUP")
|
||||
RegisterCommand("vehicleLock", function()
|
||||
local vehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0)
|
||||
if (DoesEntityExist(vehicle) and IsVehicleOrKeyOwner(vehicle)) then
|
||||
ToggleLock(vehicle, GetVehicleDoorLockStatus(vehicle) ~= LockStatus.Locked)
|
||||
end
|
||||
end, false)
|
||||
|
||||
-- Integration mit dem Mietfahrzeug-System
|
||||
RegisterNetEvent('vehiclerental:client:checkRentalKeys')
|
||||
AddEventHandler('vehiclerental:client:checkRentalKeys', function()
|
||||
TriggerServerEvent('vehiclerental:server:checkRentalKeys')
|
||||
end)
|
||||
|
||||
-- Überprüfe Mietfahrzeug-Schlüssel beim Öffnen des Schlüssel-Menüs
|
||||
if Config.useNativeUI then
|
||||
-- Speichere die ursprüngliche Funktion
|
||||
local originalGenerateKeyInventoryNativeUI = GenerateKeyInventoryNativeUI
|
||||
|
||||
-- Überschreibe die Funktion
|
||||
GenerateKeyInventoryNativeUI = function()
|
||||
-- Überprüfe Mietfahrzeug-Schlüssel
|
||||
TriggerServerEvent('vehiclerental:server:checkRentalKeys')
|
||||
|
||||
-- Warte kurz, damit die Schlüssel aktualisiert werden können
|
||||
Citizen.Wait(100)
|
||||
|
||||
-- Rufe die ursprüngliche Funktion auf
|
||||
originalGenerateKeyInventoryNativeUI()
|
||||
end
|
||||
end
|
||||
|
149
resources/[Developer]/sn_vehicleKey/config.lua
Normal file
149
resources/[Developer]/sn_vehicleKey/config.lua
Normal file
|
@ -0,0 +1,149 @@
|
|||
|
||||
Config = {}
|
||||
|
||||
-- set at least one to false, otherwise both menus will clash
|
||||
-- and don't forget to comment the menu in the fxmanifest.lua if you don't use it!
|
||||
-- Setting both to true does not work!
|
||||
-- setting both to false results in no menu being usable at all
|
||||
-- you can then just include the exports in your own menu if you have one
|
||||
Config.useContextMenu = false
|
||||
Config.useNativeUI = true
|
||||
|
||||
-- set to nil if you don't want to use the command
|
||||
Config.lockCommand = "lock"
|
||||
-- set to nil if you don't want to use the button (303, U)
|
||||
Config.lockKey = 10 -- PageUp
|
||||
|
||||
-- set to nil if you don't want to use the command
|
||||
Config.keyMenuCommand = "keys"
|
||||
-- set to nil if you don't want to use the button (311, K)
|
||||
Config.keyMenuKey = 56 -- F9
|
||||
|
||||
-- maximum distance (in meters) between the player and ContextMenu interaction point
|
||||
Config.maxDistance = 5.0
|
||||
|
||||
-- you can define more keymakers by just adding additional entries
|
||||
Config.Keymakers = {
|
||||
{
|
||||
-- ped model (yes, the ` symbols are correct)
|
||||
model = `s_m_m_autoshop_01`,
|
||||
-- position and heading vector4(x, y, z, heading)
|
||||
pos = vector4(170.33, -1799.13, 28.32, 313.0)
|
||||
},
|
||||
}
|
||||
|
||||
-- define costs for creating a new key and exchanging locks
|
||||
Config.Costs = {
|
||||
GetMoney = "cash", -- cash or bank
|
||||
newKey = 150,
|
||||
exchangeLocks = 650
|
||||
}
|
||||
|
||||
-- define job vehicles like this (this acts as a key for those vehicles)
|
||||
-- models in ``
|
||||
-- either exact plates or just a string that should be in the vehicles plate
|
||||
-- e.g. "LSPD" will let a police officer lock/unlock any vehicle with the plate "LSPD1337" or "13LSPD37"
|
||||
Config.JobVehicles = {
|
||||
-- examples:
|
||||
--["police"] = {
|
||||
--models = {
|
||||
--`police`,
|
||||
--`policeb`,
|
||||
--`pbus`
|
||||
--},
|
||||
--plates = {
|
||||
--""
|
||||
--}
|
||||
--},
|
||||
--["mechanic"] = {
|
||||
-- models = {
|
||||
-- `flatbed`
|
||||
-- },
|
||||
-- plates = {
|
||||
-- "MECH"
|
||||
-- }
|
||||
--},
|
||||
}
|
||||
|
||||
Config.Strings = {
|
||||
keymaker = "Schlüsseldienst",
|
||||
|
||||
helpText = "~w~Drück ~g~E ~w~um mit den Schlüsseldienst zu reden",
|
||||
|
||||
lockNotif = "~r~Fahrzeug Abgeschlossen",
|
||||
unlockNotif = "~g~Fahrzeug Aufgeschlossen",
|
||||
|
||||
createSuccess = "~g~Ersatzschlüssel Nachgemacht %s.",
|
||||
createNoMoney = "~r~Schlüssel kann nicht nachgemacht werden, du hast zu wenig Geld dabei",
|
||||
createFailed = "~r~Ersatzschlüssel machen Fehlgeschlagen %s!",
|
||||
|
||||
giveSuccess = "~g~Schlüssel an %s Weitergegeben.",
|
||||
giveSuccessPly = "~g~Schlüssel von %s erhalten ",
|
||||
giveFailed = "~r~Schlüssel geben von %s Fehlgeschlagen",
|
||||
|
||||
removeSuccess = "~r~Schlüssel für ~g~%s ~r~aus deiner Tasche Entfernt",
|
||||
removeNoMoney = "~r~Schloss kann nicht bezahlt werden, du hast kein Geld dabei",
|
||||
removeFailed = "~r~Entfernen von Schlüssel für ~g~%s ~r~Fehgeschlagen!",
|
||||
|
||||
deleteKeys = "~r~Du hast für dein ~g~%s ~r~Das Schloss ausgetasucht, und somit sind jetzt alle Schlüssel nicht mehr Gültig.",
|
||||
|
||||
|
||||
-- NativeUI
|
||||
NUI = {
|
||||
-- keymaker menu
|
||||
keymakerMenuTitle = "Schlüssel-System",
|
||||
keymakerMenuSub = "~g~Erstelle Schlüssel und Tausche deine Fahrzeug Schlösser aus",
|
||||
|
||||
-- create key
|
||||
createKeyTitle = "~g~Ersatzschlüssel erstellen",
|
||||
createKeyDesc = "Erstelle einen neuen Schlüssel für eines Ihrer Fahrzeuge ",
|
||||
createVehicleKey = "Erstelle einen Schlüssel für Ihr %s mit den Kennzeichen %s. ~g~Preis "..Config.Costs.newKey.."$",
|
||||
|
||||
-- invalidate Key
|
||||
invalKeyTitle = "~r~Fahrzeug Schlöss Tauschen",
|
||||
invalKeyDesc = "Tausche die Schlösser von Ihren Auto aus, alle schlüssel sind damit nicht mehr Gültig!",
|
||||
invalVehicleKey = "Schloss Tauschen von %s mit den Kennzeichen %s. ~g~Preis "..Config.Costs.exchangeLocks.."$",
|
||||
|
||||
-- key Inventory
|
||||
keyInventoryTitle = "Schlüssel",
|
||||
keyInventorySub = "~g~Da sind alle deine Schlüssel",
|
||||
|
||||
-- master keys
|
||||
masterKeysTitle = "Hauptschlüssel",
|
||||
masterKeysDesc = "~g~Zeigt alle deine Hauptschlüssel an",
|
||||
|
||||
-- additional keys
|
||||
keysTitle = "Ersatzschlüssel",
|
||||
keysDesc = "~g~Zeigt alle deine Ersatzschlüssel an",
|
||||
giveKeyTitle = "~g~Ersatzschlüssel Geben",
|
||||
giveKeyDesc = "~g~Ersatzschlüssel Geben",
|
||||
removeKeyTitle = "~r~Schlüssel Entfernen",
|
||||
removeKeyDesc = "~r~Schlüssel Entfernen",
|
||||
transferVehicleTitle = "~g~Fahrzeug übergeben",
|
||||
transferVehicleDesc = "~g~Übertrage ein Fahrzeug an einen Spieler in der Nähe",
|
||||
transferVehicleSuccess = "~g~Fahrzeug erfolgreich übergeben an %s",
|
||||
transferVehicleFailed = "~r~Fahrzeugübergabe fehlgeschlagen",
|
||||
transferVehicleReceived = "~g~Du hast ein Fahrzeug erhalten",
|
||||
noPlayersNearby = "~r~Keine Spieler in der Nähe",
|
||||
|
||||
|
||||
},
|
||||
|
||||
-- ContextMenu
|
||||
CM = {
|
||||
-- keymaker menu
|
||||
createKeyTitle = "Ersatzschlüssel",
|
||||
invalKeyTitle = "Schlossaustauschen",
|
||||
|
||||
-- key inventory
|
||||
masterKeysTitle = "~g~Hauptschlüssel",
|
||||
keysTitle = "~b~Ersatzschlüssel",
|
||||
|
||||
-- other player
|
||||
giveKey = "~r~Gebe ein Schlüssel, an der Person",
|
||||
|
||||
transferVehicleTitle = "Fahrzeug übergeben",
|
||||
|
||||
}
|
||||
}
|
||||
|
57
resources/[Developer]/sn_vehicleKey/fxmanifest.lua
Normal file
57
resources/[Developer]/sn_vehicleKey/fxmanifest.lua
Normal file
|
@ -0,0 +1,57 @@
|
|||
fx_version 'cerulean'
|
||||
games { 'gta5' }
|
||||
|
||||
author 'Mîhó'
|
||||
description 'Manage vehicle keys!'
|
||||
version '1.1.1'
|
||||
|
||||
dependency 'kimi_callbacks'
|
||||
dependency 'NativeUI'
|
||||
|
||||
server_scripts {
|
||||
--'@mysql-async/lib/MySQL.lua',
|
||||
'@oxmysql/lib/MySQL.lua',
|
||||
|
||||
'config.lua',
|
||||
'server.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
-- comment these lines if not using the ContextMenu
|
||||
--'@ContextMenu/screenToWorld.lua',
|
||||
--'@ContextMenu/Drawables/Color.lua',
|
||||
--'@ContextMenu/Drawables/Rect.lua',
|
||||
--'@ContextMenu/Drawables/Text.lua',
|
||||
--'@ContextMenu/Drawables/Sprite.lua',
|
||||
--'@ContextMenu/Menu/Item.lua',
|
||||
--'@ContextMenu/Menu/TextItem.lua',
|
||||
--'@ContextMenu/Menu/CheckboxItem.lua',
|
||||
--'@ContextMenu/Menu/SubmenuItem.lua',
|
||||
--'@ContextMenu/Menu/Separator.lua',
|
||||
--'@ContextMenu/Menu/Border.lua',
|
||||
--'@ContextMenu/Menu/Menu.lua',
|
||||
--'@ContextMenu/Menu/MenuPool.lua',
|
||||
|
||||
-- comment this line if not using NativeUILua
|
||||
'@NativeUI/NativeUI.lua',
|
||||
'@ox_lib/init.lua',
|
||||
|
||||
'config.lua',
|
||||
'client.lua'
|
||||
}
|
||||
|
||||
server_exports {
|
||||
'IsVehicleOwner',
|
||||
'IsKeyOwner',
|
||||
'IsVehicleOrKeyOwner',
|
||||
'GetPlayerKeys',
|
||||
'GetPlayerVehicles'
|
||||
}
|
||||
|
||||
exports {
|
||||
'IsVehicleOwner',
|
||||
'IsKeyOwner',
|
||||
'IsVehicleOrKeyOwner',
|
||||
'GetAllKeys',
|
||||
'GetAllVehicles'
|
||||
}
|
503
resources/[Developer]/sn_vehicleKey/server.lua
Normal file
503
resources/[Developer]/sn_vehicleKey/server.lua
Normal file
|
@ -0,0 +1,503 @@
|
|||
local CB = exports["kimi_callbacks"]
|
||||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
|
||||
-- create a new key
|
||||
CB:Register("VKC:createNewKey", function(source, plate, count)
|
||||
local src = source
|
||||
|
||||
if (plate == nil or count == nil) then
|
||||
print("^1[ERROR] \"plate\" or \"count\" was nil while creating new key for id " .. tostring(src))
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
if (Player) then
|
||||
local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper()
|
||||
|
||||
if (Player.Functions.GetMoney('cash') >= Config.Costs.newKey) then
|
||||
local results = MySQL.Sync.fetchAll("SELECT count FROM vehicle_keys WHERE owner = @owner AND (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
|
||||
local rows = 0
|
||||
if (#results > 0) then
|
||||
rows = MySQL.Sync.execute("UPDATE vehicle_keys SET count = count + @count WHERE owner = @owner AND (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate,
|
||||
["@count"] = count
|
||||
})
|
||||
else
|
||||
rows = MySQL.Sync.execute("INSERT INTO vehicle_keys (owner, plate, count) VALUES (@owner, @trimmedPlate, @count)", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@trimmedPlate"] = trimmedPlate,
|
||||
["@count"] = count
|
||||
})
|
||||
end
|
||||
|
||||
if (rows == 0) then
|
||||
return false
|
||||
end
|
||||
|
||||
Player.Functions.RemoveMoney('cash', Config.Costs.newKey)
|
||||
else
|
||||
return "noMoney"
|
||||
end
|
||||
else
|
||||
print("^1[ERROR] \"playerData\" was nil while creating new key for id " .. tostring(src))
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
-- remove a key from a plate
|
||||
CB:Register("VKC:removeKey", function(source, plate, num)
|
||||
local src = source
|
||||
|
||||
if (plate == nil or num == nil) then
|
||||
print("^1[ERROR] \"plate\" or \"num\" was nil while removing a key for id " .. tostring(src))
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
if (Player) then
|
||||
local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper()
|
||||
|
||||
local rows = MySQL.Sync.execute("DELETE FROM vehicle_keys WHERE owner = @owner and (plate = @plate OR plate = @trimmedPlate) and count = @num", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate,
|
||||
["@num"] = num
|
||||
})
|
||||
|
||||
if (rows == 0) then
|
||||
rows = MySQL.Sync.execute("UPDATE vehicle_keys SET count = count - @num WHERE owner = @owner and (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate,
|
||||
["@num"] = num
|
||||
})
|
||||
end
|
||||
|
||||
if (rows == 0) then
|
||||
return false
|
||||
end
|
||||
else
|
||||
print("^1[ERROR] \"playerData\" was nil while removing a key for id " .. tostring(src))
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
-- remove a key from a plate
|
||||
CB:Register("VKC:giveKeyToPlayer", function(source, plate, playerId)
|
||||
local src = source
|
||||
|
||||
if (plate == nil or playerId == nil) then
|
||||
print("^1[ERROR] \"plate\" or \"playerId\" was nil while giving a key for id " .. tostring(src))
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper()
|
||||
|
||||
local Playera = QBCore.Functions.GetPlayer(src) --MARK
|
||||
local Playerb = QBCore.Functions.GetPlayer(playerId)
|
||||
if (Playera and Playerb) then
|
||||
local rows = MySQL.Sync.execute("DELETE FROM vehicle_keys WHERE owner = @owner and (plate = @plate OR plate = @trimmedPlate) and count = 1", {
|
||||
["@owner"] = Playera.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
|
||||
if (rows == 0) then
|
||||
rows = MySQL.Sync.execute("UPDATE vehicle_keys SET count = count - 1 WHERE owner = @owner and (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Playera.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
end
|
||||
|
||||
if (rows == 0) then
|
||||
return false
|
||||
else
|
||||
local results = MySQL.Sync.fetchAll("SELECT count FROM vehicle_keys WHERE owner = @owner AND (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Playerb.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
|
||||
rows = 0
|
||||
if (#results > 0) then
|
||||
rows = MySQL.Sync.execute("UPDATE vehicle_keys SET count = count + 1 WHERE owner = @owner AND (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Playerb.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
else
|
||||
rows = MySQL.Sync.execute("INSERT INTO vehicle_keys (owner, plate, count) VALUES (@owner, @trimmedPlate, 1)", {
|
||||
["@owner"] = Playerb.PlayerData.citizenid,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
end
|
||||
|
||||
if (rows == 0) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
else
|
||||
print("^1[ERROR] \"playerData\" or \"playerData2\" was nil while giving a key for id " .. tostring(src))
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
TriggerClientEvent("VKC:giveKeyNotif", playerId, trimmedPlate)
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
-- remove all keys from a plate
|
||||
CB:Register("VKC:removeAllKeys", function(source, plate)
|
||||
local src = source
|
||||
|
||||
if (plate == nil) then
|
||||
print("^1[ERROR] \"plate\" was nil while removing all keys for " .. tostring(src))
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
if (Player) then
|
||||
local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper()
|
||||
|
||||
if (Player.Functions.GetMoney(Config.Costs.GetMoney) >= Config.Costs.exchangeLocks) then
|
||||
MySQL.Sync.execute("DELETE FROM vehicle_keys WHERE plate = @trimmedPlate", {
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
|
||||
Player.Functions.RemoveMoney(Config.Costs.GetMoney, Config.Costs.exchangeLocks)
|
||||
|
||||
return true
|
||||
else
|
||||
return "noMoney"
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end)
|
||||
|
||||
-- get all owned vehicles from player
|
||||
function GetPlayerVehicleData(playerId)
|
||||
if (playerId == nil) then
|
||||
print("^1[ERROR] Parameter \"playerId\" was nil while triggering server export \"GetOwnedVehicles\"!")
|
||||
return
|
||||
end
|
||||
local Player = QBCore.Functions.GetPlayer(playerId)
|
||||
local vehicles = {}
|
||||
if (Player) then
|
||||
local results = MySQL.Sync.fetchAll("SELECT plate, vehicle FROM player_vehicles WHERE citizenid = @owner", {
|
||||
["@owner"] = Player.PlayerData.citizenid
|
||||
})
|
||||
|
||||
for i = 1, #results, 1 do
|
||||
print(json.encode(results[i]))
|
||||
table.insert(vehicles, {
|
||||
results[i].plate,
|
||||
results[i].vehicle})
|
||||
--json.decode(results[i].vehicles).model})
|
||||
end
|
||||
else
|
||||
print("^1[ERROR] \"playerData\" was nil while getting owned vehicles for id " .. tostring(playerId))
|
||||
end
|
||||
|
||||
print(json.encode(vehicles))
|
||||
return vehicles
|
||||
end
|
||||
CB:Register("VKC:getPlayerVehicleData", GetPlayerVehicleData)
|
||||
|
||||
-- get all owned keys from player
|
||||
function GetPlayerKeys(playerId)
|
||||
if (playerId == nil) then
|
||||
print("^1[ERROR] Parameter \"playerId\" was nil while triggering server export \"GetOwnedKeys\"!")
|
||||
return
|
||||
end
|
||||
|
||||
local keys = {}
|
||||
|
||||
local Player = QBCore.Functions.GetPlayer(playerId)
|
||||
if (Player) then
|
||||
local results = MySQL.Sync.fetchAll("SELECT vehicle_keys.plate, vehicle_keys.count, player_vehicles.vehicle FROM vehicle_keys INNER JOIN player_vehicles ON vehicle_keys.plate = player_vehicles.plate WHERE vehicle_keys.owner = @owner", {
|
||||
["@owner"] = Player.PlayerData.citizenid
|
||||
})
|
||||
|
||||
for i = 1, #results, 1 do
|
||||
table.insert(keys, {
|
||||
plate = results[i].plate,
|
||||
count = results[i].count,
|
||||
model = results[i].vehicle --json.decode(results[i].vehicle).model
|
||||
})
|
||||
end
|
||||
else
|
||||
print("^1[ERROR] \"playerData\" was nil while getting owned keys for id " .. tostring(playerId))
|
||||
end
|
||||
|
||||
return keys
|
||||
end
|
||||
CB:Register("VKC:getPlayerKeys", GetPlayerKeys)
|
||||
|
||||
-- return if playerId is owner of vehicle
|
||||
function IsVehicleOwner(playerId, plate)
|
||||
if (playerId == nil) then
|
||||
print("^1[ERROR] Parameter \"playerId\" was nil while triggering server export \"IsVehicleOwner\"!")
|
||||
return
|
||||
end
|
||||
if (plate == nil) then
|
||||
print("^1[ERROR] Parameter \"plate\" was nil while triggering server export \"IsVehicleOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
local Player = QBCore.Functions.GetPlayer(playerId)
|
||||
if (Player) then
|
||||
local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper()
|
||||
|
||||
local results = MySQL.Sync.fetchAll("SELECT plate FROM player_vehicles WHERE citizenid = @owner and (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
|
||||
if (#results > 0) then
|
||||
return true
|
||||
end
|
||||
else
|
||||
print("^1[ERROR] \"playerData\" was nil while getting vehicle ownership for id " .. tostring(playerId))
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
CB:Register("VKC:isVehicleOwner", IsVehicleOwner)
|
||||
|
||||
-- return if playerId is owner of key
|
||||
function IsKeyOwner(playerId, plate, model)
|
||||
if (playerId == nil) then
|
||||
print("^1[ERROR] Parameter \"playerId\" was nil while triggering server export \"IsKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
if (plate == nil) then
|
||||
print("^1[ERROR] Parameter \"plate\" was nil while triggering server export \"IsKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
if (model == nil) then
|
||||
print("^1[ERROR] Parameter \"model\" was nil while triggering server export \"IsKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
local Player = QBCore.Functions.GetPlayer(playerId)
|
||||
if (Player) then
|
||||
local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper()
|
||||
|
||||
if (IsJobVehicle(Player.PlayerData.job.name, trimmedPlate, model)) then
|
||||
return true
|
||||
end
|
||||
|
||||
local results = MySQL.Sync.fetchAll("SELECT plate FROM vehicle_keys WHERE owner = @owner and (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
|
||||
if (#results > 0) then
|
||||
return true
|
||||
end
|
||||
else
|
||||
print("^1[ERROR] \"playerData\" was nil while getting key ownership for id " .. tostring(playerId))
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
exports["kimi_callbacks"]:Register("VKC:isKeyOwner", IsKeyOwner)
|
||||
|
||||
-- return if playerId is owner of vehicle or key
|
||||
function IsVehicleOrKeyOwner(playerId, plate, model)
|
||||
if (playerId == nil) then
|
||||
print("^1[ERROR] Parameter \"playerId\" was nil while triggering server export \"IsVehicleOrKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
if (plate == nil) then
|
||||
print("^1[ERROR] Parameter \"plate\" was nil while triggering server export \"IsVehicleOrKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
if (model == nil) then
|
||||
print("^1[ERROR] Parameter \"model\" was nil while triggering server export \"IsVehicleOrKeyOwner\"!")
|
||||
return
|
||||
end
|
||||
|
||||
local Player = QBCore.Functions.GetPlayer(playerId)
|
||||
if (Player) then
|
||||
local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper()
|
||||
|
||||
if (IsJobVehicle(Player.PlayerData.job.name, trimmedPlate, model)) then
|
||||
return true
|
||||
end
|
||||
|
||||
local results = MySQL.Sync.fetchAll("SELECT plate FROM player_vehicles WHERE citizenid = @owner and (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
|
||||
if (#results > 0) then
|
||||
return true
|
||||
end
|
||||
|
||||
results = MySQL.Sync.fetchAll("SELECT plate FROM vehicle_keys WHERE owner = @owner and (plate = @plate OR plate = @trimmedPlate)", {
|
||||
["@owner"] = Player.PlayerData.citizenid,
|
||||
["@plate"] = plate,
|
||||
["@trimmedPlate"] = trimmedPlate
|
||||
})
|
||||
|
||||
if (#results > 0) then
|
||||
return true
|
||||
end
|
||||
else
|
||||
print("^1[ERROR] \"playerData\" was nil while getting vehicle or key ownership for id " .. tostring(playerId))
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
CB:Register("VKC:isVehicleOrKeyOwner", IsVehicleOrKeyOwner)
|
||||
|
||||
|
||||
|
||||
-- if the given vehicle is a job vehicle
|
||||
function IsJobVehicle(job, plate, model)
|
||||
local jobData = Config.JobVehicles[job]
|
||||
|
||||
if (jobData == nil) then
|
||||
return false
|
||||
end
|
||||
|
||||
for i, m in ipairs(jobData.models) do
|
||||
if (m == model) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
for i, p in ipairs(jobData.plates) do
|
||||
if (plate:find(p:upper())) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- toggle door lock over network to ensure it always works
|
||||
RegisterServerEvent("VKC:toggleLockNet")
|
||||
AddEventHandler("VKC:toggleLockNet", function(vehicleNetId, unlocked)
|
||||
local vehicle = NetworkGetEntityFromNetworkId(vehicleNetId)
|
||||
if (DoesEntityExist(vehicle)) then
|
||||
local entityOwner = NetworkGetEntityOwner(vehicle)
|
||||
TriggerClientEvent("VKC:toggleLockOnPlayer", entityOwner, vehicleNetId, unlocked)
|
||||
end
|
||||
end)
|
||||
RegisterServerEvent("VKC:playDoorLockSoundNet")
|
||||
AddEventHandler("VKC:playDoorLockSoundNet", function(vehicleNetId, lock)
|
||||
TriggerClientEvent("VKC:playDoorLockSound", -1, vehicleNetId, lock)
|
||||
end)
|
||||
|
||||
|
||||
RegisterServerEvent('VKC:setvehkey')
|
||||
AddEventHandler('VKC:setvehkey', function(plate)
|
||||
local _source = source
|
||||
local xPlayer = QBCore.Functions.GetPlayer(_source)
|
||||
|
||||
MySQL.query("INSERT INTO vehicle_keys(owner, plate, count) VALUES (?, ?, ?)", {xPlayer.PlayerData.citizenid, plate, 1})
|
||||
end)
|
||||
|
||||
RegisterServerEvent('VKC:delvehkey')
|
||||
AddEventHandler('VKC:delvehkey', function(plate, owner)
|
||||
local _source = source
|
||||
if owner then
|
||||
local xPlayer = QBCore.Functions.GetPlayer(_source)
|
||||
|
||||
MySQL.query("DELETE FROM vehicle_keys WHERE plate = ? and owner = ?", {plate, xPlayer.PlayerData.citizenid})
|
||||
else
|
||||
MySQL.query("DELETE FROM vehicle_keys WHERE plate = ?", {plate})
|
||||
end
|
||||
end)
|
||||
|
||||
-- Fahrzeugbesitz an einen anderen Spieler übertragen
|
||||
CB:Register("VKC:transferVehicleOwnership", function(source, plate, targetPlayerId)
|
||||
local src = source
|
||||
|
||||
if (plate == nil or targetPlayerId == nil) then
|
||||
print("^1[ERROR] \"plate\" or \"targetPlayerId\" was nil while transferring vehicle ownership for id " .. tostring(src))
|
||||
return false
|
||||
end
|
||||
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
local TargetPlayer = QBCore.Functions.GetPlayer(targetPlayerId)
|
||||
|
||||
if (not Player or not TargetPlayer) then
|
||||
print("^1[ERROR] Player or target player not found while transferring vehicle ownership")
|
||||
return false
|
||||
end
|
||||
|
||||
local trimmedPlate = plate:gsub("^%s*(.-)%s*$", "%1"):upper()
|
||||
|
||||
-- Überprüfen, ob der Spieler das Fahrzeug besitzt
|
||||
local isOwner = IsVehicleOwner(src, trimmedPlate)
|
||||
if not isOwner then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Fahrzeugmodell für die Benachrichtigung abrufen
|
||||
local vehicleModel = nil
|
||||
local results = MySQL.Sync.fetchAll("SELECT vehicle FROM player_vehicles WHERE plate = @plate AND citizenid = @owner", {
|
||||
["@plate"] = trimmedPlate,
|
||||
["@owner"] = Player.PlayerData.citizenid
|
||||
})
|
||||
|
||||
if #results > 0 then
|
||||
vehicleModel = results[1].vehicle
|
||||
end
|
||||
|
||||
-- Besitz in der Datenbank übertragen
|
||||
local success = MySQL.Sync.execute("UPDATE player_vehicles SET citizenid = @newOwner WHERE plate = @plate AND citizenid = @oldOwner", {
|
||||
["@newOwner"] = TargetPlayer.PlayerData.citizenid,
|
||||
["@plate"] = trimmedPlate,
|
||||
["@oldOwner"] = Player.PlayerData.citizenid
|
||||
})
|
||||
|
||||
if success > 0 then
|
||||
-- Alle Schlüssel auf den neuen Besitzer übertragen
|
||||
MySQL.Sync.execute("DELETE FROM vehicle_keys WHERE plate = @plate", {
|
||||
["@plate"] = trimmedPlate
|
||||
})
|
||||
|
||||
-- Einen Schlüssel dem neuen Besitzer geben
|
||||
MySQL.Sync.execute("INSERT INTO vehicle_keys (owner, plate, count) VALUES (@owner, @plate, 1)", {
|
||||
["@owner"] = TargetPlayer.PlayerData.citizenid,
|
||||
["@plate"] = trimmedPlate
|
||||
})
|
||||
|
||||
-- Den Zielspieler benachrichtigen
|
||||
TriggerClientEvent("VKC:vehicleTransferNotif", targetPlayerId, trimmedPlate, vehicleModel)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end)
|
27
resources/[Developer]/sn_vehicleKey/vehicle_keys.sql
Normal file
27
resources/[Developer]/sn_vehicleKey/vehicle_keys.sql
Normal file
|
@ -0,0 +1,27 @@
|
|||
-- --------------------------------------------------------
|
||||
-- Host: 127.0.0.1
|
||||
-- Server version: 10.1.28-MariaDB - mariadb.org binary distribution
|
||||
-- Server OS: Win32
|
||||
-- HeidiSQL Version: 11.0.0.5919
|
||||
-- --------------------------------------------------------
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!50503 SET NAMES utf8mb4 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
|
||||
-- Dumping structure for table essentialmode.vehicle_keys
|
||||
CREATE TABLE IF NOT EXISTS `vehicle_keys` (
|
||||
`owner` varchar(60) NOT NULL,
|
||||
`plate` varchar(8) NOT NULL,
|
||||
`count` smallint(6) NOT NULL,
|
||||
KEY `plate` (`plate`),
|
||||
KEY `owner` (`owner`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
-- Data exporting was unselected.
|
||||
|
||||
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
Loading…
Add table
Add a link
Reference in a new issue