Подпишитесь на наш Telegram-канал, чтобы всегда быть в курсе важных обновлений! Перейти

Вопрос I wanna understand what is the C_DOTAGamerules ?

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
11 Фев 2023
Сообщения
159
Реакции
4
hey guys i wanna understand what is C_DOTAGamerules and how can i get it and is it the class the handles the game data such as ( m_nHeroPickState , m_iGameMode, m_hGameModeEntity ,m_iCreepUpgradeState , m_fGoodGlyphCooldown , m_fBadGlyphCooldown )
etc.... ??
 
hey guys i wanna understand what is C_DOTAGamerules and how can i get it and is it the class the handles the game data such as ( m_nHeroPickState , m_iGameMode, m_hGameModeEntity ,m_iCreepUpgradeState , m_fGoodGlyphCooldown , m_fBadGlyphCooldown )
etc.... ??
it's a structure that defines... the game's rules... such as the gamemode(all pick turbo ability draft etc), gamestate(hero selection, pregame, ingame), and all kinds of other settings. you can get it by checking xrefs to _g_pGameRules in client.dylib and then correlating that with client.dll, or by extracting it from C_DOTAGamerulesProxy which is an entity with m_designerName: dota_gamerules
 
what if i wanna extract the ready game id before accepting to the game it might not be through the C_DOTAGamerules OR C_DOTAGamerulesProxy but i wanna get the game id and the game players ids etc .....

how can i do that ?
 
Последнее редактирование:
what if i wanna extract the ready game id before accepting to the game it might not be through the C_DOTAGamerules OR C_DOTAGamerulesProxy but i wanna get the game id and the game players ids etc .....

how can i do that ?
earlier it could be done with protobufs but not via netchan but rather via gamecoordinator(netchan is in-match communication, gamecoordinator is out-of-match communication(such as finding matches, inventory, etc.))(they send you a lobby(CSODOTAStaticLobby or CSODOTALobby or something? don't remember) but it's currently mostly empty, used to be full of data). but they partially fixed it(they don't send that data anymore, at least normally), it's not possible anymore through naive, obvious means(or at least wasn't, last time I checked) - you'll have to explore on your own
 
Последнее редактирование:
so overall can be used for doing CMSG things right ?
u can find the command of pick whatever hero u want even if u are on a new play account
etc ... ?
1) hero selection is in-match communication, unrelated to gamecoordinator(basically gamecoordinator = dashboard only)
2) hero selection actually happens via input commands(something like console commands, but they get sent to the server instead of actually getting executed in the console. "dota_select_hero npc_dota_hero_antimage" for example is one such "fake console command" - if you type it into the console, it will get sent to the server(all commands, all the shit you type into the console gets sent to the server by default, unless it's an actual console command registered as such on the client)), no protobufs
 
how can i get the game coordinator ? i wanna que , invite friends , accept game , etc .....
try searching this forum for terms "ISteamGameCoordinator", "ProtoBufMsgHeader_t", "CGCClient"
but implementing all of that is going to be a lot more complicated than you think.
just use already existing in-game wrapper-functions for that.
 
i already got the CGCClient but i dont know how can i start the match making iam trying to dig around if u can redirect me it would be awesome <3
again, no need to touch CGCClient directly(that would be too difficult)
see CDOTA_DB_Play::StartFindingMatch and CDOTA_DB_Play::OnAcceptMatch
(check .dylib)
just use wrapper-functions that get invoked when you click on buttons in the UI, they'll do everything you need
 
again, no need to touch CGCClient directly(that would be too difficult)
see CDOTA_DB_Play::StartFindingMatch and CDOTA_DB_Play::OnAcceptMatch
(check .dylib)
just use wrapper-functions that get invoked when you click on buttons in the UI, they'll do everything you need
iam trying to understand the CGCClient so this cgcclient is the one responsible for getting the GetSOListeners and GetLobbyManager etc.... right ?

i found a code base that has something like this

GETTER(CUtlVector<ISharedObjectListener*>, GetSOListeners, 0x270);
IGETTER(CDOTAGCClientLobbyManager, GetLobbyManager, 0x700);

but when i tried to find this data inside the CGCClient itself i didnt find it

did it got removed ?
 
iam trying to understand the CGCClient so this cgcclient is the one responsible for getting the GetSOListeners and GetLobbyManager etc.... right ?

i found a code base that has something like this

GETTER(CUtlVector<ISharedObjectListener*>, GetSOListeners, 0x270);
IGETTER(CDOTAGCClientLobbyManager, GetLobbyManager, 0x700);

but when i tried to find this data inside the CGCClient itself i didnt find it

did it got removed ?
offsets is changed or you are not in the lobby
 
iam trying to understand the CGCClient so this cgcclient is the one responsible for getting the GetSOListeners and GetLobbyManager etc.... right ?

i found a code base that has something like this

GETTER(CUtlVector<ISharedObjectListener*>, GetSOListeners, 0x270);
IGETTER(CDOTAGCClientLobbyManager, GetLobbyManager, 0x700);

but when i tried to find this data inside the CGCClient itself i didnt find it

did it got removed ?
yes, CGCClient(game coordinator client) is responsible for managing/interacting with shared objects(shared, as in shared between the client and the server) (lobbies are shared objects too)
don't expect something that's X years old to be 100% relevant today. these members are probably still there, just at a (hopefully) slightly different offset(and yes, for lobby data you obviously need to be in a lobby) - look around in reclass(it displays RTTI) and maybe you'll find something.
but again, there are ready-made high-level wrapper functions that dota itself uses, CGCClient is relatively low-level stuff
 
ok i found this CDOTA_DB_Play::StartFindingMatch in the dylib but i dont know how can i get it in the actual client.dll ? its not string OR class or anything how can i find it then ?
find xrefs to it(or the stuff invoked inside of it), and all kinds of string xrefs around/inside it and correlate with client.dll
StartFindingMatch has the string xref "No gamemodes selected" inside, for example. just find "No gamemodes selected" in client.dll and hopefully the function that contains that string xref is CDOTA_DB_Play::StartFindingMatch. you can then place a breakpoint, see how it's invoked(it should be invoked by CDOTA_DB_Play::StartFindingMatch(when you click the PLAY DOTA button in the main menu) which takes less parameters and thus is easier for you to work with) etc.
 
ok i found this CDOTA_DB_Play::StartFindingMatch in the dylib but i dont know how can i get it in the actual client.dll ? its not string OR class or anything how can i find it then ?
client.dll "40 55 48 83 EC 20 48 8B E9 48 8D 15 ? ? ? ? 48 8D 4C 24 ? E8 ? ? ? ? 48 8B 4D 08 0F B7 54 24 ? 48 8B 01 FF 90 ? ? ? ? 84 C0 0F 85 ? ? ? ? 48 89 5C 24 ? 48 89 74 24 ? 33 F6 48 89 7C 24 ? 33 FF 48 C7 85"
this function contains everything that is the same at first glance as the function from the libclient, but I can’t say for sure that it is the same
 
I found it and when i take the
C++:
Expand Collapse Copy
__int64 __fastcall StartFindingMatch(__int64 a1)
{
  __int64 result; // rax
  unsigned int v3; // esi
  unsigned int v4; // edi
  __int64 v5; // rbx
  unsigned int *v6; // rax
  unsigned int *v7; // rax
  __int64 v8; // rax
  __int64 v9; // rbx
  __int64 v10; // rax
  int *v11; // rax
  unsigned int *v12; // rax
  unsigned __int16 v13; // [rsp+30h] [rbp+8h] BYREF

  sub_182E5FA00(&v13, "FindMsgInFlight");
  result = (*(__int64 (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 8) + 1240LL))(*(_QWORD *)(a1 + 8), v13);
  if ( !(_BYTE)result )
  {
    v3 = 0;
    v4 = 0;
    *(_QWORD *)(a1 + 328) = 0;
    v5 = sub_182816510();
    sub_18280E490(v5);
    if ( *(int *)(v5 + 32) <= 0 )
    {
      switch ( *(_DWORD *)(a1 + 272) )
      {
        case 0:
          v7 = (unsigned int *)sub_1830705D0(&unk_18548BBB0, 0xFFFFFFFFLL);
          if ( !v7 )
            v7 = *(unsigned int **)(qword_18548BBB8 + 8);
          v4 = *v7;
          break;
        Case 1:
        Case 9:
          v6 = (unsigned int *)sub_1830705D0(&unk_18548BBC0, 0xFFFFFFFFLL);
          if ( !v6 )
            v6 = *(unsigned int **)(qword_18548BBC8 + 8);
          v3 = 4;
          v4 = *v6;
          if ( *(_BYTE *)(a1 + 464) && *(_DWORD *)(a1 + 460) && *(_DWORD *)(a1 + 460) != *(_DWORD *)sub_182553200() )
            *(_DWORD *)sub_182553200() = *(_DWORD *)(a1 + 460);
          break;
        Case 2:
          v4 = 2;
          v3 = 1;
          break;
        Case 3:
          v4 = 0x80000;
          v3 = 7;
          break;
        Case 7:
          v8 = sub_181B87180();
          v9 = *(_QWORD *)(v8 + 1656);
          if ( v9 && (unsigned int)sub_181B84010(*(_QWORD *)(v8 + 1656)) == 1 && !(unsigned int)sub_181B84050(v9) )
          {
            v10 = sub_1823E5A70();
            sub_1823FA9E0(v10, 0);
          }
          v4 = 2;
          v3 = 12;
          break;
        case 0xB:
          v3 = 14;
          break;
        default:
          break;
      }
    }
    else
    {
      v3 = 5;
    }
    v11 = (int *)sub_1830705D0(&unk_18548BBE0, 0xFFFFFFFFLL);
    if ( !v11 )
      v11 = *(int **)(qword_18548BBE8 + 8);
    if ( *v11 >= 0 )
    {
      v12 = (unsigned int *)sub_1830705D0(&unk_18548BBE0, 0xFFFFFFFFLL);
      if ( !v12 )
        v12 = *(unsigned int **)(qword_18548BBE8 + 8);
      v3 = *v12;
    }
    sub_1820BFED0(a1, v3, v4, 0);
    return sub_1820C22A0(a1, 0);
  }
  return result;
}


i have renamed the function from sub_1820C6510 to StartFindingMatch

here is the signature i got using fusion plugin in ida
signature : 40 55 48 83 EC ? 48 8B E9 48 8D 15 ? ? ? ? 48 8D 4C 24


but the address of it was sub_1820C6510 and to get it by address u need to client.dll + 20C6510 in cheatengine
i installed breakpoint there in this location client.dll + 20C6510 then when i search for the game nothing fires
i just wanted to debug it to make sure that it is correct and check the argument that needs to be sent
 
Последнее редактирование:
I found it and when i take the
C++:
Expand Collapse Copy
__int64 __fastcall StartFindingMatch(__int64 a1)
{
  __int64 result; // rax
  unsigned int v3; // esi
  unsigned int v4; // edi
  __int64 v5; // rbx
  unsigned int *v6; // rax
  unsigned int *v7; // rax
  __int64 v8; // rax
  __int64 v9; // rbx
  __int64 v10; // rax
  int *v11; // rax
  unsigned int *v12; // rax
  unsigned __int16 v13; // [rsp+30h] [rbp+8h] BYREF

  sub_182E5FA00(&v13, "FindMsgInFlight");
  result = (*(__int64 (__fastcall **)(_QWORD, _QWORD))(**(_QWORD **)(a1 + 8) + 1240LL))(*(_QWORD *)(a1 + 8), v13);
  if ( !(_BYTE)result )
  {
    v3 = 0;
    v4 = 0;
    *(_QWORD *)(a1 + 328) = 0;
    v5 = sub_182816510();
    sub_18280E490(v5);
    if ( *(int *)(v5 + 32) <= 0 )
    {
      switch ( *(_DWORD *)(a1 + 272) )
      {
        case 0:
          v7 = (unsigned int *)sub_1830705D0(&unk_18548BBB0, 0xFFFFFFFFLL);
          if ( !v7 )
            v7 = *(unsigned int **)(qword_18548BBB8 + 8);
          v4 = *v7;
          break;
        Case 1:
        Case 9:
          v6 = (unsigned int *)sub_1830705D0(&unk_18548BBC0, 0xFFFFFFFFLL);
          if ( !v6 )
            v6 = *(unsigned int **)(qword_18548BBC8 + 8);
          v3 = 4;
          v4 = *v6;
          if ( *(_BYTE *)(a1 + 464) && *(_DWORD *)(a1 + 460) && *(_DWORD *)(a1 + 460) != *(_DWORD *)sub_182553200() )
            *(_DWORD *)sub_182553200() = *(_DWORD *)(a1 + 460);
          break;
        Case 2:
          v4 = 2;
          v3 = 1;
          break;
        Case 3:
          v4 = 0x80000;
          v3 = 7;
          break;
        Case 7:
          v8 = sub_181B87180();
          v9 = *(_QWORD *)(v8 + 1656);
          if ( v9 && (unsigned int)sub_181B84010(*(_QWORD *)(v8 + 1656)) == 1 && !(unsigned int)sub_181B84050(v9) )
          {
            v10 = sub_1823E5A70();
            sub_1823FA9E0(v10, 0);
          }
          v4 = 2;
          v3 = 12;
          break;
        case 0xB:
          v3 = 14;
          break;
        default:
          break;
      }
    }
    else
    {
      v3 = 5;
    }
    v11 = (int *)sub_1830705D0(&unk_18548BBE0, 0xFFFFFFFFLL);
    if ( !v11 )
      v11 = *(int **)(qword_18548BBE8 + 8);
    if ( *v11 >= 0 )
    {
      v12 = (unsigned int *)sub_1830705D0(&unk_18548BBE0, 0xFFFFFFFFLL);
      if ( !v12 )
        v12 = *(unsigned int **)(qword_18548BBE8 + 8);
      v3 = *v12;
    }
    sub_1820BFED0(a1, v3, v4, 0);
    return sub_1820C22A0(a1, 0);
  }
  return result;
}


i have renamed the function from sub_1820C6510 to StartFindingMatch

here is the signature i got using fusion plugin in ida
signature : 40 55 48 83 EC ? 48 8B E9 48 8D 15 ? ? ? ? 48 8D 4C 24


but the address of it was sub_1820C6510 and to get it by address u need to client.dll + 20C6510 in cheatengine
i installed breakpoint there in this location client.dll + 20C6510 then when i search for the game nothing fires
i just wanted to debug it to make sure that it is correct and check the argument that needs to be sent
update your dota(if you haven't already) and re-open the new dll in ida(or just don't use it at all, most of the stuff can be done directly in x64dbg or cheat engine or whatever else). the dll you analyzed is outdated
it's not 20C6510 anymore, it's 20C6530(client.dll - sha1: 377f3f21be0d9d4216f43d3755f7df6ab7ba8b0d timestamp: 1761161544(19:32:24 22 Oct 2025))
 
Назад
Сверху Снизу