- PVSM.RU - https://www.pvsm.ru -

Верификация данных пользователей в онлайн приложениях

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

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

Техническое отступление

И дабы не остаться теоретическим материалом была написана небольшая демка. Ее можно запустить, посмотреть какими данными обмениваются клиент и сервер. На чьём примере и будет рассмотрено клиент-серверное взаимодействие.

Приложение использует технологию canvas для графики и websockets для взаимодействия с сервером. Код не является предметом обсуждения, поэтому писался быстро (основная часть около 2-3 часов), без проектирования и рефакторинга. Я не рекомендую использовать его или его часть где бы то ни было.

Вы выбираете героя, сервер вас регистрирует, ищет игру. Ждёт пока не войдут достаточное кол-во игроков.

Верификация данных пользователей в онлайн приложениях - 1

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

Каждый герой имеет свои характеристики атаки, защиты, дальности хода, запаса жизней.

Выбор героя осуществляется клавишами 1 — 4. Поиск игры с выбранным героем — Enter.

Верификация данных пользователей в онлайн приложениях - 2

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

Можно было и не так вырвиглазно нарисовать, но не суть.

Какие данные имеются?

Как и в любой онлайн игре, мы имеем данные об игроках. Тут для упрощения данные о игре и игроках живут только на протяжении игры, а в дальнейшем удаляются.

По порядку:

  • Местоположение всех юнитов в игре;
  • Парамерты героев, выбранных игроками;
  • Принадлежность к команде;
  • Очерёдность хода.

Поговорим отдельно про каждый пункт.

1. Местоположение юнитов. Конечно на основе этой информации рисуются юниты на поле, но можем ли мы не хранить эти данные на сервере? Нет, и вот почему. Если эта информация не хранится, то и проверять то как передвигаются юниты мы не можем. А значит в независимости от скорости персонажа, он может хоть в другой конец карты, хоть на луну.

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

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

4. Принадлежность

Теперь всё вышеперечисленное на примере запроса на атаку (unit1 атакует unit2):

ATTACK unit1_id unit2_id

Запрос в реальной игре, в зависимости от механики, может посылать дополнительные данные:

{"game_key":"...","private_key":"...","action":"attack","attacked":{"x":4,"y":2},"old_position":{"x":4,"y":3}}

Где attacked это положение атакуемого юнита, a old_position — положение откуда будет производиться атака.

На самом деле это всё, что нужно серверу. Ему остаётся провести следующие операции:

  1. Проверить что ход принадлежит unit1
  2. Проверить что запрос отправлен от пользователя которому принадлежит unit1
  3. Проверить может ли unit1 атаковать unit2

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

Верификация данных пользователей в онлайн приложениях - 3

Как клиент обновляет своё состояние? Запрос сервера (да, именно запрос):

{"new_position": {"y": 2, "x": 2}, "request": "move"}

И этого достаточно. Ведь игра знает какому юниту принадлежит ход. И знает что информация проверена. А значит нужно просто перерисовать активного юнита по новым координатам.

Если вы только начинаете, не грех будет дать совет, дублируйте вообще всю информацию.

Как поступать с неверными данными?

Это самый сложный вопрос, однозначного ответа на него нет. Можно например не принимать эти запросы и оставлять состояние игры неизменным. Можно блокировать игрока посылающего такое запросы, а победу присудить его сопернику. Можно дополнительно изменять параметры такого игрока, путь его герой имеет всего одну жизнь (или искусственно завысить сложность игры). Тут мы ограничены только воображением.

Исходный код [1]

Если найдётся достаточно пользователей можно потестить [2].

P.S. Ищу работу Python/Django разработчика. По всем вопросам в личные сообщения или на почту.

Автор: RokkerRuslan

Источник [3]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/235811

Ссылки в тексте:

[1] Исходный код: https://bitbucket.org/rokkerruslan/habrabattle/src

[2] потестить: http://rokkerruslan.bitbucket.org/

[3] Источник: https://habrahabr.ru/post/319882/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best