617 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			617 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| ---@diagnostic disable: duplicate-set-field
 | |
| if Config.framework ~= "ESX" then return end
 | |
| Utils.Framework = {}
 | |
| 
 | |
| -- Framework init
 | |
| ESX = nil
 | |
| if Config.ESX_settings.is_updated then
 | |
| 	ESX = exports["es_extended"]:getSharedObject() 
 | |
| else
 | |
| 	TriggerEvent(Config.ESX_settings.shared_object, function(obj) ESX = obj end)
 | |
| end
 | |
| 
 | |
| -- Framework functions
 | |
| function Utils.Framework.getPlayerIdLog(source)
 | |
| 	local user_id = Utils.Framework.getPlayerId(source)
 | |
| 	local player_name = GetPlayerName(source)
 | |
| 	return user_id.." ("..player_name..")"
 | |
| end
 | |
| 
 | |
| -- Framework functions
 | |
| function Utils.Framework.getPlayers()
 | |
| 	return ESX.GetPlayers()
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getPlayerId(source)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if xPlayer then
 | |
| 		return xPlayer.identifier
 | |
| 	end
 | |
| 	return nil
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getPlayerSource(user_id)
 | |
| 	local xPlayer = ESX.GetPlayerFromIdentifier(user_id)
 | |
| 	if xPlayer then
 | |
| 		return xPlayer.source
 | |
| 	end
 | |
| 	return nil
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getPlayerName(user_id)
 | |
| 	local xPlayer = ESX.GetPlayerFromIdentifier(user_id)
 | |
| 	if xPlayer then
 | |
| 		return xPlayer.name
 | |
| 	else
 | |
| 		local sql = "SELECT firstname, lastname FROM `users` WHERE identifier = @user_id";
 | |
| 		local query = MySQL.Sync.fetchAll(sql,{['@user_id'] = user_id});
 | |
| 		if query and query[1] and query[1].firstname then
 | |
| 			return query[1].firstname.." "..query[1].lastname
 | |
| 		end
 | |
| 	end
 | |
| 	return false
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getOnlinePlayers()
 | |
| 	local online_players = {}
 | |
| 	if Config.ESX_settings.is_updated then
 | |
| 		-- ESX 1.9+
 | |
| 		local xPlayers = ESX.GetExtendedPlayers()
 | |
| 		for _, xPlayer in pairs(xPlayers) do
 | |
| 			table.insert(online_players, {
 | |
| 				source		= xPlayer.source,
 | |
| 				identifier	= xPlayer.identifier,
 | |
| 				name		= xPlayer.name
 | |
| 			})
 | |
| 		end
 | |
| 	else
 | |
| 		-- ESX older than 1.9.0
 | |
| 		local xPlayers = ESX.GetPlayers()
 | |
| 		for i=1, #xPlayers, 1 do
 | |
| 			local xPlayer = ESX.GetPlayerFromId(xPlayers[i])
 | |
| 			table.insert(online_players, {
 | |
| 				source		= xPlayer.source,
 | |
| 				identifier	= xPlayer.identifier,
 | |
| 				name		= xPlayer.name
 | |
| 			})
 | |
| 		end
 | |
| 	end
 | |
| 	return online_players
 | |
| end
 | |
| 
 | |
| function Utils.Framework.giveAccountMoney(source,amount,account)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if account == 'money' or account == 'cash' then
 | |
| 		xPlayer.addMoney(amount)
 | |
| 	else
 | |
| 		xPlayer.addAccountMoney(account, amount)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function Utils.Framework.tryRemoveAccountMoney(source,amount,account)
 | |
| 	local money = 0
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if account == 'money' or account == 'cash' then
 | |
| 		money = xPlayer.getMoney()
 | |
| 	else
 | |
| 		money = xPlayer.getAccount(account).money
 | |
| 	end
 | |
| 	if money >= amount then
 | |
| 		if account == 'money' or account == 'cash' then
 | |
| 			xPlayer.removeMoney(amount)
 | |
| 		else
 | |
| 			xPlayer.removeAccountMoney(account, amount)
 | |
| 		end
 | |
| 		return true
 | |
| 	else
 | |
| 		return false
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getPlayerAccountMoney(source,account)
 | |
| 	local money = 0
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if account == 'money' or account == 'cash' then
 | |
| 		money = xPlayer.getMoney()
 | |
| 	else
 | |
| 		money = xPlayer.getAccount(account).money
 | |
| 	end
 | |
| 	return money
 | |
| end
 | |
| 
 | |
| function Utils.Framework.hasJobs(source,jobs)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	local PlayerJob = xPlayer.getJob()
 | |
| 	if Config.debug_job then
 | |
| 		print("Job name: "..PlayerJob.name)
 | |
| 	end
 | |
| 	for k,v in pairs(jobs) do
 | |
| 		if PlayerJob.name == v then
 | |
| 			return true
 | |
| 		end
 | |
| 	end
 | |
| 	return false
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getPlayerJob(source)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	local PlayerJob = xPlayer.getJob()
 | |
| 	if Config.debug_job then
 | |
| 		print("Job name: "..PlayerJob.name)
 | |
| 	end
 | |
| 	return PlayerJob.name, true
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getPlayerInventory(source)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	local inventory = {}
 | |
| 	for k, v in pairs(xPlayer.getInventory()) do
 | |
| 		if v.count and v.count > 0 then
 | |
| 			table.insert(inventory, { amount = v.count, name = string.lower(v.name), label = v.label })
 | |
| 		end
 | |
| 	end
 | |
| 	return inventory
 | |
| end
 | |
| 
 | |
| local function canStoreItemInInventory(source,item,amount)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	local weight_ok = false
 | |
| 	if Config.ESX_settings.esx_version == 'limit' then
 | |
| 		local sourceItem = xPlayer.getInventoryItem(item)
 | |
| 		if sourceItem == nil or sourceItem.limit == -1 or (sourceItem.count + amount) <= sourceItem.limit then
 | |
| 			weight_ok = true
 | |
| 		else
 | |
| 			weight_ok = false
 | |
| 		end
 | |
| 	elseif Config.ESX_settings.esx_version == 'weight' then
 | |
| 		if xPlayer.canCarryItem(item, amount) then
 | |
| 			weight_ok = true
 | |
| 		else
 | |
| 			weight_ok = false
 | |
| 		end
 | |
| 	else
 | |
| 		weight_ok = true
 | |
| 	end
 | |
| 	return weight_ok
 | |
| end
 | |
| 
 | |
| function Utils.Framework.givePlayerItem(source,item,amount,metadata)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if Config.custom_scripts_compatibility.inventory == "ox_inventory" then
 | |
| 		if exports['ox_inventory']:CanCarryItem(source, item, amount) then
 | |
| 			return exports['ox_inventory']:AddItem(source, item, amount, metadata)
 | |
| 		end
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "qs-inventory" then
 | |
| 		return exports['qs-inventory']:AddItem(source, item, amount, nil, metadata)
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "ps-inventory" then
 | |
| 		error("ps-inventory not available for ESX")
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "tgiann-inventory" then
 | |
| 		exports["tgiann-inventory"]:AddItem(source, item, amount, nil, metadata)
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "default" then
 | |
| 		if canStoreItemInInventory(source,item,amount) then
 | |
| 			xPlayer.addInventoryItem(item, amount)
 | |
| 			return true
 | |
| 		else
 | |
| 			return false
 | |
| 		end
 | |
| 	else
 | |
| 		return Utils.CustomScripts.givePlayerItem(source,item,amount,metadata)
 | |
| 	end
 | |
| 	return false
 | |
| end
 | |
| 
 | |
| function Utils.Framework.insertWeaponInInventory(source,item,amount,metadata)
 | |
| 	local ammo = 0
 | |
| 	if metadata and metadata.ammo then
 | |
| 		ammo = metadata.ammo
 | |
| 	end
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if Config.custom_scripts_compatibility.inventory == "ox_inventory" then
 | |
| 		if exports['ox_inventory']:CanCarryItem(source, item, amount) then
 | |
| 			return exports['ox_inventory']:AddItem(source, item, amount, metadata)
 | |
| 		end
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "qs-inventory" then
 | |
| 		return exports['qs-inventory']:AddItem(source, item, amount, metadata)
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "ps-inventory" then
 | |
| 		error("ps-inventory not available for ESX")
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "tgiann-inventory" then
 | |
| 		exports["tgiann-inventory"]:AddItem(source, item, amount, nil, metadata)
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "default" then
 | |
| 		xPlayer.addWeapon(item, ammo)
 | |
| 		return true
 | |
| 	else
 | |
| 		return Utils.CustomScripts.givePlayerWeapon(source,item,amount,metadata)
 | |
| 	end
 | |
| 	return false
 | |
| end
 | |
| 
 | |
| function Utils.Framework.givePlayerWeapon(source,item,amount,metadata)
 | |
| 	if Config.custom_scripts_compatibility.mdt == "ps-mdt" then
 | |
| 		error("ps-mdt not available for ESX")
 | |
| 	elseif Config.custom_scripts_compatibility.mdt == "redutzu-mdt" then
 | |
| 		error("redutzu-mdt not available for ESX")
 | |
| 	elseif Config.custom_scripts_compatibility.mdt == "lb-tablet" then
 | |
| 		error("lb-tablet not available for ESX")
 | |
| 	elseif Config.custom_scripts_compatibility.mdt == "default" then
 | |
| 		return Utils.Framework.insertWeaponInInventory(source,item,amount,metadata)
 | |
| 	else
 | |
| 		return Utils.CustomScripts.createWeaponInMdt(source,item,amount,metadata)
 | |
| 	end
 | |
| 	return false
 | |
| end
 | |
| 
 | |
| function Utils.Framework.playerHasItem(source,item,amount)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if xPlayer.getInventoryItem(item) and xPlayer.getInventoryItem(item).count >= amount then
 | |
| 		return true
 | |
| 	else
 | |
| 		return false
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getPlayerItem(source,item,amount)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if Config.custom_scripts_compatibility.inventory == "ox_inventory" then
 | |
| 		return exports['ox_inventory']:RemoveItem(source, item, amount)
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "qs-inventory" then
 | |
| 		if Utils.Framework.playerHasItem(source,item,amount) then
 | |
| 			exports['qs-inventory']:RemoveItem(source, item, amount)
 | |
| 			return true
 | |
| 		else
 | |
| 			return false
 | |
| 		end
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "ps-inventory" then
 | |
| 		error("ps-inventory not available for ESX")
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "tgiann-inventory" then
 | |
| 		exports["tgiann-inventory"]:RemoveItem(source, item, amount)
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "default" then
 | |
| 		if Utils.Framework.playerHasItem(source,item,amount) then
 | |
| 			xPlayer.removeInventoryItem(item,amount)
 | |
| 			return true
 | |
| 		else
 | |
| 			return false
 | |
| 		end
 | |
| 	else
 | |
| 		return Utils.CustomScripts.getPlayerItem(source,item,amount)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getPlayerWeapon(source,item,amount)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	if Config.custom_scripts_compatibility.inventory == "ox_inventory" then
 | |
| 		return exports['ox_inventory']:RemoveItem(source, item, amount)
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "qs-inventory" then
 | |
| 		if Utils.Framework.playerHasItem(source,item,amount) then
 | |
| 			exports['qs-inventory']:RemoveItem(source, item, amount)
 | |
| 			return true
 | |
| 		else
 | |
| 			return false
 | |
| 		end
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "ps-inventory" then
 | |
| 		error("ps-inventory not available for ESX")
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "tgiann-inventory" then
 | |
| 		exports["tgiann-inventory"]:RemoveItem(source, item, amount)
 | |
| 	elseif Config.custom_scripts_compatibility.inventory == "default" then
 | |
| 		if Utils.Framework.playerHasItem(source,item,amount) then
 | |
| 			xPlayer.removeInventoryItem(item,amount)
 | |
| 			return true
 | |
| 		else
 | |
| 			return false
 | |
| 		end
 | |
| 	else
 | |
| 		return Utils.CustomScripts.getPlayerWeapon(source,item,amount)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function Utils.Framework.hasWeaponLicense(source)
 | |
| 	local hasLicense = nil
 | |
| 	TriggerEvent('esx_license:checkLicense', source, "weapon", function(hasWeaponLicense)
 | |
| 		if hasWeaponLicense then
 | |
| 			hasLicense = true
 | |
| 		else
 | |
| 			hasLicense = false
 | |
| 		end
 | |
| 	end)
 | |
| 	while hasLicense == nil do
 | |
| 		Wait(10)
 | |
| 	end
 | |
| 	return hasLicense
 | |
| end
 | |
| 
 | |
| function Utils.Framework.registerUsableItem(item_id, event_name, is_server_event, ...)
 | |
| 	local args = {...}
 | |
| 	ESX.RegisterUsableItem(item_id, function(playerId)
 | |
| 		local xPlayer = ESX.GetPlayerFromId(playerId)
 | |
| 		if is_server_event then
 | |
| 			TriggerEvent(event_name, xPlayer.source, item_id, xPlayer.identifier, table.unpack(args))
 | |
| 		else
 | |
| 			TriggerClientEvent(event_name, xPlayer.source, item_id, xPlayer.identifier, table.unpack(args))
 | |
| 		end
 | |
| 	end)
 | |
| end
 | |
| 
 | |
| -----------------------------------------------------------------------------------------------------------------------------------------
 | |
| -- Vehicles
 | |
| -----------------------------------------------------------------------------------------------------------------------------------------
 | |
| local vehList = {}
 | |
| function Utils.Framework.setvehList(l)
 | |
| 	vehList = l
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getVehicleModelFromVehicleColumn(vehicle)
 | |
| 	local vehicleProps = json.decode(vehicle)
 | |
| 	return vehList[vehicleProps.model] or "CARNOTFOUND"
 | |
| end
 | |
| 
 | |
| function Utils.Framework.givePlayerVehicle(source, vehicle, vehicle_type, plate_format, vehicle_props, state, finance_details)
 | |
| 	local xPlayer = ESX.GetPlayerFromId(source)
 | |
| 	local plate = vehicle_props and vehicle_props.plate or Utils.Framework.generatePlate(plate_format)
 | |
| 	local mods = vehicle_props and vehicle_props or { model = joaat(vehicle), plate = plate, tankHealth = 1000.0, bodyHealth = 1000.0, engineHealth = 1000.0 }
 | |
| 	local state = state or 1
 | |
| 	local finance_details = finance_details or {}
 | |
| 	local vehicle_type = vehicle_type or 'car'
 | |
| 	local garage = Config.owned_vehicles['default'].garage
 | |
| 	if Config.owned_vehicles[vehicle_type] then
 | |
| 		garage = Config.owned_vehicles[vehicle_type].garage
 | |
| 	end
 | |
| 	Utils.Database.execute('INSERT INTO owned_vehicles (owner, plate, vehicle, type, stored, parking, balance, paymentamount, paymentsleft, financetime) VALUES (@owner, @plate, @vehicle, @type, @stored, @parking, @balance, @paymentamount, @paymentsleft, @financetime)',
 | |
| 	{
 | |
| 		['@owner'] = xPlayer.identifier,
 | |
| 		['@plate'] = plate,
 | |
| 		['@vehicle'] = json.encode(mods),
 | |
| 		['@stored'] = state, -- 1 = inside garage | 0 = outside garage
 | |
| 		['@type'] = vehicle_type,
 | |
| 		['@parking'] = garage,
 | |
| 		['@balance'] = finance_details.balance or 0,
 | |
| 		['@paymentamount'] = finance_details.paymentamount or 0,
 | |
| 		['@paymentsleft'] = finance_details.paymentsleft or 0,
 | |
| 		['@financetime'] = finance_details.financetime or 0
 | |
| 	})
 | |
| 	return true
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getVehiclesData(plate, user_id, query_data)
 | |
| 	query_data = query_data or {}
 | |
| 	local sql = "SELECT owner as user_id, vehicle, plate, balance, paymentamount, paymentsleft, financetime FROM `owned_vehicles` WHERE 1=1";
 | |
| 	local params = {}
 | |
| 
 | |
| 	if plate then
 | |
| 		sql = sql .. " AND plate = @plate"
 | |
| 		params['@plate'] = plate
 | |
| 	end
 | |
| 
 | |
| 	if user_id then
 | |
| 		sql = sql .. " AND owner = @user_id"
 | |
| 		params['@user_id'] = user_id
 | |
| 	end
 | |
| 
 | |
| 	if query_data.only_financed_vehicles then
 | |
| 		sql = sql .. " AND balance > 0"
 | |
| 	end
 | |
| 
 | |
| 	local query = Utils.Database.fetchAll(sql, params)
 | |
| 	for k, v in pairs(query) do
 | |
| 		query[k].vehicle = Utils.Framework.getVehicleModelFromVehicleColumn(v.vehicle)
 | |
| 	end
 | |
| 	return query
 | |
| end
 | |
| 
 | |
| function Utils.Framework.updateVehicleData(plate, user_id, vehicle_data)
 | |
| 	if not vehicle_data or vehicle_data == {} then return end
 | |
| 	assert(plate, "plate cannot be null")
 | |
| 	assert(next(vehicle_data) ~= nil, "vehicle_data table must have at least one element")
 | |
| 
 | |
| 	local sql = "UPDATE `owned_vehicles` SET ";
 | |
| 
 | |
| 	local params = {
 | |
| 		['@plate'] = plate
 | |
| 	}
 | |
| 
 | |
| 	if vehicle_data.balance then
 | |
| 		sql = sql .. "balance = @balance, "
 | |
| 		params['@balance'] = vehicle_data.balance
 | |
| 	end
 | |
| 
 | |
| 	if vehicle_data.paymentamount then
 | |
| 		sql = sql .. "paymentamount = @paymentamount, "
 | |
| 		params['@paymentamount'] = vehicle_data.paymentamount
 | |
| 	end
 | |
| 
 | |
| 	if vehicle_data.paymentsleft then
 | |
| 		sql = sql .. "paymentsleft = @paymentsleft, "
 | |
| 		params['@paymentsleft'] = vehicle_data.paymentsleft
 | |
| 	end
 | |
| 
 | |
| 	if vehicle_data.financetime then
 | |
| 		sql = sql .. "financetime = @financetime, "
 | |
| 		params['@financetime'] = vehicle_data.financetime
 | |
| 	end
 | |
| 
 | |
| 	sql = sql:sub(1, -3)
 | |
| 
 | |
| 	sql = sql .. " WHERE plate = @plate"
 | |
| 
 | |
| 	if user_id then
 | |
| 		sql = sql .. " AND owner = @user_id"
 | |
| 		params['@user_id'] = user_id
 | |
| 	end
 | |
| 
 | |
| 	Utils.Database.execute(sql, params);
 | |
| end
 | |
| 
 | |
| function Utils.Framework.deleteOwnedVehicle(plate, user_id)
 | |
| 	assert(plate, "plate cannot be null")
 | |
| 	local sql = "DELETE FROM `owned_vehicles` WHERE plate = @plate"
 | |
| 
 | |
| 	local params = {
 | |
| 		['@plate'] = plate
 | |
| 	}
 | |
| 
 | |
| 	if user_id then
 | |
| 		sql = sql .. " AND owner = @user_id"
 | |
| 		params['@user_id'] = user_id
 | |
| 	end
 | |
| 
 | |
| 	Utils.Database.execute(sql, params)
 | |
| end
 | |
| 
 | |
| function Utils.Framework.deductFinanceTimeFromPlayerVehicles(user_id, financetime)
 | |
| 	local sql = "UPDATE owned_vehicles SET financetime = financetime - @financetime WHERE owner = @user_id AND balance > 0";
 | |
| 	Utils.Database.execute(sql, {['@user_id'] = user_id, ['@financetime'] = financetime});
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getVehicleDataByPlates(plates)
 | |
| 	local plate_str = table.concat(plates, "','")
 | |
| 	local sql = ("SELECT owner as user_id, vehicle, plate, balance, paymentamount, paymentsleft, financetime FROM `owned_vehicles` WHERE plate IN('%s')"):format(plate_str);
 | |
| 	local query = Utils.Database.fetchAll(sql, {});
 | |
| 	for k, v in pairs(query) do
 | |
| 		query[k].vehicle = Utils.Framework.getVehicleModelFromVehicleColumn(v.vehicle)
 | |
| 	end
 | |
| 	return query
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getVehicleOwner(plate)
 | |
| 	local query = Utils.Database.fetchAll("SELECT owner as user_id FROM owned_vehicles WHERE plate = @plate", {['@plate'] = plate})
 | |
| 	if query[1] then
 | |
| 		return query[1].user_id
 | |
| 	else
 | |
| 		return false
 | |
| 	end
 | |
| end
 | |
| Utils.Framework.isOwnedVehicle = Utils.Framework.getVehicleOwner -- Adv. vehicles
 | |
| 
 | |
| function Utils.Framework.dontAskMeWhatIsThis(user_id)
 | |
| 	local sql = [[
 | |
| 		SELECT O.owner, O.vehicle, O.plate, R.price, R.id, R.status
 | |
| 		FROM `owned_vehicles` O
 | |
| 		LEFT JOIN `dealership_requests` R ON R.plate = O.plate
 | |
| 		WHERE O.owner = @user_id OR R.user_id = @user_id AND R.request_type = 0
 | |
| 			UNION
 | |
| 		SELECT O.owner, R.vehicle, R.plate, R.price, R.id, R.status
 | |
| 		FROM `owned_vehicles` O
 | |
| 		RIGHT JOIN `dealership_requests` R ON R.plate = O.plate
 | |
| 		WHERE O.owner = @user_id OR R.user_id = @user_id AND R.request_type = 0
 | |
| 	]];
 | |
| 	local vehicles = Utils.Database.fetchAll(sql,{['@user_id'] = user_id});
 | |
| 
 | |
| 	local owned_vehicles = {}
 | |
| 	for k,v in pairs(vehicles) do
 | |
| 		if not v.id then -- Not in requests table
 | |
| 			local vehicleProps = json.decode(v.vehicle)
 | |
| 			local model = vehicleProps.model
 | |
| 			table.insert(owned_vehicles, {model = model, plate = v.plate, price = v.price, id = v.id, status = v.status})
 | |
| 		else
 | |
| 			table.insert(owned_vehicles, {vehicle = v.vehicle, plate = v.plate, price = v.price, id = v.id, status = v.status})
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	local data = {}
 | |
| 	for k,v in pairs(owned_vehicles) do
 | |
| 		if not v.vehicle then
 | |
| 			local vehName = vehList[v.model]
 | |
| 			if vehName == nil then vehName = "CARNOTFOUND" end
 | |
| 			table.insert(data, {plate=v.plate, price = v.price, id = v.id, status = v.status, vehicle = vehName})
 | |
| 		else
 | |
| 			table.insert(data, {plate=v.plate, price = v.price, id = v.id, status = v.status, vehicle = v.vehicle})
 | |
| 		end
 | |
| 	end
 | |
| 	return data
 | |
| end
 | |
| 
 | |
| function Utils.Framework.generatePlate(plate_format)
 | |
| 	local plateFormat = plate_format or Config.owned_vehicles.plate_format
 | |
| 	local generatedPlate = ''
 | |
| 	math.randomseed(os.time())
 | |
| 	for i = 1, math.min(#plateFormat, 8) do
 | |
| 		local currentChar = string.sub(plateFormat, i, i)
 | |
| 		if currentChar == 'n' then
 | |
| 			local a = math.random(0, 9)
 | |
| 			generatedPlate = generatedPlate .. a
 | |
| 		elseif currentChar == 'l' then
 | |
| 			local a = string.char(math.random(65, 90))
 | |
| 			generatedPlate = generatedPlate .. a
 | |
| 		elseif currentChar == 'x' then
 | |
| 			local isLetter = math.random(0, 1)
 | |
| 			if isLetter == 1 then
 | |
| 				local a = string.char(math.random(65, 90))
 | |
| 				generatedPlate = generatedPlate .. a
 | |
| 			else
 | |
| 				local a = math.random(0, 9)
 | |
| 				generatedPlate = generatedPlate .. a
 | |
| 			end
 | |
| 		else
 | |
| 			generatedPlate = generatedPlate .. string.upper(currentChar)
 | |
| 		end
 | |
| 	end
 | |
| 	local isDuplicate = MySQL.Sync.fetchScalar('SELECT COUNT(1) FROM owned_vehicles WHERE plate = @plate', {
 | |
| 		['@plate'] = generatedPlate
 | |
| 	})
 | |
| 	if isDuplicate == 1 then
 | |
| 		generatedPlate = Utils.Framework.generatePlate(plateFormat)
 | |
| 	end
 | |
| 	return generatedPlate
 | |
| end
 | |
| 
 | |
| Citizen.CreateThread(function()
 | |
| 	Wait(2000)
 | |
| 	Utils.Database.validateOwnedVehicleTableColumns("owned_vehicles")
 | |
| end)
 | |
| -----------------------------------------------------------------------------------------------------------------------------------------
 | |
| -- Trucker
 | |
| -----------------------------------------------------------------------------------------------------------------------------------------
 | |
| 
 | |
| function Utils.Framework.getTopTruckers()
 | |
| 	local sql = [[SELECT U.lastname as name, U.firstname, T.user_id, T.exp, T.traveled_distance 
 | |
| 		FROM trucker_users T 
 | |
| 		INNER JOIN users U ON T.user_id = U.identifier
 | |
| 		WHERE traveled_distance > 0 ORDER BY traveled_distance DESC LIMIT 10]];
 | |
| 	return Utils.Database.fetchAll(sql,{});
 | |
| end
 | |
| 
 | |
| function Utils.Framework.getpartyMembers(party_id)
 | |
| 	local sql = [[SELECT U.lastname as name, U.firstname, P.* 
 | |
| 		FROM `trucker_party_members` P
 | |
| 		INNER JOIN users U ON P.user_id = U.identifier
 | |
| 		WHERE party_id = @party_id]];
 | |
| 	return Utils.Database.fetchAll(sql,{['@party_id'] = party_id});
 | |
| end
 | |
| 
 | |
| -----------------------------------------------------------------------------------------------------------------------------------------
 | |
| -- Fisher
 | |
| -----------------------------------------------------------------------------------------------------------------------------------------
 | |
| 
 | |
| function Utils.Framework.getTopFishers()
 | |
| 	local sql = [[SELECT U.lastname as name, U.firstname, F.user_id, F.exp, SUM(C.amount) as fishes_caught
 | |
| 		FROM fishing_simulator_users F 
 | |
| 		INNER JOIN users U ON F.user_id = U.identifier
 | |
| 		LEFT JOIN fishing_simulator_fishes_caught C ON F.user_id = C.user_id
 | |
| 		WHERE F.exp > 0
 | |
| 		GROUP BY U.lastname, U.firstname, F.user_id, F.exp
 | |
| 		ORDER BY F.exp DESC
 | |
| 		LIMIT 10]];
 | |
| 	return Utils.Database.fetchAll(sql,{});
 | |
| end
 | |
| 
 | |
| -----------------------------------------------------------------------------------------------------------------------------------------
 | |
| -- Collations
 | |
| -----------------------------------------------------------------------------------------------------------------------------------------
 | |
| 
 | |
| function Utils.Framework.validateTableCollations(script_table, script_column, alter_queries)
 | |
| 	local collation_sql = [[SELECT COLLATION_NAME, CHARACTER_SET_NAME 
 | |
| 		FROM information_schema.columns
 | |
| 		WHERE table_schema = (SELECT DATABASE() AS default_schema)
 | |
| 		AND table_name = 'users'
 | |
| 		AND column_name = 'identifier']]
 | |
| 	local query_collation = Utils.Database.fetchAll(collation_sql,{})[1];
 | |
| 	local collation_sql_script = [[SELECT COLLATION_NAME, CHARACTER_SET_NAME
 | |
| 		FROM information_schema.columns
 | |
| 		WHERE table_schema = (SELECT DATABASE() AS default_schema)
 | |
| 		AND table_name = ']]..script_table..[['
 | |
| 		AND column_name = ']]..script_column..[[']]
 | |
| 	local query_collation_script = Utils.Database.fetchAll(collation_sql_script,{})[1];
 | |
| 	if query_collation and query_collation['COLLATION_NAME'] and query_collation['CHARACTER_SET_NAME'] and query_collation_script and query_collation_script['COLLATION_NAME'] and query_collation['COLLATION_NAME'] ~= query_collation_script['COLLATION_NAME'] then
 | |
| 		for _, alter_query in ipairs(alter_queries) do
 | |
| 			Utils.Database.execute(alter_query:format(query_collation['CHARACTER_SET_NAME'],query_collation['COLLATION_NAME']), {})
 | |
| 		end
 | |
| 	end
 | |
| end
 | 
