Guides
Anti Cheat Explained
Howdy,
Today you will learn about The West's anti cheat measure, method and demonstration.
Check the end of the article to see a video demonstrating how the anti-cheat is getting custom scripts at runtime.
The West's anti-cheat system employs a 3-layer detection method that monitors your game client in real-time. Every login, the system scans for:
Layer 1: Global Variable Detection
How it works?
Every time you log in, the game captures a snapshot of all global variables in your browser:
// Game's detection code (simplified):
var initVarPos = Object.keys(window).length; // Initial count
// Later, after scripts load:
var keys = Object.keys(window);
if (keys.length > initVarPos) {
var newVars = keys.slice(initVarPos); // Get NEW variables
Chat.Request.VarDec(newVars); // Send to server
// Also log to Grafana monitoring:
newVars.forEach(varName => {
faro.api.pushLog(['script', varName], {level: 'info'});
});
}
What Gets Detected
BAD - Creates global variables:
// These are IMMEDIATELY detected:
GJ = { version: '1.15' }; // ← Detected
window.MyScript = {}; // ← Detected
MyHelper = function() { }; // ← Detected
GOOD - Uses local scope:
// This is invisible to detection:
(function() {
'use strict';
var GJ = { version: '1.15' }; // ← NOT detected (local variable)
var MyScript = {}; // ← NOT detected
})();
Example Detection
Script: Gold Jobs Finder v1.15
Detected Variables:
- GJ (main object)
- GJlang (language settings)
- scriptRequest (boolean flag)
- scriptUp (update checker)
- sI (setInterval ID for scriptUp loader)
Result: 5 global variables logged => Script identified as "Gold Jobs Finder"
The first 4 variables are found in the main script.
The 5th variable is present in an external script called by the main script (sUp.js).
The game automatically logs ALL global variables to their database, but cannot automatically identify which script they belong to. This is where the admin's script database comes in.
Admin Script Database: Admins maintain a reference database that maps variable signatures to known scripts:
Below you can see an example of a record they have of a script called "TW Gold Jobs Finder".
Important! This is not the exact same structure but something close to it based on their front-end logic.
{
"Script-1": {
"name": "TW Gold Jobs Finder",
"source_url": "https://greasyfork.org/scripts/7226",
"severity": "HIGH",
"variables": ["GJ", "GJlang", "scriptRequest", "scriptUp"],
"css_selectors": ["div#CC_pin_items"],
"description": "Shows all gold and silver jobs on the map"
}
}
The Detection Process:
- Automatic Collection: When you log in, the game captures all your global variables
- Pattern Matching: Admins search the database for users whose variables match known script signatures
- Identification: If your variables match the signature => Script identified
Important Notes:
- The system cannot automatically know what a variable like GJ means
- Admins must manually add scripts to their reference database
- Unknown/new scripts won't be identified until admins add them
- Scripts with unique variable names are easier to identify
What it means?
- Popular scripts (Gold Jobs Finder, Duel Warner, etc.) are already in their database
- Your variables ARE being logged, even if not yet identified
- Admins can retroactively identify you once they add a script to their database
- Having generic variable names (like app, helper) makes identification harder
Layer 2: CSS Stylesheet Detection
How it works?
The game monitors document.styleSheets for any new CSS added after page load:
// Game's CSS detection code (simplified):
var styleList = new Set(); // Initial stylesheets
var pushStyles = function() {
const diff = (new Set(document.styleSheets)).difference(styleList);
if (!diff.size) return;
const styles = Array.from(diff).slice(0, 4).map(function(sheet) {
if (sheet.href) {
// External stylesheet
return [null, null, null, sheet.href];
}
// Inline stylesheet - extract rules
const rules = sheet.cssRules;
const firstItem = rules.item(0);
const lastItem = rules.item(rules.length - 1);
return [
rules.length, // Number of rules
firstItem ? firstItem.selectorText : null, // First selector
lastItem ? lastItem.selectorText : null, // Last selector
null
];
});
Chat.Request.StyleDec(styles); // Send to server
};
!What Gets Detected
Any CSS you inject is logged:
Logged Data:
{
type: 'inline',
ruleCount: 3,
firstSelector: 'div#CC_pin_items', // ← Unique fingerprint!
lastSelector: '.goldwindow'
}
Why CSS Detection Matters:
- CSS is required for UI scripts - You can't add custom panels/buttons without CSS
- Unique fingerprints - Class names like .goldenJobs or #CC_pin_items uniquely identify scripts
- Hard to bypass - CSS must be in the DOM to work, making it unavoidable
- Even 1 rule = detected - Any injected CSS triggers logging
Example Detection
Script: Gold Jobs Finder (via update script)
Detected CSS:
Result: CSS fingerprint #CC_pin_items logged => Matched to Gold Jobs Finder database entry
Layer 3: WebDriver Detection (Python/Selenium)
How it works?
The game sends your WebDriver status directly to their anti-cheat server on every page load:
// From game's initialization code:
Ajax.remoteCall('anti_cheat', 'record_fp', {
fp: "browser_fingerprint_hash",
gv: undefined,
wd: navigator.webdriver // ← Sent to server!
});
What Gets Logged:
{
user_id: 12345,
timestamp: "2026-01-10 14:30:00",
browser_fingerprint: "a1b2c3d4e5f6...",
webdriver: true, // ← YOU ARE FLAGGED
// Additional fingerprint data:
canvas_fp: "...",
webgl_fp: "...",
screen_resolution: [1920, 1080],
timezone: -300,
fonts: [...],
// ~30 other browser characteristics
}
Detection accuracy:
- true = Selenium/Playwright/Puppeteer => DETECTED
- undefined = Normal browser => Clean
- false = Rare (some browsers) => Probably clean / false alert
Important Notes:
This is separate from fingerprinting- The browser fingerprint (`fp`) identifies your specific browser
- The WebDriver flag (`wd`) identifies automation
- Both are sent together to the server
- Admins can search: "Show all users with `wd: true`
They use Fingerprint2 library
- Creates a unique hash from ~30 browser characteristics
- This means they can track you even if you:
- Clear cookies
- Use incognito mode
- Change IP address
- The fingerprint stays mostly the same unless you change hardware/browser
Python/Selenium Bypass Methods:
The game checks `navigator.webdriver` on line load. To bypass:
Method 1: Undetected ChromeDriver (Easiest):
import undetected_chromedriver as uc
driver = uc.Chrome()
# Sets navigator.webdriver = undefined
# Bypasses many other detection methods
Method 2: Chrome DevTools Protocol (Before Page Load)
from selenium import webdriver
driver = webdriver.Chrome()
# Execute BEFORE navigating to the page
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
'''
})
driver.get("https://the-west.net")
# WebDriver hidden before game's check
Method 3: Selenium Stealth
from selenium import webdriver
from selenium_stealth import stealth
driver = webdriver.Chrome()
stealth(driver,
languages=["en-US", "en"],
vendor="Google Inc.",
platform="Win32",
webgl_vendor="Intel Inc.",
renderer="Intel Iris OpenGL Engine",
fix_hairline=True
)