An open source FiveM Anti-cheat, helping keep your server free of cheaters. No sketchy obfuscated files and runtime reloadable modules that keep you in control, Valkyrie aims to be your solution in preventing cheaters from wreaking havoc on your server.
No Anti-cheat is a silver bullet, especially not the paid versions, notice how most claim 99% protection against cheaters π. You as the server owner/developer should be taking an active role in preventing the exploitation of resources on your server because nothing is a substitute for good programming practices.
The main
branch is pushed to regularly and may include breaking changes! Only code downloaded from the releases section is considered to be stable.
Ensure you have a non modified and up-to-date version of the cfx-server-data chat resource, Valkyrie uses the registerMessageHook
export for message filtering, which is not available in older or some modified versions of the resource.
Download the most recent version from the releases section on GitHub ("Valkyrie-version.zip")
Extract the contents from the zip file into resources/Valkyrie
Open your server.cfg
file, and add the following, making sure ensure Valkyrie
is added after the config file execution.
exec @Valkyrie/config.cfg
exec @Valkyrie/permission.cfg
ensure Valkyrie
Save the server.cfg file then start your server
You're done, you've installed Valkyrie! Now move on to the configuration portion of this README
Note ποΈ: These settings can be updated during runtime using the vac:sync
command or by restarting the resource
LOG_LEVEL {
1 = info
2 = trace
3 = warn
}
ConVar | Default | Description | Parameter |
---|---|---|---|
vac:internal:contact_link | "" | Set the contact link or string for banned players to appeal or contact administration | string |
vac:internal:log_level | 1 | Sets the level of detail for server logs | LOG_LEVEL number |
vac:main:super_jump_check | false | Checks all players uisng IS_PLAYER_USING_SUPER_JUMP unless the "vac:superjump" permission has been granted | bool |
vac:main:god_mode_check | false | Checks all players using GET_PLAYER_INVINCIBLE unless the "vac:invincibility" permission has been granted | bool |
Best Practice π: It is recommed to use entity lockdown (sv_entityLockdown) and your own server side creation logic for better protection. A future implementation of Valkyrie may include a rudimentary example that can be used as a guide for server owners/developers.
ConVar | Default | Description | Parameter |
---|---|---|---|
vac:entity:validate_entities | false | Perform entity validation via the entityCreating event | bool |
vac:entity:blocked_models | [] | List of model names to parse through | array |
ConVar | Default | Description | Parameter(s) | |
---|---|---|---|---|
vac:ptfx:prohibit_particles | false | Enable particle filtration | bool | |
vac:ptfx:prohibited_particles | { assetName": [], "effectName": []} | List of PTFX asset & effect names to prohibit | JSON Object |
If my understanding is correct the assetName is the parent "directory" (for lack of a better term) for the effectName so prohibiting the assetName will completely block any effects from that directory. This needs more testing.....
ConVar | Default | Description | Parameter(s) |
---|---|---|---|
vac:connect:check_username_content | false | Should Valkyrie check username for prohibited content | bool |
vac:connect:prohibited_username_content | [] | List of strings to check for in a connecting players username | list |
ConVar | Default | Description | Parameter(s) |
---|---|---|---|
vac:cmd:requestPermission | true | Allow players to request permission for a specific bypass | bool |
Note ποΈ: These settings can be updated during runtime using the vac:sync
command or by restarting the resource.
Object | Description |
---|---|
vac:ultraviolet | Bypass everything! Users will not be added to the PlayerCache registery and are seen as "invisible" to the resource |
vac:explosion | Bypass explosion checks |
Event Name | Description | Parameter(s) |
---|---|---|
__vac_internal:initialize | Used to reload a specific module or the entire module stack | string |
TL;DR: Certain popular detection methods rely solely on the client having accurate data basic software security practices teach us to never rely on the client and is why certain features are "missing". If you believe a feature is missing and could be built into the Anti-cheat without relying on the client, don't hesitate to open an issue on GitHub describing implementation details!
"Injection detection" (Prohibited variable detection)
Injected code on the client, usually written in a Lua source file utilizes the FiveM Lua ScRT, to gain access to GTA5 and FiveM native functions. Since the Lua runtime not specific to FiveM has a global environment table where all variables and their values are stored, this allows for checks on prohibited variables to be ran as shown below.
local PROHIBITED_VARIABLES <const> = {'Dopamine', 'LynxEvo', 'WarMenu'}
function checkVariables()
for i = 1, #PROHIBITED_VARIABLES do
local variable = PROHIBITED_VARIABLES[i]
if (_G[variable] ~= nil) then
TriggerServerEvent('anticheat:banMe')
end
end
end
This however can be easily bypassed, simply by setting the variable we want to hide to nil in the global envrionment table. This process could be easily automated as shown below.
local MY_VARIABLES <const> = {'Dopamine', 'Dopamine.openMenu'}
function hideVariables()
for i = 1, #MY_VARIABLES do
_G[MY_VARIABLES[i]] = nil
end
end
This also comes with the downside of modifying all resource manifest files to include a reference to this check (client_script @anticheat/check.lua
). Although a small addition it has the potentional to break certain resources and depending on the resources requirements can cause false positive.
Detect/Prevent connections with a VPN/Proxy
Valkyrie already purposefully skips over the IP addres of any player when saving identifiers. IP's are generally not static and have the chance of changing at any point making them unreliable for long term identification.
Most people using a proxy (including myself) don't have any bad intentions in mind and may just want to hide their network activity as an overall strategy to protect their online privacy.
Certain circumstances may require the use of a proxy just to join your server! This can range from geographical restrictions to government censorship and without knowing the circumstances of all connecting players scrutinizing them for using a proxy doesn't seem fair.
Blocking NUI DevTools.
FiveM uses CEF (Chromium Embedded Framework) an embedded version of Chrome which "offers an asynchronous, performant way of creating in-game UI." CEF like Chrome comes with access to DevTools commonly found by pressing F12 or "Inspect Element" in your browser, for a while now users have been waiting to block access to these tools to protect their assets from getting "dumped" or to detect "malicious" individuals. But as is outlined in this post it's rather easy to bypass.
Optical character recognition (OCR)
You've probably seen this advertised by other Anti-cheats are their "AI" detection system but more than likely they're just using tesseract.....
Abnormal Key Detection
Third party software for capturing gameplay for example Nvidia's ShadowPlay or SteelSeries Moments is very commonly used among players with the capture button(s) usually being assigned to what some server owners deem to be abnormal keys......
One of the many features offered by FiveM through state awareness mode aka OneSync, entity lockdown allows for the creation of objects, vehicles and peds solely by the server. This completely prevents events like mass spawning of entities however, you'll need to update all of your resources to support server side entity creation. You can find more information on the FiveM docs
Resource creators may have legitimate use cases for wanting to make a player invinciple temporarily or permanetly, thankfully the FiveM permission system is dynamic so we can add these permissions to players during runtime. Valkyrie makes this very easy to implement using the addPermission and removePermission exports respectfully, an example implementation can be seen below.
RegisterNetEvent('server:hospital:inpatient', function(data)
if exports["Valkyrie"]:addPermission(source, 'vac:godmode') then
SetPlayerInvincible(source, true)
end
-- event code
end)
RegisterNetEvent('server:hospital:outpatient', function(data)
-- Remove player enhancements before removing permission
SetPlayerInvincible(source, false)
if exports["Valkyrie"]:removePermission(source, 'vac:godmode') then
-- Permission successfully removed
end
-- event code
end)
[]: Add Grafana Loki as the prefered logging system\ []: Vulnerability scanner
Note: To maintain compatibility support will only be provided to those using the latest recommend or above server artifacts.
Please open an issue on GitHub if you need help securing your server, want to report a critical security concern, or you're facing an issue with the resource.