653 lines
29 KiB
Lua
653 lines
29 KiB
Lua
local QBCore = exports['qb-core']:GetCoreObject()
|
|
|
|
-- if not LoadResourceFile("Renewed-Banking", 'web/public/build/bundle.js') then
|
|
-- error('Unable to load UI. Build Renewed-Banking or download the latest release.\n ^https://github.com/Renewed-Scripts/Renewed-Banking/releases/latest/download/Renewed-Banking.rar^0\n If you are using a custom build of the UI, please make sure the resource name is Renewed-Banking (you may not rename the resource).')
|
|
-- end
|
|
|
|
local cachedAccounts = {}
|
|
local cachedPlayers = {}
|
|
|
|
CreateThread(function()
|
|
MySQL.query('SELECT * FROM bank_accounts_new', {}, function(accounts)
|
|
for _,v in pairs (accounts) do
|
|
local job = v.id
|
|
v.auth = json.decode(v.auth)
|
|
cachedAccounts[job] = { -- cachedAccounts[#cachedAccounts+1]
|
|
id = job,
|
|
type = Lang:t("ui.org"),
|
|
name = QBCore.Shared.Jobs[job] and QBCore.Shared.Jobs[job].label or QBCore.Shared.Gangs[job] and QBCore.Shared.Gangs[job].label or job,
|
|
frozen = v.isFrozen == 1,
|
|
amount = v.amount,
|
|
transactions = json.decode(v.transactions),
|
|
auth = {},
|
|
creator = v.creator
|
|
}
|
|
if #v.auth >= 1 then
|
|
for k=1, #v.auth do
|
|
cachedAccounts[job].auth[v.auth[k]] = true
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
end)
|
|
|
|
local function getTimeElapsed(seconds)
|
|
local retData
|
|
local minutes = math.floor(seconds / 60)
|
|
local hours = math.floor(minutes / 60)
|
|
local days = math.floor(hours / 24)
|
|
local weeks = math.floor(days / 7)
|
|
|
|
if weeks ~= 0 and weeks > 1 then
|
|
retData = Lang:t("time.weeks",{time=weeks})
|
|
elseif weeks ~= 0 and weeks == 1 then
|
|
retData = Lang:t("time.aweek")
|
|
elseif days ~= 0 and days > 1 then
|
|
retData = Lang:t("time.days",{time=days})
|
|
elseif days ~= 0 and days == 1 then
|
|
retData = Lang:t("time.aday")
|
|
elseif hours ~= 0 and hours > 1 then
|
|
retData = Lang:t("time.hours",{time=hours})
|
|
elseif hours ~= 0 and hours == 1 then
|
|
retData = Lang:t("time.ahour")
|
|
elseif minutes ~= 0 and minutes > 1 then
|
|
retData = Lang:t("time.mins",{time=minutes})
|
|
elseif minutes ~= 0 and minutes == 1 then
|
|
retData = Lang:t("time.amin")
|
|
else
|
|
retData = Lang:t("time.secs")
|
|
end
|
|
return retData
|
|
end
|
|
|
|
local function updatePlayerAccount(cid)
|
|
MySQL.query('SELECT * FROM player_transactions WHERE id = @id ', {['@id'] = cid}, function(account)
|
|
local query = '%' .. cid .. '%'
|
|
MySQL.query("SELECT * FROM bank_accounts_new WHERE auth LIKE ? ", {query}, function(shared)
|
|
cachedPlayers[cid] = {
|
|
isFrozen = 0,
|
|
transactions = #account > 0 and json.decode(account[1].transactions) or {},
|
|
accounts = {}
|
|
}
|
|
|
|
if #shared >= 1 then
|
|
for k=1, #shared do
|
|
cachedPlayers[cid].accounts[#cachedPlayers[cid].accounts+1] = shared[k].id
|
|
end
|
|
end
|
|
end)
|
|
end)
|
|
end
|
|
|
|
local function getBankData(source)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
local bankData = {}
|
|
local time = os.time()
|
|
local cid = Player.PlayerData.citizenid
|
|
if not cachedPlayers[cid] then updatePlayerAccount(cid) end
|
|
|
|
bankData[#bankData+1] = {
|
|
id = cid,
|
|
type = Lang:t("ui.personal"),
|
|
name = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname),
|
|
frozen = cachedPlayers[cid].isFrozen,
|
|
amount = Player.PlayerData.money.bank,
|
|
cash = Player.PlayerData.money.cash,
|
|
transactions = json.decode(json.encode(cachedPlayers[cid].transactions)),
|
|
}
|
|
|
|
for k=1, #bankData[1].transactions do
|
|
bankData[1].transactions[k].time = getTimeElapsed(time-bankData[1].transactions[k].time)
|
|
end
|
|
|
|
if config.renewedMultiJob then
|
|
local jobs = exports['qb-phone']:getJobs(cid)
|
|
|
|
for k,v in pairs(jobs) do
|
|
if cachedAccounts[k] then
|
|
local job = json.decode(json.encode(cachedAccounts[k]))
|
|
if job and QBCore.Shared.Jobs[k].grades[tostring(v.grade)].bankAuth then
|
|
for i=1, #job.transactions do
|
|
job.transactions[i].time = getTimeElapsed(time-job.transactions[i].time)
|
|
end
|
|
bankData[#bankData+1] = job
|
|
end
|
|
end
|
|
end
|
|
else
|
|
local job = json.decode(json.encode(cachedAccounts[Player.PlayerData.job.name]))
|
|
if job and QBCore.Shared.Jobs[Player.PlayerData.job.name].grades[tostring(Player.PlayerData.job.grade.level)].bankAuth then
|
|
for k=1, #job.transactions do
|
|
job.transactions[k].time = getTimeElapsed(time-job.transactions[k].time)
|
|
end
|
|
bankData[#bankData+1] = job
|
|
end
|
|
end
|
|
|
|
local gang = json.decode(json.encode(cachedAccounts[Player.PlayerData.gang.name]))
|
|
if gang and QBCore.Shared.Gangs[Player.PlayerData.gang.name].grades[tostring(Player.PlayerData.gang.grade.level)].bankAuth then
|
|
for k=1, #gang.transactions do
|
|
gang.transactions[k].time = getTimeElapsed(time-gang.transactions[k].time)
|
|
end
|
|
bankData[#bankData+1] = gang
|
|
end
|
|
|
|
local sharedAccounts = cachedPlayers[cid].accounts
|
|
for k=1, #sharedAccounts do
|
|
local sAccount = json.decode(json.encode(cachedAccounts[sharedAccounts[k]]))
|
|
for i=1, #sAccount.transactions do
|
|
sAccount.transactions[i].time = getTimeElapsed(time-sAccount.transactions[i].time)
|
|
end
|
|
bankData[#bankData+1] = sAccount
|
|
end
|
|
|
|
return bankData
|
|
end
|
|
|
|
QBCore.Functions.CreateCallback("renewed-banking:server:initalizeBanking", function(source, cb)
|
|
local bankData = getBankData(source)
|
|
cb(bankData)
|
|
end)
|
|
|
|
RegisterNetEvent('QBCore:Server:OnPlayerLoaded', function()
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
local cid = Player.PlayerData.citizenid
|
|
updatePlayerAccount(cid)
|
|
end)
|
|
|
|
-- Events
|
|
AddEventHandler('onResourceStart', function(resourceName)
|
|
if resourceName == GetCurrentResourceName() then
|
|
for _, v in pairs(QBCore.Functions.GetPlayers()) do
|
|
local Player = QBCore.Functions.GetPlayer(v)
|
|
if Player then
|
|
local cid = Player.PlayerData.citizenid
|
|
updatePlayerAccount(cid)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
local function genTransactionID()
|
|
local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
|
return string.gsub(template, '[xy]', function (c)
|
|
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
|
|
return string.format('%x', v)
|
|
end)
|
|
end
|
|
|
|
local function handleTransaction(account, title, amount, message, issuer, receiver, type, transID)
|
|
local transaction = {
|
|
trans_id = transID or genTransactionID(),
|
|
title = title,
|
|
amount = amount,
|
|
trans_type = type,
|
|
receiver = receiver,
|
|
message = message,
|
|
issuer = issuer,
|
|
time = os.time()
|
|
}
|
|
if cachedAccounts[account] then
|
|
table.insert(cachedAccounts[account].transactions, 1, transaction)
|
|
MySQL.query("INSERT INTO bank_accounts_new (id, transactions) VALUES (:id, :transactions) ON DUPLICATE KEY UPDATE transactions = :transactions",{
|
|
['id'] = account,
|
|
['transactions'] = json.encode(cachedAccounts[account].transactions)
|
|
})
|
|
elseif cachedPlayers[account] then
|
|
table.insert(cachedPlayers[account].transactions, 1, transaction)
|
|
MySQL.query("INSERT INTO player_transactions (id, transactions) VALUES (:id, :transactions) ON DUPLICATE KEY UPDATE transactions = :transactions",{
|
|
['id'] = account,
|
|
['transactions'] = json.encode(cachedPlayers[account].transactions)
|
|
})
|
|
else
|
|
print(Lang:t("logs.invalid_account",{account=account}))
|
|
end
|
|
return transaction
|
|
end exports("handleTransaction", handleTransaction)
|
|
|
|
local function getAccountMoney(account)
|
|
if not cachedAccounts[account] then
|
|
Lang:t("logs.invalid_account",{account=account})
|
|
return false
|
|
end
|
|
return cachedAccounts[account].amount
|
|
end exports('getAccountMoney', getAccountMoney)
|
|
|
|
local function updateBalance(account)
|
|
MySQL.query("UPDATE bank_accounts_new SET amount = ? WHERE id = ?",{ cachedAccounts[account].amount, account })
|
|
end
|
|
|
|
local function addAccountMoney(account, amount)
|
|
if not cachedAccounts[account] then
|
|
Lang:t("logs.invalid_account",{account=account})
|
|
return false
|
|
end
|
|
cachedAccounts[account].amount += amount
|
|
updateBalance(account)
|
|
return true
|
|
end exports('addAccountMoney', addAccountMoney)
|
|
|
|
QBCore.Functions.CreateCallback("Renewed-Banking:server:deposit", function(source, cb, data)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
local amount = tonumber(data.amount)
|
|
if not amount or amount < 1 then
|
|
QBCore.Functions.Notify(source, Lang:t("notify.invalid_amount",{type="deposit"}), 'error', 5000)
|
|
cb(false)
|
|
return
|
|
end
|
|
local name = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)
|
|
if not data.comment or data.comment == "" then data.comment = Lang:t("notify.comp_transaction",{name = name, type="deposited", amount = amount}) end
|
|
if Player.Functions.RemoveMoney('cash', amount, data.comment) then
|
|
if cachedAccounts[data.fromAccount] then
|
|
addAccountMoney(data.fromAccount, amount)
|
|
else
|
|
Player.Functions.AddMoney('bank', amount, data.comment)
|
|
end
|
|
handleTransaction(data.fromAccount,Lang:t("ui.personal_acc") .. data.fromAccount, amount, data.comment, name, data.fromAccount, "deposit")
|
|
local bankData = getBankData(source)
|
|
cb(bankData)
|
|
else
|
|
TriggerClientEvent('Renewed-Banking:client:sendNotification', source, Lang:t("notify.not_enough_money"))
|
|
cb(false)
|
|
end
|
|
end)
|
|
|
|
local function removeAccountMoney(account, amount)
|
|
if not cachedAccounts[account] then
|
|
print(Lang:t("logs.invalid_account",{account=account}))
|
|
return false
|
|
end
|
|
if cachedAccounts[account].amount < amount then
|
|
print(Lang:t("logs.broke_account",{account=account, amount=amount}))
|
|
return false
|
|
end
|
|
|
|
cachedAccounts[account].amount -= amount
|
|
updateBalance(account)
|
|
return true
|
|
end exports('removeAccountMoney', removeAccountMoney)
|
|
|
|
QBCore.Functions.CreateCallback("Renewed-Banking:server:withdraw", function(source, cb, data)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
local amount = tonumber(data.amount)
|
|
if not amount or amount < 1 then
|
|
QBCore.Functions.Notify(source, Lang:t("notify.invalid_amount",{type="withdraw"}), 'error', 5000)
|
|
cb(false)
|
|
return
|
|
end
|
|
local name = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)
|
|
if not data.comment or data.comment == "" then data.comment = Lang:t("notify.comp_transaction",{name = name, type="withdrawed", amount = amount}) end
|
|
|
|
local canWithdraw
|
|
if cachedAccounts[data.fromAccount] then
|
|
canWithdraw = removeAccountMoney(data.fromAccount, amount)
|
|
else
|
|
canWithdraw = Player.PlayerData.money.bank >= amount and Player.Functions.RemoveMoney('bank', amount, data.comment) or false
|
|
end
|
|
if canWithdraw then
|
|
Player.Functions.AddMoney('cash', amount, data.comment)
|
|
handleTransaction(data.fromAccount,Lang:t("ui.personal_acc") .. data.fromAccount, amount, data.comment, data.fromAccount, name, "withdraw")
|
|
local bankData = getBankData(source)
|
|
cb(bankData)
|
|
else
|
|
TriggerClientEvent('Renewed-Banking:client:sendNotification', source, Lang:t("notify.not_enough_money"))
|
|
cb(false)
|
|
end
|
|
end)
|
|
|
|
local function getPlayerData(source, id)
|
|
local Player = QBCore.Functions.GetPlayer(tonumber(id))
|
|
if not Player then Player = QBCore.Functions.GetPlayerByCitizenId(id) end
|
|
if not Player then
|
|
Player = QBCore.Functions.GetOfflinePlayerByCitizenId(id)
|
|
if Player and not cachedPlayers[Player.PlayerData.citizenid] then
|
|
local pushingP = promise.new()
|
|
MySQL.query('SELECT * FROM player_transactions WHERE id = @id ', {['@id'] = id}, function(account)
|
|
local resolve = account[1] and json.decode(account[1].transactions) or {}
|
|
pushingP:resolve(resolve)
|
|
end)
|
|
local offlineTrans = Citizen.Await(pushingP)
|
|
cachedPlayers[id] = {transactions = offlineTrans}
|
|
end
|
|
end
|
|
if not Player then
|
|
local msg = ("Cannot Find Account(%s)"):format(id)
|
|
print(Lang:t("logs.invalid_account",{account=id}))
|
|
if source then
|
|
QBCore.Functions.Notify(source, msg, 'error', 5000)
|
|
end
|
|
end
|
|
return Player
|
|
end
|
|
|
|
QBCore.Functions.CreateCallback("Renewed-Banking:server:transfer", function(source, cb, data)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
local amount = tonumber(data.amount)
|
|
if not amount or amount < 1 then
|
|
QBCore.Functions.Notify(source, Lang:t("notify.invalid_amount",{type="transfer"}), 'error', 5000)
|
|
cb(false)
|
|
return
|
|
end
|
|
if cachedAccounts[data.fromAccount] then
|
|
if not data.comment or data.comment == "" then data.comment = Lang:t("notify.comp_transaction",{name = data.fromAccount, type="transfered", amount = amount}) end
|
|
if cachedAccounts[data.stateid] then
|
|
local canTransfer = removeAccountMoney(data.fromAccount, amount)
|
|
if canTransfer then
|
|
addAccountMoney(data.stateid, amount)
|
|
local title = ("%s / %s"):format(cachedAccounts[data.fromAccount].name, data.fromAccount)
|
|
local transaction = handleTransaction(data.fromAccount, title, amount, data.comment, cachedAccounts[data.fromAccount].name, cachedAccounts[data.stateid].name, "withdraw")
|
|
handleTransaction(data.stateid, title, amount, data.comment, cachedAccounts[data.fromAccount].name, cachedAccounts[data.stateid].name, "deposit", transaction.trans_id)
|
|
else
|
|
TriggerClientEvent('Renewed-Banking:client:sendNotification', source, Lang:t("notify.not_enough_money"))
|
|
cb(false)
|
|
return
|
|
end
|
|
else
|
|
local Player2 = getPlayerData(source, data.stateid)
|
|
if not Player2 then
|
|
TriggerClientEvent('Renewed-Banking:client:sendNotification', source, Lang:t("notify.fail_transfer"))
|
|
cb(false)
|
|
return
|
|
end
|
|
local canTransfer = removeAccountMoney(data.fromAccount, amount)
|
|
if canTransfer then
|
|
Player2.Functions.AddMoney('bank', amount, data.comment)
|
|
local name = ("%s %s"):format(Player2.PlayerData.charinfo.firstname, Player2.PlayerData.charinfo.lastname)
|
|
local transaction = handleTransaction(data.fromAccount, ("%s / %s"):format(cachedAccounts[data.fromAccount].name, data.fromAccount), amount, data.comment, cachedAccounts[data.fromAccount].name, name, "withdraw")
|
|
handleTransaction(data.stateid, ("%s / %s"):format(cachedAccounts[data.fromAccount].name, data.fromAccount), amount, data.comment, cachedAccounts[data.fromAccount].name, name, "deposit", transaction.trans_id)
|
|
else
|
|
TriggerClientEvent('Renewed-Banking:client:sendNotification', source, Lang:t("notify.not_enough_money"))
|
|
cb(false)
|
|
return
|
|
end
|
|
end
|
|
else
|
|
local name = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)
|
|
if not data.comment or data.comment == "" then data.comment = Lang:t("notify.comp_transaction",{name = data.fromAccount, type="transfered", amount = amount}) end
|
|
if cachedAccounts[data.stateid] then
|
|
if Player.PlayerData.money.bank >= amount and Player.Functions.RemoveMoney('bank', amount, data.comment) then
|
|
addAccountMoney(data.stateid, amount)
|
|
local transaction = handleTransaction(data.fromAccount, Lang:t("ui.personal_acc") .. data.fromAccount, amount, data.comment, name, cachedAccounts[data.stateid].name, "withdraw")
|
|
handleTransaction(data.stateid, Lang:t("ui.personal_acc") .. data.fromAccount, amount, data.comment, name, cachedAccounts[data.stateid].name, "deposit", transaction.trans_id)
|
|
else
|
|
TriggerClientEvent('Renewed-Banking:client:sendNotification', source, Lang:t("notify.not_enough_money"))
|
|
cb(false)
|
|
return
|
|
end
|
|
else
|
|
local Player2 = getPlayerData(source, data.stateid)
|
|
if not Player2 then
|
|
TriggerClientEvent('Renewed-Banking:client:sendNotification', source, Lang:t("notify.fail_transfer"))
|
|
cb(false)
|
|
return
|
|
end
|
|
|
|
if Player.PlayerData.money.bank >= amount and Player.Functions.RemoveMoney('bank', amount, data.comment) then
|
|
Player2.Functions.AddMoney('bank', amount, data.comment)
|
|
local name2 = ("%s %s"):format(Player2.PlayerData.charinfo.firstname, Player2.PlayerData.charinfo.lastname)
|
|
local transaction = handleTransaction(data.fromAccount, Lang:t("ui.personal_acc") .. data.fromAccount, amount, data.comment, name, name2, "withdraw")
|
|
handleTransaction(data.stateid, Lang:t("ui.personal_acc") .. data.fromAccount, amount, data.comment, name, name2, "deposit", transaction.trans_id)
|
|
else
|
|
TriggerClientEvent('Renewed-Banking:client:sendNotification', source, Lang:t("notify.not_enough_money"))
|
|
cb(false)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
local bankData = getBankData(source)
|
|
cb(bankData)
|
|
end)
|
|
|
|
RegisterNetEvent('Renewed-Banking:server:createNewAccount', function(accountid)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
if cachedAccounts[accountid] then QBCore.Functions.Notify(source, Lang:t("notify.account_taken"), "error") return end
|
|
cachedAccounts[accountid] = {
|
|
id = accountid,
|
|
type = Lang:t("ui.org"),
|
|
name = accountid,
|
|
frozen = 0,
|
|
amount = 0,
|
|
transactions = {},
|
|
auth = { [Player.PlayerData.citizenid] = true },
|
|
creator = Player.PlayerData.citizenid
|
|
|
|
}
|
|
cachedPlayers[Player.PlayerData.citizenid].accounts[#cachedPlayers[Player.PlayerData.citizenid].accounts+1] = accountid
|
|
MySQL.query("INSERT INTO bank_accounts_new (id, amount, transactions, auth, isFrozen, creator) VALUES (:id, :amount, :transactions, :auth, :isFrozen, :creator) ",{
|
|
['id'] = accountid,
|
|
['amount'] = cachedAccounts[accountid].amount,
|
|
['transactions'] = json.encode(cachedAccounts[accountid].transactions),
|
|
['auth'] = json.encode({Player.PlayerData.citizenid}),
|
|
['isFrozen'] = cachedAccounts[accountid].frozen,
|
|
['creator'] = Player.PlayerData.citizenid
|
|
})
|
|
end)
|
|
|
|
RegisterNetEvent("Renewed-Banking:server:getPlayerAccounts", function()
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
local accounts = cachedPlayers[Player.PlayerData.citizenid].accounts
|
|
local data = {}
|
|
if #accounts >= 1 then
|
|
for k=1, #accounts do
|
|
if cachedAccounts[accounts[k]].creator == Player.PlayerData.citizenid then
|
|
data[#data+1] = accounts[k]
|
|
end
|
|
end
|
|
end
|
|
TriggerClientEvent("Renewed-Banking:client:accountsMenu", source, data)
|
|
end)
|
|
|
|
RegisterNetEvent("Renewed-Banking:server:viewMemberManagement", function(data)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
|
|
local account = data.account
|
|
local retData = {
|
|
account = account,
|
|
members = {}
|
|
}
|
|
|
|
for k,_ in pairs(cachedAccounts[account].auth) do
|
|
local Player2 = getPlayerData(source, k)
|
|
if Player.PlayerData.citizenid ~= Player2.PlayerData.citizenid then
|
|
local charInfo = Player2.PlayerData.charinfo
|
|
retData.members[k] = ("%s %s"):format(charInfo.firstname, charInfo.lastname)
|
|
end
|
|
end
|
|
|
|
TriggerClientEvent("Renewed-Banking:client:viewMemberManagement", Player.PlayerData.source, retData)
|
|
end)
|
|
|
|
RegisterNetEvent('Renewed-Banking:server:addAccountMember', function(account, member)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
|
|
if Player.PlayerData.citizenid ~= cachedAccounts[account].creator then print(Lang:t("logs.illegal_action", {name=GetPlayerName(source)})) return end
|
|
local Player2 = getPlayerData(source, member)
|
|
if not Player2 then return end
|
|
|
|
local targetCID = Player2.PlayerData.citizenid
|
|
if not Player2.Offline and cachedPlayers[targetCID] then
|
|
cachedPlayers[targetCID].accounts[#cachedPlayers[targetCID].accounts+1] = account
|
|
end
|
|
|
|
local auth = {}
|
|
for k in pairs(cachedAccounts[account].auth) do auth[#auth+1] = k end
|
|
auth[#auth+1] = targetCID
|
|
cachedAccounts[account].auth[targetCID] = true
|
|
MySQL.update('UPDATE bank_accounts_new SET auth = ? WHERE id = ?',{json.encode(auth), account})
|
|
end)
|
|
|
|
RegisterNetEvent('Renewed-Banking:server:removeAccountMember', function(data)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
if Player.PlayerData.citizenid ~= cachedAccounts[data.account].creator then print(Lang:t("logs.illegal_action", {name=GetPlayerName(source)})) return end
|
|
local Player2 = getPlayerData(source, data.cid)
|
|
if not Player2 then return end
|
|
|
|
local targetCID = Player2.PlayerData.citizenid
|
|
local tmp = {}
|
|
for k in pairs(cachedAccounts[data.account].auth) do
|
|
if targetCID ~= k then
|
|
tmp[#tmp+1] = k
|
|
end
|
|
end
|
|
|
|
if not Player2.Offline and cachedPlayers[targetCID] then
|
|
local newAccount = {}
|
|
if #cachedPlayers[targetCID].accounts >= 1 then
|
|
for k=1, #cachedPlayers[targetCID].accounts do
|
|
if cachedPlayers[targetCID].accounts[k] ~= data.account then
|
|
newAccount[#newAccount+1] = cachedPlayers[targetCID].accounts[k]
|
|
end
|
|
end
|
|
end
|
|
cachedPlayers[targetCID].accounts = newAccount
|
|
end
|
|
cachedAccounts[data.account].auth[targetCID] = nil
|
|
MySQL.update('UPDATE bank_accounts_new SET auth = ? WHERE id = ?',{json.encode(tmp), data.account})
|
|
end)
|
|
|
|
local split = QBCore.Shared.SplitStr
|
|
local function updateAccountName(account, newName, src)
|
|
if not split then split = QBCore.Shared.SplitStr end
|
|
if not account or not newName then return false end
|
|
if not cachedAccounts[account] then
|
|
local getTranslation = Lang:t("logs.invalid_account",{account=account})
|
|
print(getTranslation)
|
|
if src then QBCore.Functions.Notify(src, split(getTranslation, '0')[2], 'error', 5000) end
|
|
return false
|
|
end
|
|
if cachedAccounts[newName] then
|
|
local getTranslation = Lang:t("logs.existing_account",{account=account})
|
|
print(getTranslation)
|
|
if src then QBCore.Functions.Notify(src, split(getTranslation, '0')[2], 'error', 5000) end
|
|
return false
|
|
end
|
|
if src then
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if Player.PlayerData.citizenid ~= cachedAccounts[account].creator then
|
|
local getTranslation = Lang:t("logs.illegal_action", {name=GetPlayerName(src)})
|
|
print(getTranslation)
|
|
QBCore.Functions.Notify(src, split(getTranslation, '0')[2], 'error', 5000)
|
|
return false
|
|
end
|
|
end
|
|
|
|
cachedAccounts[newName] = json.decode(json.encode(cachedAccounts[account]))
|
|
cachedAccounts[newName].id = newName
|
|
cachedAccounts[newName].name = newName
|
|
cachedAccounts[account] = nil
|
|
|
|
for _, v in pairs(QBCore.Functions.GetPlayers()) do
|
|
local Player2 = QBCore.Functions.GetPlayer(v)
|
|
if Player2 then
|
|
local cid = Player2.PlayerData.citizenid
|
|
if #cachedPlayers[cid].accounts >= 1 then
|
|
for k=1, #cachedPlayers[cid].accounts do
|
|
if cachedPlayers[cid].accounts[k] == account then
|
|
table.remove(cachedPlayers[cid].accounts, k)
|
|
cachedPlayers[cid].accounts[#cachedPlayers[cid].accounts+1] = newName
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
MySQL.update('UPDATE bank_accounts_new SET id = ? WHERE id = ?',{newName, account})
|
|
return true
|
|
end
|
|
|
|
RegisterNetEvent('Renewed-Banking:server:changeAccountName', function(account, newName)
|
|
updateAccountName(account, newName, source)
|
|
end) exports("changeAccountName", updateAccountName)-- Should only use this on very secure backends to avoid anyone using this as this is a server side ONLY export --
|
|
|
|
local function addAccountMember(account, member)
|
|
if not account or not member then return end
|
|
|
|
if not cachedAccounts[account] then print(Lang:t("logs.invalid_account",{account=account})) return end
|
|
|
|
local Player2 = getPlayerData(false, member)
|
|
if not Player2 then return end
|
|
|
|
local targetCID = Player2.PlayerData.citizenid
|
|
if not Player2.Offline and cachedPlayers[targetCID] then
|
|
cachedPlayers[targetCID].accounts[#cachedPlayers[targetCID].accounts+1] = account
|
|
end
|
|
|
|
local auth = {}
|
|
for k, _ in pairs(cachedAccounts[account].auth) do auth[#auth+1] = k end
|
|
auth[#auth+1] = targetCID
|
|
cachedAccounts[account].auth[targetCID] = true
|
|
MySQL.update('UPDATE bank_accounts_new SET auth = ? WHERE id = ?',{json.encode(auth), account})
|
|
|
|
end exports("addAccountMember", addAccountMember)
|
|
|
|
local function removeAccountMember(account, member)
|
|
local Player2 = getPlayerData(false, member)
|
|
|
|
if not Player2 then return end
|
|
if not cachedAccounts[account] then print(Lang:t("logs.invalid_account",{account=account})) return end
|
|
|
|
local targetCID = Player2.PlayerData.citizenid
|
|
|
|
local tmp = {}
|
|
for k in pairs(cachedAccounts[account].auth) do
|
|
if targetCID ~= k then
|
|
tmp[#tmp+1] = k
|
|
end
|
|
end
|
|
|
|
if not Player2.Offline and cachedPlayers[targetCID] then
|
|
local newAccount = {}
|
|
if #cachedPlayers[targetCID].accounts >= 1 then
|
|
for k=1, #cachedPlayers[targetCID].accounts do
|
|
if cachedPlayers[targetCID].accounts[k] ~= account then
|
|
newAccount[#newAccount+1] = cachedPlayers[targetCID].accounts[k]
|
|
end
|
|
end
|
|
end
|
|
cachedPlayers[targetCID].accounts = newAccount
|
|
end
|
|
|
|
cachedAccounts[account].auth[targetCID] = nil
|
|
|
|
MySQL.update('UPDATE bank_accounts_new SET auth = ? WHERE id = ?',{json.encode(tmp), account})
|
|
end exports("removeAccountMember", removeAccountMember)
|
|
|
|
exports("getAccountTransactions", function(account)
|
|
if cachedAccounts[account] then
|
|
return cachedAccounts[account].transactions
|
|
elseif cachedPlayers[account] then
|
|
return cachedPlayers[account].transactions
|
|
end
|
|
print(Lang:t("logs.invalid_account",{account=account}))
|
|
return false
|
|
end)
|
|
|
|
QBCore.Commands.Add('givecash', Lang:t('menu.givecash'), {{name = 'id', help = 'Player ID'}, {name = 'amount', help = 'Amount'}}, true, function(source, args)
|
|
local src = source
|
|
local id = tonumber(args[1])
|
|
local amount = math.ceil(tonumber(args[2]))
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
if not id or not amount then QBCore.Functions.Notify(src, Lang:t('menu.givecash'), 'error', 5000) return end
|
|
|
|
local iPlayer = QBCore.Functions.GetPlayer(id)
|
|
if not iPlayer then QBCore.Functions.Notify(src, Lang:t('notify.unknown_player', {id=id}), 'error', 5000) return end
|
|
|
|
if Player.PlayerData.metadata["isdead"] then QBCore.Functions.Notify(src, Lang:t('notify.dead'), 'error', 5000) return end
|
|
local distance = Player.PlayerData.metadata["inlaststand"] and 3.0 or 10.0
|
|
if #(GetEntityCoords(GetPlayerPed(src)) - GetEntityCoords(GetPlayerPed(id))) > distance then QBCore.Functions.Notify(src, Lang:t('notify.too_far_away'), 'error', 5000) return end
|
|
if amount < 0 then QBCore.Functions.Notify(src, Lang:t('notify.invalid_amount', {type="give"}), 'error', 5000) return end
|
|
|
|
if Player.Functions.RemoveMoney('cash', amount) then
|
|
if iPlayer.Functions.AddMoney('cash', amount) then
|
|
local nameA = ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)
|
|
local nameB = ("%s %s"):format(iPlayer.PlayerData.charinfo.firstname, iPlayer.PlayerData.charinfo.lastname)
|
|
QBCore.Functions.Notify(src, Lang:t('notify.give_cash',{id = nameB, cash = tostring(amount)}), 'success', 5000)
|
|
QBCore.Functions.Notify(id, Lang:t('notify.received_cash',{id = nameA, cash = tostring(amount)}), 'success', 5000)
|
|
else -- Return player cash
|
|
Player.Functions.AddMoney('cash', amount)
|
|
end
|
|
else
|
|
QBCore.Functions.Notify(id, Lang:t('notify.not_enough_money'), 'error', 5000)
|
|
end
|
|
end) |