Neler yeni

Foruma hoş geldin, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Türkiye'nin İlk ve tek FiveM forum adresi

Forum adresimize hoş geldin FiveMTürk olarak amacımız siz değerli kullanıcılarımıza en aktif fikir ve paylaşım platformu sunmak bir yana en güvenilir şekilde alışveriş yapabileceğiniz bir platform sunmaktır.
DF DF
DF DF
DF DF
DF DF
DF DF

Paylaşım [ÜCRETSİZ] Güvenli Eşya Takas Sistemi v0.1 [BETA]

sardem41

Üye
FT Kullanıcı
Katılım
13 gün
Mesajlar
2
Kullanımı şu şekildedir, /takas yazdıktan sonra açılan menüde yanınızdaki oyuncuya takas daveti gönderiyosunuz, kabul edildiği taktirde açılan menüde takas işlemini başarıyla yapabilirsiniz. Daha beta süreci olduğu için ve testini tek başıma gerçekleştiremediğim için olası bir bug için testleri sizin yapmanız gerekmektedir. Eğer herhangi bir bug tespit edilirse çözümü için tartışabiliriz. Teşekkürler.

fxmanifest.lua
Kod:
fx_version 'cerulean'
game 'gta5'

author 'SARDEM NETWORK'
description 'Guvenli Takas Sistemi for QBCore'
version '1.0.0'

lua54 'yes'

shared_script 'config.lua'

client_script 'client.lua'
server_script 'server.lua'

dependencies {
    'qb-core',
    'qb-menu',
    'qb-input',
    'qb-inventory'
}

config.lua
Kod:
fx_version 'cerulean'
game 'gta5'

author 'SARDEM NETWORK'
description 'Menu Based Secure Trade System for QBCore'
version '1.0.0'

lua54 'yes'

shared_script 'config.lua'

client_script 'client.lua'
server_script 'server.lua'

dependencies {
    'qb-core',
    'qb-menu',
    'qb-input',
    'qb-inventory'
}

client.lua
Kod:
local QBCore = exports['qb-core']:GetCoreObject()

local CurrentTrade = nil
local CurrentView = nil

local function Notify(msg, msgType)
    QBCore.Functions.Notify(msg, msgType or 'primary')
end

local function FormatOffer(offer)
    if not offer then
        return 'Boş'
    end

    local parts = {}

    if offer.cash and offer.cash > 0 then
        parts[#parts + 1] = ('$%s nakit'):format(offer.cash)
    end

    if offer.items then
        for _, item in ipairs(offer.items) do
            parts[#parts + 1] = ('%s x%s'):format(item.label or item.name, item.amount)
        end
    end

    if #parts == 0 then
        return 'Boş'
    end

    return table.concat(parts, ' | ')
end

local function OpenMainMenu()
    exports['qb-menu']:openMenu({
        {
            header = 'Güvenli Takas',
            txt = 'Yakındaki oyuncuyla item/para takası yap',
            isMenuHeader = true
        },
        {
            header = 'Yakındaki Oyuncuya Takas İsteği Gönder',
            txt = ('Maksimum mesafe: %.1f metre'):format(Config.MaxDistance),
            icon = 'fa-solid fa-handshake',
            params = {
                event = 'sardem_trade:client:requestClosest'
            }
        },
        {
            header = 'Menüyü Kapat',
            icon = 'fa-solid fa-xmark',
            params = {
                event = 'qb-menu:client:closeMenu'
            }
        }
    })
end

local function OpenTradeMenu()
    if not CurrentView or not CurrentTrade then
        return
    end

    local readyText = CurrentView.selfReady and 'Hazır durumundasın' or 'Hazır değilsin'
    local otherReadyText = CurrentView.otherReady and 'Karşı taraf hazır' or 'Karşı taraf hazır değil'

    local menu = {
        {
            header = 'Güvenli Takas',
            txt = ('Karşı taraf: %s'):format(CurrentView.otherName or 'Bilinmiyor'),
            isMenuHeader = true
        },
        {
            header = 'Sen Veriyorsun',
            txt = FormatOffer(CurrentView.selfOffer),
            isMenuHeader = true
        },
        {
            header = 'Karşı Taraf Veriyor',
            txt = FormatOffer(CurrentView.otherOffer),
            isMenuHeader = true
        },
        {
            header = 'Nakit Miktarını Ayarla',
            txt = 'Takas içine koyacağın nakit miktarı',
            icon = 'fa-solid fa-money-bill',
            params = {
                event = 'sardem_trade:client:inputCash'
            }
        },
        {
            header = 'Item Ekle',
            txt = 'Item adı ve miktar gir',
            icon = 'fa-solid fa-plus',
            params = {
                event = 'sardem_trade:client:inputAddItem'
            }
        },
        {
            header = 'Item Çıkar',
            txt = 'Eklediğin itemden miktar düş',
            icon = 'fa-solid fa-minus',
            params = {
                event = 'sardem_trade:client:inputRemoveItem'
            }
        },
        {
            header = CurrentView.selfReady and 'Hazır Durumunu Kaldır' or 'Hazırım',
            txt = readyText .. ' | ' .. otherReadyText,
            icon = 'fa-solid fa-check',
            params = {
                event = 'sardem_trade:client:toggleReady'
            }
        }
    }

    if CurrentView.selfReady and CurrentView.otherReady then
        menu[#menu + 1] = {
            header = 'Son Onay Ver',
            txt = 'İki taraf da onaylarsa takas gerçekleşir',
            icon = 'fa-solid fa-lock',
            params = {
                event = 'sardem_trade:client:confirmTrade'
            }
        }
    else
        menu[#menu + 1] = {
            header = 'Son Onay Kilitli',
            txt = 'İki taraf da hazır olmadan açılamaz',
            icon = 'fa-solid fa-lock',
            disabled = true
        }
    end

    menu[#menu + 1] = {
        header = 'Takası İptal Et',
        txt = 'Takas tamamen kapanır',
        icon = 'fa-solid fa-ban',
        params = {
            event = 'sardem_trade:client:cancelTrade'
        }
    }

    exports['qb-menu']:openMenu(menu)
end

RegisterCommand('takas', function()
    OpenMainMenu()
end, false)

RegisterNetEvent('sardem_trade:client:requestClosest', function()
    local closestPlayer, closestDistance = QBCore.Functions.GetClosestPlayer()

    if closestPlayer == -1 or closestDistance > Config.MaxDistance then
        Notify(Config.Text.noNearby, 'error')
        return
    end

    local targetServerId = GetPlayerServerId(closestPlayer)

    TriggerServerEvent('sardem_trade:server:requestTrade', targetServerId)
end)

RegisterNetEvent('sardem_trade:client:incomingRequest', function(data)
    exports['qb-menu']:openMenu({
        {
            header = 'Takas İsteği',
            txt = (data.requesterName or 'Bir oyuncu') .. ' seninle takas yapmak istiyor.',
            isMenuHeader = true
        },
        {
            header = 'Kabul Et',
            icon = 'fa-solid fa-check',
            params = {
                event = 'sardem_trade:client:answerRequest',
                args = {
                    requestId = data.requestId,
                    accepted = true
                }
            }
        },
        {
            header = 'Reddet',
            icon = 'fa-solid fa-xmark',
            params = {
                event = 'sardem_trade:client:answerRequest',
                args = {
                    requestId = data.requestId,
                    accepted = false
                }
            }
        }
    })
end)

RegisterNetEvent('sardem_trade:client:answerRequest', function(data)
    TriggerServerEvent('sardem_trade:server:answerRequest', data.requestId, data.accepted)
end)

RegisterNetEvent('sardem_trade:client:updateTrade', function(view)
    CurrentTrade = view.tradeId
    CurrentView = view
    OpenTradeMenu()
end)

RegisterNetEvent('sardem_trade:client:tradeClosed', function()
    CurrentTrade = nil
    CurrentView = nil
    exports['qb-menu']:closeMenu()
end)

RegisterNetEvent('sardem_trade:client:inputCash', function()
    if not CurrentTrade then return end

    local dialog = exports['qb-input']:ShowInput({
        header = 'Nakit Ayarla',
        submitText = 'Kaydet',
        inputs = {
            {
                text = 'Nakit miktarı',
                name = 'amount',
                type = 'number',
                isRequired = true
            }
        }
    })

    if not dialog or not dialog.amount then
        OpenTradeMenu()
        return
    end

    TriggerServerEvent('sardem_trade:server:setCash', CurrentTrade, tonumber(dialog.amount))
end)

RegisterNetEvent('sardem_trade:client:inputAddItem', function()
    if not CurrentTrade then return end

    local dialog = exports['qb-input']:ShowInput({
        header = 'Item Ekle',
        submitText = 'Ekle',
        inputs = {
            {
                text = 'Item adı / spawn name',
                name = 'item',
                type = 'text',
                isRequired = true
            },
            {
                text = 'Miktar',
                name = 'amount',
                type = 'number',
                isRequired = true
            }
        }
    })

    if not dialog or not dialog.item or not dialog.amount then
        OpenTradeMenu()
        return
    end

    TriggerServerEvent('sardem_trade:server:addItem', CurrentTrade, dialog.item, tonumber(dialog.amount))
end)

RegisterNetEvent('sardem_trade:client:inputRemoveItem', function()
    if not CurrentTrade then return end

    local dialog = exports['qb-input']:ShowInput({
        header = 'Item Çıkar',
        submitText = 'Çıkar',
        inputs = {
            {
                text = 'Item adı / spawn name',
                name = 'item',
                type = 'text',
                isRequired = true
            },
            {
                text = 'Miktar',
                name = 'amount',
                type = 'number',
                isRequired = true
            }
        }
    })

    if not dialog or not dialog.item or not dialog.amount then
        OpenTradeMenu()
        return
    end

    TriggerServerEvent('sardem_trade:server:removeItem', CurrentTrade, dialog.item, tonumber(dialog.amount))
end)

RegisterNetEvent('sardem_trade:client:toggleReady', function()
    if not CurrentTrade then return end
    TriggerServerEvent('sardem_trade:server:toggleReady', CurrentTrade)
end)

RegisterNetEvent('sardem_trade:client:confirmTrade', function()
    if not CurrentTrade then return end
    TriggerServerEvent('sardem_trade:server:confirmTrade', CurrentTrade)
end)

RegisterNetEvent('sardem_trade:client:cancelTrade', function()
    if not CurrentTrade then return end
    TriggerServerEvent('sardem_trade:server:cancelTrade', CurrentTrade)
end)

server.lua
Kod:
local QBCore = exports['qb-core']:GetCoreObject()

local PendingRequests = {}
local Trades = {}
local TradeCounter = 0

local function Notify(src, msg, msgType)
    TriggerClientEvent('QBCore:Notify', src, msg, msgType or 'primary')
end

local function GetDisplayName(src)
    local Player = QBCore.Functions.GetPlayer(src)

    if not Player then
        return ('ID %s'):format(src)
    end

    local charinfo = Player.PlayerData.charinfo or {}
    local firstname = charinfo.firstname or 'Oyuncu'
    local lastname = charinfo.lastname or ''

    return (firstname .. ' ' .. lastname):gsub('%s+', ' ')
end

local function IsPlayerInTrade(src)
    for _, trade in pairs(Trades) do
        if trade.a == src or trade.b == src then
            return true
        end
    end

    return false
end

local function IsNear(src, target)
    local pedA = GetPlayerPed(src)
    local pedB = GetPlayerPed(target)

    if pedA == 0 or pedB == 0 then
        return false
    end

    local coordsA = GetEntityCoords(pedA)
    local coordsB = GetEntityCoords(pedB)

    return #(coordsA - coordsB) <= Config.MaxDistance
end

local function CleanItemName(itemName)
    if not itemName then return nil end

    itemName = tostring(itemName):lower()
    itemName = itemName:gsub('%s+', '')

    if itemName == '' then
        return nil
    end

    return itemName
end

local function IsBlockedItem(itemName)
    return Config.BlockedItems[itemName] == true
end

local function ResetTradeState(trade)
    trade.ready[trade.a] = false
    trade.ready[trade.b] = false
    trade.confirmed[trade.a] = false
    trade.confirmed[trade.b] = false
end

local function BuildOfferView(offer)
    local items = {}

    for itemName, amount in pairs(offer.items) do
        local itemData = QBCore.Shared.Items[itemName]
        items[#items + 1] = {
            name = itemName,
            label = itemData and itemData.label or itemName,
            amount = amount
        }
    end

    table.sort(items, function(a, b)
        return a.name < b.name
    end)

    return {
        cash = offer.cash or 0,
        items = items
    }
end

local function SendTradeUpdate(tradeId)
    local trade = Trades[tradeId]

    if not trade then
        return
    end

    for _, src in ipairs({ trade.a, trade.b }) do
        local other = src == trade.a and trade.b or trade.a

        TriggerClientEvent('sardem_trade:client:updateTrade', src, {
            tradeId = tradeId,
            selfName = GetDisplayName(src),
            otherName = GetDisplayName(other),
            selfOffer = BuildOfferView(trade.offers[src]),
            otherOffer = BuildOfferView(trade.offers[other]),
            selfReady = trade.ready[src] or false,
            otherReady = trade.ready[other] or false,
            selfConfirmed = trade.confirmed[src] or false,
            otherConfirmed = trade.confirmed[other] or false
        })
    end
end

local function CloseTrade(tradeId, reason, msgType)
    local trade = Trades[tradeId]

    if not trade then
        return
    end

    TriggerClientEvent('sardem_trade:client:tradeClosed', trade.a)
    TriggerClientEvent('sardem_trade:client:tradeClosed', trade.b)

    if reason then
        Notify(trade.a, reason, msgType or 'primary')
        Notify(trade.b, reason, msgType or 'primary')
    end

    Trades[tradeId] = nil
end

local function ValidateOffer(src, offer)
    local Player = QBCore.Functions.GetPlayer(src)

    if not Player then
        return false, 'Oyuncu bulunamadı.'
    end

    local cash = tonumber(offer.cash) or 0

    if cash < 0 then
        return false, 'Geçersiz nakit miktarı.'
    end

    if cash > Config.MaxCash then
        return false, 'Nakit miktarı çok yüksek.'
    end

    if Player.PlayerData.money.cash < cash then
        return false, 'Üzerinde yeterli nakit yok.'
    end

    for itemName, amount in pairs(offer.items) do
        amount = tonumber(amount) or 0

        if amount <= 0 then
            return false, 'Geçersiz item miktarı.'
        end

        if IsBlockedItem(itemName) then
            return false, ('Bu item takasa kapalı: %s'):format(itemName)
        end

        if not QBCore.Shared.Items[itemName] then
            return false, ('Böyle bir item yok: %s'):format(itemName)
        end

        local invItem = Player.Functions.GetItemByName(itemName)

        if not invItem or invItem.amount < amount then
            return false, ('Yeterli item yok: %s x%s'):format(itemName, amount)
        end
    end

    return true
end

local function CanReceiveItems(src, items)
    for itemName, amount in pairs(items) do
        local ok, canAdd = pcall(function()
            return exports['qb-inventory']:CanAddItem(src, itemName, amount)
        end)

        if ok and canAdd == false then
            return false, ('Karşı tarafın envanterinde yer yok: %s x%s'):format(itemName, amount)
        end
    end

    return true
end

local function SendDiscordLog(title, description)
    if not Config.DiscordWebhook or Config.DiscordWebhook == '' then
        return
    end

    PerformHttpRequest(Config.DiscordWebhook, function() end, 'POST', json.encode({
        username = 'Sardem Secure Trade',
        embeds = {
            {
                title = title,
                description = description,
                color = 3066993
            }
        }
    }), {
        ['Content-Type'] = 'application/json'
    })
end

local function OfferToText(offer)
    local text = {}

    if offer.cash and offer.cash > 0 then
        text[#text + 1] = ('$%s nakit'):format(offer.cash)
    end

    for itemName, amount in pairs(offer.items) do
        text[#text + 1] = ('%s x%s'):format(itemName, amount)
    end

    if #text == 0 then
        return 'Boş'
    end

    return table.concat(text, ', ')
end

local function FinalizeTrade(tradeId)
    local trade = Trades[tradeId]

    if not trade then
        return
    end

    local srcA = trade.a
    local srcB = trade.b

    local PlayerA = QBCore.Functions.GetPlayer(srcA)
    local PlayerB = QBCore.Functions.GetPlayer(srcB)

    if not PlayerA or not PlayerB then
        CloseTrade(tradeId, 'Oyunculardan biri bulunamadı, takas iptal edildi.', 'error')
        return
    end

    if not IsNear(srcA, srcB) then
        CloseTrade(tradeId, 'Oyuncular uzaklaştığı için takas iptal edildi.', 'error')
        return
    end

    local offerA = trade.offers[srcA]
    local offerB = trade.offers[srcB]

    local okA, errA = ValidateOffer(srcA, offerA)
    if not okA then
        Notify(srcA, errA, 'error')
        Notify(srcB, 'Karşı tarafın takası geçersiz.', 'error')
        SendTradeUpdate(tradeId)
        return
    end

    local okB, errB = ValidateOffer(srcB, offerB)
    if not okB then
        Notify(srcB, errB, 'error')
        Notify(srcA, 'Karşı tarafın takası geçersiz.', 'error')
        SendTradeUpdate(tradeId)
        return
    end

    local canB, canBErr = CanReceiveItems(srcB, offerA.items)
    if not canB then
        Notify(srcA, canBErr, 'error')
        Notify(srcB, canBErr, 'error')
        return
    end

    local canA, canAErr = CanReceiveItems(srcA, offerB.items)
    if not canA then
        Notify(srcA, canAErr, 'error')
        Notify(srcB, canAErr, 'error')
        return
    end

    if offerA.cash > 0 then
        PlayerA.Functions.RemoveMoney('cash', offerA.cash, 'secure-trade')
        PlayerB.Functions.AddMoney('cash', offerA.cash, 'secure-trade')
    end

    if offerB.cash > 0 then
        PlayerB.Functions.RemoveMoney('cash', offerB.cash, 'secure-trade')
        PlayerA.Functions.AddMoney('cash', offerB.cash, 'secure-trade')
    end

    for itemName, amount in pairs(offerA.items) do
        PlayerA.Functions.RemoveItem(itemName, amount, false, 'secure-trade')
        PlayerB.Functions.AddItem(itemName, amount, false, false, 'secure-trade')
        TriggerClientEvent('inventory:client:ItemBox', srcA, QBCore.Shared.Items[itemName], 'remove', amount)
        TriggerClientEvent('inventory:client:ItemBox', srcB, QBCore.Shared.Items[itemName], 'add', amount)
    end

    for itemName, amount in pairs(offerB.items) do
        PlayerB.Functions.RemoveItem(itemName, amount, false, 'secure-trade')
        PlayerA.Functions.AddItem(itemName, amount, false, false, 'secure-trade')
        TriggerClientEvent('inventory:client:ItemBox', srcB, QBCore.Shared.Items[itemName], 'remove', amount)
        TriggerClientEvent('inventory:client:ItemBox', srcA, QBCore.Shared.Items[itemName], 'add', amount)
    end

    local logText = ('**%s [%s] verdi:** %s\n**%s [%s] verdi:** %s'):format(
        GetDisplayName(srcA),
        srcA,
        OfferToText(offerA),
        GetDisplayName(srcB),
        srcB,
        OfferToText(offerB)
    )

    SendDiscordLog('Güvenli Takas Tamamlandı', logText)

    CloseTrade(tradeId, Config.Text.tradeDone, 'success')
end

RegisterNetEvent('sardem_trade:server:requestTrade', function(targetId)
    local src = source
    targetId = tonumber(targetId)

    if not targetId or src == targetId then
        Notify(src, 'Geçersiz oyuncu.', 'error')
        return
    end

    local Player = QBCore.Functions.GetPlayer(src)
    local Target = QBCore.Functions.GetPlayer(targetId)

    if not Player or not Target then
        Notify(src, 'Oyuncu bulunamadı.', 'error')
        return
    end

    if IsPlayerInTrade(src) or IsPlayerInTrade(targetId) then
        Notify(src, 'Sen veya karşı taraf zaten takasta.', 'error')
        return
    end

    if not IsNear(src, targetId) then
        Notify(src, 'Oyuncu çok uzakta.', 'error')
        return
    end

    local requestId = ('%s_%s_%s'):format(src, targetId, os.time())

    PendingRequests[requestId] = {
        requester = src,
        target = targetId,
        expires = os.time() + Config.RequestExpireSeconds
    }

    TriggerClientEvent('sardem_trade:client:incomingRequest', targetId, {
        requestId = requestId,
        requester = src,
        requesterName = GetDisplayName(src)
    })

    Notify(src, Config.Text.requestSent, 'success')

    SetTimeout(Config.RequestExpireSeconds * 1000, function()
        if PendingRequests[requestId] then
            PendingRequests[requestId] = nil
            Notify(src, Config.Text.requestExpired, 'error')
            Notify(targetId, Config.Text.requestExpired, 'error')
        end
    end)
end)

RegisterNetEvent('sardem_trade:server:answerRequest', function(requestId, accepted)
    local src = source
    local request = PendingRequests[requestId]

    if not request or request.target ~= src then
        Notify(src, 'Geçersiz veya süresi dolmuş takas isteği.', 'error')
        return
    end

    PendingRequests[requestId] = nil

    local requester = request.requester
    local target = request.target

    if not accepted then
        Notify(requester, 'Takas isteği reddedildi.', 'error')
        Notify(target, 'Takas isteğini reddettin.', 'primary')
        return
    end

    if IsPlayerInTrade(requester) or IsPlayerInTrade(target) then
        Notify(src, 'Oyunculardan biri zaten takasta.', 'error')
        return
    end

    if not IsNear(requester, target) then
        Notify(requester, 'Oyuncular uzaklaştı, takas iptal edildi.', 'error')
        Notify(target, 'Oyuncular uzaklaştı, takas iptal edildi.', 'error')
        return
    end

    TradeCounter = TradeCounter + 1
    local tradeId = ('trade_%s_%s'):format(TradeCounter, os.time())

    Trades[tradeId] = {
        a = requester,
        b = target,
        offers = {
            [requester] = {
                cash = 0,
                items = {}
            },
            [target] = {
                cash = 0,
                items = {}
            }
        },
        ready = {
            [requester] = false,
            [target] = false
        },
        confirmed = {
            [requester] = false,
            [target] = false
        }
    }

    SendTradeUpdate(tradeId)
end)

RegisterNetEvent('sardem_trade:server:setCash', function(tradeId, amount)
    local src = source
    local trade = Trades[tradeId]

    if not trade or not trade.offers[src] then
        Notify(src, 'Aktif takas bulunamadı.', 'error')
        return
    end

    amount = math.floor(tonumber(amount) or 0)

    if amount < 0 then amount = 0 end

    if amount > Config.MaxCash then
        Notify(src, 'Bu kadar yüksek nakit koyamazsın.', 'error')
        return
    end

    local Player = QBCore.Functions.GetPlayer(src)

    if not Player then return end

    if Player.PlayerData.money.cash < amount then
        Notify(src, 'Üzerinde bu kadar nakit yok.', 'error')
        return
    end

    trade.offers[src].cash = amount
    ResetTradeState(trade)
    SendTradeUpdate(tradeId)
end)

RegisterNetEvent('sardem_trade:server:addItem', function(tradeId, itemName, amount)
    local src = source
    local trade = Trades[tradeId]

    if not trade or not trade.offers[src] then
        Notify(src, 'Aktif takas bulunamadı.', 'error')
        return
    end

    itemName = CleanItemName(itemName)
    amount = math.floor(tonumber(amount) or 0)

    if not itemName or amount <= 0 then
        Notify(src, 'Geçersiz item veya miktar.', 'error')
        return
    end

    if IsBlockedItem(itemName) then
        Notify(src, 'Bu item takasa kapalı.', 'error')
        return
    end

    if not QBCore.Shared.Items[itemName] then
        Notify(src, 'Böyle bir item yok.', 'error')
        return
    end

    local Player = QBCore.Functions.GetPlayer(src)
    local invItem = Player and Player.Functions.GetItemByName(itemName)

    local currentAmount = trade.offers[src].items[itemName] or 0
    local newAmount = currentAmount + amount

    if not invItem or invItem.amount < newAmount then
        Notify(src, 'Üzerinde yeterli item yok.', 'error')
        return
    end

    trade.offers[src].items[itemName] = newAmount
    ResetTradeState(trade)
    SendTradeUpdate(tradeId)
end)

RegisterNetEvent('sardem_trade:server:removeItem', function(tradeId, itemName, amount)
    local src = source
    local trade = Trades[tradeId]

    if not trade or not trade.offers[src] then
        Notify(src, 'Aktif takas bulunamadı.', 'error')
        return
    end

    itemName = CleanItemName(itemName)
    amount = math.floor(tonumber(amount) or 0)

    if not itemName or amount <= 0 then
        Notify(src, 'Geçersiz item veya miktar.', 'error')
        return
    end

    local currentAmount = trade.offers[src].items[itemName] or 0

    if currentAmount <= 0 then
        Notify(src, 'Bu item takasta yok.', 'error')
        return
    end

    local newAmount = currentAmount - amount

    if newAmount <= 0 then
        trade.offers[src].items[itemName] = nil
    else
        trade.offers[src].items[itemName] = newAmount
    end

    ResetTradeState(trade)
    SendTradeUpdate(tradeId)
end)

RegisterNetEvent('sardem_trade:server:toggleReady', function(tradeId)
    local src = source
    local trade = Trades[tradeId]

    if not trade or not trade.offers[src] then
        Notify(src, 'Aktif takas bulunamadı.', 'error')
        return
    end

    local ok, err = ValidateOffer(src, trade.offers[src])

    if not ok then
        Notify(src, err, 'error')
        return
    end

    trade.ready[src] = not trade.ready[src]
    trade.confirmed[trade.a] = false
    trade.confirmed[trade.b] = false

    SendTradeUpdate(tradeId)
end)

RegisterNetEvent('sardem_trade:server:confirmTrade', function(tradeId)
    local src = source
    local trade = Trades[tradeId]

    if not trade or not trade.offers[src] then
        Notify(src, 'Aktif takas bulunamadı.', 'error')
        return
    end

    if not trade.ready[trade.a] or not trade.ready[trade.b] then
        Notify(src, 'İki taraf da hazır olmadan son onay verilemez.', 'error')
        return
    end

    trade.confirmed[src] = true

    local other = src == trade.a and trade.b or trade.a
    Notify(src, 'Son onay verdin. Karşı taraf bekleniyor.', 'success')
    Notify(other, 'Karşı taraf son onay verdi.', 'primary')

    if trade.confirmed[trade.a] and trade.confirmed[trade.b] then
        FinalizeTrade(tradeId)
    else
        SendTradeUpdate(tradeId)
    end
end)

RegisterNetEvent('sardem_trade:server:cancelTrade', function(tradeId)
    local src = source
    local trade = Trades[tradeId]

    if not trade or not trade.offers[src] then
        return
    end

    CloseTrade(tradeId, Config.Text.tradeCancelled, 'error')
end)

AddEventHandler('playerDropped', function()
    local src = source

    for tradeId, trade in pairs(Trades) do
        if trade.a == src or trade.b == src then
            CloseTrade(tradeId, 'Oyuncu çıktığı için takas iptal edildi.', 'error')
            break
        end
    end
end)

En son server.cfg config dosyasının içine de "ensure pluginklasorismi" şeklinde de sunucuya aktarmayı unutmayın. kurulum tamamdır.

Son olarak aklınıza takılan bir şey olursa forumda tartışabiliriz. Fikirlerinizi bekliyorum.
 

Forumdan daha fazla yararlanmak için giriş yapın yada üye olun!

Forumdan daha fazla yararlanmak için giriş yapın veya kayıt olun!

Kayıt ol

Forumda bir hesap oluşturmak tamamen ücretsizdir.

Şimdi kayıt ol
Giriş yap

Eğer bir hesabınız var ise lütfen giriş yapın

Giriş yap

Bu konuyu görüntüleyen kullanıcılar

Tema düzenleyici

Tema özelletirmeleri

Granit arka planlar

Lütfen Javascript'i etkinleştirin!Javascript'i etkinleştirin!
// Adblock Kod Start // // Adblock Kod End//