The repository carried two different servers side by side - the early
`justrp` prototype with its Python auth API, and a snapshot of the real
one under `server-code/`. Only the second one is a server anyone should
start from, so the prototype is gone and the real one moved to the root.
Taken from the live box, so the UI is the finished version (the tokens,
the county-records sheets and the variable fonts landed after the last
snapshot was pushed):
resources/[rp]/ rp_db, rp_core, rp_session, rp_loading, rp_ui,
rp_selftest, rp_dbtest
bin/ supervise.sh (keep-alive + console FIFO), rcon, init script
etc/schema.sql accounts, characters, transactions, inventory, vehicles
assets/fonts/ the bundled subsets
docs/SERVER.md how it is put together, resource by resource
install.sh turns a clean Ubuntu/Debian box into this server in one
command: recommended FXServer build, MariaDB with the schema, resources,
server.cfg + a generated database password, boot entry (systemd or
init.d), then it waits for the Cfx registration. --name/--port/--db-name
let a second server live on the same machine. Tested end to end on a
spare install root: build 25770 fetched, schema applied, boot entry
written, FXServer started and stopped exactly where a wrong licence key
should stop it.
No secrets travel with it: the licence key and the database password live
in data/secrets.cfg on the machine, and .gitignore now names it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
100 lines
4.3 KiB
Lua
100 lines
4.3 KiB
Lua
-- ---------------------------------------------------------------------------
|
|
-- Shared configuration. Loaded on both server and client.
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
Config = {}
|
|
|
|
Config.ServerName = 'LOS SANTOS'
|
|
Config.ServerTag = 'ROLEPLAY'
|
|
Config.MaxChars = 3
|
|
|
|
-- Shown on the loading screen while the world streams in.
|
|
Config.Rules = {
|
|
{ title = 'Stay in character', body = 'Your character does not know what you know. Breaking character in the world is the fastest way to lose the story.' },
|
|
{ title = 'Value your life', body = 'Act like the consequences are permanent. A gun in your face changes what you are willing to do.' },
|
|
{ title = 'No random deathmatch', body = 'Violence needs a reason the other person can understand. Escalate, do not detonate.' },
|
|
{ title = 'Do not power game', body = 'Give people a fair chance to react. Winning is not the point of a scene.' },
|
|
{ title = 'Leave the scene alive', body = 'If you die, your character forgets the thirty minutes before it. No revenge from the grave.' },
|
|
}
|
|
|
|
-- Spawn choices offered after character select. Coordinates are real map
|
|
-- locations; `cam` is where the establishing shot sits before it flies down.
|
|
Config.SpawnPoints = {
|
|
{
|
|
id = 'legion',
|
|
label = 'Legion Square',
|
|
area = 'Downtown',
|
|
blurb = 'Concrete, noise and opportunity. Everything starts here eventually.',
|
|
coords = vector4(195.12, -933.75, 30.69, 145.0),
|
|
cam = { pos = vector3(214.0, -880.0, 90.0), look = vector3(195.0, -933.0, 32.0) },
|
|
map = { x = 0.512, y = 0.548 },
|
|
},
|
|
{
|
|
id = 'vespucci',
|
|
label = 'Vespucci Beach',
|
|
area = 'West coast',
|
|
blurb = 'Sand, boardwalk hustlers and the smell of two-stroke engines.',
|
|
coords = vector4(-1223.45, -1490.32, 4.38, 125.0),
|
|
cam = { pos = vector3(-1250.0, -1440.0, 60.0), look = vector3(-1223.0, -1490.0, 6.0) },
|
|
map = { x = 0.318, y = 0.700 },
|
|
},
|
|
{
|
|
id = 'sandy',
|
|
label = 'Sandy Shores',
|
|
area = 'Blaine County',
|
|
blurb = 'Dust, trailers and people who would rather not be found.',
|
|
coords = vector4(1961.29, 3740.68, 32.34, 300.0),
|
|
cam = { pos = vector3(1995.0, 3700.0, 80.0), look = vector3(1961.0, 3740.0, 34.0) },
|
|
map = { x = 0.760, y = 0.245 },
|
|
},
|
|
{
|
|
id = 'paleto',
|
|
label = 'Paleto Bay',
|
|
area = 'North coast',
|
|
blurb = 'A town small enough that everyone will know your name by Friday.',
|
|
coords = vector4(-108.71, 6467.32, 31.63, 225.0),
|
|
cam = { pos = vector3(-160.0, 6420.0, 80.0), look = vector3(-108.0, 6467.0, 33.0) },
|
|
map = { x = 0.470, y = 0.075 },
|
|
},
|
|
{
|
|
id = 'mirror',
|
|
label = 'Mirror Park',
|
|
area = 'East Vinewood',
|
|
blurb = 'Quiet streets, loud neighbours, and rent you cannot quite afford.',
|
|
coords = vector4(1050.12, -720.45, 57.05, 90.0),
|
|
cam = { pos = vector3(1100.0, -680.0, 100.0), look = vector3(1050.0, -720.0, 58.0) },
|
|
map = { x = 0.640, y = 0.505 },
|
|
},
|
|
}
|
|
|
|
-- Establishing shots used behind the login / character screens. Each entry is
|
|
-- a slow dolly from `from` to `to` while looking at `look`.
|
|
Config.CinematicShots = {
|
|
{ from = vector3(-1900.0, -600.0, 130.0), to = vector3(-1700.0, -500.0, 120.0), look = vector3(-1450.0, -400.0, 60.0) },
|
|
{ from = vector3(-75.0, -818.0, 320.0), to = vector3(30.0, -700.0, 290.0), look = vector3(-200.0, -1000.0, 60.0) },
|
|
{ from = vector3(1200.0, -1600.0, 160.0),to = vector3(1000.0, -1450.0, 150.0), look = vector3(500.0, -1200.0, 60.0) },
|
|
{ from = vector3(-1550.0, -1450.0, 90.0),to = vector3(-1400.0, -1550.0, 80.0), look = vector3(-1100.0, -1700.0, 20.0) },
|
|
{ from = vector3(730.0, 1200.0, 400.0), to = vector3(640.0, 1100.0, 380.0), look = vector3(300.0, 800.0, 200.0) },
|
|
}
|
|
|
|
-- Where a character stands while being edited or previewed. Flat, empty apron
|
|
-- at the airport: always streamed, no props to clip through, and dark enough
|
|
-- at the overridden clock time to light the ped cleanly.
|
|
Config.CreatorScene = {
|
|
ped = vector4(-1037.20, -2738.60, 20.17, 328.0),
|
|
}
|
|
|
|
Config.Money = {
|
|
startingCash = 500,
|
|
startingBank = 2500,
|
|
}
|
|
|
|
Config.Session = {
|
|
-- how long a client may sit at the auth screen before it is dropped
|
|
authTimeoutMs = 300000,
|
|
-- failed logins allowed per identity within the window
|
|
maxAttempts = 6,
|
|
attemptWindowS = 900,
|
|
autosaveSeconds = 300,
|
|
}
|