GithubHelp home page GithubHelp logo

sapphonie / stac-tf2 Goto Github PK

View Code? Open in Web Editor NEW
115.0 12.0 21.0 17.06 MB

steph's anticheat (StAC). a built-from-scratch sourcemod based solution to cheating in Team Fortress 2.

Home Page: https://sappho.io

License: GNU General Public License v3.0

SourcePawn 85.28% Pawn 6.73% C++ 7.99%
teamfortress2 anticheat sourcemod sourcemod-plugin antiabuse teamfortress sourceengine open-fortress team-fortress-2-classic

stac-tf2's Introduction

STeph's AntiCheat

Version Downloads Dev discord Donations

StAC

Support me on Patreon!

This plugin - "StAC" - and the ones bundled with it, can detect, log, patch, and punish for a majority of the cheats, macros, and unfair scripts available for Team Fortress 2, including:

  • pSilentAim / NoRecoil / Angle Repeat cheats
  • Plain aimsnap / Aimbot cheats
  • Auto bhop cheats
  • Fake eye angle cheats
  • NoLerp cheats
  • Some FoV cheats

It also prevents and/or detects:

  • Newlines/invalid characters in chat messages
  • Cmdnum manipulation (clientside nospread)
  • Tickcount manipulation (backtracking) - Thank you to J_Tanzanite, author of LilAC!
  • Interp/lerp abuse
  • Clients using +right/+left inputs
  • "Ping reducing" cheats (and patches "pingmasking" by legit clients as well)
  • Clients purposefully not authorizing with Steam
  • Cheat to cheat communication
  • Several server crashing and server lagging exploits
  • Admin spoofing
  • Unkickable players

I hate cheaters. Everyone does. But you know what I hate more? Taking the sweet time out of my day to catch them. A lot of TF2 cheats do a lot of the same things, and if you know what to look for, you can detect their patterns and ban them automatically!

But wait. Don't server-side anticheats suck?

They don't have to.

Of course, there's limitations to what this plugin can do. It can't scan the memory or programs on your computer, it can't see exactly what keys you're pressing on your keyboard, and players don't live inside the server room, so there's always the factor of lag and loss.

But StAC is written so that it has as few false detections as possible, because no one wants to get banned when they weren't cheating. I've reverse engineered cheats, installed them myself (on an alt, don't worry!) and I've tested and refined this plugin over the course of years and thousands of hours of work so that it ignores legit clients, and only goes after naughty cheaters.

Even better, this plugin is set up to be as easy to use and install as possible, so you don't have to be a sourcemod guru to get rid of cheaters on your nfoserver.

Jeers

Cheers

Installation & Configuration

  1. Install and configure Discord API for Discord Webhook logging, if you'd like
  2. download the latest release (called stac.zip) from here. StAC automatically includes the latest versions of SourceTVManager, SteamWorks, Connect, and Conplex, and will not run without them. If you have issues with installation, feel free to join the discord and I'd be happy to help you out.
  3. extract the downloaded zip, and copy all the folders inside of it into /tf/addons/sourcemod/ on your tf2 server. Overwrite any files if prompted.
  4. restart your server

The current list of cvars and admin commands is listed here. The defaults should be good for most people, if you want to the plugin to autoban. If not, you can set any "detection" cvar to 0 to never ban, and to -1 to never even log or check in the first place. If you want to edit cvars,

  1. wait 30 seconds after doing the above
  2. edit /tf/cfg/sourcemod/stac.cfg to your liking
  3. restart your server again

You should be good to go!

Sourcebans

This plugin is compatible with SourceBans, gbans, and the default TF2 ban handler, and auto detects which it should use. The plugin, by default, logs the currently recording demo (if one is recording) to the sourcebans ban message. To disable this, set stac_include_demoname_in_sb to 0.

Chat logging, file logging and Discord logging

This plugin prints detections to any clients on the server with the sm_ban permission, and the running SourceTV bot, if one exists. It saves more verbose logs to /tf/addons/sourcemod/logs/stac/stac_month_day_year.log by default, as well. To disable this verbose logging to file, set stac_log_to_file to 0. This plugin can also log to a Discord channel via a webhook, in combination with zipcore's Discord API plugin. Edit /tf/addons/sourcemod/configs/discord.cfg, to look like the following code snippet, and StAC will print all detections to that channel as well.

"Discord"
{
    "stac"
    {
        "url"   "discord webhook url"
    }
}

Disclaimers

Though I wrote StAC to throw as few false positives as possible, I can't guarantee perfection. I also can't guarantee that everything will always work how it's supposed to. Please submit a bug report if you can reproduce a way to trigger false positives, or for any bug or feature request. If you're more comfortable talking to me personally about it, join the development discord for StAC here: https://discord.gg/tUGgCByZVJ

Philosophy

StAC isn't perfect. It can't be, no anticheat can, but especially not a serverside one. It does what it can, with the information available to it. This means, in simple terms, it's not gonna ban every single cheater. I essentially take the philosophy of a popular php malware scanner:

"Of course it's trivial to bypass [[StAC]], but its goal is to catch skiddies and idiots, not people with a working brain. If you report a stupid tailored bypass for [[StAC]], you likely belong to one (or both) category, and should re-read the previous statement.

TL:DR; If you want actually good anticheat, pester Valve to hire more anticheat engineers, or play Open Fortress and/or Team Fortress 2 Classic, which are source mods of TF2 that I head both the anticheat department of, of which I have access to client code to much more easily prevent people from cheating.

Special Thanks etc.

LilAC: https://forums.alliedmods.net/showthread.php?t=321480 - JTanz rocks!

SMAC: https://github.com/Silenci0/SMAC

SSaC: Private - [AS] Nacho Replay, dog, and Miggy - RIP

Backwards - coding

Asherkin - coding

Addie - coding

JoinedSenses - coding

Everyone else in the sourcemod discord who had to put up with my asinine questions

Aad

dog - beta testing

elektro - beta testing

Creators.TF Community - beta testing

Cheddzy - for the COOL ass icon

Nanochip - rare code audits

Miggy - this one's for you, bud.

stac-tf2's People

Contributors

blueberryy avatar iboonie avatar killshotzz avatar kitsumyfox avatar kysmith-csg avatar magnat2645 avatar maxijabase avatar q1085909155 avatar sapphonie avatar tiagoquix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stac-tf2's Issues

Unauthorized with steam kick is confusingly buggy

Not sure if there is a way to actually check if a client is purposefully not authorizing without kicking far too many legit clients than I am comfortable with. this seems to happen more often when steam is unstable.

Steamworks/Steamtools will show steam as being online, but clients cant connect to the network on their computers, resulting in kicks until the server "catches up" to Steam's offline / unstable status.

Add SteamID to file logs

Hey, is it possible to add the player's Steam ID alongside their username in the file logs? Something like this:

L 08/12/2021 - 03:29:31: [stac.smx] [StAC] Player VIORA <[U:1:123456]> bhopped!

It would be very useful to have this information so that when I'm looking at the logs I can be sure that I'm investigating the right person without having to correlate their username to connection logs.

Thanks :)

interval duration of cvar checks

i see that the plugin is programmed to check after fifteen seconds from the plugin's init, and then it begins checking at random intervals of one to five minutes.

is there a reason for making the subsequent intervals random? (like server performance concerns, or something?)

if not, perhaps it'd be better to make this interval more frequent and not random, like say every thirty seconds (or less even, if possible) as players could be using binds to change their rates for short periods of time.

Triggerbot detects macroing users

TODO:

  • Adjust defaults to 0 (never autoban), add description in cvar
  • maybe add cvar(s) to allow warning and/or kicking users for triggerbotting instead of permabanning
  • maybe adjust triggerbot check use tracerays or something and move the current existing checks to a "macro" check. doubtful that this will happen as it's resource intensive and buggy though.

[Feature Req] API

StAC should have its own API (even if it's very basic) for other plugins to use. For example, there is rage_matrix_attack ability for FF2 which changes sv_cheats for all clients during slowmo and StAC can ban all these clients.

So it would be really useful if StAC had StAC_OnCheatDetected forward (just like in SMAC) and probably other forwards & natives to control through the code.

pipes.cpp Bug and perfomance major bug var x2

src/common/pipes.cpp (560) : Assertion Failed: m_OutstandingCallbackThreadId != ThreadGetCurrentId()
src/common/pipes.cpp (560) : Assertion Failed: m_OutstandingCallbackThreadId != ThreadGetCurrentId()
src/common/pipes.cpp (560) : Assertion Failed: m_OutstandingCallbackThreadId != ThreadGetCurrentId()
src/common/pipes.cpp (560) : Assertion Failed: m_OutstandingCallbackThreadId != ThreadGetCurrentId()

n+ spam every tick at empty server

@sapphonie

russian / danish translations incorrect with 5.0.0

@Blueberryy @ksgoescoding - your translations for this plugin are greatly appreciated, however, stac has recieved numerous updates since you contributed them. if you could update them based off of v5.0.0, it would be much appreciated. if not, i'm gonna go ahead and remove them for now.

File handle invaild.

L 05/17/2022 - 16:03:32: SourceMod log file session started (file "c:\users\username\desktop\windowssgm\servers\2\serverfiles\tf\addons\sourcemod\logs\L20220517.log") (Version "1.10.0.6528")
L 05/17/2022 - 16:03:32: [TF2ITEMS] "GiveNamedItem" offset = 481
L 05/17/2022 - 16:03:32: [GEOIP] GeoIP database info: GEO-106FREE 20120207 Build 1 Copyright (c) 2011 MaxMind Inc All Rights Reserved
L 05/17/2022 - 16:03:33: [stac.smx] [StAC] File handle invalid!
L 05/17/2022 - 16:03:45: [stac.smx] [StAC] StAC directory not extant! Creating...

L 05/17/2022 - 16:03:46: [TF2_Stats.smx] TF2_Stats connected to MySQL Database!

============================================================

Sourcemod 1.10, Any idea why the file handle is invalid?

Block spam connects

If a user attempts to connect x times within y seconds, they should be temp banned to prevent spamming server chat

False choke detections

image
A mod of mine reported this today (shortly after we implemented StAC on the servers).

Quote:

It's called me several times for having choke hacks or whatever (i have 79 ping currently connected to SF)

Discord Translations

StacDetectionDiscordNotify and StacGeneralPlayerDiscordNotify should be translatable (especially title and name keys).

For example:

	"discord_detection_title"
	{
		"en"		"StAC Detection!"
		"ru"		"Обнаружение от StAC!"
	}

	"discord_message_title"
	{
		"en"		"StAC Message"
		"ru"		"Сообщение от StAC"
	}

	"discord_player_field"
	{
		"en"		"Player"
		"ru"		"Игрок"
	}

	"discord_detection_type_field"
	{
		"en"		"Detection type"
		"ru"		"Тип обнаружения"
	}

	"discord_detection_count_field"
	{
		"en"		"Detections"
		"ru"		"Обнаружений"
	}

	"discord_message_field"
	{
		"en"		"Message"
		"ru"		"Сообщение"
	}

	"discord_hostname_field"
	{
		"en"		"Hostname"
		"ru"		"Сервер"
	}

	"discord_hostip_field"
	{
		"en"		"Host IP"
		"ru"		"IP сервера"
	}

	"discord_demo_field"
	{
		"en"		"Current Demo Recording"
		"ru"		"Текущее демо"
	}

	"discord_unix_timestamp_field"
	{
		"en"		"Unix timestamp of detection"
		"ru"		"Unix-отметка времени обнаружения"
	}

Snippet:

void StacDetectionDiscordNotify(int userid, char[] type, int detections)
{
    static char detectionTemplate[1024] = \
    "{ \"embeds\": [ { \"title\": \"%t\", \"color\": 16738740, \"fields\": [ { \"name\": \"%t\", \"value\": \"%N\" } , { \"name\": \"SteamID\", \"value\": \"%s\" }, { \"name\": \"%t\", \"value\": \"%s\" }, { \"name\": \"%t\", \"value\": \"%i\" }, { \"name\": \"%t\", \"value\": \"%s\" }, { \"name\": \"%t\", \"value\": \"%s\" } , { \"name\": \"%t\", \"value\": \"%s\" } , { \"name\": \"%t\", \"value\": \"%i\" } ] } ] }";

    if (!DISCORD)
    {
        return;
    }

    char msg[1024];

    int Cl = GetClientOfUserId(userid);
    char ClName[64];
    GetClientName(Cl, ClName, sizeof(ClName));
    Discord_EscapeString(ClName, sizeof(ClName));
    GetDemoName();
    // we technically store the url in this so it has to be bigger
    char steamid[96];
    // ok we store these on client connect & auth, this shouldn't be null
    if (!IsActuallyNullString(SteamAuthFor[Cl]))
    {
        // make this a clickable link in discord
        Format(steamid, sizeof(steamid), "[%s](https://steamid.io/lookup/%s)", SteamAuthFor[Cl], SteamAuthFor[Cl]);
    }
    // if it is, that means the plugin reloaded or steam is being fussy.
    else
    {
        steamid = "N/A";
    }

    SetGlobalTransTarget( LANG_SERVER ); // new

    Format
    (
        msg,
        sizeof(msg),
        detectionTemplate,
        "discord_detection_title" // new
        "discord_player_field", // new
        Cl,
        steamid,
        "discord_detection_type_field", // new
        type,
        "discord_detection_count_field", // new
        detections,
        "discord_hostname_field", // new
        hostname,
        "discord_hostip_field", // new
        hostipandport,
        "discord_demo_field", // new
        demoname,
        "discord_unix_timestamp_field", // new
        GetTime()
    );
    SendMessageToDiscord(msg);
}

disallow banned / kicked clients from rejoining

  • hook player_disconnect
  • hook server_addban
  • hook server_removeban
disconnectHook()
{
    if (reason contains "StAC" || "cheat" || "hack" || "[GB]" || "[SourceSlueth]" || "ban")
    {
        AddSteamIDToStringTable()
    }
}
addbanHook()
{
    AddSteamIDToStringTable()
}
removebanHook()
{
    RmSteamFromStringTable()
}
OnClientAuthorized(etc)
{
    if (SteamID in BannedStringList)
    {
        KickClient()
    }
}

Translation Improvements

Here's Russian translation: stac.phrases.txt
It isn't perfect cuz you can't translate every cheat/exploit name but imo it is better than current (with some fixes).
There's also no DA translations because they were cut by me (this file's from my server).

Also you should remove {hotpink}[StAC]{white} from chat translations and move it into macro (or global constant string):
#define CHAT_PREFIX "{hotpink}[StAC]{white}"
and then just add it to chat messages, for example:

Format(pubreason, sizeof(pubreason), CHAT_PREFIX ... " %t", "AimsnapBanAllChat", Cl, aimsnapDetects[Cl]);

Triggerbot detection false positives when using mice with 2ms debouce (de-click)

A regular in our community found that the Triggerbot was printing false positives when he was "slamming" his mouse down on the mousepad. I use quotes on slamming because he wasn't rage smashing the mouse -- it was when he would pick his mouse up to adjust for running out of mousepad.

His description of the mouse used to test:
"im using a mouse with 1000hz polling rate and 2ms debounce time, which is practically instantaneous response rate".

His working theory on the problem:
craig: its because the mouse's clicks are controlled by mechanical switches that are very easy to activate, hence why the response time is so fast. But because the response time is so quick and the switches are so light, if i slam my mouse on the desk it thinks im using triggerbot because the response rate is just that fast.

He also created a video to demonstrate the issue. The video shows him tapping the mouse against his desk repeatably, which you'd never do in a game obviously, but the issue can be consistently re-created in-context (one tap can still trigger it like when you're picking the mouse up to adjust for no more mousepad).

Video: https://www.youtube.com/watch?v=K8aXs-m3j0E
Link to mouse used to test: https://www.pcgamingrace.com/products/glorious-model-o-wireless-matte-black

Ban Duration (and False Positive)

Would be good to have a ConVar (or ConVars, for every cheat) for ban duration because there are false positives like

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.87 134.40 0.00.
Detections so far: 1
L 07/26/2021 - 19:34:53: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:34:54: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.58 351.14 0.00.
Detections so far: 2
L 07/26/2021 - 19:34:54: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.11 214.22 0.00.
Detections so far: 3
L 07/26/2021 - 19:35:00: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.62 220.97 0.00.
Detections so far: 4
L 07/26/2021 - 19:35:00: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.91 322.95 0.00.
Detections so far: 5
L 07/26/2021 - 19:35:00: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.67 16.03 0.00.
Detections so far: 6
L 07/26/2021 - 19:35:00: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.50 20.63 0.00.
Detections so far: 7
L 07/26/2021 - 19:35:00: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.44 21.58 0.00.
Detections so far: 8
L 07/26/2021 - 19:35:00: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.44 21.58 0.00.
Detections so far: 9
L 07/26/2021 - 19:35:00: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] 

----------

[StAC] Player :troll: has invalid eye angles!
Current angles: 89.44 21.58 0.00.
Detections so far: 10
L 07/26/2021 - 19:35:00: [stac.smx] 
 Player: :troll:<173><[U:1:865755532]><>
 StAC cached SteamID: STEAM_0:0:432877766
L 07/26/2021 - 19:35:00: [stac.smx] [StAC] No STV demo is being recorded, no demo name will be printed to the ban reason!

So i had to disable banning for fakeangle.
And permaban isn't a good thing in these cases.

Add "lag timeout" for better ignoring of laggy players

There is an extreme corner case involving laggy players who lag hard for a couple seconds and then have perfect connection to the server otherwise, and StAC doesn't handle these events as well as I'd like.

Solution:

Every time a player dips above any of the lag thresholds (repeating cmdnums, too fast/too slow usercmds, too high loss, etc), they get put in a "timeout" of seconds, where stac will not run any angle checks on them.

This is a todo.

my consolences

hey staph, heard things have been tough with keeping the house, hope u can get through it, we've all been there or will be there 1 nce in our life but be sure that things are looking high. /s

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.