- Почему и зачем: длинная и необязательная преамбула
- Что же там внутри?
- =========================
- Ally_killed_by_player
- Ammo_bay_damaged
- Armor_not_pierced_by_player
- Armor_pierced_by_player
- Armor_pierced_crit_by_player
- Armor_ricochet_by_player
- Commander_killed
- Driver_killed
- Enemy_fire_started_by_player
- Enemy_killed_by_player
- Engine_damaged
- Engine_destroyed
- Engine_functional
- Fire_started
- Fire_stopped
- Fuel_tank_damaged
- Gun_damaged
- Gun_destroyed
- Gun_functional
- Gunner_killed
- Loader_killed
- Radio_damaged
- Radioman_killed
- Start_battle
- Surveying_devices_damaged
- Surveying_devices_destroyed
- Surveying_devices_functional
- Track_cut
- Track_damaged
- Track_destroyed
- Track_functional
- Track_functional_can_move
- Turret_rotator_damaged
- Turret_rotator_destroyed
- Turret_rotator_functional
- Vehicle_destroyed
- Wwise-voice-wot-blitz
- Рентген мод (исходники) — библиотека читов world of tanks на
Почему и зачем: длинная и необязательная преамбула
Хорошо, что опыта игрового модостроительства у меня было немного — так, пару кастомных прицелов для Deer Hunter 2005 и «нелицензионный» недоклиент
с сопутствущим «взломом» протокола последнего. Ещё лучше, что ни разу не приходилось с головой погружаться в сколь-нибудь трудоёмкую и длительную отладку и дизассемблирование. То есть, с IDA и OllyDBG я поверхностно знаком, но не как с ежедневными рабочими инструментами.
В WOT играю с начала 2022 года. Не запоем, а, скорее, набегами — по 5-6 боёв вечером. Было время 2 года назад, наш клан состоял в Красном Альянсе, ходил на глобалку по ночам, выполнял какие-то тактические задачи на европейском ТВД, устраивал тренировки и спарринги, вовсю бурлили внутриигровые политические страсти, отпочковывались учебные кланы. Сейчас всего этого уже нет, и наш золотой ёжик превратился в табличку над «Домом Ветеранов».
Впадать в ересь сравнения танков с другими MMO не буду, так как хорошо знаком только с танками. Тем более не знаком ни с одним другим проектом, использующим BigWorld, поэтому искренне верю WarGaming’у на слово, что существуют и (не)тривиально (не)преодолеваются различные техномагические ограничения движка — на размер карты, на максимальную скорость юнита, на численность команд и прочее.
Оставаясь в рамках внутренней критики, я также понимаю, что, с точки зрения целевой аудитории танков вообще, и их активного игрового коммьюнити в частности, каждое нововведение из очередного патча, безусловно, гораздо более востребовано и обосновано, сколь бы малым оно ни было.
Итак, я уверен, что в обозримом будущем никаких планов по введению полноценного режима спектатора в WOT нет и не будет. Под полноценным режимом спектатора я понимаю множественные подключения игроков в сеанс боя изначально как невзаимодействующих на игру «привидений»-наблюдателей, а не на технике.
Это тот самый режим, из-за отсутствия которого комментаторы на чемпионатах WOT вынуждены заходить в бой 15-м танком, убиваемым своими на базе. Это тот самый режим, из-за которого появились моды «командирского zoom» и «кинематографической камеры» — по сути, просто костыли.
А нужен такой режим затем, чтобы командир роты занимался командованием, а не скакал впереди на лихом танке по-чапаевски, чтобы он видел ситуацию на карте в целом непрерывно, а не отвлекался на неё в пылу нападения из засады. В идеале, командиру даже не нужны красоты трёхмерного мира — достаточно одной большой карты на весь монитор с игровой ситуацией в реальном времени — HP, повреждениями модулей, членов экипажа, направлениями стволов и прицелов союзной техники, засвеченных в каждый момент вражеских юнитов и прочей вспомогательной информации.
WOT предоставляет широкие возможности модостроительства, но такая идея выходит за рамки классического «заменить пару swf-файлов на свои». Потребуется перехват и разбор самого игрового протокола для того, чтобы иметь возможность передать на командирский планшет своё видение игровой ситуации.
Что же там внутри?
Здесь матёрые гуру реверс-инжиниринга, в духе
подумают: «ага, ну теперь можно написать на питонеэзотерическом языке вот такой скриптплагин для олькииды, который будет делать с этими данными всё что хочешь и даже за пивом сбегает». Но мы пойдём другим путём. Я хочу сразу ориентироваться на то, что ещё до того, как дело дойдёт до разработки командирского планшета, то есть даже для самого полноценного разбора протокола WOT мне понадобятся помощники и тестировщики, далёкие от мира программирования. Им нужен будет простой инструмент с понятным интерфейсом, выдающий легко читаемые данные.
Так что предвидя скептические ухмылки, я засел за Lazarus и набросал в нём специализированный win32-отладчик, основной функцией которого является поставить два INT3-брекпоинта в нужных местах и по их срабатыванию вытаскивать данные по адресу и длине буфера, лежащим на стеке по известным смещениям.
А вот так он себя ведёт уже находясь в ангаре.
Какие выводы можно сделать, даже не смотря на пояснения к пакетам, которые я поленился убрать для этих скриншотов? Сразу несколько.
Во-первых, видно, что все пакеты начинаются либо с 0x48, либо с 0x58, либо с 0x78; какой-нибудь закономерности на этот счёт я ещё не уловил, кроме того, что пакеты с уже известной функцией свой значащий байт не меняют.
Во-вторых, почти в каждом пакете есть один или несколько счётчиков сообщений; например, в keep-alive и ответах на них этим занимается третий и четвёртый байт в заголовке, кроме того сам пакет содержит ещё счётчик сообщений общий (включая keep-alive) и какой-то специфический (считающий пакеты без учёта количества keep-alive); всё это имеет отношение к контролю доставки пакетов, который пришлось прикрутить к UDP, вероятно, для оценки потерь и пересылки BLOBов (об этом позже).
Размеры всех пакетов выравнены по границам 8 байт, что ненавязчиво указывает нам на размер блока всё того же BlowFish; пока я до этого догадался, прошло немало времени в попытках обьяснить странную «контрольную сумму» в конце, да ещё и переменной длины. В конце концов, получив в этом паддинге вместо простого мусора слово «Flags» я, наконец, прозрел.
Ну и в лучших хакерских традициях, в конце каждого пакета находится сигнатура мёртвой говядины; кто бы мог подумать где мы её найдём 🙂
После получения Session ID от сервера приезжает пакет, содержащий номер игрока в неожиданно текстовом формате (792067). А вот пакет, который начинается на 0x78 0x00 на первом скриншоте — особо интересен. Сочетание сигнатуры 0x80 0x20 вкупе с тем, что перед каждым строковым литералом в нём стоит 0x55 и байт длины строки, а после каждого 0x71 находится возрастающий номер, должно насторожить опытных питонщиков — это же, чёрт побери, Python Pickle со своим запихиванием всего подряд в мемо! Вот он такой:
Dct[15]:(xmpp_host = wot-ru.loc captchaKey = 6Lc8GcASAAAAAKffZdxeZZvOvmSTNXbZvsy6CgBR voipDomain = www.wotp.vivox.com file_server = Dct[6]:(clan_emblems_small = Dct[1]:(url_template = http://ce.worldoftanks.ru/dcont/clans/emblems/%d/emblem_32x32.png) clan_emblems_big = Dct[1]:(url_template = http://ce.worldoftanks.ru/dcont/clans/emblems/%d/emblem_64x64.png) rare_achievements_images_big = Dct[1]:(url_template = http://ce.worldoftanks.ru/dcont/achievements/medals/180x180/%d.png) clan_emblems = Dct[1]:(url_template = http://ce.worldoftanks.ru/dcont/clans/emblems/%d/emblem_64x64_tank.png) rare_achievements_images = Dct[1]:(url_template = http://ce.worldoftanks.ru/dcont/achievements/medals/67x71/%d.png) rare_achievements_texts = Dct[1]:(url_template = http://ce.worldoftanks.ru/dcont/achievements/medals/medals_%s.xml)) newbieBattlesCount = 100 roaming = Lst[4]:(1,1,Lst[3]:(Lst[4]:(1,1,499999999,RU),Lst[4]:(2,500000000,999999999,EU),Lst[4]:(3,1000000000,1499999999,NA)),Lst[0]:()) xmpp_enabled = True jdCutouts = 0 xmpp_port = 5222 isTutorialEnabled = True wallet = Lst[2]:(True,True) xmpp_connections = Lst[1]:(Lst[2]:(xmppcs.worldoftanks.net,5222)) xmpp_resource = wot regional_settings = Dct[2]:(starting_day_of_a_new_week = 0 starting_time_of_a_new_day = 0) reCaptchaParser = )
В следующей части, если она заинтересует уважаемых обитателей Хабра, я расскажу о том, как в протоколе WOT передаются файлы, размеры которых намного больше реалистичного размера UDP пакета и MTU. И о том, что эти файлы оказывается сжатыми zlib’ом а внутри у них всё тот же Python Pickle с разными неожиданными вещами.
Спасибо за внимание!
UPD. Свежие новости! По агентурным данным из самого сердца КВГ, мой лёгкий намёк на потенциал коммерческого использования командирского планшета поднял «небольшой бугурт» (дословно), в результате чего кровавые модераторы в полнейшей панике наконец заметили и слили в мусорник тему проекта на официальном форуме танков, а мне было доверительным шёпотом посоветовано замылить данные своего аккаунта на скриншотах.
Я, имярек, находясь в здравом уме и трезвой памяти, торжественно клянусь, что разработка эта имеет исключительно академический характер, клянусь никогда в жизни не покупать компанию WarGaming.net за несметные миллиарды, вырученные от продажи ещё даже не существующей разработки либо иным способом покушаться на финансовое благополучие любимой фирмы! Аминь.
UPD2.
=========================
Я думаю, вам это не составит труда. В проекте настроено всё (от задержки, до расстановки фраз в контейнеры[По ивентам] и привязки фраз к громкости игры)После этой долго проделанной работы открываем пункт SoundBanks, в нём открываем Default Work Unit, в нём нажимаем правой кнопкой мыши по voiceover_crewи нажимаем на пункт Generate Soundbank(s) for current platformПосле завершения генерации будет результат Completed with error(s) с красным цветом текста, мы не обращаем на это вниманияДальше мы открываем папку с проектом(куда вы её распаковали) и в нём открываем папку GeneratedSoundBanks дальше открываем Windows и в нём открываем English(US)
Для установки озвучки на стим клиент:
- Узнаём, куда была установлена игра
- Открываем папки: Data; WwiseSound; (Выбираем нужный нам язык, я выбираю папку ru) ru
- В эту папку мы вставляем нашу озвучку (уже в формате dvpl) и подтверждаем замену файлов
Озвучка установлена!
Для установки на андроид:
- Настройка в игре
1.1) Заходим в игру
1.2) После авторизации заходим в настройки
1.3) Выбираем раздел Другое
1.4) Включаем пункт «Загрузить все ресурсы игры» (если доступен) - Установка озвучки в файловом менеджере
2.1) (Необязательно)Если захотите вернуть озвучку, сделайте бэкап кэша
2.2) Копируем voiceover_crew.bnk.dvpl по пути:
(Копируем туда, куда были загружены файлы игры)
Android/data/net.wargaming.wot.blitz/files/packs/WwiseSound/(Выбираем нужный нам язык, я выбираю папку ru)ru
Именно в папку ru(на нужный нам язык) мы вставляем озвучку
Подтверждаем замену файлов
Озвучка установлена!
Ally_killed_by_player
Уничтожение союзника вами
- ally_killed_by_player_01.wav
- ally_killed_by_player_02.wav
Ammo_bay_damaged
Повреждение боеукладки
- ammo_bay_damaged_01.wav
- ammo_bay_damaged_02.wav
- ammo_bay_damaged_03.wav
Armor_not_pierced_by_player
Броня не пробита
- armor_not_pierced_by_player_01.wav
- armor_not_pierced_by_player_02.wav
- armor_not_pierced_by_player_03.wav
- armor_not_pierced_by_player_04.wav
- armor_not_pierced_by_player_05.wav
Armor_pierced_by_player
Пробитие
- armor_pierced_by_player_01.wav
- armor_pierced_by_player_02.wav
- armor_pierced_by_player_03.wav
- armor_pierced_by_player_04.wav
- armor_pierced_by_player_05.wav
- armor_pierced_by_player_06.wav
- armor_pierced_by_player_07.wav
- armor_pierced_by_player_08.wav
- armor_pierced_by_player_09.wav
- armor_pierced_by_player_10.wav
- armor_pierced_by_player_11.wav
- armor_pierced_by_player_12.wav
Armor_pierced_crit_by_player
Попадание
- armor_pierced_crit_by_player_01.wav
- armor_pierced_crit_by_player_02.wav
- armor_pierced_crit_by_player_03.wav
- armor_pierced_crit_by_player_04.wav
- armor_pierced_crit_by_player_05.wav
- armor_pierced_crit_by_player_06.wav
- armor_pierced_crit_by_player_07.wav
- armor_pierced_crit_by_player_08.wav
- armor_pierced_crit_by_player_09.wav
Armor_ricochet_by_player
Рикошет
- armor_ricochet_by_player_01.wav
- armor_ricochet_by_player_02.wav
- armor_ricochet_by_player_03.wav
- armor_ricochet_by_player_04.wav
- armor_ricochet_by_player_05.wav
- armor_ricochet_by_player_06.wav
- armor_ricochet_by_player_07.wav
Commander_killed
Командир ранен
- commander_killed_01.wav
- commander_killed_02.wav
- commander_killed_03.wav
Driver_killed
Мех-Вод ранен
- driver_killed_01.wav
- driver_killed_02.wav
- driver_killed_03.wav
Enemy_fire_started_by_player
Враг горит
- enemy_fire_started_by_player_01.wav
- enemy_fire_started_by_player_02.wav
- enemy_fire_started_by_player_03.wav
- enemy_fire_started_by_player_04.wav
Enemy_killed_by_player
Противник уничтожен
- enemy_killed_by_player_01.wav
- enemy_killed_by_player_02.wav
- enemy_killed_by_player_03.wav
- enemy_killed_by_player_04.wav
- enemy_killed_by_player_05.wav
- enemy_killed_by_player_06.wav
- enemy_killed_by_player_07.wav
- enemy_killed_by_player_08.wav
- enemy_killed_by_player_09.wav
Engine_damaged
Двигатель повреждён
- engine_damaged_01.wav
- engine_damaged_02.wav
- engine_damaged_03.wav
- engine_damaged_04.wav
- engine_damaged_05.wav
Engine_destroyed
Двигатель выведен из строя
- engine_destroyed_01.wav
- engine_destroyed_02.wav
- engine_destroyed_03.wav
Engine_functional
Двигатель частично восстановлен, можно ехать
- engine_functional_01.wav
- engine_functional_02.wav
Fire_started
Танк горит
- fire_started_01.wav
- fire_started_02.wav
Fire_stopped
Пожар потушен
- fire_stopped_01.wav
- fire_stopped_02.wav
- fire_stopped_03.wav
Fuel_tank_damaged
Бак повреждён
- fuel_tank_damaged_01.wav
- fuel_tank_damaged_02.wav
- fuel_tank_damaged_03.wav
- fuel_tank_damaged_04.wav
Gun_damaged
Орудие повреждено
- gun_damaged_01.wav
- gun_damaged_02.wav
- gun_damaged_03.wav
- gun_damaged_04.wav
Gun_destroyed
Орудие выведено из строя, стрельба невозможна
- gun_destroyed_01.wav
- gun_destroyed_02.wav
- gun_destroyed_03.wav
Gun_functional
Орудие частично восстановлено, можно стрелять
- gun_functional_01.wav
- gun_functional_02.wav
- gun_functional_03.wav
- gun_functional_04.wav
Gunner_killed
Наводчик ранен
- gunner_killed_01.wav
- gunner_killed_02.wav
- gunner_killed_03.wav
Loader_killed
Заряжающий ранен
- loader_killed_01.wav
- loader_killed_02.wav
Radio_damaged
Рация повреждена
(НЕ ЗАДЕЙСТВОВАНА В ИГРЕ)[МОЖНО ПРОПУСТИТЬ]
- radio_damaged_01.wav
- radio_damaged_02.wav
- radio_damaged_03.wav
- radio_damaged_04.wav
- radio_damaged_05.wav
Radioman_killed
Радист ранен
(НЕ ЗАДЕЙСТВОВАНА В ИГРЕ)[МОЖНО ПРОПУСТИТЬ]
Start_battle
Бой начинается
- start_battle_01.wav
- start_battle_02.wav
- start_battle_03.wav
- start_battle_04.wav
- start_battle_05.wav
- start_battle_06.wav
- start_battle_07.wav
- start_battle_08.wav
Surveying_devices_damaged
Приборы наблюдения повреждены
- surveying_devices_damaged_01.wav
- surveying_devices_damaged_02.wav
- surveying_devices_damaged_03.wav
- surveying_devices_damaged_04.wav
- surveying_devices_damaged_05.wav
Surveying_devices_destroyed
Приборы наблюдения выведены из строя
- surveying_devices_destroyed_01.wav
- surveying_devices_destroyed_02.wav
- surveying_devices_destroyed_03.wav
- surveying_devices_destroyed_04.wav
- surveying_devices_destroyed_05.wav
- surveying_devices_destroyed_06.wav
Surveying_devices_functional
Приборы наблюдения восстановлены
- surveying_devices_functional_01.wav
- surveying_devices_functional_02.wav
- surveying_devices_functional_03.wav
- surveying_devices_functional_04.wav
- surveying_devices_functional_05.wav
- surveying_devices_functional_06.wav
Track_cut
Гусеница сбита, можем откатиться
- track_destroyed_cut_01.wav
Track_damaged
Повреждение гусеницы
- track_damaged_01.wav
- track_damaged_02.wav
- track_damaged_03.wav
- track_damaged_04.wav
Track_destroyed
Гусеница сбита, движение невозможно
- track_destroyed_01.wav
- track_destroyed_02.wav
- track_destroyed_03.wav
- track_destroyed_04.wav
Track_functional
Гусеница восстановлена
- track_functional_01.wav
- track_functional_02.wav
- track_functional_03.wav
- track_functional_04.wav
Track_functional_can_move
Гусеница восстановлена, можно ехать
- track_functional_can_move_01.wav
- track_functional_can_move_02.wav
- track_functional_can_move_03.wav
- track_functional_can_move_04.wav
- track_functional_can_move_05.wav
Turret_rotator_damaged
Башня повреждена, скорость поворота башни снижена
- turret_rotator_damaged_01.wav
- turret_rotator_damaged_02.wav
Turret_rotator_destroyed
Башня выведена из строя, вращение невозможно
- turret_rotator_destroyed_01.wav
- turret_rotator_destroyed_02.wav
Turret_rotator_functional
Башня частично восстановлена, скорость вращения снижена
- turret_rotator_functional_01.wav
- turret_rotator_functional_02.wav
Vehicle_destroyed
Танк уничтожен
- vehicle_destroyed_01.wav
- vehicle_destroyed_02.wav
- vehicle_destroyed_03.wav
Wwise-voice-wot-blitz
Исходный код проекта WWISE для создания озвучки экипажа к игре World of Tanks Blitz
Данный проект поможет сделать вам свою озвучку к игре World of Tanks Blitz с помощью программы Audiokinetic WWISE
Данный проект WWISE хорошо функционирует с версией: 2022.2.9.7459
Как создать свою озвучку:
- Скачиваем WWISE Launcher из официального сайта аудиодвижка
- Устанавливаем WWISE Launcher
- Запускаем WWISE Launcher
- В WWISE Launcher выбираем пункт WWISE (второй с левого ряда)
- В пункте INSTALL NEW VERSION из пункта Latest выбираем пункт All
- Справа от All меняем 2021.1 на 2022.2
- Справа от 2022.2 выбираем версию WWISE 2022.2.9.7459
- После выбранной версии нажимаем снизу на кнопку Install…
- После установки открываем Загрузки в Проводнике
- Распаковываем WWISE VOICE WOT BLITZ проект полностью (лучше в удобное место)
- Открываем двумя быстрыми кликами файл WOTB_WWISE_VOICE.wproj
- После открытия открываем пункт Audio
и открываем Actor-Mixer Hierarchy
Дальше открываем Default Work Unit
Теперь открываем voice и тут много контейнеров, в них мы должны вставить аудиофайлы, вот их список:
(К фразам идёт название аудиофайла и его формат, фразу сохраняем под нужным названием и форматом)
(Просто перенесите аудиофайл из папки в программу под нужный контейнер, она сама настроит его(если под правильным названием и форматом))