Pull to refresh
0
Pixonic
Developing and publishing games since 2009

Как мы перебанили обычных игроков и заDDoSили свои сервера: практическое руководство

Reading time 4 min
Views 41K
Рассказывать о новых проектах это, конечно, хорошо, но не всегда всё получается, как мы хотим.

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



Проиграл — получи бан


Было время, когда нашу игру War Robots из-за недостатков в архитектуре атаковали читеры. Были утилиты, увеличивающие запас здоровья до космических значений, что делало их практически бессмертными. Таск с читерами мы в итоге закрыли, но не сразу.

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

  1. Каждый робот после матча проходил проверку на полученные повреждения.
  2. Если повреждения, полученные роботом, превышали значение его максимального здоровья — то игрок признавался читером, а его аккаунт блокировался.

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

Когда у игроков сильно шалит интернет-соединение (а в мобильных играх это нормальная ситуация), при обмене данными между клиентом и серверами могут происходить совершенно волшебные вещи. Запросы от клиентов приходят неполными, не в том порядке или с сильной задержкой. В общем, один серверный баг допускал, что при плохом соединении клиент может присылать результаты боя два или даже три раза подряд. Соответственно, игроки могли получать в 2-3 раза больше наград или случайно потратить на ремонт вдвое больше ресурсов.

Эту проблему мы решили довольно быстро: профиль-сервер научился игнорировать лишние результаты боя от одного клиента. После успешного тестирования мы зарелизили новую версию.

Вот тут-то нас и накрыло.

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

Всех, конечно, разбанили и даже компенсацию выплатили, но ситуация так себе, не позитивная точно.



Как устроить самому себе DDoS


Уже писали про эволюцию нашей инфраструктуры серверов, а сейчас вспомнили один случай того времени.

В конце 2015 года состоялся релиз долгожданной фичи в War Robots — кланов. Когда вышло обновление (а это было поздно вечером), мы открыли шампанское и все было бы хорошо. Но радоваться пришлось недолго — серверам внезапно стало плохо. Оказалось, что мы собственными руками устроили себе DDoS-атаку.

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

Той же ночью мы запилили флажок (шампанское мы при этом закрыть не успели), который контролировался с профиль-сервера — он полностью блокировал работу Hangar Client API. Игрокам, которые уже вступили в кланы, мы этот флажок оставили включенным, то есть у них все работало, потому что их количество было недостаточно, чтобы заDDoSить сервера.

В итоге мы начали корректно обрабатывать ответы сервера в игре, а в случае ошибки — увеличивать таймаут на повтор запроса.

«Бесплатный» рейтинг


Отдельная история — это когда некачественная реализация встречает человеческий фактор. Только теперь никого не банили, а наоборот раздавали рейтинг налево и направо. Короче, как-то ночью наш мониторинг (а мы мониторим вообще всё) зафиксировал слишком быстрый рост рейтинга игроков.

Потом выяснилось, что сама реализация подсчета очков в теории позволяла дублировать данные. Но никто бы на это не обратил бы внимания, если бы дежурный админ из-за опечатки в одной букве случайно рестартнул сервер, который не должен был работать. Именно он и начал удваивать игрокам рейтинги.

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

Бесценный приз


С опечаткой был еще один факап, но куда более серьезный.

Как-то на Хэллоуин мы запускали новую гачу — лотерею. Если кто не знает, гача — это механика получения предмета из нескольких разных случайным образом. В лотерее у игрока был ограниченный видимый набор призов разной ценности. За каждое открытие игрок получал 1 приз, этот приз вынимался из набора, а цена открытия с каждым разом возрастала. Таким образом игрок мог гарантированно скупить все призы лотереи, а счастливчики вынимали самые ценные призы на первых открытиях (и соответственно получали их очень дёшево).

В общем, потом и кровью мы запилили фичу к ивенту, протестили, выложили. Запускаем, обновляем графики… УРА! Они рванули вверх!.. И одновременно на нас обрушиваются тонны негатива в комьюнити, что мы якобы обманываем своих игроков.

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

В интерфейсе лотереи указана стоимость текущего открытия (та, которая возрастала с каждым разом), например, PRICE: 100 Gold. Вот как выглядел концепт (обратите внимание, что по задумке на каждой карточке также дополнительно указана цена ее открытия):



А вот как это вышло на проде, когда в результате ряда «улучшений» PRICE (цена за участие в лотерее) внезапно для проектировщика превратилась в PRIZE (приз):



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

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

Ситуацию в итоге развернули, ввели дополнительные чек-поинты, золото игрокам вернули и локали запилили на сервере, чтобы ничего подобного не повторялось.

Самое время вводить хештег #косякинапроде
Tags:
Hubs:
+102
Comments 31
Comments Comments 31

Articles

Information

Website
pixonic.com
Registered
Founded
Employees
201–500 employees
Location
Кипр