FiveRP: the server from the hosting account, not the earlier one
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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
71856b15e9
commit
c857979a55
@@ -0,0 +1,133 @@
|
||||
/* FiveRP — loading screen behaviour.
|
||||
|
||||
The game drives this page by posting messages at `window`. The only field
|
||||
that is a genuine 0..1 measure of progress is `loadProgress.loadFraction`;
|
||||
everything else is narration we turn into the phase and detail lines. */
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
const elPct = document.getElementById('pct');
|
||||
const elFill = document.getElementById('fill');
|
||||
const elPhase = document.getElementById('phase');
|
||||
const elDetail = document.getElementById('detail');
|
||||
const elTip = document.getElementById('tip');
|
||||
|
||||
/* ------------------------------------------------------------- progress */
|
||||
|
||||
// Shown and target values are kept apart so the number eases toward the
|
||||
// truth instead of jumping. The game reports progress in coarse steps.
|
||||
let shown = 0;
|
||||
let target = 0;
|
||||
|
||||
function setTarget(fraction) {
|
||||
const pct = Math.max(0, Math.min(100, fraction * 100));
|
||||
// Never walk backwards: a later phase reporting a lower fraction would
|
||||
// otherwise make the bar visibly retreat.
|
||||
if (pct > target) target = pct;
|
||||
}
|
||||
|
||||
function tick() {
|
||||
const gap = target - shown;
|
||||
if (gap > 0.05) {
|
||||
shown += Math.max(gap * 0.08, 0.05);
|
||||
if (shown > target) shown = target;
|
||||
elFill.style.width = shown.toFixed(2) + '%';
|
||||
elPct.textContent = Math.floor(shown);
|
||||
}
|
||||
requestAnimationFrame(tick);
|
||||
}
|
||||
requestAnimationFrame(tick);
|
||||
|
||||
/* ---------------------------------------------------------------- phases */
|
||||
|
||||
function phase(text) {
|
||||
if (elPhase.textContent !== text) elPhase.textContent = text;
|
||||
}
|
||||
|
||||
function detail(text) {
|
||||
const clean = String(text || '').trim();
|
||||
if (!clean) return;
|
||||
elDetail.textContent = clean.length > 88 ? clean.slice(0, 87) + '…' : clean;
|
||||
}
|
||||
|
||||
// Init function names arrive as engine internals ("CPathServer::InitSession").
|
||||
// Strip the noise so the line reads as a status, not a stack trace.
|
||||
function humanise(name) {
|
||||
return String(name || '')
|
||||
.replace(/^dlc_?/i, 'DLC ')
|
||||
.replace(/::.*$/, '')
|
||||
.replace(/^C(?=[A-Z])/, '')
|
||||
.replace(/([a-z])([A-Z])/g, '$1 $2');
|
||||
}
|
||||
|
||||
window.addEventListener('message', function (event) {
|
||||
const data = event.data || {};
|
||||
|
||||
switch (data.eventName) {
|
||||
case 'loadProgress':
|
||||
setTarget(Number(data.loadFraction) || 0);
|
||||
break;
|
||||
|
||||
case 'startInitFunctionOrder':
|
||||
phase('Loading game');
|
||||
break;
|
||||
|
||||
case 'startInitFunction':
|
||||
phase('Loading game');
|
||||
break;
|
||||
|
||||
case 'initFunctionInvoking':
|
||||
phase('Loading game');
|
||||
detail(humanise(data.name));
|
||||
// The engine gives idx/count per order; use it when loadProgress is
|
||||
// quiet so the bar keeps creeping during long orders.
|
||||
if (data.count) setTarget(0.1 + 0.5 * (Number(data.idx) / Number(data.count)));
|
||||
break;
|
||||
|
||||
case 'startDataFileEntries':
|
||||
phase('Streaming content');
|
||||
detail('Mounting ' + (data.count || 0) + ' data files');
|
||||
break;
|
||||
|
||||
case 'performMappedDataFileEntry':
|
||||
phase('Streaming content');
|
||||
detail(String(data.name || '').split('/').pop());
|
||||
break;
|
||||
|
||||
case 'onLogLine':
|
||||
detail(data.message);
|
||||
break;
|
||||
|
||||
case 'onDataFileEntry':
|
||||
phase('Streaming content');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
/* ------------------------------------------------------------------ tips */
|
||||
|
||||
const TIPS = [
|
||||
'Your account and your character are separate — one login can hold your identity for good.',
|
||||
'Names are issued once. Pick a first and last name you want to be known by.',
|
||||
'Press F8 at any time to open the console if something looks wrong.',
|
||||
'Your passport is proof of residency — officers may ask to see it.',
|
||||
'Use a real email address. It is the only way to recover an account.',
|
||||
'Speak in character. The city is more fun when everyone stays in the story.',
|
||||
'Lost? The Legion Square spawn is the heart of downtown Los Santos.'
|
||||
];
|
||||
|
||||
let tipIndex = 0;
|
||||
setInterval(function () {
|
||||
tipIndex = (tipIndex + 1) % TIPS.length;
|
||||
elTip.classList.add('is-swapping');
|
||||
setTimeout(function () {
|
||||
elTip.textContent = TIPS[tipIndex];
|
||||
elTip.classList.remove('is-swapping');
|
||||
}, 450);
|
||||
}, 7000);
|
||||
|
||||
/* Nothing has reported in yet — creep to a believable floor so the screen
|
||||
never sits at a dead 0% while the engine warms up. */
|
||||
setTimeout(function () { setTarget(0.04); }, 400);
|
||||
})();
|
||||
Reference in New Issue
Block a user