-- Variables local coin = Crypto.Coin local QBCore = exports['qb-core']:GetCoreObject() local bannedCharacters = { '%', '$', ';' } -- Function local function RefreshCrypto() local result = MySQL.query.await('SELECT * FROM crypto WHERE crypto = ?', { coin }) if result ~= nil and result[1] ~= nil then Crypto.Worth[coin] = result[1].worth if result[1].history ~= nil then Crypto.History[coin] = json.decode(result[1].history) TriggerClientEvent('qb-crypto:client:UpdateCryptoWorth', -1, coin, result[1].worth, json.decode(result[1].history)) else TriggerClientEvent('qb-crypto:client:UpdateCryptoWorth', -1, coin, result[1].worth, nil) end end end local function ErrorHandle(error) for k, v in pairs(Ticker.Error_handle) do if string.match(error, k) then return v end end return false end local function GetTickerPrice() -- Touch = no help local ticker_promise = promise.new() PerformHttpRequest('https://min-api.cryptocompare.com/data/price?fsym=' .. Ticker.coin .. '&tsyms=' .. Ticker.currency .. '&api_key=' .. Ticker.Api_key, function(Error, Result, _) local result_obj = json.decode(Result) if not result_obj['Response'] then local this_resolve = { error = Error, response_data = result_obj[string.upper(Ticker.currency)] } ticker_promise:resolve(this_resolve) --- Could resolve Error aswell for more accurate Error messages? Solved in else else local this_resolve = { error = result_obj['Message'] } ticker_promise:resolve(this_resolve) end end, 'GET') Citizen.Await(ticker_promise) if type(ticker_promise.value.error) ~= 'number' then local get_user_friendly_error = ErrorHandle(ticker_promise.value.error) if get_user_friendly_error then return get_user_friendly_error else return '\27[31m Unexpected error \27[0m' --- Raised an error which we did not expect, script should be capable of sticking with last recorded price and shutting down the sync logic end else return ticker_promise.value.response_data end end local function HandlePriceChance() local currentValue = Crypto.Worth[coin] local prevValue = Crypto.Worth[coin] local trend = math.random(0, 100) local event = math.random(0, 100) local chance = event - Crypto.ChanceOfCrashOrLuck if event > chance then if trend <= Crypto.ChanceOfDown then currentValue = currentValue - math.random(Crypto.CasualDown[1], Crypto.CasualDown[2]) elseif trend >= Crypto.ChanceOfUp then currentValue = currentValue + math.random(Crypto.CasualUp[1], Crypto.CasualUp[2]) end else if math.random(0, 1) == 1 then currentValue = currentValue + math.random(Crypto.Luck[1], Crypto.Luck[2]) else currentValue = currentValue - math.random(Crypto.Crash[1], Crypto.Crash[2]) end end if currentValue <= Crypto.Lower then currentValue = Crypto.Lower elseif currentValue >= Crypto.Upper then currentValue = Crypto.Upper end if Crypto.History[coin][4] then -- Shift array index 1 to 3 for k = 3, 1, -1 do Crypto.History[coin][k] = Crypto.History[coin][k + 1] end -- Assign array index 4 to the latest result Crypto.History[coin][4] = { PreviousWorth = prevValue, NewWorth = currentValue } else Crypto.History[coin][#Crypto.History[coin] + 1] = { PreviousWorth = prevValue, NewWorth = currentValue } end Crypto.Worth[coin] = currentValue local history = json.encode(Crypto.History[coin]) local props = { ['worth'] = currentValue, ['history'] = history, ['crypto'] = coin } MySQL.update( 'UPDATE crypto set worth = :worth, history = :history where crypto = :crypto', props, function(affectedRows) if affectedRows < 1 then print('Crypto not found, inserting new record for ' .. coin) MySQL.insert('INSERT INTO crypto (crypto, worth, history) VALUES (:crypto, :worth, :history)', props) end RefreshCrypto() end ) end -- Commands QBCore.Commands.Add('setcryptoworth', 'Set crypto value', { { name = 'crypto', help = 'Name of the crypto currency' }, { name = 'Value', help = 'New value of the crypto currency' } }, false, function(source, args) local src = source local crypto = tostring(args[1]) if crypto ~= nil then if Crypto.Worth[crypto] ~= nil then local NewWorth = math.ceil(tonumber(args[2])) if NewWorth ~= nil then local PercentageChange = math.ceil(((NewWorth - Crypto.Worth[crypto]) / Crypto.Worth[crypto]) * 100) local ChangeLabel = '+' if PercentageChange < 0 then ChangeLabel = '-' PercentageChange = (PercentageChange * -1) end if Crypto.Worth[crypto] == 0 then PercentageChange = 0 ChangeLabel = '' end Crypto.History[crypto][#Crypto.History[crypto] + 1] = { PreviousWorth = Crypto.Worth[crypto], NewWorth = NewWorth } TriggerClientEvent('QBCore:Notify', src, 'You have changed the value of ' .. Crypto.Labels[crypto] .. ' from: $' .. Crypto.Worth[crypto] .. ' to: $' .. NewWorth .. ' (' .. ChangeLabel .. ' ' .. PercentageChange .. '%)') Crypto.Worth[crypto] = NewWorth TriggerClientEvent('qb-crypto:client:UpdateCryptoWorth', -1, crypto, NewWorth) MySQL.insert('INSERT INTO crypto (worth, history) VALUES (:worth, :history) ON DUPLICATE KEY UPDATE worth = :worth, history = :history', { ['worth'] = NewWorth, ['history'] = json.encode(Crypto.History[crypto]), }) else TriggerClientEvent('QBCore:Notify', src, Lang:t('text.you_have_not_given_a_new_value', { crypto = Crypto.Worth[crypto] })) end else TriggerClientEvent('QBCore:Notify', src, Lang:t('text.this_crypto_does_not_exist')) end else TriggerClientEvent('QBCore:Notify', src, Lang:t('text.you_have_not_provided_crypto_available_qbit')) end end, 'admin') QBCore.Commands.Add('checkcryptoworth', '', {}, false, function(source) local src = source TriggerClientEvent('QBCore:Notify', src, Lang:t('text.the_qbit_has_a_value_of', { crypto = Crypto.Worth['qbit'] })) end) QBCore.Commands.Add('crypto', '', {}, false, function(source) local src = source local Player = QBCore.Functions.GetPlayer(src) local MyPocket = math.ceil(Player.PlayerData.money.crypto * Crypto.Worth['qbit']) TriggerClientEvent('QBCore:Notify', src, Lang:t('text.you_have_with_a_value_of', { playerPlayerDataMoneyCrypto = Player.PlayerData.money.crypto, mypocket = MyPocket })) end) -- Events RegisterServerEvent('qb-crypto:server:FetchWorth', function() for name, _ in pairs(Crypto.Worth) do local result = MySQL.query.await('SELECT * FROM crypto WHERE crypto = ?', { name }) if result[1] ~= nil then Crypto.Worth[name] = result[1].worth if result[1].history ~= nil then Crypto.History[name] = json.decode(result[1].history) TriggerClientEvent('qb-crypto:client:UpdateCryptoWorth', -1, name, result[1].worth, json.decode(result[1].history)) else TriggerClientEvent('qb-crypto:client:UpdateCryptoWorth', -1, name, result[1].worth, nil) end end end end) RegisterServerEvent('qb-crypto:server:ExchangeFail', function() local src = source local Player = QBCore.Functions.GetPlayer(src) local ItemData = Player.Functions.GetItemByName('cryptostick') if ItemData ~= nil then exports['qb-inventory']:RemoveItem(src, 'cryptostick', 1, false, 'qb-crypto:server:ExchangeFail') TriggerClientEvent('qb-inventory:client:ItemBox', src, QBCore.Shared.Items['cryptostick'], 'remove') TriggerClientEvent('QBCore:Notify', src, Lang:t('error.cryptostick_malfunctioned'), 'error') end end) RegisterServerEvent('qb-crypto:server:Rebooting', function(state, percentage) Crypto.Exchange.RebootInfo.state = state Crypto.Exchange.RebootInfo.percentage = percentage end) RegisterServerEvent('qb-crypto:server:GetRebootState', function() local src = source TriggerClientEvent('qb-crypto:client:GetRebootState', src, Crypto.Exchange.RebootInfo) end) RegisterServerEvent('qb-crypto:server:SyncReboot', function() TriggerClientEvent('qb-crypto:client:SyncReboot', -1) end) RegisterServerEvent('qb-crypto:server:ExchangeSuccess', function(LuckChance) local src = source local Player = QBCore.Functions.GetPlayer(src) local ItemData = Player.Functions.GetItemByName('cryptostick') if ItemData ~= nil then local LuckyNumber = math.random(1, 10) local DeelNumber = 1000000 local Amount = (math.random(611111, 1599999) / DeelNumber) if LuckChance == LuckyNumber then Amount = (math.random(1599999, 2599999) / DeelNumber) end exports['qb-inventory']:RemoveItem(src, 'cryptostick', 1, false, 'qb-crypto:server:ExchangeSuccess') Player.Functions.AddMoney('crypto', Amount, 'qb-crypto:server:ExchangeSuccess') TriggerClientEvent('QBCore:Notify', src, Lang:t('success.you_have_exchanged_your_cryptostick_for', { amount = Amount }), 'success', 3500) TriggerClientEvent('qb-inventory:client:ItemBox', src, QBCore.Shared.Items['cryptostick'], 'remove') TriggerClientEvent('qb-phone:client:AddTransaction', src, Player, {}, Lang:t('credit.there_are_amount_credited', { amount = Amount }), 'Credit') end end) -- Callbacks QBCore.Functions.CreateCallback('qb-crypto:server:HasSticky', function(source, cb) local Player = QBCore.Functions.GetPlayer(source) local Item = Player.Functions.GetItemByName('cryptostick') if Item ~= nil then cb(true) else cb(false) end end) QBCore.Functions.CreateCallback('qb-crypto:server:GetCryptoData', function(source, cb, name) local Player = QBCore.Functions.GetPlayer(source) local CryptoData = { History = Crypto.History[name], Worth = Crypto.Worth[name], Portfolio = Player.PlayerData.money.crypto, WalletId = Player.PlayerData.metadata['walletid'], } cb(CryptoData) end) QBCore.Functions.CreateCallback('qb-crypto:server:BuyCrypto', function(source, cb, data) local Player = QBCore.Functions.GetPlayer(source) local total_price = math.floor(tonumber(data.Coins) * tonumber(Crypto.Worth['qbit'])) if Player.PlayerData.money.bank >= total_price then local CryptoData = { History = Crypto.History['qbit'], Worth = Crypto.Worth['qbit'], Portfolio = Player.PlayerData.money.crypto + tonumber(data.Coins), WalletId = Player.PlayerData.metadata['walletid'], } Player.Functions.RemoveMoney('bank', total_price, 'bought crypto') TriggerClientEvent('qb-phone:client:AddTransaction', source, Player, data, Lang:t('credit.you_have_qbit_purchased', { dataCoins = tonumber(data.Coins) }), 'Credit') Player.Functions.AddMoney('crypto', tonumber(data.Coins), 'bought crypto') cb(CryptoData) else cb(false) end end) QBCore.Functions.CreateCallback('qb-crypto:server:SellCrypto', function(source, cb, data) local Player = QBCore.Functions.GetPlayer(source) if Player.PlayerData.money.crypto >= tonumber(data.Coins) then local CryptoData = { History = Crypto.History['qbit'], Worth = Crypto.Worth['qbit'], Portfolio = Player.PlayerData.money.crypto - tonumber(data.Coins), WalletId = Player.PlayerData.metadata['walletid'], } Player.Functions.RemoveMoney('crypto', tonumber(data.Coins), 'sold crypto') local amount = math.floor(tonumber(data.Coins) * tonumber(Crypto.Worth['qbit'])) TriggerClientEvent('qb-phone:client:AddTransaction', source, Player, data, Lang:t('debit.you_have_sold', { dataCoins = tonumber(data.Coins) }), 'Debit') Player.Functions.AddMoney('bank', amount, 'sold crypto') cb(CryptoData) else cb(false) end end) QBCore.Functions.CreateCallback('qb-crypto:server:TransferCrypto', function(source, cb, data) local newCoin = tostring(data.Coins) local newWalletId = tostring(data.WalletId) for _, v in pairs(bannedCharacters) do newCoin = string.gsub(newCoin, '%' .. v, '') newWalletId = string.gsub(newWalletId, '%' .. v, '') end data.WalletId = newWalletId data.Coins = tonumber(newCoin) local Player = QBCore.Functions.GetPlayer(source) if Player.PlayerData.money.crypto >= tonumber(data.Coins) then local query = '%"walletid":"' .. data.WalletId .. '"%' local result = MySQL.query.await('SELECT * FROM `players` WHERE `metadata` LIKE ?', { query }) if result[1] ~= nil then local CryptoData = { History = Crypto.History['qbit'], Worth = Crypto.Worth['qbit'], Portfolio = Player.PlayerData.money.crypto - tonumber(data.Coins), WalletId = Player.PlayerData.metadata['walletid'], } Player.Functions.RemoveMoney('crypto', tonumber(data.Coins), 'transfer crypto') TriggerClientEvent('qb-phone:client:AddTransaction', source, Player, data, 'You have ' .. tonumber(data.Coins) .. " Qbit('s) transferred!", 'Debit') local Target = QBCore.Functions.GetPlayerByCitizenId(result[1].citizenid) if Target ~= nil then Target.Functions.AddMoney('crypto', tonumber(data.Coins), 'transfer crypto') TriggerClientEvent('qb-phone:client:AddTransaction', Target.PlayerData.source, Player, data, 'There are ' .. tonumber(data.Coins) .. " Qbit('s) credited!", 'Credit') else local MoneyData = json.decode(result[1].money) MoneyData.crypto = MoneyData.crypto + tonumber(data.Coins) MySQL.update('UPDATE players SET money = ? WHERE citizenid = ?', { json.encode(MoneyData), result[1].citizenid }) end cb(CryptoData) else cb('notvalid') end else cb('notenough') end end) -- Threads CreateThread(function() while true do Wait(Crypto.RefreshTimer * 60000) HandlePriceChance() end end) -- You touch = you break if Ticker.Enabled then Citizen.CreateThread(function() local Interval = Ticker.tick_time * 60000 if Ticker.tick_time < 2 then Interval = 120000 end while (true) do local get_coin_price = GetTickerPrice() if type(get_coin_price) == 'number' then Crypto.Worth['qbit'] = get_coin_price else print('\27[31m' .. get_coin_price .. '\27[0m') Ticker.Enabled = false break end Citizen.Wait(Interval) end end) end