local newPlayer = 'INSERT INTO `users` SET `accounts` = ?, `identifier` = ?, `discord` = ?, `name` = ?, `group` = ?, `license` = ?' local loadPlayer = 'SELECT `accounts`, `level`, `job`, `job_grade`, `job2`, `job2_grade`, `group`, `position`, `playtime`, `inventory`, `skin`, `status`, `loadout`, `invoices`, `citizenid`, `discord`, `zorgverzekering`' if Config.Multichar then newPlayer = newPlayer .. ', `firstname` = ?, `lastname` = ?, `dateofbirth` = ?, `sex` = ?, `height` = ?' end if Config.Multichar or Config.Identity then loadPlayer = loadPlayer .. ', `firstname`, `lastname`, `dateofbirth`, `sex`, `height`' end loadPlayer = loadPlayer .. ' FROM `users` WHERE identifier = ? LIMIT 1' local canJoin = true exports('toggleJoining', function(src) canJoin = not canJoin if src and src ~= '0' and src ~= '' then if canJoin then TriggerClientEvent('chatMessage', src, 'SYSTEEM', 'success', 'De Server valt weer succesvol te joinen!') else TriggerClientEvent('chatMessage', src, 'SYSTEEM', 'error', 'De Server is tijdelijk dichtgegooid, gebruik dit command weer om de Server te openen!') end end end) if Config.Multichar then AddEventHandler('esx:onPlayerJoined', function(src, char, data) while not next(ESX.Jobs) do Wait(50) end if not ESX.Players[src] then local identifier = ESX.GetIdentifier(src) if data then createESXPlayer(identifier, src, data) else loadESXPlayer(identifier, src, false) end end end) else RegisterNetEvent('esx:onPlayerJoined') AddEventHandler('esx:onPlayerJoined', function() local _source = source while not next(ESX.Jobs) do Wait(50) end if not ESX.Players[_source] then onPlayerJoined(_source) end end) end function onPlayerJoined(playerId) local identifier = ESX.GetIdentifier(playerId) if identifier then if ESX.GetPlayerFromIdentifier(identifier) then DropPlayer(playerId, ('[🚧] Er is iets misgegaan met het ophalen van je character!\nError code: identifier-active\n\nDe oorzaak van deze foutmelding komt doordat er iemand op hetzelfde account speelt. Zorg ervoor dat je maar op 1 account speelt.\n\nJouw identifier: %s'):format(identifier)) else local result = MySQL.scalar.await('SELECT 1 FROM users WHERE identifier = ?', {identifier}) if result then loadESXPlayer(identifier, playerId, false) else createESXPlayer(identifier, playerId) end end else DropPlayer(playerId, '[🚧] Er is iets misgegaan met het ophalen van je character!\nError code: identifier-missing-ingame\n\nDe oorzaak van deze foutmelding komt doordat er geen identifier is gevonden. Kom later terug of neem contact op met het support team!') end end function createESXPlayer(identifier, playerId, data) local accounts = {} for account, money in pairs(Config.StartingAccountMoney) do accounts[account] = money end if not Config.Multichar then local discord = GetPlayerIdentifierByType(playerId, 'discord') local license = GetPlayerIdentifierByType(playerId, 'license') local name = GetPlayerName(playerId) MySQL.prepare(newPlayer, {json.encode(accounts), identifier, discord, name, defaultGroup, license}, function() loadESXPlayer(identifier, playerId, true) end) else local discord = GetPlayerIdentifierByType(playerId, 'discord') local license = GetPlayerIdentifierByType(playerId, 'license') local name = GetPlayerName(playerId) MySQL.prepare(newPlayer, {json.encode(accounts), identifier, discord, name, defaultGroup, license, data.firstname, data.lastname, data.dateofbirth, data.sex, data.height}, function() loadESXPlayer(identifier, playerId, true) end) end end if not Config.Multichar then AddEventHandler('playerConnecting', function(name, setCallback, deferrals) deferrals.defer() local playerId = source local steam = GetPlayerIdentifierByType(playerId, 'steam') local discord = GetPlayerIdentifierByType(playerId, 'discord') if not discord then deferrals.done('[🚧] Er is iets misgegaan met het ophalen van je character!\nError code: discord-missing\n\nDe oorzaak hiervan is dat Discord geen verbinding kan maken met jouw FiveM software, start Discord/FiveM opnieuw op en probeer het opnieuw.') return end if steam then if ESX.GetPlayerFromIdentifier(steam) then deferrals.done(('[🚧] Er is iets misgegaan met het ophalen van je character!\nError code: identifier-active\n\nDe oorzaak van deze foutmelding komt doordat er iemand op hetzelfde account speelt. Zorg ervoor dat je maar op 1 account speelt.\n\nJouw identifier: %s'):format(steam)) else local license = GetPlayerIdentifierByType(playerId, 'license') local name = GetPlayerName(playerId) local result = MySQL.prepare.await('SELECT `discord`, `identifier`, `name`, `group`, `power` FROM users WHERE discord = ? OR license = ? LIMIT 1', {discord, license}) local group, power if result then group = result.group power = result.power if result.identifier ~= steam then if result.name then deferrals.done('[🚧] Er is iets misgegaan met het ophalen van je character!\nError code: duping-found\n\nDe oorzaak hiervan is dat je een andere account (' .. result.name .. ') hebt gekoppeld waar je op hebt gespeeld, probeer het opnieuw.') else deferrals.done('[🚧] Er is iets misgegaan met het ophalen van je character!\nError code: duping-found\n\nDe oorzaak hiervan is dat je een andere account hebt gekoppeld waar je op hebt gespeeld, probeer het opnieuw.') end return end else group = 'user' power = 0 end if canJoin then deferrals.update('[🚧] Toevoegen aan queue van Future, even geduld..') exports['frp-queue']:addPlayertoQueue(playerId, name, setCallback, deferrals, steam, discord, group, power) else deferrals.done('[🚧] De Server heeft een geplande restart of is tijdelijk dicht gegooid, wacht even een paar minuten met opnieuw joinen!') end end else deferrals.done('[🚧] Er is iets misgegaan met het ophalen van je character!\nError code: identifier-missing\n\nDe oorzaak hiervan is dat je Steam geen verbinding kan maken met jouw FiveM software, start je Steam (opnieuw) op en probeer het opnieuw.') end end) end function loadESXPlayer(identifier, playerId, isNew) local userData = { accounts = {}, inventory = {}, job = {}, job2 = {}, loadout = {}, playerName = GetPlayerName(playerId), steamName = GetPlayerName(playerId), discord = GetPlayerIdentifierByType(playerId, 'discord'), license = GetPlayerIdentifierByType(playerId, 'license'), weight = 0 } local result = MySQL.prepare.await(loadPlayer, {identifier}) local job, grade, jobObject, gradeObject = result.job, tostring(result.job_grade) local job2, grade2, job2Object, grade2Object = result.job2, tostring(result.job2_grade) local foundAccounts, foundItems = {}, {} userData.level = result.level userData.zorgverzekering = tonumber(result.zorgverzekering) == 1 and true or false userData.seconds = tonumber(result.playtime) if result.accounts and result.accounts ~= '' then local accounts = json.decode(result.accounts) for account, money in pairs(accounts) do foundAccounts[account] = money end end for account, label in pairs(Config.Accounts) do userData.accounts[#userData.accounts+1] = { name = account, money = foundAccounts[account] or Config.StartingAccountMoney[account] or 0, label = label } end if ESX.DoesJobExist(job, grade) then jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] else print(('[^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(identifier, job, grade)) job, grade = 'unemployed', '0' jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] end userData.job.id = jobObject.id userData.job.name = jobObject.name userData.job.label = jobObject.label userData.job.grade = tonumber(grade) userData.job.grade_name = gradeObject.name userData.job.grade_label = gradeObject.label userData.job.grade_salary = gradeObject.salary userData.job.onDuty = Config.OnDuty if ESX.DoesJob2Exist(job2, grade2) then job2Object, grade2Object = ESX.Jobs[job2], ESX.Jobs[job2].grades[grade2] else print(('[^3WARNING^7] Ignoring invalid job2 for %s [job2: %s, grade: %s]'):format(identifier, job2, grade2)) job2, grade2 = 'unemployed', '0' job2Object, grade2Object = ESX.Jobs[job2], ESX.Jobs[job2].grades[grade2] end userData.job2.id = job2Object.id userData.job2.name = job2Object.name userData.job2.label = job2Object.label userData.job2.grade = tonumber(grade2) userData.job2.grade_name = grade2Object.name userData.job2.grade_label = grade2Object.label userData.job2.grade_salary = grade2Object.salary userData.job2.skin_male = {} userData.job2.skin_female = {} if gradeObject.skin_male then userData.job2.skin_male = json.decode(grade2Object.skin_male) end if gradeObject.skin_female then userData.job2.skin_female = json.decode(grade2Object.skin_female) end if result.inventory and result.inventory ~= '' then userData.inventory = json.decode(result.inventory) else userData.inventory = {} end if result.group then if result.group == "superadmin" then userData.group = "admin" else userData.group = result.group end else userData.group = 'user' end if result.position and result.position ~= '' then userData.coords = json.decode(result.position) else print('[^3WARNING^7] Column ^5"position"^0 in ^5"users"^0 table is missing required default value. Using backup coords, fix your database.') userData.coords = { x = -552.1413, y = -191.9286, z = 38.2269, heading = 209.3245 } end local invoices = json.decode(result.invoices) if invoices then userData.invoices = invoices end if result.skin and result.skin ~= '' then userData.skin = json.decode(result.skin) else if userData.sex == 'f' then userData.skin = { sex = 1 } else userData.skin = { sex = 0 } end end userData.name = userData.playerName if result.firstname and result.firstname ~= '' then userData.firstname = result.firstname userData.lastname = result.lastname userData.playerName = userData.firstname .. ' ' .. userData.lastname if result.dateofbirth then userData.dateofbirth = result.dateofbirth end if result.sex then userData.sex = result.sex end if result.height then userData.height = result.height end end userData.citizenId = result.citizenid ~= nil and tonumber(result.citizenid) ~= 0 and tonumber(result.citizenid) or Core.GenerateCitizenId(identifier) local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.weight, userData.job, userData.job2, userData.loadout, userData.playerName, userData.coords, userData.citizenId, userData.discord, userData.steamName, userData.level, userData.invoices) ESX.Players[playerId] = xPlayer Core.IdentifierIndex[identifier] = playerId if userData.firstname then xPlayer.set('firstName', userData.firstname) xPlayer.set('lastName', userData.lastname) if userData.dateofbirth then xPlayer.set('dateofbirth', userData.dateofbirth) end if userData.sex then xPlayer.set('sex', userData.sex) end if userData.height then xPlayer.set('height', userData.height) end end xPlayer.set('citizenId', userData.citizenId) xPlayer.set('discord', userData.discord) xPlayer.set('sessiontime', os.time()) xPlayer.set('playtime', userData.seconds) if xPlayer.group ~= 'user' then exports['frp-boilerplate']:addStaff(playerId) end TriggerEvent('esx:playerLoaded', playerId, xPlayer, isNew) xPlayer.triggerEvent('esx:playerLoaded', { accounts = xPlayer.getAccounts(), coords = xPlayer.getCoords(), identifier = xPlayer.getIdentifier(), inventory = playerInv, job = xPlayer.getJob(), job2 = xPlayer.getJob2(), loadout = xPlayer.getLoadout(), maxWeight = xPlayer.getMaxWeight(), money = xPlayer.getMoney(), exp = xPlayer.getEXP(), group = xPlayer.group, dead = false }, isNew, userData.skin) local ply = GetPlayerPed(playerId) Entity(ply).state.group = xPlayer.group if not Config.OxInventory then xPlayer.triggerEvent('esx:createMissingPickups', Core.Pickups) else exports.ox_inventory:setPlayerInventory(xPlayer, userData.inventory) end if isNew then exports.ox_inventory:AddItem(playerId, 'money', 5000) TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) else if not result.firstname or result.firstname == '' then TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source) end end xPlayer.triggerEvent('esx:registerSuggestions', Core.RegisteredCommands) xPlayer.triggerEvent('frp-facturen:client:sync:facturen', userData.invoices, os.time()) xPlayer.set('zorgverzekering', userData.zorgverzekering) local playerInv = xPlayer.getInventory() local status = json.decode(result.status) local inv = '' local firstLogin = isNew and 'Ja' or 'Nee' local otherinformation = '[Job: ' .. xPlayer.job.name .. ' - ' .. xPlayer.job.grade ..'] [Job2: ' .. xPlayer.job2.name .. ' - ' .. xPlayer.job2.grade .. '] [Bank: €' .. xPlayer.getAccount('bank').money .. '] [Nieuwe speler: ' .. firstLogin .. ']' exports['frp-hungerthirst']:loginStatus(playerId, status) if playerInv then for i=1, #playerInv do local slot = playerInv[i] if slot then if slot.metadata and slot.metadata.serial then inv = inv .. '[' .. slot.name ..' x' .. slot.count .. ' ~ ' .. slot.metadata.serial .. '] | ' else inv = inv .. '[' .. slot.name ..' x' .. slot.count .. '] | ' end end end end if inv == '' then inv = 'Geen spullen gevonden.' end if not result.license then exports['oxmysql']:query('UPDATE `users` SET `license` = ? WHERE `identifier` = ? LIMIT 1', { userData.license, xPlayer.identifier }) end end RegisterNetEvent('es_extended:server:newPlayer') AddEventHandler('es_extended:server:newPlayer', function() local src = source exports['frp-boilerplate']:playerJoined(src) end) RegisterNetEvent('es_extended:server:verify:job') AddEventHandler('es_extended:server:verify:job', function(PlayerDataJob) local src = source local xPlayer = ESX.GetPlayerFromId(src) if xPlayer.job.name ~= PlayerDataJob.name then ESX.FlagPlayer(src, 'Heeft geprobeerd client-sided zijn/haar job te veranderen terwijl die niet overeen komt met de Server', true) end end) AddEventHandler('playerDropped', function(reason) local playerId = source local xPlayer = ESX.GetPlayerFromId(playerId) exports['frp-boilerplate']:playerLeaved(playerId) if xPlayer then if xPlayer.group ~= 'user' then exports['frp-boilerplate']:removeStaff(playerId) end TriggerEvent('esx:playerDropped', playerId, reason, xPlayer) exports['frp-hungerthirst']:logoutStatus(xPlayer) local inv = '' local playerInv = xPlayer.getInventory() for i=1, #playerInv do local slot = playerInv[i] if slot then if slot.metadata and slot.metadata.serial then inv = inv .. '[' .. slot.name ..' x' .. slot.count .. ' ~ ' .. slot.metadata.serial .. '] | ' else inv = inv .. '[' .. slot.name ..' x' .. slot.count .. '] | ' end end end if inv == '' then inv = 'Geen spullen gevonden.' end local otherinformation = '[Job: ' .. xPlayer.job.name .. ' - ' .. xPlayer.job.grade ..'] [Job2: ' .. xPlayer.job2.name .. ' - ' .. xPlayer.job2.grade .. '] [Bank: €' .. xPlayer.getAccount('bank').money .. ']' Core.SavePlayer(xPlayer, function() Core.IdentifierIndex[xPlayer.identifier] = nil ESX.Players[playerId] = nil end) end end) AddEventHandler('esx:playerLogout', function(playerId, cb) local xPlayer = ESX.GetPlayerFromId(playerId) if xPlayer then TriggerEvent('esx:playerDropped', playerId) Core.SavePlayer(xPlayer, function() Core.IdentifierIndex[xPlayer.identifier] = nil ESX.Players[playerId] = nil if cb then cb() end end) end TriggerClientEvent("esx:onPlayerLogout", playerId) end) AddEventHandler('chatMessage', function(playerId, author, message) if message:sub(1, 1) == '/' and playerId > 0 then CancelEvent() end end) RegisterNetEvent('esx:updateCoords') AddEventHandler('esx:updateCoords', function(coords) local xPlayer = ESX.GetPlayerFromId(source) if xPlayer then xPlayer.updateCoords(coords) end end) RegisterNetEvent('esx:checkWeapon') AddEventHandler('esx:checkWeapon', function(weaponName, hash) local src = source local xPlayer = ESX.GetPlayerFromId(src) if weaponName == 'bye' then ESX.FlagPlayer(src, 'Heeft geprobeerd een onbekend wapen in te cheaten. [' .. hash ..']', true) return end local weaponname = string.lower(weaponName) local count = exports['ox_inventory']:GetItem(src, weaponname, false, true) if not count or count <= 0 then ESX.FlagPlayer(src, 'Heeft geprobeerd een ' .. weaponName .. ' in te cheaten.', true) end end) RegisterNetEvent('frp-anticheat:server:secured:victory') AddEventHandler('frp-anticheat:server:secured:victory', function(reason) local src = source ESX.FlagPlayer(src, 'Heeft geprobeerd ' .. reason .. ' te gebruiken', true) end) ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) cb({ identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(), job2 = xPlayer.getJob2(), loadout = xPlayer.getLoadout(), money = xPlayer.getMoney(), position = xPlayer.getCoords(true) }) end) ESX.RegisterServerCallback('esx:isUserAdmin', function(source, cb) cb(Core.IsPlayerAdmin(source)) end) ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target) local xPlayer = ESX.GetPlayerFromId(target) cb({ identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(), job2 = xPlayer.getJob2(), loadout = xPlayer.getLoadout(), money = xPlayer.getMoney(), position = xPlayer.getCoords(true) }) end) ESX.RegisterServerCallback('esx:getPlayerNames', function(source, cb, players) players[source] = nil for playerId, v in pairs(players) do local xPlayer = ESX.GetPlayerFromId(playerId) if xPlayer then players[playerId] = xPlayer.getName() else players[playerId] = nil end end cb(players) end) AddEventHandler('txAdmin:events:scheduledRestart', function(eventData) if eventData.secondsRemaining == 60 then CreateThread(function() Core.SavePlayers() Wait(200) canJoin = false exports['frp-queue']:preventJoin() exports['frp-crashhandler']:notCrashed() Citizen.SetTimeout(30000, function() local xPlayers = ESX.GetExtendedPlayers() for i=1, #xPlayers do local xPlayer = xPlayers[i] DropPlayer(xPlayer.source, '[🚧]: Future Roleplay heeft een geplande restart, wacht even met opnieuw joinen!') end end) end) end end) AddEventHandler('giveWeaponEvent', function(sender, ev) local id = tonumber(sender) ESX.FlagPlayer(id, 'Heeft geprobeerd een wapen te geven aan iemand anders', true) CancelEvent() end) RegisterNetEvent('fg:NewUpdate') AddEventHandler('fg:NewUpdate', function(oldVersion, newVersion) if source == 0 or source == '' then ExecuteCommand('refresh') Wait(5000) ExecuteCommand('ensure frp-manualapi') end end) ESX.RegisterServerCallback('esx:srv:sp:veh', function(source, cb, model, modelType, coords, heading) local src = source local rb = GetPlayerRoutingBucket(src) local veh = CreateVehicleServerSetter(model, modelType, coords.x, coords.y, coords.z, heading) local tries = 0 while not DoesEntityExist(veh) do Wait(0) tries = tries + 1 if tries > 350 then break end end SetEntityRoutingBucket(veh, rb) local netID = NetworkGetNetworkIdFromEntity(veh) cb(netID) end)