В прошлых статьях я рассказывал, как «немножко обманывать» игрока и давать ему ощущение естественного поведения игры, про давно известные приёмы, которые широко опробованы в сингловых играх. Но всё меняется, когда появляется сеть и логику приходится разносить между сервером и клиентами, и выясняется, что матч не должен одновременно владеть инвентарём, аккаунтами и прочим хозяйством игры, а компьютер, на котором игра запущена, внезапно... принадлежит игроку, а не разработчику. Если мы по недосмотру доверили клиенту право сообщать серверу, где находится персонаж, сколько у него денег и кого он только что убил, то рано или поздно найдётся человек, который трактует эти права гораздо шире, чем предполагал разработчик.

Обязательно находится Вася, который играет давно и на рейтинг ему в общем‑то пофиг, но проигрывать он не любит. Не любит настолько, что готов потратить на подготовку к матчу больше денег и времени, чем на сам матч, а его соперник заводчанин Василий, который приходит вечером после работы и хочет просто поиграть, имеет средний компьютер, домашний Wi‑Fi через две стены и реакцию уставшего человека. Василий иногда выигрывает, но чаще проигрывает, и его это в целом устраивает, пока он уверен, что проигрывает честно.

Васю клеймят позорным словом «читер» и представляют как человека с аимботом, который неестественно быстро переводит прицел на головы противников за стеной, и это, наверное, самый зрелищный вариант и его легко показать в ролике и легко заклеймить в комментариях. Но технически аимбот всего лишь один из простейших представителей большого семейства способов сказать игре неправду, причём неправда работает в обе стороны. И если можно подменить то, что видит другой игрок, то можно и увидеть то, чего видеть не положено, или вмешаться в обмен данными, или вообще не трогать клиент, а эксплуатировать людей, экономику и доверие саппорта команды разработчика. Вася, разумеется, пробовал всё... иначе, какой же он Вася, а иногда это еще и способ получить работу, стать белым и уважаемым «консультантом по безопаности» и ломать игровые сервисы за зарплату, но это уже другая история.


Дать клиенту быть главным

Предположим, персонаж перемещается по карте, и клиент после каждого кадра отправляет серверу свою новую позицию. Пока игра маленькая и никому не известная, это даже удобно: компьютер игрока уже посчитал движение, серверу остаётся сохранить координаты и разослать их остальным. Только вместе с координатами мы отдали Васе право рассказывать серверу любую историю о своём перемещении, какую он сочтёт подходящей, и сегодня его персонаж прошёл лишние два метра, завтра оказался за стеной, а послезавтра выяснилось, что законы физики в Васиной версии игры не действуют.

Так устроена схема читов teleport и speedhack, и так же устроены схема на деньги, предметы и опыт, появляющиеся из ниоткуда. Если клиент может сказать «я заработал тысячу монет», а сервер записал эту тысячу, не спрашивая, как она была заработана, то перед нами не столько сложный взлом, сколько плохо распределённые обязанности. Васе достаточно изменить состояние клиента или сформировать запрос, который игра не собиралась принимать от обычного игрока, чтобы сервер услужливо оформил результат. Поэтому все рекомандации по защите от читерства советует выносить критическую логику на сервер и только на сервер, а клиент считать точкой компрометации данных, а если уж без расчетов на клиенте не обойтись, то проверять, что завершён уровень, который игрок начинал, что итоговый счёт лежит в допустимых пределах и что потраченные предметы действительно были в инвентаре.

Следующий шаг это авторитетный сервер, в котором клиент больше не сообщает «я уже стою в точке X», а отправляет только намерение двигаться в такую‑то сторону, или желание нажать кнопку, или применить способность. Потому сервер проверяет команду, сам выполняет симуляцию и публикует новое состояние клиентам, Вася от этого не стал честнее, но уже не может продиктовать результат и рассчитывать, что его примут. Примерно так же продавцу на рынке можно уверенно сказать, что вы уже заплатили, а терминалу в магазине так не получится, какие бы честные глаза у вас не были.

Деньги из воздуха

Вася играл в детстве в Fallout и накидывал себе крышечек через сканер памяти, схема знакома любому, кто хоть раз открывал артмани. У персонажа 1000 крышечек, ищем в памяти процесса все ячейки со значением 1000, тратим немного, ищем среди найденного 950, и через пару итераций остаётся один адрес, в который можно записать что угодно. В сингловой игре на этом история заканчивается и вы портите себе только удовольствие от игры, а в сетевой всё зависит от того, кому эта ячейка принадлежит. Если золото живёт на сервере, а клиент держит лишь копию для отображения, то кулхацер увидит у себя миллион крышек от ядерколы и не сможет купить на него даже похлебку из радскорпиона, но если клиент при покупке сообщает серверу что он просто купил что‑то, то миллион внезапно становится настоящим.

Когда артмани перестаёт помогать, Вася переходит к пакетам. Он ставит прокси между клиентом и сервером, смотрит, что уходит при покупке, и обнаруживает там что‑нибудь вроде «купить предмет 517 за 100 монет», но цена в этом запросе обычно и не нужна, сервер и так знает, сколько стоит предмет 517, но раз уж клиент её прислал, а сервер её прочитал, то Вася меняет 100 на 1 и уходит с покупкой. Ошибка и дыра обработки пакетов настолько частая и оплаченная чужими экономиками, что её внесли в обязательный список проверок при разработке сетевой игры и всё, что можно посчитать на сервере, на сервере и считается, а из клиента приходит только идентификатор того, что игрок хочет сделать. Но известная, не значит пофикшеная и большинство игр все равно выходят на первых порах с такой дырой в протоколе.

Отдельная классика это отрицательные числа, когда Вася продаёт торговцу минус один меч или передаёт другу минус пятьсот крышечек или кладёт на склад минус десять зелий, и если где‑то по дороге знаковое число превратилось в беззнаковое или проверка «хватает ли у игрока предметов» написана только для положительного количества, то сервер честно выполняет арифметику и начисляет Васе деньги за меч, которого не было. Такие ошибки годами лежат в MMO, и они почти никогда не выглядят как уязвимость при кодревью, ну просто функция, в которой забыли, что количество мечей не может быть меньше нуля.

Еще один трюк из этой серии называется replay, когда Вася перехватывает запрос «забрать награду за ежедневное задание» и отправляет его ещё двадцать раз подряд. Если сервер не помнит, что награда уже выдана, или запросы обрабатываются параллельно и проверка проходит у всех одновременно, то двадцать наград Вася и получит. Дырка безопасности заклеивается одноразовыми идентификаторами операций, которые сервер запоминает и второй раз не исполняет, и ограничением частоты для всего, что начисляет ценности. Бедный Василий о таких вещах не задумывается и просто однажды замечает, что у сервера редкий маунт, который выдается раз в день.

Когда сервер не успел

Даже если сервер ничего не принимает на веру, то Васе остаётся «хак на время», точнее, промежутки между событиями, которые сервер считает атомарными, а они таковыми не являются. Классический дюп выглядит так, что Вася начинает обмен предметом с другом и в момент подтверждения выдёргивает сетевой кабель, шутка... Предмет уже записан в инвентарь друга, но запись об удалении из инвентаря Васи не успела сохраниться и сервер откатывает Васю к последнему сохранению, и меч теперь существует в двух экземплярах.

Вариантов у этой схемы десятки, и постоянно появляются новые. Два параллельных запроса на перемещение предмета, схема с разными контейнерами, переход между игровыми серверами, заход одним клиентом одновременно на два шарда, падение сервера после выдачи награды, ддосинг базы запросами на запись, дозапись в базу после отката или вайпа, и еще чуть‑чуть. Во всех случаях Вася не ломает ни клиент, ни протокол, он просто ищет место, где логика игры рассчитывает, что две операции произойдут вместе, а сервер инвентаря об этом не знает или не успевает обработать.

Лечится дюп скучно и дорого уникальными идентификаторами и одним владельцем, перемещения оформляются транзакцией, которая либо прошла целиком, либо не прошла вовсе, а фоновые проверки ищут в базе предметы с одинаковыми идентификаторами и аномальный прирост ценностей у отдельных аккаунтов. Честный Василий, конечно, ничего не дюпал, но последствия видит первым, когда цены на аукционе за неделю падают в десять раз, а его честно выбитый меч больше ничего не стоит. И тогда разработчики выкатывают вайп или откат, который бьёт по всем, а не только по Васе.

Быстрее, чем время

Когда сервер перестал принимать координаты, хитрый Вася не расстроился, а перешёл к классическому читу на время «speedhack», только он работает уже не с позицией, а с часами. Игра узнаёт, сколько прошло времени между кадрами обычно через системные таймеры, и если подменить их, чтобы за реальную секунду клиент насчитывал полторы, то персонаж будет честно бегать со своей обычной скоростью, просто секунд у Васи станет больше, чем у всех остальных. И в клиент‑авторитетной игре этого достаточно, а в серверной Вася начинает слать команды движения чаще, чем положено, или с временными метками, которые убегают вперёд.

Приходится делать на сервер собственные часы, и смотреть, сколько времени прошло с прошлой команды, учитывать максимальную скорость персонажа и считать, какое расстояние за это время вообще было достижимо, а заодно ограничить число команд, которые клиент может прислать за тик. Делается это через бюджет движения, когда у клиента добавляется копилка допустимого перемещения, которая пополняется с течением серверного времени и тратится на каждый экшен, так что короткий рывок после лага пройдёт, а систематическое превышение быстро упрётся в пустую копилку.

Но жёстко без допусков такую проверку опять же сделать не получится, и пакеты Василия приходят пачками, потому что его роутер иногда лагает или отваливается, а потом отдаёт всё разом, и с точки зрения сервера Василий в этот момент выглядит как Вася со speedhack. Поэтому за подозрительное перемещение обычно не банят сразу, а просто возвращают персонажа в последнюю допустимую позицию, виденное вами не раз «резиновое» дёргание, если играли на плохом интернете. А еще обязательно копят статистику, чтобы потом разбираться, кто из двоих реальный Вася, а кто просто Василий.

Когда Вася видит всё

Wallhack и ESP дают Васе уже не скорость, а знание контуров противников за стенами, их имена, здоровье, оружие и прочие данные, которые в обычной игре скрыты, но клиенту они известны, а как иначе рисовать других игроков?

Иногда подменяют отображение на клиенте и чит просто рисует дополнительную информацию, но гораздо неприятнее если клиент получает от сервера данные, которых клиенту знать не нужно. Если сервер отправил координаты противника, стоящего за непрозрачной стеной, то спрятать его от Васи одной настройкой рендеринга уже не получится и любая информация, покинувшая сервер, перестаёт быть безопасной, и дальше мы можем надеяться только на добросовестность программы, которой владеет клиент.

Поэтому защита от wallhack начинается с вопроса, что сервер рассылает каждому клиенту. Если Василий физически не может видеть Васю, его клиенту обычно не нужны точные координаты Васи, и сервер может отправлять только ту часть состояния, которая нужна для текущей картинки, с учётом расстояния, линии видимости и правил игры. Riot в своё время подробно описывала, как в Valorant сервер сам считает видимость и придерживает позиции противников, пока те не окажутся близко к зоне обзора, и это, пожалуй, самый известный пример такого подхода в соревновательном шутере.

Бесплатным это решение конечно не будет, и если отправлять противника когда он стал виден, он будет появляться из воздуха с задержкой на пинг, поэтому видимость считают с запасом, предсказывают, кто выглянет из‑за угла в ближайшие кадры, и тратят на это серверное время, которого и так всегда не хватает. Есть еще звук, когда шаги противника за стеной Василий должен слышать, а значит, клиенту нужна хотя бы примерная позиция их источника, и Вася с радостью превращает этот звук в метку на экране, но если сервер не будет этим заниматься, он собственными руками выдаст Васе часть преимущества, с которым потом будет бороться античит.

Freecam и увеличение обзора

Иногда Васе даже не нужно видеть сквозь стены и достаточно отодвинуть камеру подальше, или отвязать её от персонажа и полетать по карте в режиме freecam. В стратегиях и играх с большой зоной обзора это позволяет заранее посмотреть, куда движется противник, а в шутере лишний угол обзора может показать то, что обычная камера скрывает за краем экрана. Это не всегда взлом серверного состояния, чаще можн просто изменить клиент, чтобы показать картинку, которую дизайнер игры не собирались выдавать, и потому ограничения камеры тоже оказываются частью правил честной игры.

Здесь история читов начинается с однопользовательских игр, в которых разработчики оставляли режимы свободной камеры или команды телепортации, или отключения столкновений для отладки уровней. В старых играх подобные возможности нередко были доступны через консоль разработчика, а в некоторых проектах оставались и после релиза, поскольку никому не хотелось ломать привычный процесс тестирования ради удаления одной команды. В многопользовательских играх та же отладочная камера превратилась в бесплатную разведку, хотя увеличение FOV не обязательно является читом само по себе, а вот обход ограничений камеры или получение информации за пределами разрешённого обзора уже может давать нечестное преимущество.

Когда весь мир у каждого

В стратегиях Вася ведёт себя по‑другому, потому что сеть там устроена иначе и большинство классических RTS, даже современных, работают по схеме детерминированного lockstep, когда по сети ходят не снимки уровня, а только команды игроков и каждый клиент сам симулирует весь мир целиком со всеми участниками, но благодаря детерминизму у всех получается одинаковый результат. Это позволяет гонять тысячи юнитов через медленный канал, не передавая ни одной позиции вообще, но у этой схемы есть очевидная обратная сторона, потому что всё состояние матча, включая армию противника на другом конце карты, лежит в памяти у каждого участника, а туман войны существует только на уровне отрисовки.

Отсюда и мапхак, который в StarCraft, Warcraft III и Age of Empires стал почти отдельным жанром, и васе достаточно просто убрать туман или вывести на мини‑карту то, что клиент и так знает, и он видит, сколько у Василия рабочих, где строится вторая база и куда идёт армия. Спрятать эти данные сервер уже не может, потому что без них клиент Васи просто не сможет считать симуляцию, и тут авторитетный сервер в привычном смысле уже не помогает.

Зато у lockstep есть приятное свойство, которое Вася узнаёт, когда пытается пойти дальше. Если он не только читает память, но и подкидывает себе ресурсов или ускоряет строительство, его симуляция расходится с симуляцией Василия и контрольные суммы состояния перестают совпадать, а матч разваливается в рассинхрон. Получается, что lockstep сам по себе хорошо защищает от изменения состояния и совершенно не защищает от его чтения, поэтому мапхак ловят в основном по поведению и по реакции что игрок не мог сейчас разведать или увидеть, по кликам и перемещению камеры в зону тумана, по анализу повторов, которые в таких играх почти бесплатны, потому что повтор это просто список команд.

Аимбот, который не трогает игру

Аимбот решает за Васю задачу прицеливания: определить, где противник, и навести туда прицел, но реализации у него очень разные. Классический вариант читает позиции из памяти клиента и подкручивает углы камеры, triggerbot скромнее и только нажимает на спуск, когда прицел оказался на противнике, а с ростом защиты внутри процесса Вася постепенно выносит чит всё дальше от игры.

Сначала за пределы процесса: DMA‑карта, вставленная в PCIe‑слот, читает память игрового компьютера напрямую, и анализирует её второй компьютер, на котором никакого античита нет, а в игровой системе нет ни постороннего процесса, ни подозрительного драйвера. Потом за пределы компьютера вообще: картинка с экрана уходит через карту захвата на второй ПК, нейросеть находит на ней противников, а команды возвращаются через устройство, которое для системы выглядит как самая обычная мышь. На консолях похожую нишу заняли адаптеры вроде Cronus Zen и XIM, которые позволяют играть мышью там, где её не ждали, и умеют выполнять скрипты компенсации отдачи, и Activision в 2023 году отдельно объявляла, что Ricochet научился такие устройства распознавать.

Здесь защита, ориентированная на память процесса, упирается в потолок, потому что прочитать мир за пределами клиента она не может, и чем меньше чит вмешивается в саму игру, тем меньше пользы от методов, которые ищут привычные следы вмешательства. Для такого Васи игра превращается в очень динамичную задачу компьютерного зрения, а для сервера он выглядит как игрок, который просто очень быстро и очень точно двигает мышью.

И тогда возникает главный вопрос этой статьи: чем быстрорукий Вася отличается от Василия, который вчера выспался и сегодня в ударе? Ответ ищут в статистике, а не в отдельном выстреле. У человека время реакции плавает, траектория мыши имеет характерный разгон и торможение, промахи распределены определённым образом, и даже очень хороший игрок иногда перелетает прицелом через цель и возвращается. Чит, даже с добавленным шумом, обычно слишком стабилен: реакция в одно и то же число миллисекунд, доводка прицела без перелёта, наведение, которое начинается до того, как противник появился на экране. Valve ещё на GDC 2018 рассказывала про VACnet, который учится отличать такие паттерны на записях матчей в CS:GO, и с тех пор подобные системы есть почти у всех крупных шутеров. Но граница остаётся размытой, и чем лучше Вася маскирует бота под человека, тем больше шансов, что очень хорошего Василия заподозрят вместе с ним.

No‑recoil, no‑spread и rapid fire

Но даже если Вася не хочет доверять прицеливание нейросети, у него остаются читы, которым вообще не нужно двигать мышью. Например можно компенсировать отдачу (No‑recoil), или убрать разброс (no‑spread), или заставить оружие стрелять чаще, чем положено (rapid fire). В некоторых играх такие вещи делаются внутриигровыми макросами или изменением поведения клиента, в других упираются в серверные проверки темпа стрельбы и результатов выстрела. Это отдельная неприятность для античита, потому что игрок может целиться совершенно самостоятельно, но его оружие ведёт себя как супер золотая голд пуха, у которой отменили половину недостатков.

Первые широко известные варианты подобных читов стали особенно заметны вместе с развитием сетевых шутеров конца девяностых, и в играх вроде контры быстро появились сторонние программы, которые изменяли поведение оружия или автоматизировали повторяющиеся действия без полноценного вмешательства в игровой код. По мере того как разработчики начали проверять действия игроков на сервере, простого изменения локальной анимации стало недостаточно для получения некоторых преимуществ, но способы обхода продолжили развиваться вместе с конкретными играми. Для Василия разница, впрочем, не особенно важна, потому что в любом случае Вася почему‑то стреляет как Т800 без промахов и сожалений.

Silent aim

Есть и более хитрый вариант под названием silent aim, когда на экране прицел вовсе не обязан смотреть прямо на Василия, а результат выстрела обрабатывается так, будто направление было другим. Это уже зависит от устройства конкретной игры и не означает, что любой клиент может приказать серверу засчитать попадание куда угодно, но хорошо показывает разницу между картинкой, которую видит игрок, и данными, на основании которых игра принимает решение. Обычный аимбот старается незаметно подвести прицел к цели, а silent aim оставляет прицел на месте и подменяет отправляемые данные выстрела.

Такие техники особенно востребованы в сетевых комерческих шутерах, когда обычные аимботы начали привлекать внимание не только игроков, но и античитов, которые обнаруживали слишком резкие движения прицела или подозрительно точное наведение. Эта отрась читостроения выросла в отдельное направление с оборотом, на минуточку, под 100$ млн в год, согласитесь такие обороты на пустом месте не появятся.

Но и сам silent aim не является отдельной технологией, а скорее названием целого класса приёмов, и если сервер самостоятельно определяет результат выстрела по проверяемым данным, возможностей для подобных манипуляций становится меньше, но не значит что использовать это нельзя и хитрорукий... здесь видимо должно быть другое прилагательно, Вася может продолжать смотреть в одну сторону, а его пушка вертится сама по себе.

Если у Васи оч умелые ручки

Похожая история с читами на дальность удара, когда Вася достаёт мечом противника с расстояния, на котором обычная игровая логика даже не предложила бы нажимать кнопку атаки. Это достигается или изменением клиента, или эксплуатацией ошибки в обработке попадания, но защита в обоих случаях сводится к тому, что сервер сам проверяет дистанцию, состояние персонажей, линию атаки и допустимость действия в конкретный момент. Если же сервер просто верит сообщению «я попал», что случается не так уже и редко, то у Васи внезапно оказывается очень длинный меч, а у Василия возникает вполне резонный вопрос, зачем вообще качать броню.

Сама идея появилась не вчера, но раньше она выглядела несколько иначе. В старых играх с локальной симуляцией достаточно было изменить значения в памяти или воспользоваться ошибкой в проверке столкновений, чтобы атаковать из невозможного положения. Но с развитием сетевых игр подобные трюки переместились на границу между клиентом и сервером, где Вася уже не обязательно меняет длину меча в буквальном смысле, а ищет ситуацию, в которой сервер неправильно проверяет дистанцию или использует устаревшее положение персонажа. Думаю понятно, почему такие ошибки стали интересны в играх с ближним боем, где даже несколько сантиметров или несколько кадров вполне могут решить исход схватки.

Ваш роутер тоже обманывает сервер

Сетевая игра существует сразу в нескольких местах и постоянно примиряет состояния, которые немного отличаются друг от друга: пакеты задерживаются, теряются или приходят не по порядку, клиенты предсказывают движение, пока ждут ответа сервера, а сервер при попадании отматывает мир назад, чтобы проверить, что стрелок видел на своём экране. Вся эта машинерия нужна, чтобы Василий с пингом в 80 миллисекунд мог нормально играть, и Вася пользуется ею потому, что она изначально рассчитана прощать сетевые проблемы.

Самый известный пример это lag switch, намеренное создание задержек или коротких провалов связи, и инструментов для этого в интернете вагон и маленькая тележка, начиная с совершенно безобидных утилит для тестирования плохих сетей. Вася на секунду «замораживает» отправку, за это время пробегает простреливаемый участок, а остальные видят, как его персонаж дёргается, пропадает и потом оказывается уже за препятствием. С компенсацией лагов можно сделать и обратное: держать искусственно высокий пинг, чтобы сервер отматывал время дальше, и Василий, который на своём экране уже спрятался за стену, всё равно получал пулю из прошлого. Поэтому окно отмотки всегда ограничивают, а клиентам со слишком большой задержкой уменьшают её пользу, хотя каждое такое ограничение бьёт и по честным игрокам с плохой связью.

Неприятность в том, что задержка сама по себе ничего не доказывает. У Василия действительно может быть плохой Wi‑Fi, перегруженный роутер или маршрут до сервера через половину Европы, и отличить периодические «замедления» Васи от его проблем примерно так же весело, как работать местным отделом ТСПУ. Поэтому смотрят не на один высокий пинг, а на сочетание событий: повторяемость провалов, последовательность команд до и после задержки, и главное, как часто провал совпадает с выгодным для игрока моментом. И чем агрессивнее такая система, тем чаще она превращается в генератор банов для людей, у которых просто неудачно стоит точка доступа.

Манипуляции с порядком сетевых пакетов

При чем тут роутер? Ну просто пакеты можно не только задерживать, но и пытаться переигрывать их порядок или отправлять последовательности сообщений, на которые сервер не рассчитывал. Если протокол плохо связывает команды между собой, то хитроумный Вася может попытаться заставить разные части игры обработать события в разном порядке и например, сначала принять действие, а потом проверить условие, которое должно было его запрещать. Сам по себе пакет, пришедший не по порядку, ещё не чит, потому что нормальный сетевой протокол обязан учитывать потери и перестановки, но если обработчики полагаются на то, что события всегда придут в ожидаемой последовательности, у Василия появляется шанс стать быстрым фрагом.

В ранних сетевых играх манипуляции сетевым обменом нередко позволяли влиять на ход матча, а когда задержками научились управлять намеренно, lag switch стал бичом в гонках. Но задержка пакетов и изменение их порядка не означают автоматически, что сервер можно обмануть, и Вася, как человек исключительно внимательный к чужим ошибкам, решает проверить это предположение на практике.

Боты, макросы и совсем не техническое читерство

Не всякое преимущество требует лезть в память или протокол. Макрос повторяет комбинацию с одинаковыми до миллисекунды интервалами, бот часами фармит ресурсы, пока Вася спит, и в играх с живой экономикой эти ресурсы потом продаются за реальные деньги, так что у ботоводов появляется вполне коммерческий интерес, а у разработчиков отдельный отдел, который этих ботов ищет по слишком ровному распорядку дня и слишком повторяющимся маршрутам.

Дальше начинается территория, где техника почти не нужна. Вася за деньги поднимает чужой аккаунт, садясь за него сам. В королевской битве Вася с другом попадают в разные отряды, созваниваются в Discord и играют вместе против всех, а на стриме Василия Вася просто смотрит трансляцию и знает, где тот прячется, и поэтому серьёзные турниры показывают матчи с задержкой.

Сканер исполняемых файлов в таких случаях бесполезен, матч нечестный, но в клиенте нет ничего запрещённого, участник эксплуатирует правила снаружи игры. Поэтому античит постепенно вырос из программы, которая ищет запрещённый файл, в систему, которая смотрит на клиент, сетевые события, результаты матчей и долгосрочное поведение аккаунта. Большой брат, как там дальше?

Принудительное отключение соперника

Есть и вариант, когда цель не выиграть перестрелку, а вообще не дать Василию закончить матч и в играх с прямым соединением между участниками или с неудачно устроенной обработкой сетевых сообщений можно пытаться выбить соперника из сессии. Иногда достаточно вызвать ошибку, после которой матч зависнет или будет признан недействительным, что уже не lag switch, где Вася портит собственную связь в удобный момент, а атака на чужое соединение или общую сессию. Защищаться от такого приходится архитектурно, скрывать адреса игроков, делая промежуточные релеи, и не позволяя одному клиенту управлять жизненным циклом всего матча.

Эта проблема становилась все заметнее по мере того, как сетевые игры начали переходить от локальных сетей и прямых соединений к массовым интернет‑сессиям. В архитектурах, где один из игроков выступал хостом, у него могло быть больше возможностей влиять на сессию, а намеренный разрыв соединения иногда позволял избежать поражения или сорвать матч, что конечно обидно, но локально. Сейчас такие атаки довольно быстро локализуются, а важные матчи проводятся на выделенных подсетях, которые работают только на доверенных адресах.

(тут у меня кончились гифки примеров)

Манипуляции с рейтингом

Иногда Вася даже не пытается мухлевать внутри матча, а подбирает себе удобных соперников через саму систему рейтинга: заходит в очередь группой с подходящими аккаунтами или использует особенности начисления рейтинга после победы. Здесь уязвимость строится на алгоритмах, которые решают, с кем Вася будет играть и сколько очков получит за результат. Технически такие нарушения ловить очень сложно и граница между нарушением и просто неприятным поведением определяется только кожаными, а с точки зрения системы это допустимо, хотя и искажает подбор соперников, экономику и доверие к таблицам лидеров.

Разновидность, таких, назовем их «рейтинговых читов» появилась и развивалась параллельно с рейтингами, ранговыми матчами и автоматическим подбором соперников. И как только игры начали оценивать мастерство игрока некоторым числом и использовать его для формирования матчей, так нашлись и желающие управлять этим числом не только честными победами.

Намеренные поражения (или deranking, intentional losing), использовались для попадания в более простые матчи, а со smurf‑аккаунта Вася в хорошем настроении идёт «отдохнуть» на низкий рейтинг, где его соперником становится Василий, который только начал разбираться в игре. Позже к этому добавились манипуляции очередями, договорняки и слитые матчи между знакомыми игроками, в том числе на турнирах, чтобы повлиять на рейтинговые алгоритмы.

В отличие от wallhack, здесь Вася может вообще ничего не устанавливать, потому что эксплуатирует не код клиента, а людей и правила самой системы, что, пожалуй, самый неприятный случай для разработчика, и остаётся только анализировать результаты матчей, связи между аккаунтами и поведение игроков на дистанции в несколько месяцев... как говорил дядя Гейб — пироги с котятками не получатся без одного важного ингридиента.

Жизнь Васи после бана

Рано или поздно Васю банят, и выясняется, что для него это скорее неудобство, чем наказание. В бесплатной игре новый аккаунт стоит одну почту, поэтому следом за аккаунтом начинают банить железо: античит запоминает серийные номера дисков, материнской платы, MAC‑адреса и прочие идентификаторы, и на втором круге Вася узнаёт про HWID‑спуферы, которые эти идентификаторы подменяют. Дальше в ход идут привязка к телефону, к платёжному методу, ограничения на рейтинговые режимы для новых аккаунтов, и каждый такой шаг делает Васе дороже следующий заход, но одновременно усложняет жизнь Василию, который просто купил новый ноутбук или поменял номер.

Ещё один приём, который придумали против Васи, это банволны. Если банить сразу после срабатывания детекта, Вася получает очень точную обратную связь: вот эта версия чита попалась, а вот эта нет, и разработчик чита быстро чинит место, по которому его поймали. Поэтому подтверждённых читеров часто копят неделями и банят одной волной, так что связать бан с конкретным детектом гораздо сложнее, а заплатившие за подписку на чит успевают её продлить.

А до бана Вася может довольно долго играть в своём отдельном мире. Системы вроде Trust Factor в CS подбирают игроков с похожей репутацией, и аккаунты с подозрительной историей постепенно начинают встречаться преимущественно друг с другом. Вася формально не забанен и продолжает побеждать, только побеждает он теперь таких же Вась, а Василий ничего не замечает, потому что просто перестал их встречать.

Из чего на самом деле состоит защита

Самой надёжной защитой до сих пор остаётся правильное распределение доверия, и с неё всё начинается. Сервер сам владеет важным состоянием: позицией персонажа, здоровьем, инвентарём, валютой, прогрессом и итогами матча, команды клиента проверяются на допустимость, а критические действия ограничены по частоте и контексту, так что Вася не может за секунду заработать то, на что по правилам нужны недели, перепрыгнуть уровень одной командой или потратить предмет, которого у него никогда не было. Этот слой не ловит читеров вообще, он просто делает значительную часть читов бессмысленными.

Поверх него работает клиентский античит, который проверяет целостность игрового процесса, ищет известные инструменты вмешательства и замечает попытки читать или менять память игры. Часть таких решений живёт в пользовательском режиме, а часть ставит вместе с игрой драйвер уровня ядра, который видит систему гораздо шире, и вокруг этих драйверов давно идут споры о приватности и безопасности, ведь игре фактически выдают права, которых нет у большинства остальных программ на компьютере. Большинство игроков, включая Василия, давно воспринимают такой драйвер как данность и ставят не читая, а Вася в ответ уходит туда, куда драйвер не дотягивается, на DMA‑карты и вторые компьютеры.

Третья часть это анализ поведения, которым занимаются уже отдельные команды. Они собирают всё, что доступно серверу, от тепловой карты перемещений и истории команд до темпа действий, точности и серий результатов, и ищут в этом картину, которая плохо объясняется человеческой игрой. Один идеальный выстрел ничего не доказывает, хороший игрок умеет сделать красивый фраг, но когда в длинной серии матчей сходятся необычно точное наведение, маловероятные реакции и знание позиций, которые нельзя было разведать, подозрение становится обоснованным, и к этому моменту обычно приходит банволна.

Обманывать надо самого Васю

Один из самых симпатичных подходов показали Activision, когда в 2023 году добавила в Ricochet так называемые галлюцинации. Идея в том, чтобы создавать в мире приманки, которые видны только через чит: ложные цели за стеной или внутри неё, которые честный клиент не рисует и о которых Василий никогда не узнает. Если Вася начинает следить за пустым местом, наводит туда прицел или обходит угол так, будто там кто‑то стоит, сервер получает сигнал, что его клиент видит больше, чем ему положено, и чит фактически сам сдаёт своего хозяина.

Та же логика у мер, которые не столько наказывают, сколько обезоруживают. В Ricochet, например, есть режим, при котором пули подозрительного игрока перестают наносить урон, и режим, при котором он теряет оружие прямо посреди матча, а сам Вася в это время продолжает думать, что ему просто не везёт. Для соревновательного шутера это спорный ход, но общий принцип полезен: сначала не дать эксплойту испортить матч Василию, а уже потом спокойно решать вопрос с наказанием.

И здесь же становится понятно, почему все матчи пишут подробные логи. У каждого матча есть идентификатор, события и метки действий игроков, которые можно связать с конкретной сессией, по ним строятся повторы и собирается независимая статистика. Логи сами по себе не найдут аимбот, но позволяют разобрать конкретный инцидент, проверить жалобу Василия и не превращать одну испорченную комнату в проблему всего сервиса.

Но обманывают опять Василия...

До сих пор разработчик в этой истории защищал Василия от Васи, но доверие работает в обе стороны, и коммерческая игра тоже может использовать технические средства так, что игрок совершенно неправильно понимает происходящее. Самый неприятный пример это боты, которые выдают себя за живых игроков: с человеческими никами, аватарками и историей матчей, они заполняют пустые места в лобби и при желании оператора могут помогать определённым участникам добиваться лучших результатов. Василий думает, что соревнуется с людьми, иногда ещё и на реальные деньги или призы, хотя часть его соперников сгенерирована платформой, и в индустрии время от времени всплывают обвинения такого рода.

Важно не путать это с честными ботами. Боты в PvE, в тренировочном режиме или в очереди, где игра прямо говорит, что добавила искусственных соперников, вполне разумный способ сократить ожидание, и технически это могут быть те же самые боты на тех же алгоритмах. Разница только в том, что Василию сказали правду, и когда от исхода матча зависят деньги, эта разница перестаёт быть мелочью.

Более мягкие формы встречаются ещё чаще: таймеры «предложение сгорит через 10 минут», награды, которые исчезают, если не зайти в игру завтра, бесконечные цепочки заданий, которые подталкивают вернуться прямо сейчас. Таймер сам по себе не обман, и система прогрессии не обязана быть построена против игрока, но когда реальный шанс получить награду, природа соперников или условия соревнования намеренно скрыты, хорошим UX это уже не назовёшь.

По сути это тот же Вася, только сидящий по другую сторону сервера. Вася хочет, чтобы сервер поверил ложному утверждению о позиции, попадании или балансе, а нечестная игра хочет, чтобы Василий поверил ложному утверждению о числе живых соперников или смысле результата, и в обоих случаях одна сторона принимает решение на основании информации, которую не может проверить сама.

Честная игра начинается не с античита

Устранить читерство одним способом нельзя, это не флаг AntiCheat = true, после которого все участники внезапно становятся честными. Каждая новая защита меняет экономику создания читов, каждый новый чит заставляет пересматривать, где проходит граница уже сделанной работы, и Вася за время этой статьи прошёл путь от сканера памяти до второго компьютера с картой захвата не потому, что ему так интереснее, а потому, что все более простые дороги ему по очереди закрыли.

Большая часть этих закрытых дорог выглядит совсем не эффектно: клиенту не выдают полномочий, которые ему не нужны, критические изменения проверяются на сервере, предметы двигаются транзакциями, матчи изолированы друг от друга, данных собирается достаточно для расследования, а подозрение не путают с доказательством. В ролики на YouTube и Twitch такое не попадает, зато сорок Василиев в пятницу вечером спорят о балансе оружия, а не возмущаются быстроруким Васей, появившемся на сервере.

Посмотреть и поиграться с примерами

Комментарии (3)


  1. xSVPx
    28.10.2026 17:45

    Предмет уже записан в инвентарь друга, но запись об удалении из инвентаря Васи не успела сохраниться

    Да что у вас там происходит.

    Не предметы в игроках надо хранить, а ссылку на владельца в предметах...


    1. dalerank Автор
      28.10.2026 17:45

      у нас тут всяко-разно происходит, вы даже не представляете как можно накосячить. например хранить текстовое представление предмета нехешированое, или хранить хеши предметов в памяти инвентаря


  1. cher-nov
    28.10.2026 17:45

    Есть еще звук, когда шаги противника за стеной Василий должен слышать, а значит, клиенту нужна хотя бы примерная позиция их источника

    А если слать не позицию источника, а панораму звука относительно игрока? Для воспроизведения этого достаточно, а обратно позицию отсюда не высчитать. Хотя серверу придётся знать, что за аудиосистема у клиента - наушники из пятёрочки или объёмно-многоканальное DOLBIT NORMAL’NO во все стороны.