@Quttar

Возможно ли реализовать одноранговый мультиплеер с защитой от жульничества?

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

Я считаю, что проще всего будет пояснить на примере шутера, пусть CS 1.6

Пусть есть 2 игрока A и B которые играют друг против друга.

Сценарий 1: Игрок А решает установить у себя произвольную сумму денег. Как не разрешить ему это сделать?
Решение: Клиенты игры на компьютере каждого из игроков отслеживают баланс каждого игрока на сервере, и если игрок А покупает оружие, на которое у него определенно недостаточно денег, то делается вывод, что этот игрок жульничает и клиент разрывает соединение с данными игроком.

Тут задача решается просто. Но мой вопрос, относится как разрешить следующий сценарий.

Сценарий 2: Игрок А решает узнать, где находится игрок B. Как не разрешить ему это сделать?

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

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

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

Эту задачу не так сложно решить методами линейной алгебры. Когда у нас есть конкретные координаты.
Вопрос в следующем, можно ли использовать какое-то особенное шифрование и модификацию методов линейной алгебры, которые позволят не раскрывать позицию игроков, но если между игроками нет стен, то об этом сразу удастся узнать?
  • Вопрос задан
  • 191 просмотр
Пригласить эксперта
Ответы на вопрос 3
@rPman
Проблема византийских генералов, решалась в криптовалютах, успешно только с помощью proof of work.

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

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

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

Никакими средствами надежно нельзя будет решить проблему автоматизации. Ее решают статистически (т.е. с некоторой вероятностью ошибки в обе стороны), собирая информацию о типовом поведении игроков, ботов можно выявить по не типичному поведению (есть алгоритмы на основе нейросетей и не только). Дико дорогая операция, эту проблему не могут нормально решить крупные компании, теряя миллионы на читерах.
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
Это не одноранговая игра, это клиент-серверная.

ИДЕЯ 1. Передавать с сервера картинку. Всё, читерство пресечено на корню. Это те самые Google Stadia и PS Now. Недостатки — в огромной нагрузке на сервер и задержках между управлением и картинкой. Как их решить?

ИДЕЯ 2. Передавать с сервера некую информацию, по которой клиент будет строить картинку. Нагрузка на сервер меньше — он не занимается рендерингом. Зато появляется первая предпосылка к жульничеству — по этой информации жульническая программа определяет, где находится враг, и наводит оружие. Но остаётся недостаток: всё та же огромная задержка между управлением и картинкой. При этом задержку никак нельзя улучшить — у нас то самое «пространство-время», знакомое из теории относительности.

О чём я: между Землёй и Луной секунда, и случились два события, на Земле и на Луне. Возможны три варианта: а) свет доходит от Земли до Луны, и событие на Земле заведомо раньше для любого наблюдателя; б) свет доходит от Луны до земли, и событие на Луне заведомо раньше; в) не успевает дойти ни тот, ни другой свет, и хрен его знает, какое раньше — для одних наблюдателей земное, для других лунное. Подобное пространство-время есть и в любом динамичном мультиплеере.

ИДЕЯ 3. Ну, если задержку не улучшить, купируем её тем, что клиент может как-то предсказывать, чтó остальные будут делать, пока пакет ползёт от сервера. Чего не хватает? 1) Клиенты могут внезапно появляться в поле зрения, и не очень хотелось бы, чтобы мы зашкерились за углом, а враг появился ХЗ где, причём где — это зависит от нашего пинга; 2) Из соображений серверной производительности вопрос «видит ли клиент А клиента Б?» желательно решать очень приблизительно, с запасом — Z-буфер решит эту задачу значительно лучше, чем вычисление на процессоре, видит ли клиент А мизинец клиента Б.

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

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

Вот, собственно, и причина wallhack’ов: сервер принял решение, что клиент А, возможно, видит клиента Б, и начинает передавать его положение. И потому wallhack’и обычно не работают, если Б далеко: сервер понимает, что Б не виден и в ближайшее время не будет виден.

Есть ещё такая помощь клиенту, связанная с тем, что есть мощные виды оружия вроде снайперской винтовки, с огромной разницей между «попал» и «промазал». Каждый клиент видит своё в зависимости от работы сети (вспомните фразу «ХЗ, что раньше»), и в момент прихода информации о выстреле сервер пытается восстановить, что именно видел клиент на своём экране, и по этой картинке решает, попал или нет (на этом основан глюк «спрятался за углом, и всё равно убили»). Но эту помощь тоже эксплуатируют: представьте себе, пакеты клиент→сервер, которые идут по штуке за, скажем, 50 мс, отправляют по пачке за 0,3 секунды — больше типичного времени компенсации задержек, но меньше типичного времени реакции. Получается, что персонаж скачет (клиенты, заглядывающие наперёд на 100 мс, отказываются предсказывать дальше — пусть он лучше зависает, чем тыкается в стены), причём скачет так, что в него хрен выстрелишь (пока среагируешь, он перескочит в другое место). А поскольку пакеты сервер→клиент ходят исправно, а сервер руководствуется прикидкой, что видел клиент, клиент всё видит и метко стреляет, а в него никто попасть не может. Если этот трюк исполнять автоматически только при появлении врага на экране, это будет максимально беспалевно — ну у игрока начались перекэширования из-за того, что видеопамяти не хватило. Эту штуку можно сделать даже на приставке, даже не разбирая её — нужен свитч (приставки всё-таки насобачились сообщать, что кто-то физически режет провод), кусок витой пары, моторчик с оптопарой и педалька под ногу. А для некоторых игр хватает свитча и педали, главное не жадничать и отпускать её иногда.

А теперь вместо «чечни» (я так обозвал Counter-Strike — он появился в те времена, когда война в Чечне превратилась в антитеррористическую операцию) возьмём какой-нибудь преферанс. В чём разница? А в том, что игра не динамичная! И потому тактика «передавать только те данные, что нужны для рендеринга» вдруг становится годной. И если вы в преферансе сможете палить чужие карты — автор разгильдяй!

Скажу честно, я не знаю, как на всех этих chess.com компенсируют задержки в шахматном суперблице типа «три минуты на партию». Если средняя игра тридцать-сорок ходов, то задержки в 0,1 секунды отъедят 3…4 секунды, а задержки в 0,2 — 6…8. Но из-за шахматного жульничества и далеко ушедшей дебютной теории основной формат игры — именно суперблиц.

В общем, хрен вы реализуете диплом о защите от жульничества, не понимая, как работает мультиплеер и откуда жульничество берётся. А берётся жульничество из трёх предпосылок: 1) участники мультиплеера живут в релятивистском пространстве-времени; 2) очень хочется экономить вычисления на сервере; 3) жульничество иногда маскируют под обычные для компьютерного мира явления вроде сетевого затора или долгого кадра.

Да, как реально защищают от жульничества: 1) Не допускают никого постороннего в программу-клиент, чтобы даже пакеты нельзя было расшифровать; 2) Ловят программы-жулики по принципу антивируса; 3) Передают клиентам как можно меньше того, что они знать не обязаны; 4) Ловят признаки компьютерного вмешательства в изображение или управление.
Ответ написан
Комментировать
dollar
@dollar
Делай добро и бросай его в воду.
В общем случае это реплеи матчей от лица каждого, обмен которыми происходит автоматически в конце. Если игрок сомневается в честности другого, то он может просто посмотреть его реплей и убедиться, что не было магии, а были просто удачные решения и обычная ловкость рук. В случае же нарушения можно пожаловаться, - и блокируется весь аккаунт вместе со всеми достижениями, включая выигранный матч. Но только постфактум.

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

Если вы настаиваете на защите в реальном времени, то ответ - невозможно. Можно лишь частично подключить "защиту от дурака", но не гарантировать защиту от любых читеров.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы