Предотвратить мультиплеерный обман

10

Я почти заканчиваю разработку небольшой многопользовательской игры в стиле инди. В то время как я намерен позволить людям обманывать в одиночной игре, это явно неприемлемо для многопользовательской игры. Кто-нибудь знает, как можно помешать обычному Джо использовать что-то вроде Cheat-Engine для модификации частей игры? В настоящее время я планирую, чтобы клиент загружал хэш MD5 каждого файла настроек, который игра использует (хранится в виде XML), на игровой сервер для проверки каждые несколько секунд, но есть ли что-то, что я могу сделать, чтобы остановить такие вещи, как редакторы памяти и т. Д. ?

User093203920
источник
2
Я бы рекомендовал эту статью « Создание многопользовательских игр - безопасность», написанная для некоторого многопользовательского API, но идеи хороши и все еще применимы
Cyral

Ответы:

8

Если вас беспокоит локально модифицированный код, то как вы можете быть уверены, что кто-то не просто изменил ваш код уведомления для отправки статического списка хешей MD5, того же, который вы ожидаете? На самом деле, вам даже не нужна модификация кода для этого, вам просто нужен довольно простой прокси-сервер (если не использовать SSL, но даже это может быть подделано с небольшим усилием).

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

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

Мэтью Шарли
источник
2
@ user185812: Обычно лучше подождать несколько часов, прежде чем отмечать принятый ответ. Хотя лично я думаю, что мой ответ довольно велик (я предвзят), у других, скорее всего, будет больший вклад, и видение принятого ответа нередко является сдерживающим фактором для ответа других.
Мэтью Шарли
@ MatthewScharley - не беспокойся. ;)
Мартин Сойка
11

Клиент в руках врага. ( Законы дизайна онлайн мира )

Действительно, единственный способ победить большинство читов - это сделать клиента «тонким клиентом», а именно: действовать только как устройство ввода и вывода и никогда не предоставлять ему больше информации, чем ему точно необходимо.

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

Это не остановит людей, взламывающих друг друга через искаженные сообщения, на которые ссылается сервер - ваш клиент должен защищать от сообщений с сервера так же, как вы защищаете свои веб-сайты от атак SQL-инъекций.

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

Предлагаемое чтение:

Мартин Сойка
источник
2

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

Теперь есть и другие способы мошенничества, но это все о том, как устроена ваша игра.

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

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

API-Beast
источник
Я не согласен с видимостью хаков. Разве это не может быть предотвращено, не давая клиенту информацию, пока ее персонаж не узнает об этом? Не поймите меня неправильно, это может не быть хорошим дизайном. Но это отличается от невозможности предотвратить.
xuincherguixe
@xuincherguixe Я думаю, что это невозможно в некоторых обстоятельствах. Например, оба клиента играют под одним и тем же IP-адресом и одним и тем же портом. В таком случае только добрая воля клиента мешает ему читать данные, предназначенные для другого.
Водзу
1

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

Например, у меня 245 GOLD ... с Cheat Engine я делаю поиск 245 и нахожу много мест в памяти. Затем я играю еще немного и довожу свое золото до 314, затем я ищу в предыдущем результате поиска значение 314 и легко нахожу в памяти место, где хранится GOLD.

Способ предотвратить это - никогда не хранить реальное значение в ячейке памяти. Например, я храню значение в объекте, который должен вычислять реальное значение по требованию, когда это требуется. Итак, допустим, что у игрока 245 ЗОЛОТО. Если они выполняют поиск ячейки памяти со значением 245, они могут найти много, но ни одна из них не будет той ячейкой памяти, где на самом деле хранится значение золота, потому что вы не сохраняете значение 245 для золота. Когда игре нужно узнать, сколько золота, она спросит у объекта, который его оценивает, и рассчитает его по требованию.

Теперь возникает вопрос: как именно вы храните значение таким образом, чтобы оно не раскрывалось? Это становится немного сложнее и уродливее, и я уверен, что есть много способов сделать это. Что мне нравится делать - это хранить логический массив (или байтовый массив). Длина массива может быть любой, но допустим, что это 13. Тогда у вас есть счетчик, который представляет, сколько раз 13 входит в это фактическое значение. Таким образом, если мы хотим представить 245, тогда счетчик будет иметь значение 18. Теперь массив будет иметь все логические значения, установленные в true для оставшейся части 245/13 ... в основном, модуль. В данном случае это 11, поэтому первые 11 логических значений в массиве будут установлены в true, а остальные в false. Чтобы получить значение, все, что вам нужно сделать, это умножить счетчик на длину массива, а затем добавить 1 для каждого логического значения, установленного в true (останавливаясь на первом значении false). Теперь число 245 никогда не будет сохранено где-либо, и будет трудно найти место в памяти, которым нужно будет манипулировать, чтобы изменить количество золота. Возможно, вы захотите установить длину массива на разные размеры (возможно, случайным образом выбрать число в некотором разумном диапазоне) при создании этого объекта.

РЕДАКТИРОВАТЬ: Это полезно для многопользовательской и одиночной игры. Есть мошенничество, которое также может быть сделано в мультиплеере, где значения в пакетах могут быть изменены. Это потребует различных методов предотвращения, таких как подписывание каждого пакета.

Хосе Мартинес
источник
1
Как правило, для предотвращения мошенничества многопользовательские игры рассчитывают все на сервере, поэтому изменение значения на клиенте или в пакете, отправляемом на сервер, ничего не меняет в реальной игре. Но все же остальная часть ответа интересна.
Vaillancourt
@AlexandreVaillancourt Хороший вопрос. Я обеспокоен сбоем вычислений подписей ЦП сервера. Я хочу сохранить сервер быстрым, просто передавая пакеты между двумя игроками, но теперь я внимательно посмотрю, как вы на это указали.
Хосе Мартинес
Если вы отправляете только входные данные от клиента на сервер, вам не нужно подписывать каждый пакет. Находясь на сервере, если ввод не имеет смысла, он либо просто отклоняется, либо клиент исключается за мошенничество. Сервер рассчитывает следующее состояние игры, а затем отправляет новое состояние всем игрокам, что, как правило, позволяет избежать мошенничества (вы не избавляетесь от подобных ботов, но, по крайней мере, избегаете случайного обмана игроков) ,
Vaillancourt
1
Чтобы избежать этого, вы позволяете серверу обновить новую жизнь, а затем отправить новую жизнь клиенту. Все рассчитывается на сервере, и пусть клиенты просто будут «тупыми терминалами» для всех важных вещей: клиент будет отвечать за захват входных данных от игрока («нажал в точке x, y в момент времени T», «нажал» кнопка X в момент времени T »), отправка их на сервер и получение нового состояния от сервера (« игрок теперь находится в положении X, Y »,« игрок имеет жизнь ZZZ ») и отображение его игроку.
Vaillancourt
1
При этом мошенник (человек посередине) может испортить все, что они хотят, с пакетами, он не изменит состояние игры на сервере, потому что сервер убедится, что ввод действителен («хм, клиент нажал»). в пяти разных местах за последние 0,03 секунды, это ненормально, давайте отвергнем эти клики ") и запустим всю симуляцию.
Vaillancourt