В последнем обновлении Brawl Stars из игры внезапно пропали... ящики?Да, они самые! Но пропали они из редактора карт в столкновении: просто нет их там больше и всё. Как обычно бывает, сначала мне пожаловались на эту проблему в Null's Brawl, а потом довольно быстро стало понятно — это не я сломал, это снова Supercell
😇В целом, мне бы хотелось сразу сказать — редактор карт в игре сделан максимально отвратно. От начала и до конца. Настолько плохо, что и сами разработчики не спешат это лишний раз трогать, ибо себе дороже
😑И так, начнем с того, что у каждого режима есть свои особенные блоки или сущности, такие как ящики в ШД или, условно, второстепенные точки респавна в Бравлмячике. Для того, чтобы показывать лишь нужные блоки в нужном режиме, ребята определили в коде функцию,
MapEditorHUD.tileVisibleForMode(LogicTileData const*)
, которая возвращает true (1), если блок доступен в данном режиме
🙂При этом игровой режим для данной функции не является аргументом, она получала его сама из полей объекта-синглтона
MapEditorScreen. И далее логика данной функции была похожа на что-то такое (до v58):
int gamemode = MapEditorScreen.instance.gamemode;
/* ... */
if (tile == LogicDataTables.getCrateTileData()) {
return (gamemode == 6 || gamemode == 9);
}
/* ... */
Однако помните, что в последнем обновлении ребята начали использовать информацию о режимах из ресурсов игры (game_mode_variations.csv)? Для этого они наравне с числовым ID режима (
int gamemode) начинают использовать также объект
GameModeVariationData. Соответствующее поле появляется в клиентской (
LogicBattleModeClient) и серверной (
LogicBattleModeServer) логике боев, а также — в нашем любимом
MapEditorScreen.
И теперь код начинает выглядеть как-то так (начиная с v59):
int gamemode = MapEditorScreen.instance.gamemode;
GameModeVariationData gmvData = MapEditorScreen.instance.gmvData;
/* ... */
if (tile == LogicDataTables.getCrateTileData()) {
return (gmvData != null && gmvData.playersCollectPowerBuffs);
}
/* ... */
И казалось бы, всё хорошо? Стало лучше и красивее? Да, но... я же говорил, что ребята не трогают лишний раз редактор карт? Именно поэтому в функции
MapEditorScreen.enter()
, там где они всегда присваивали значение полю
gamemode, они вовсе забыли про
gmvData, в котором всегда оставался nullptr.
Ах да, забыли причем ровно на половину — ведь у них там есть ветвление, и в одной части (которая выполняется, кажется, при очень специфических условиях, в которые я не вникал) ставится таки оба поля, но в другой — по старому, лишь одно
😴На самом деле, данный анализ было бы сложно провести без Frida. Например, именно с помощью нее я довольно быстро понял, что поле не выставляется вовсе. Да и исправляется проблема тоже всего лишь интерцептором на нужную функцию, добавляющий код, о котором забыли Supercell. Вот он, кстати, на скрине к посту прикреплен
👍