Вопрос Авто выбор героя

Новичок
Новичок
Статус
Оффлайн
Регистрация
5 Фев 2020
Сообщения
3
Реакции
0
Здравствуйте!

Подскажите, пожалуйста, какая функция отвечает за выбор героя в Dota 2 на стадии пика (all pick)? Например, чтоб выбрать C_DOTA_Unit_Hero_DrowRanger

Я пытался искать через x64dbg, но находил только функции, связанные с обновлением UI игрока. Также пробовал проходить по всему EntityList, но находил только PlayerController всех игроков

Буду очень признателен за любую подсказку или направление!
 
Здравствуйте!

Подскажите, пожалуйста, какая функция отвечает за выбор героя в Dota 2 на стадии пика (all pick)? Например, чтоб выбрать C_DOTA_Unit_Hero_DrowRanger

Я пытался искать через x64dbg, но находил только функции, связанные с обновлением UI игрока. Также пробовал проходить по всему EntityList, но находил только PlayerController всех игроков

Буду очень признателен за любую подсказку или направление!
dota_select_hero команда на сервер отправляется. консольные команды(то что ты в консоль вводишь), которые не имеют коллбека на клиенте(т.е. незнакомые клиенту), отправляются на сервер.
просто скорми "dota_select_hero npc_dota_hero_drow_ranger" консольке. поищи в клиенте строки типа "dota_select_hero блаблабла" и посмотри куда там эти строки потом передаются(там чето типо CEngineClient::ClientCmd).
 
Интерфейс InputService_001 в engine2.dll
25 индекс CmdCommand
InputService->CmdCommand(("dota_select_hero " + name_hero).c_str());
поаккуратней ток с такими конструкциями(.data()/.c_str() и т.д. на временном объекте), особенно новичкам лучше такое не повторять.
All temporary objects are destroyed as the last step in evaluating the
Пожалуйста, авторизуйтесь для просмотра ссылки.
that (lexically) contains the point where they were created, and if multiple temporary objects were created, they are destroyed in the order opposite to the order of creation. This is true even if that evaluation ends in throwing an exception.
в данном случае все норм - вся строчка кода является full-expression(красным выделено(зеленым выделено подвыражение(на самом деле там в этом зелёном ещё подвыражение ("dota_select_hero " + name_hero) есть но я не стал выделять, сути не меняет)))(грубо говоря full-expression это то, после чего нужно ставить точку с запятой(ну разве что в условиях в if и подобных конструкциях она не ставится), т.е. полноценное и полностью законченное выражение которое не является частью какого-либо другого выражения(т.е. является частью конструкции(например, блока кода)) - в общем это фулл строка кода(или несколько строк) от первой буквы до точки с запятой(если она должна ставиться в данной конструкции)). все временные объекты внутри full-expression(и его подвыражений) гарантированно живут до конца этого full-expression(а не подвыражения) (т.е. их уничтожение будут как бы "следующей" строчкой кода после точки с запятой)(т.е. временная переменная из зелёного(точнее синего но не суть) спокойно доживёт до конца красного(там где точка с запятой), и к концу зелёного(точнее синего, но и зелёного тоже) еще не умрёт(это ко всем подвыражениям относится, временные переменные в них все умирают только после full-expression которое их содержит, т.е. они способны прожить гораздо дольше чем позволяет их непосредственный масштаб(подвыражение))), но если разделить это на два отдельных full-expression(например сохранить этот указатель(на буффер временной строки, которая сдохнет после точки с запятой) в переменную и потом юзать эту переменную в других full-expression) - будет больно, но в теории компилятор и другие тулзы для статического анализа должны о такой хуйне(ну конкретно в данном случае все норм т.к. тут токо одно full-expression) предупреждать если они смогут это задетектить(поэтому варнинги надо включать на максимум в компиляторе и ставить им критичность как у ошибок чтобы не компилило с варнингами(там можно отключить анализ для внешних файлов типа чужих либ и т.д. в настройках)). но в любом случае лучше не трогать такие вещи, особенно начинающим, чтобы не было сюрпризов
 
поаккуратней ток с такими конструкциями(.data()/.c_str() и т.д. на временном объекте), особенно новичкам лучше такое не повторять.

в данном случае все норм - вся строчка кода является full-expression(красным выделено(зеленым выделено подвыражение(на самом деле там в этом зелёном ещё подвыражение ("dota_select_hero " + name_hero) есть но я не стал выделять, сути не меняет)))(грубо говоря full-expression это то, после чего нужно ставить точку с запятой(ну разве что в условиях в if и подобных конструкциях она не ставится), т.е. полноценное и полностью законченное выражение которое не является частью какого-либо другого выражения(т.е. является частью конструкции(например, блока кода)) - в общем это фулл строка кода(или несколько строк) от первой буквы до точки с запятой(если она должна ставиться в данной конструкции)). все временные объекты внутри full-expression(и его подвыражений) гарантированно живут до конца этого full-expression(а не подвыражения) (т.е. их уничтожение будут как бы "следующей" строчкой кода после точки с запятой)(т.е. временная переменная из зелёного(точнее синего но не суть) спокойно доживёт до конца красного(там где точка с запятой), и к концу зелёного(точнее синего, но и зелёного тоже) еще не умрёт(это ко всем подвыражениям относится, временные переменные в них все умирают только после full-expression которое их содержит, т.е. они способны прожить гораздо дольше чем позволяет их непосредственный масштаб(подвыражение))), но если разделить это на два отдельных full-expression(например сохранить этот указатель(на буффер временной строки, которая сдохнет после точки с запятой) в переменную и потом юзать эту переменную в других full-expression) - будет больно, но в теории компилятор и другие тулзы для статического анализа должны о такой хуйне(ну конкретно в данном случае все норм т.к. тут токо одно full-expression) предупреждать если они смогут это задетектить(поэтому варнинги надо включать на максимум в компиляторе и ставить им критичность как у ошибок чтобы не компилило с варнингами(там можно отключить анализ для внешних файлов типа чужих либ и т.д. в настройках)). но в любом случае лучше не трогать такие вещи, особенно начинающим, чтобы не было сюрпризов
const char* cmd = ("dota_select_hero " + name_hero).c_str();
InputService->CmdCommand(cmd);
Будет хуже
 
const char* cmd = ("dota_select_hero " + name_hero).c_str();
InputService->CmdCommand(cmd);
Будет хуже
да, там два full-expression, и зелёное умирает после конца красного, т.е. к моменту синего оно уже дохлое и трогать его нельзя(а cmd сохранила себе указатель на оперативную память из-под этой дохлой строки, которая уже подчистилась к моменту синего)
при чём
C++:
Expand Collapse Copy
const char* cmd;
cmd = ("dota_select_hero " + name_hero).c_str(), InputService->CmdCommand(cmd);
будет работать нормально)
потому что там в пределах одного full-expr(которое второе. первое const char* cmd; это тоже full-expr но там ничего не используется) эта временная строка создаётся и используется, т.к. запятая это operator comma(он просто возвращает самый правый аргумент из списка), т.е. код на самом деле
C++:
Expand Collapse Copy
operator comma(cmd = ("dota_select_hero " + name_hero).c_str(), printf(cmd));
а это одно целое выражение(не важно какая там вложенность подвыражений - вызов функции внутри вызова функции внутри вызова функции не суть, всё равно всё что создавалось будет жить до точки с запятой)
ну и можно ещё упомянуть что в С++(это от С досталось к сожалению) в стандарте не прописан порядок выполнения подвыражений(за исключением некоторых стандартных операторов(comma(,) или логических например || && и т.д.), но только непосредственно в пределах подвыражения), т.е. когда компилятор видит код типа
printf("%d %d", printf("a"), printf("b"));
он может сначала сгенерить выполнение второго подвыражения(принт а), потом третьего(принт б), т.е. слева-направо как нам привычно(так clang генерит например)(этот код "ab1 1" выведет в консоль на кленге)
а может и наоборот сначала третье(принт б) потом второе(принт а) - так например MSVC(visual studio)(и gcc тоже) генерит(этот код "ba1 1" выведет в консоль на мсвс и гсс)
а может и любой другой порядок использовать(если выражений много), как захочет(ну естественно там не просто так эти решения принимаются, компилятор может выбрать какойто вариант потому что там удобнее регистры аллоцируются при генерации кода и так далее)(собирает подвыражения в выражения то конечно в правильном порядке в итоге, да, то есть аргументы компилятор местами не путает, но вот в каком порядке он их будет "вычислять" это не прописано в стандарте), т.е. С++ это не совсем "слева-направо"(компилятор из соображений оптимизации может в разном порядке генерить выполнение подвыражений, т.е. поменять местами подвыражения в коде). слева-направо гарантируется только с некоторыми операторами и то в пределах подвыражения
printf("%d %d", (printf("a"), printf("b")), (printf("c"), printf("d")));
тут внутри (printf("a"), printf("b")) гарантирован порядок(это comma operator) и внутри (printf("c"), printf("d")), т.е. ba или dc никогда не выведет, но вот в каком порядке сами эти подвыражения будут(сначала ab или сначала cd) - компилятор как хочет так и решает
поэтому в выражениях типа
array[i] = i++;
т.е.
operator=(operator[](array, i), operator++(i, int{}));
всё будет плохо(ну там начиная с С++17 вроде конкретно в данном случае порядок гарантирован но это не распространяется на более сложные выражения, это еще относительно простой пример.) - может сначала второе подвыражение запуститься(i++) а может сначала первое(array [ i ]). и работать такой код на разных компиляторах(и даже на одном и том же, и даже в пределах одной программы) будет по-разному(т.е. может записать в array[0] а может записать в array[1] - такой код не надо писать иначе будет пизда)
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Последнее редактирование:
Назад
Сверху Снизу