- 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
config.lua
client.lua
server.lua
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.
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.



