Wrong server was published before. This is the one that runs on the hosting account the video was made on: FiveRP - two-step registration (account, then an identity printed onto a passport), login that returns you to your resident, and a loading screen driven by the game's own streaming events. resources/[local]/fiverp-auth NUI + scrypt hashes + oxmysql resources/[local]/fiverp-characters identity, character load, spawn resources/[local]/fiverp-loadscreen loading screen sql/schema.sql accounts, characters docs/DESIGN.md the design system every screen follows docs/screens/ shot from the live server Only our own code is in here. cfx-server-data and oxmysql are fetched by install.sh instead of being vendored, which keeps the repo at 3.7 MB. install.sh does the whole box in one command: recommended FXServer build, cfx-server-data, oxmysql, MariaDB with the schema, resources, server.cfg (mode 600 - it carries the key and the database password), boot entry, then it waits for the Cfx registration. Tested end to end on a spare install root: 29 resources scanned, database and schema created, and it stopped exactly where a wrong licence key should stop it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
146 lines
4.1 KiB
Lua
146 lines
4.1 KiB
Lua
local isOpen = false
|
|
local cam = nil
|
|
local authDone = false
|
|
|
|
-- A slow drift over the city gives the glass something to sit on.
|
|
local CAM_POS = vector3(-1030.0, -2730.0, 320.0)
|
|
local CAM_LOOK = vector3(-75.0, -815.0, 220.0)
|
|
local SPAWN_POS = vector3(195.17, -889.36, 30.69)
|
|
local SPAWN_HDG = 145.0
|
|
|
|
local function startCamera()
|
|
cam = CreateCamWithParams('DEFAULT_SCRIPTED_CAMERA',
|
|
CAM_POS.x, CAM_POS.y, CAM_POS.z, 0.0, 0.0, 0.0, 55.0, false, 0)
|
|
PointCamAtCoord(cam, CAM_LOOK.x, CAM_LOOK.y, CAM_LOOK.z)
|
|
SetCamActive(cam, true)
|
|
RenderScriptCams(true, false, 0, true, true)
|
|
|
|
-- Drift the camera so the backdrop is never a frozen still.
|
|
CreateThread(function()
|
|
local angle = 0.0
|
|
while cam and DoesCamExist(cam) and not authDone do
|
|
angle = angle + 0.02
|
|
local radius = 260.0
|
|
SetCamCoord(cam,
|
|
CAM_POS.x + math.cos(math.rad(angle)) * radius,
|
|
CAM_POS.y + math.sin(math.rad(angle)) * radius,
|
|
CAM_POS.z)
|
|
PointCamAtCoord(cam, CAM_LOOK.x, CAM_LOOK.y, CAM_LOOK.z)
|
|
Wait(20)
|
|
end
|
|
end)
|
|
end
|
|
|
|
local function stopCamera()
|
|
if cam and DoesCamExist(cam) then
|
|
RenderScriptCams(false, true, 900, true, true)
|
|
DestroyCam(cam, false)
|
|
cam = nil
|
|
end
|
|
end
|
|
|
|
local function openAuth()
|
|
isOpen = true
|
|
SetNuiFocus(true, true)
|
|
SendNUIMessage({ action = 'open' })
|
|
DoScreenFadeIn(600)
|
|
end
|
|
|
|
local function closeAuth()
|
|
isOpen = false
|
|
SetNuiFocus(false, false)
|
|
SendNUIMessage({ action = 'close' })
|
|
end
|
|
|
|
-- Keep the unauthenticated player parked and invisible behind the glass.
|
|
CreateThread(function()
|
|
while not authDone do
|
|
local ped = PlayerPedId()
|
|
SetEntityVisible(ped, false, false)
|
|
SetEntityCollision(ped, false, false)
|
|
FreezeEntityPosition(ped, true)
|
|
SetPlayerInvincible(PlayerId(), true)
|
|
DisableAllControlActions(0)
|
|
Wait(0)
|
|
end
|
|
end)
|
|
|
|
-- Any map resource can re-enable auto spawn when it starts, so hold the gate
|
|
-- shut every time that happens until the player actually has an identity.
|
|
AddEventHandler('onClientMapStart', function()
|
|
if not authDone then
|
|
exports.spawnmanager:setAutoSpawn(false)
|
|
end
|
|
end)
|
|
|
|
CreateThread(function()
|
|
-- Take spawning away from spawnmanager until the player has an identity.
|
|
exports.spawnmanager:setAutoSpawn(false)
|
|
|
|
DoScreenFadeOut(0)
|
|
while not NetworkIsSessionStarted() do Wait(100) end
|
|
Wait(500)
|
|
|
|
startCamera()
|
|
openAuth()
|
|
end)
|
|
|
|
-- The account is known; fiverp-characters owns everything from here — the
|
|
-- slot screen, the appearance creator and the spawn itself. Auth only has to
|
|
-- fade out, release its camera and step aside.
|
|
local function enterCity()
|
|
authDone = true
|
|
closeAuth()
|
|
DoScreenFadeOut(500)
|
|
Wait(600)
|
|
stopCamera()
|
|
exports.spawnmanager:setAutoSpawn(false)
|
|
TriggerEvent('fiverp-chars:begin')
|
|
end
|
|
|
|
-- ------------------------------------------------------------- NUI callbacks
|
|
RegisterNUICallback('registerAccount', function(data, cb)
|
|
TriggerServerEvent('fiverp-auth:register:account', data)
|
|
cb({})
|
|
end)
|
|
|
|
RegisterNUICallback('registerIdentity', function(data, cb)
|
|
TriggerServerEvent('fiverp-auth:register:identity', data)
|
|
cb({})
|
|
end)
|
|
|
|
RegisterNUICallback('resumeIdentity', function(data, cb)
|
|
TriggerServerEvent('fiverp-auth:resume:identity', data)
|
|
cb({})
|
|
end)
|
|
|
|
RegisterNUICallback('login', function(data, cb)
|
|
TriggerServerEvent('fiverp-auth:login', data)
|
|
cb({})
|
|
end)
|
|
|
|
-- --------------------------------------------------------------- server said
|
|
RegisterNetEvent('fiverp-auth:register:accountResult', function(result)
|
|
SendNUIMessage({ action = 'accountResult', payload = result })
|
|
end)
|
|
|
|
RegisterNetEvent('fiverp-auth:register:identityResult', function(result)
|
|
SendNUIMessage({ action = 'identityResult', payload = result })
|
|
if result.ok then
|
|
CreateThread(function()
|
|
Wait(1600) -- let the permit finish stamping before the fade
|
|
enterCity(result.firstName, result.lastName)
|
|
end)
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent('fiverp-auth:loginResult', function(result)
|
|
SendNUIMessage({ action = 'loginResult', payload = result })
|
|
if result.ok and not result.needsIdentity then
|
|
CreateThread(function()
|
|
Wait(1200)
|
|
enterCity(result.firstName, result.lastName)
|
|
end)
|
|
end
|
|
end)
|