Anti-cheat
Anti-cheat
Every money and stock decision is made on the server. The client draws the pump and reports what happened; it never decides what anything costs or how much went in.
What the server enforces
- Pump sessions. Opening a pump asks the server for a session token. Paying requires that token, and the litres billed are capped by how long the session was actually open at the configured flow rate. A client claiming more than the pump could physically have delivered is trimmed to what the clock allows.
- Session expiry. Tokens are single-use, tied to the player who opened them, and thrown away after
PumpSessionTimeout. An expired session bills nothing. - Distance checks. Buying, refuelling, charging, swapping a battery, filling a can, ordering stock and every dashboard action re-check on the server that the player is really at that station, with
DistanceSlackmetres of margin for ped position lag. - Rate limiting. Every event and callback costs a token from a per-player bucket that refills at
PerSecondand never stacks pastBurst. A stuck keybind still works; a spam loop hits a wall almost immediately. - Value clamping. Prices, wages, orders, withdrawals and deposits are all bounds-checked and type-checked server-side. Nothing above
MaxAmountis accepted at all, and prices are held insideConfig.Refuel.PriceLimits. - Permission checks on every action. Staff permissions are re-verified server-side per request, never trusted from the UI. Hiring, firing and editing anyone who holds the
employeespermission is owner-only, so an employee cannot promote themselves. Transfer and sell-back are owner-only and require the station name typed back. - Stock and bank are server state. A sale only happens if the station actually has the litres and the customer actually has the money; both sides move in the same server-side step.
Config.AntiCheat = {
RateLimit = { Burst = 14, PerSecond = 6 },
MaxLitresPerPay = 200.0,
LitreGrace = 3.0,
PumpSessionTimeout = 900,
DistanceSlack = 15.0,
MaxAmount = 100000000,
MaxWage = 25000,
JerryPourTimeout = 600,
}| Setting | Purpose |
|---|---|
RateLimit |
Burst size and refill rate of the per-player event bucket |
MaxLitresPerPay |
Hard ceiling on a single pump or charger session, whatever the timing says |
LitreGrace |
Slack on the timing check, in litres. Covers a laggy tick |
PumpSessionTimeout |
Seconds a session stays valid |
DistanceSlack |
Extra metres allowed on top of a station's radius |
MaxAmount |
Ceiling on any money value accepted from a client |
MaxWage |
Highest wage an owner can put on an employee |
JerryPourTimeout |
Seconds an unfinished pour is remembered before the leftover can no longer be claimed back |
Tuning
The defaults suit a normal server. The two worth touching:
LitreGrace— raise it a litre or two if players on bad connections are being short-changed at the pump. Keep it small; it is free fuel.RateLimit.Burst— raise it if a legitimately busy forecourt starts refusing actions. Lower it if you want a tighter leash.
⚠
Loosening MaxLitresPerPay or DistanceSlack a long way removes the ceiling those checks exist to provide. Only change them if honest players are visibly being blocked.