В этом посте хотел бы рассмотреть такую тему как вылет из-за десинхронизации. Штука неприятная и хаотичная, особенно когда играешь часок другой в RPG, а тебя тут кикает. Перед тем как разберем причины - рассмотрим немного протокол игры.
Латенси - интервал отправки action пакетов всем игрокам.
Action пакет - набор данных, который говорит другим игрокам о желаемом действии.
Keep-avile пакет - пакет, который содержит контрольную сумму состояния игры.
Action пакет - набор данных, который говорит другим игрокам о желаемом действии.
Keep-avile пакет - пакет, который содержит контрольную сумму состояния игры.
Схема с хостботом
Основная проблема хостбота в том, что он не знает что происходит на поле боя. Он может просматривать action пакеты и догадываться о том, что на самом деле произошло (отсылка к w3mmd, dota stats). Боту приходит action пакет от клиентов игры, он складывается в очередь. Как только пришло время отсылать их всем (раз в латенси секунд) бот берет все пакеты из очереди и отсылает игрокам. Игроки когда получили от бота пачку пакетов отсылают пакет Keep-avile в знак того, что они успешно обработали порцию игровых данных. Keep-avile пакет содержит контрольную сумму, алгоритм вычисления которой известен только Blizzard. Простым смертным остается лишь экспериментальным путем догадываться что влияет, а что нет. Исходя из незнания этого алгоритма бот сверяет все контрольные суммы и если у всех они сошлись - все ок. Иначе рассинхрон и правильной контрольной суммой является та, которую прислали большее число игроков.
Схема без бота
Схема с хостом-игроком отличается лишь тем, что хост знает как считается контрольная сумма и сверяет остальные со своей. Если не сошлись - кик.
Что влияет на контрольную сумму
В первую очередь это сами action пакеты. Так-же влияет состояние поля боя (количество юнитов, декораций и прочее). Профессиональные мапмейкеры могут его вызвать и триггерами. А профессиональные программисты ботов - своим кодом.
Причины рассинхрона
- Хостбот не рассылает всем одинаковые action пакеты. Зачем? Есть пару разумных решений с этими примерами: антисейв и антитрейд.Но чаще всего пакет не добавляется в очередь, а игрока сразу кикает за сейв или трейд с соответствующим сообщением всем.
- GetLocalPlayer. При помощи этой нативки можно выполнять код у произвольных игроков. У одного юнит создался у другого нет. Рассинхрон. Решение: использовать эту нативку с умом.
- Карты с мемхаком. Неправильно написанный патч для памяти, да и в целом неаккуратное обращение с этим инструментом может вызывать рассинхроны не только в самой карте с мемхаком, но и еще и в других играх. Если в самой карте память правится по одному и тому же принципу и поведение у всех может быть одинаковое (рассинхрона не будет). Но после игры пользователи могут разбежаться в другие кастомки, где из-за правленного блока памяти, который карта забыла вернуть обратно при выходе, у него уже могут быть проблемы. Решение: перезапустить Warcraft III
- Межплатформеная игра. Бот хостит на 2 версии Warcraft III - 1.26, 1.28. И кто его знает что меняли Blizzard в своих алгоритмах. Но есть iCCup и Garena. Вроде как на одинаковой версии работают, но по функционалу совсем разные платформы. Garena практически не лезет в Warcraft III (ставит разве что Winsock хуки, чтобы подсовывать свои пакеты игрокам). Про iCCup не скажешь такого: золотой ник в лобби, контроль курьера, птс вместо рассы/клана. Все это говорит о том, что лаунчер много поправил в коде Warcraft. Таких правок нет на других платформах. Если про птс и золотой ник рассинхрон притянут, то из-за курьера вполне реален. В панели контроля есть соответствующие пункты даже в других кастомках Решение: играть только с игроками с iCCup, либо без них вообще.
- Несоответствие ника коннектора и ника в LAN при игре через коннектор. Обычно это проявляется при загрузке кода в сейв/лоад картах. Тут причины аналогичны GetLocalPlayer(). Решение: установить одинаковые ники Внимание: вы в LAN не сможете установить цветной ник. Придется его убрать.