@adrenalinruslan

Как реализовать многопользовательскую игру?

Возьмем к примеру самую простую игру, нажав на одну из клавиш: W, S, A, D, квадратик на холсте будет двигаться по осям X, Y.

Когда пользователь нажимает на одну из клавиш, socket-ом на сервер отправляется json массив event, на сервере этот массив обрабатывается и socket-ом клиенту отправляются данные с конечными координатами. Затем у всех пользователей обновляется координаты квадратика в холсте.

Как это правильно реализовать на javascript ? Если я не ошибаюсь, то пользователь может подставить свои данные в запросе, как это обойти? Допустим пользователю должно было прийти координаты: x = 500, y = 500, а он вместо этих, подставил свои
  • Вопрос задан
  • 160 просмотров
Пригласить эксперта
Ответы на вопрос 3
Robur
@Robur
Знаю больше чем это необходимо
Правильно - строить логику игры так чтобы подставление пользователем своих данных не давало ему каких-то преимуществ, а наоборот.
Многопользовательские игры реализуются на сервере, на клиенте только рисование картинки как скажет сервер и слушание какие кнопки он нажал.
Если он себе квадратик нарисует не там где ему сервер сказал нарисовать - он только себе хуже сделает и никак не повлияет на ход игры.

Пользователь может обмануть сервер только в плане когда и какие кнопки он нажимал, иногда это имеет значение иногда нет. Если имеет - то тут уже всякие системы обнаружения таких случаев, в зависимости от логики игры и на сколько фантазии хватит
Ответ написан
Комментировать
@dimoff66
Кратко о себе: Я есть
Отсылайте на сервер только нажатую клавишу, все расчеты координат делайте на сервере.
Ответ написан
Комментировать
dollar
@dollar
Делай добро и бросай его в воду.
Проблемы начинаются не только при читерстве, но и банально при обрыве связи с сервером. Например, когда у пользователя пропадает Интернет. И если вы разрешаете игроку перемещаться локально, отсылая координаты, то с точки зрения сервера игрок исчезнет на некоторое время, а потом появится в других координатах, далеких от тех, где он был.

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

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

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

Что касается того, что игрок может у себя поменять какие-то данные, приходящие от сервера, то это не должно касаться других игроков. Да, игрок сможет нарисовать себе миллион долларов и переместить себя за стену, изменив координаты локально. Но на сервере это должно игнорироваться. То есть сервер должен посчитать, что игрок не мог туда попасть, и блокировать все попытки действий в той области. Как посчитать - это уже зависит от игры, от логики геймплея. Например, у игрока было слишком мало времени, чтобы преодолеть такое расстояние (считаем путь обхода стены).

Если говорить про чисто техническую защиту от изменения кода на клиенет, то лучшее, что вы можете сделать, это обернуть весь код в анонимную функцию. Она будет как бы глобальным пространством для других функций и переменных, но через консоль к ней нельзя будет получить доступ.
(function() {
  let x = 50;
  let y = 50;
  // и т.д. всё, как обычно, только в обертке
})();

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

Войдите, чтобы написать ответ

Похожие вопросы