From 3ddb7cd650a739fdb15fc1f11e592d4301359f2b Mon Sep 17 00:00:00 2001 From: Nordi98 Date: Tue, 29 Jul 2025 10:14:29 +0200 Subject: [PATCH] Update server.lua --- .../[inventory]/nordi_vending/server.lua | 459 ++++++++++-------- 1 file changed, 245 insertions(+), 214 deletions(-) diff --git a/resources/[inventory]/nordi_vending/server.lua b/resources/[inventory]/nordi_vending/server.lua index 9e877da76..3c6938332 100644 --- a/resources/[inventory]/nordi_vending/server.lua +++ b/resources/[inventory]/nordi_vending/server.lua @@ -17,24 +17,38 @@ CreateThread(function() items = json.decode(data.items) or {}, prices = json.decode(data.prices) or {}, managers = json.decode(data.managers) or {}, - stash = 'vending_' .. data.id + stash = 'vending_' .. data.id, + entityId = data.entity_id } end print("^2[VENDING]^7 Loaded " .. #result .. " vending machines") end end) +-- Helper function to get machine ID by entity +function getMachineIdByEntity(entityId) + for id, machine in pairs(vendingMachines) do + if machine.entityId == entityId then + print("^2[VENDING]^7 Found machine #" .. id .. " by entity ID: " .. entityId) + return id + end + end + print("^1[VENDING]^7 No machine found with entity ID: " .. entityId) + return nil +end + -- Register vending machine (when player buys it) -RegisterNetEvent('vending:server:registerMachine', function(coords, prop) +RegisterNetEvent('vending:server:registerMachine', function(coords, prop, entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - -- Check if there's already a machine at these coords + print("^2[VENDING]^7 Registering machine: Entity ID: " .. entityId .. ", Prop: " .. prop) + + -- Check if there's already a machine with this entity ID for id, machine in pairs(vendingMachines) do - local dist = #(vector3(coords.x, coords.y, coords.z) - vector3(machine.coords.x, machine.coords.y, machine.coords.z)) - if dist < 2.0 then - TriggerClientEvent('QBCore:Notify', src, 'Hier ist bereits ein Automat registriert!', 'error') + if machine.entityId == entityId then + TriggerClientEvent('QBCore:Notify', src, 'Dieser Automat ist bereits registriert!', 'error') return end end @@ -49,14 +63,15 @@ RegisterNetEvent('vending:server:registerMachine', function(coords, prop) Player.Functions.RemoveMoney('cash', Config.VendingMachinePrice) -- Create machine in database - local machineId = MySQL.insert.await('INSERT INTO vending_machines (owner, coords, prop, money, items, prices, managers) VALUES (?, ?, ?, ?, ?, ?, ?)', { + local machineId = MySQL.insert.await('INSERT INTO vending_machines (owner, coords, prop, money, items, prices, managers, entity_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', { Player.PlayerData.citizenid, json.encode(coords), prop, 0, json.encode({}), json.encode({}), - json.encode({}) + json.encode({}), + entityId }) -- Add to memory @@ -69,22 +84,23 @@ RegisterNetEvent('vending:server:registerMachine', function(coords, prop) items = {}, prices = {}, managers = {}, - stash = 'vending_' .. machineId + stash = 'vending_' .. machineId, + entityId = entityId } - print("^2[VENDING]^7 New vending machine registered: " .. machineId) + print("^2[VENDING]^7 New vending machine registered: #" .. machineId .. " | Entity ID: " .. entityId .. " | Owner: " .. Player.PlayerData.citizenid) TriggerClientEvent('QBCore:Notify', src, 'Verkaufsautomat erfolgreich gekauft für $' .. Config.VendingMachinePrice .. '!', 'success') TriggerClientEvent('vending:client:refreshTargets', -1) end) -- Sell vending machine -RegisterNetEvent('vending:server:sellMachine', function(coords, machineId) +RegisterNetEvent('vending:server:sellMachine', function(machineId, entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end if not machineId then - machineId = getMachineIdByCoords(coords) + machineId = getMachineIdByEntity(entityId) end if not machineId then @@ -141,13 +157,25 @@ end) -- Check if player can manage machine function canManageMachine(playerId, machineId) local Player = QBCore.Functions.GetPlayer(playerId) - if not Player then return false end + if not Player then + print("^1[VENDING]^7 canManageMachine: Player not found") + return false + end local machine = vendingMachines[machineId] - if not machine then return false end + if not machine then + print("^1[VENDING]^7 canManageMachine: Machine not found") + return false + end -- Check if player is owner - if machine.owner == Player.PlayerData.citizenid then + local isOwner = (machine.owner == Player.PlayerData.citizenid) + print("^2[VENDING]^7 canManageMachine: Player " .. playerId .. " checking machine #" .. machineId) + print("^2[VENDING]^7 canManageMachine: Machine owner: " .. machine.owner) + print("^2[VENDING]^7 canManageMachine: Player citizenid: " .. Player.PlayerData.citizenid) + print("^2[VENDING]^7 canManageMachine: Is owner: " .. tostring(isOwner)) + + if isOwner then return true end @@ -155,25 +183,37 @@ function canManageMachine(playerId, machineId) if machine.managers then for _, manager in pairs(machine.managers) do if manager == Player.PlayerData.citizenid then + print("^2[VENDING]^7 canManageMachine: Player is manager") return true end end end + print("^1[VENDING]^7 canManageMachine: Player is NOT owner or manager") return false end -- Open management menu -RegisterNetEvent('vending:server:openManagement', function(coords) +RegisterNetEvent('vending:server:openManagement', function(entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - local machineId = getMachineIdByCoords(coords) - if not machineId then return end + print("^2[VENDING]^7 Player " .. src .. " trying to manage machine. Entity ID: " .. entityId) + + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end local machine = vendingMachines[machineId] + -- Debug output + print("^2[VENDING]^7 Player " .. src .. " (citizenid: " .. Player.PlayerData.citizenid .. ") trying to manage machine #" .. machineId) + print("^2[VENDING]^7 Machine owner: " .. machine.owner) + print("^2[VENDING]^7 Is owner: " .. tostring(machine.owner == Player.PlayerData.citizenid)) + -- Check if player can manage if not canManageMachine(src, machineId) then TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung diesen Automaten zu verwalten!', 'error') @@ -182,18 +222,22 @@ RegisterNetEvent('vending:server:openManagement', function(coords) -- Add isOwner flag to distinguish between owner and manager machine.isOwner = (machine.owner == Player.PlayerData.citizenid) + print("^2[VENDING]^7 Setting isOwner flag to: " .. tostring(machine.isOwner)) TriggerClientEvent('vending:client:openManagement', src, machine) end) -- Open stash -RegisterNetEvent('vending:server:openStash', function(coords) +RegisterNetEvent('vending:server:openStash', function(entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - local machineId = getMachineIdByCoords(coords) - if not machineId then return end + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end -- Check if player can manage if not canManageMachine(src, machineId) then @@ -210,14 +254,18 @@ RegisterNetEvent('vending:server:openStash', function(coords) label = 'Vending Machine #' .. machine.id }) end) + -- Set item price -RegisterNetEvent('vending:server:setItemPrice', function(coords, itemName, price) +RegisterNetEvent('vending:server:setItemPrice', function(itemName, price, entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - local machineId = getMachineIdByCoords(coords) - if not machineId then return end + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end -- Check if player can manage if not canManageMachine(src, machineId) then @@ -235,13 +283,16 @@ RegisterNetEvent('vending:server:setItemPrice', function(coords, itemName, price end) -- Withdraw money -RegisterNetEvent('vending:server:withdrawMoney', function(coords, amount) +RegisterNetEvent('vending:server:withdrawMoney', function(amount, entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - local machineId = getMachineIdByCoords(coords) - if not machineId then return end + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end -- Check if player can manage if not canManageMachine(src, machineId) then @@ -266,13 +317,16 @@ RegisterNetEvent('vending:server:withdrawMoney', function(coords, amount) end) -- Buy item from vending machine with quantity selection -RegisterNetEvent('vending:server:buyItem', function(coords, itemName, amount) +RegisterNetEvent('vending:server:buyItem', function(itemName, amount, entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - local machineId = getMachineIdByCoords(coords) - if not machineId then return end + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end local machine = vendingMachines[machineId] local price = machine.prices[itemName] or Config.DefaultPrice @@ -335,13 +389,16 @@ RegisterNetEvent('vending:server:buyItem', function(coords, itemName, amount) end) -- Add manager to vending machine -RegisterNetEvent('vending:server:addManager', function(coords, targetId) +RegisterNetEvent('vending:server:addManager', function(targetId, entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - local machineId = getMachineIdByCoords(coords) - if not machineId then return end + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end local machine = vendingMachines[machineId] @@ -379,13 +436,16 @@ RegisterNetEvent('vending:server:addManager', function(coords, targetId) end) -- Remove manager from vending machine -RegisterNetEvent('vending:server:removeManager', function(coords, citizenid) +RegisterNetEvent('vending:server:removeManager', function(citizenid, entityId) local src = source local Player = QBCore.Functions.GetPlayer(src) if not Player then return end - local machineId = getMachineIdByCoords(coords) - if not machineId then return end + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end local machine = vendingMachines[machineId] @@ -431,9 +491,148 @@ RegisterNetEvent('vending:server:removeManager', function(coords, citizenid) end end) +-- Start robbery +RegisterNetEvent('vending:server:startRobbery', function(entityId) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + if not Player then return end + + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end + + local machine = vendingMachines[machineId] + + -- Check if player has required item + local hasItem = Player.Functions.GetItemByName(Config.RobberyItem) + if not hasItem or hasItem.amount < 1 then + TriggerClientEvent('QBCore:Notify', src, 'Du benötigst einen ' .. Config.RobberyItem, 'error') + return + end + + -- Check if already being robbed + if robberyInProgress[machineId] then + TriggerClientEvent('QBCore:Notify', src, 'Dieser Automat wird bereits aufgebrochen!', 'error') + return + end + + -- Check if machine has money + if machine.money < Config.MinRobberyAmount then + TriggerClientEvent('QBCore:Notify', src, 'Nicht genug Geld im Automaten!', 'error') + return + end + + robberyInProgress[machineId] = true + + -- Alert police + local streetHash = GetStreetNameAtCoord(machine.coords.x, machine.coords.y, machine.coords.z) + local streetName = GetStreetNameFromHashKey(streetHash) + + local players = QBCore.Functions.GetQBPlayers() + for k, v in pairs(players) do + if v.PlayerData.job.name == 'police' and v.PlayerData.job.onduty then + TriggerClientEvent('vending:client:policeAlert', v.PlayerData.source, machine.coords, streetName) + end + end + + -- Alert owner and managers + for _, playerId in ipairs(QBCore.Functions.GetPlayers()) do + local targetPlayer = QBCore.Functions.GetPlayer(playerId) + if targetPlayer then + if targetPlayer.PlayerData.citizenid == machine.owner then + TriggerClientEvent('QBCore:Notify', targetPlayer.PlayerData.source, 'Dein Verkaufsautomat wird gerade aufgebrochen! Standort: ' .. streetName, 'error', 10000) + elseif machine.managers then + for _, manager in pairs(machine.managers) do + if targetPlayer.PlayerData.citizenid == manager then + TriggerClientEvent('QBCore:Notify', targetPlayer.PlayerData.source, 'Ein Verkaufsautomat, den du verwaltest, wird gerade aufgebrochen! Standort: ' .. streetName, 'error', 10000) + break + end + end + end + end + end + + TriggerClientEvent('vending:client:startRobbery', src, entityId) +end) + +-- Complete robbery +RegisterNetEvent('vending:server:completeRobbery', function(entityId, success) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + if not Player then return end + + local machineId = getMachineIdByEntity(entityId) + if not machineId then + TriggerClientEvent('QBCore:Notify', src, 'Automat nicht gefunden!', 'error') + return + end + + local machine = vendingMachines[machineId] + robberyInProgress[machineId] = false + + if success then + local stolenAmount = math.random(Config.MinRobberyAmount, math.min(machine.money, Config.MaxRobberyAmount)) + + -- Remove money from machine + machine.money = machine.money - stolenAmount + MySQL.update('UPDATE vending_machines SET money = ? WHERE id = ?', {machine.money, machineId}) + + -- Give money to player + Player.Functions.AddMoney('cash', stolenAmount) + TriggerClientEvent('QBCore:Notify', src, 'Du hast $' .. stolenAmount .. ' gestohlen!', 'success') + + -- Remove robbery item with chance + if math.random(1, 100) <= Config.RobberyItemBreakChance then + Player.Functions.RemoveItem(Config.RobberyItem, 1) + TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[Config.RobberyItem], 'remove') + TriggerClientEvent('QBCore:Notify', src, 'Dein ' .. Config.RobberyItem .. ' ist kaputt gegangen!', 'error') + end + else + TriggerClientEvent('QBCore:Notify', src, 'Aufbruch fehlgeschlagen!', 'error') + end +end) + +-- Get machine data by entity +QBCore.Functions.CreateCallback('vending:server:getMachineByEntity', function(source, cb, entityId) + local machineId = getMachineIdByEntity(entityId) + if machineId then + cb(vendingMachines[machineId]) + else + cb(nil) + end +end) + +-- Get stash items for vending machine menu +QBCore.Functions.CreateCallback('vending:server:getStashItems', function(source, cb, entityId) + local machineId = getMachineIdByEntity(entityId) + if not machineId then + cb({}) + return + end + + local machine = vendingMachines[machineId] + + -- Get stash items using correct export + local stashItems = exports["tgiann-inventory"]:GetSecondaryInventoryItems("stash", machine.stash) + local items = {} + + if stashItems then + for slot, item in pairs(stashItems) do + if item.amount > 0 then + item.price = machine.prices[item.name] or Config.DefaultPrice + table.insert(items, item) + end + end + end + + cb(items) +end) + -- Get managers list -QBCore.Functions.CreateCallback('vending:server:getManagers', function(source, cb, coords) - local machineId = getMachineIdByCoords(coords) +QBCore.Functions.CreateCallback('vending:server:getManagers', function(source, cb, entityId) + local machineId = getMachineIdByEntity(entityId) if not machineId then cb({}) return @@ -485,177 +684,15 @@ QBCore.Functions.CreateCallback('vending:server:getManagers', function(source, c cb(managersList) end) --- Start robbery -RegisterNetEvent('vending:server:startRobbery', function(coords) - local src = source - local Player = QBCore.Functions.GetPlayer(src) - if not Player then return end - - local machineId = getMachineIdByCoords(coords) - if not machineId then return end - - local machine = vendingMachines[machineId] - - -- Check if player has required item - local hasItem = Player.Functions.GetItemByName(Config.RobberyItem) - if not hasItem or hasItem.amount < 1 then - TriggerClientEvent('QBCore:Notify', src, 'Du benötigst einen ' .. Config.RobberyItem, 'error') - return - end - - -- Check if already being robbed - if robberyInProgress[machineId] then - TriggerClientEvent('QBCore:Notify', src, 'Dieser Automat wird bereits aufgebrochen!', 'error') - return - end - - -- Check if machine has money - if machine.money < Config.MinRobberyAmount then - TriggerClientEvent('QBCore:Notify', src, 'Nicht genug Geld im Automaten!', 'error') - return - end - - robberyInProgress[machineId] = true - - -- Alert police - local streetHash = GetStreetNameAtCoord(coords.x, coords.y, coords.z) - local streetName = GetStreetNameFromHashKey(streetHash) - - local players = QBCore.Functions.GetQBPlayers() - for k, v in pairs(players) do - if v.PlayerData.job.name == 'police' and v.PlayerData.job.onduty then - TriggerClientEvent('vending:client:policeAlert', v.PlayerData.source, coords, streetName) - end - end - - -- Alert owner and managers - for _, playerId in ipairs(QBCore.Functions.GetPlayers()) do - local targetPlayer = QBCore.Functions.GetPlayer(playerId) - if targetPlayer then - if targetPlayer.PlayerData.citizenid == machine.owner then - TriggerClientEvent('QBCore:Notify', targetPlayer.PlayerData.source, 'Dein Verkaufsautomat wird gerade aufgebrochen! Standort: ' .. streetName, 'error', 10000) - elseif machine.managers then - for _, manager in pairs(machine.managers) do - if targetPlayer.PlayerData.citizenid == manager then - TriggerClientEvent('QBCore:Notify', targetPlayer.PlayerData.source, 'Ein Verkaufsautomat, den du verwaltest, wird gerade aufgebrochen! Standort: ' .. streetName, 'error', 10000) - break - end - end - end - end - end - - TriggerClientEvent('vending:client:startRobbery', src, coords) -end) - --- Complete robbery -RegisterNetEvent('vending:server:completeRobbery', function(coords, success) - local src = source - local Player = QBCore.Functions.GetPlayer(src) - if not Player then return end - - local machineId = getMachineIdByCoords(coords) - if not machineId then return end - - local machine = vendingMachines[machineId] - robberyInProgress[machineId] = false - - if success then - local stolenAmount = math.random(Config.MinRobberyAmount, math.min(machine.money, Config.MaxRobberyAmount)) - - -- Remove money from machine - machine.money = machine.money - stolenAmount - MySQL.update('UPDATE vending_machines SET money = ? WHERE id = ?', {machine.money, machineId}) - - -- Give money to player - Player.Functions.AddMoney('cash', stolenAmount) - TriggerClientEvent('QBCore:Notify', src, 'Du hast $' .. stolenAmount .. ' gestohlen!', 'success') - - -- Remove robbery item with chance - if math.random(1, 100) <= Config.RobberyItemBreakChance then - Player.Functions.RemoveItem(Config.RobberyItem, 1) - TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[Config.RobberyItem], 'remove') - TriggerClientEvent('QBCore:Notify', src, 'Dein ' .. Config.RobberyItem .. ' ist kaputt gegangen!', 'error') - end - else - TriggerClientEvent('QBCore:Notify', src, 'Aufbruch fehlgeschlagen!', 'error') - end -end) - --- Helper function to get machine ID by coordinates -function getMachineIdByCoords(coords) - for id, machine in pairs(vendingMachines) do - local dist = #(vector3(coords.x, coords.y, coords.z) - vector3(machine.coords.x, machine.coords.y, machine.coords.z)) - if dist < 2.0 then - return id - end - end - return nil -end - --- Get machine data by coordinates -QBCore.Functions.CreateCallback('vending:server:getMachineByCoords', function(source, cb, coords) - local machineId = getMachineIdByCoords(coords) - if machineId then - cb(vendingMachines[machineId]) - else - cb(nil) - end -end) - --- Get stash items for vending machine menu -QBCore.Functions.CreateCallback('vending:server:getStashItems', function(source, cb, coords) - local machineId = getMachineIdByCoords(coords) - if not machineId then - cb({}) - return - end - - local machine = vendingMachines[machineId] - - -- Get stash items using correct export - local stashItems = exports["tgiann-inventory"]:GetSecondaryInventoryItems("stash", machine.stash) - local items = {} - - if stashItems then - for slot, item in pairs(stashItems) do - if item.amount > 0 then - item.price = machine.prices[item.name] or Config.DefaultPrice - table.insert(items, item) - end - end - end - - cb(items) -end) - --- Check if player owns machine -QBCore.Functions.CreateCallback('vending:server:isOwner', function(source, cb, coords) - local Player = QBCore.Functions.GetPlayer(source) - if not Player then - cb(false) - return - end - - local machineId = getMachineIdByCoords(coords) - if not machineId then - cb(false) - return - end - - local machine = vendingMachines[machineId] - cb(machine.owner == Player.PlayerData.citizenid) +-- Check if machine exists +QBCore.Functions.CreateCallback('vending:server:machineExists', function(source, cb, entityId) + local machineId = getMachineIdByEntity(entityId) + cb(machineId ~= nil) end) -- Check if player can manage machine -QBCore.Functions.CreateCallback('vending:server:canManage', function(source, cb, coords) - local Player = QBCore.Functions.GetPlayer(source) - if not Player then - cb(false) - return - end - - local machineId = getMachineIdByCoords(coords) +QBCore.Functions.CreateCallback('vending:server:canManage', function(source, cb, entityId) + local machineId = getMachineIdByEntity(entityId) if not machineId then cb(false) return @@ -664,12 +701,6 @@ QBCore.Functions.CreateCallback('vending:server:canManage', function(source, cb, cb(canManageMachine(source, machineId)) end) --- Check if machine exists at coords -QBCore.Functions.CreateCallback('vending:server:machineExists', function(source, cb, coords) - local machineId = getMachineIdByCoords(coords) - cb(machineId ~= nil) -end) - -- Get online players for manager selection QBCore.Functions.CreateCallback('vending:server:getOnlinePlayers', function(source, cb) local src = source @@ -703,7 +734,7 @@ QBCore.Commands.Add('vendingdebug', 'Debug vending machines (Admin Only)', {}, f local count = 0 for id, machine in pairs(vendingMachines) do count = count + 1 - print("^2[VENDING]^7 Machine #" .. id .. " | Owner: " .. machine.owner .. " | Money: $" .. machine.money) + print("^2[VENDING]^7 Machine #" .. id .. " | Owner: " .. machine.owner .. " | Money: $" .. machine.money .. " | Entity ID: " .. (machine.entityId or "none")) end TriggerClientEvent('QBCore:Notify', source, count .. ' Verkaufsautomaten geladen', 'success') @@ -712,4 +743,4 @@ QBCore.Commands.Add('vendingdebug', 'Debug vending machines (Admin Only)', {}, f end end, 'admin') - +