Смотрите видео ниже, чтобы узнать, как установить наш сайт в качестве веб-приложения на домашнем экране.
Примечание: Эта возможность может быть недоступна в некоторых браузерах.
cl_showents(CCommandContext const&, CCommand const&)
// #STR: "(missing),", "(missing)", "Ent %3d: %s class %s\n"
__int64 cl_showents()
{
unsigned int v0; // ebx
__int64 v1; // rax
_QWORD *v2; // rax
char v4; // [rsp+0h] [rbp-230h]
char v5; // [rsp+100h] [rbp-130h]
if ( (signed int)CGameEntitySystem::GetHighestEntityIndex(g_pGameEntitySystem) >= 0 )
{
v0 = -1;
do
{
v1 = CGameEntitySystem::GetBaseEntity((__int64)g_pGameEntitySystem, ++v0);
if ( v1 )
{
v5 = 0;
v2 = (_QWORD*)(* (__int64 (__fastcall**)(__int64, _QWORD))( *(_QWORD *)v1 + 240LL))(v1, v0);
V_snprintf(&v4, 256, "'%s'", *v2);
ConMsg("Ent %3d: %s class %s\n", v0, &v5, &v4);
}
else
{
V_snprintf(&v5, 256, "(missing), ");
V_snprintf(&v4, 256, "(missing)");
}
}
while ( (signed int)v0 < (signed int)CGameEntitySystem::GetHighestEntityIndex(g_pGameEntitySystem) );
}
return __stack_chk_guard;
}
00007FFDAB25D890 | 8B81 30150000 | mov eax,dword ptr ds:[rcx+1530] |
00007FFDAB25D896 | 8902 | mov dword ptr ds:[rdx],eax |
00007FFDAB25D898 | 48:8BC2 | mov rax,rdx |
00007FFDAB25D89B | C3 | ret |
something like this ?
hooking is when you intercept someone else's(the game's) invocation of a function(in an attempt to observe/modify the game's behavior(react to the game performing some action or lie to the game about something)). basically a callback but forcefully installed. why would you need to hook this?Посмотреть вложение 294121
is it function needs to be hooked or 2100h is the new offset for highest entityindex ?
// #STR: "Ent %5d: class %s name \"%s\"\n"
unsigned int sub_18136E1C0()
{
__int64 Ent; // r14
int v1; // edx
__int64 v2; // rcx
__int64 v3; // rsi
int v4; // eax
int v5; // edi
int v6; // eax
__int64 v7; // rdx
int v8; // ebx
__int64 v9; // r8
int v10; // eax
char *EntInstance; // r14
char *v12; // r15
__int64 Entity; // rsi
const char *entName; // rdi
const char *className; // rbx
unsigned int result; // eax
char v17[24]; // [rsp+20h] [rbp-E0h] BYREF
void **v18; // [rsp+38h] [rbp-C8h] BYREF
int v19; // [rsp+40h] [rbp-C0h]
char *EntityInstance; // [rsp+48h] [rbp-B8h] BYREF
unsigned int v21; // [rsp+50h] [rbp-B0h]
int v22; // [rsp+54h] [rbp-ACh]
char v23[8200]; // [rsp+58h] [rbp-A8h] BYREF
unsigned int entIndex; // [rsp+2090h] [rbp+1F90h] BYREF
EntityInstance = 0i64;
v21 = 1024;
v22 = 0x80000000;
if ( (&EntityInstance & 7) != 0 )
sub_182E7E4D0();
EntityInstance = v23;
v19 = 0;
sub_182A80FC0(v17, &v18, 0i64);
v18 = &CDefaultTypedEntityInstanceFilter<C_BaseEntity>::`vftable';
for ( Ent = sub_182A8B5A0(v17); Ent; Ent = sub_182A8F8F0(v17) )
{
v1 = v19;
v2 = v21;
v3 = v19;
if ( v19 != v21 || (v4 = v22, (v22 & 0x40000000) != 0) )
{
v9 = EntityInstance;
}
else
{
if ( v21 == 0x7FFFFFFF )
{
UtlMemory_FailedAllocation(0x7FFFFFFFi64, 1i64);
v4 = v22;
v2 = v21;
}
v5 = v2 + 1;
v6 = UtlMemory_CalcNewAllocationCount(v2, v4 & 0x3FFFFFFF, (v2 + 1), 8i64);
v8 = v6;
if ( v6 < v5 )
{
if ( v6 || v5 > -1 )
{
do
{
v7 = ((v8 + v5) >> 31);
v8 = (v8 + v5) / 2;
}
while ( v8 < v5 );
}
else
{
v8 = -1;
}
}
LOBYTE(v7) = (v22 & 0xC0000000) == 0;
v9 = UtlMemory_Alloc(EntityInstance, v7, 8i64 * v8, 8i64 * v21);
EntityInstance = v9;
if ( (v22 & 0xC0000000) != 0 )
v22 &= 0x3FFFFFFFu;
v1 = v19;
v21 = v8;
}
v19 = v1 + 1;
*(v9 + 8 * v3) = Ent;
}
v10 = v19;
if ( v19 > 1 )
{
V_qsort(EntityInstance, v19, 8i64, sub_181358FA0);
v10 = v19;
}
EntInstance = EntityInstance;
v12 = &EntityInstance[8 * v10];
if ( EntityInstance != v12 )
{
do
{
Entity = *EntInstance;
entName = &unk_182FB02FA;
if ( *(*(*EntInstance + 16i64) + 24i64) )
entName = *(*(*EntInstance + 16i64) + 24i64);
className = *((*(**EntInstance + 352i64))(*EntInstance) + 8);
sub_182AA0100(Entity, &entIndex);
ConMsg("Ent %5d: class %s name \"%s\"\n", entIndex, className, entName);
EntInstance += 8;
}
while ( EntInstance != v12 );
EntInstance = EntityInstance;
}
v19 = 0;
if ( (v21 & 0x80000000) != 0 || EntInstance == v23 )
{
result = v22;
}
else
{
if ( EntInstance && (v22 & 0xC0000000) == 0 )
(*(*g_pMemAlloc + 24i64))(g_pMemAlloc, EntInstance);
EntInstance = v23;
EntityInstance = v23;
result = v22 & 0x3FFFFFFF | 0x80000000;
v21 = 1024;
v22 = result;
}
if ( (result & 0xC0000000) == 0 )
{
if ( EntInstance )
return (*(*g_pMemAlloc + 24i64))(g_pMemAlloc, EntInstance);
}
return result;
}
They removed GetHighestEntityIndex. They have a different way of iterating all entities now
C++:// #STR: "Ent %5d: class %s name \"%s\"\n" unsigned int sub_18136E1C0() { __int64 Ent; // r14 int v1; // edx __int64 v2; // rcx __int64 v3; // rsi int v4; // eax int v5; // edi int v6; // eax __int64 v7; // rdx int v8; // ebx __int64 v9; // r8 int v10; // eax char *EntInstance; // r14 char *v12; // r15 __int64 Entity; // rsi const char *entName; // rdi const char *className; // rbx unsigned int result; // eax char v17[24]; // [rsp+20h] [rbp-E0h] BYREF void **v18; // [rsp+38h] [rbp-C8h] BYREF int v19; // [rsp+40h] [rbp-C0h] char *EntityInstance; // [rsp+48h] [rbp-B8h] BYREF unsigned int v21; // [rsp+50h] [rbp-B0h] int v22; // [rsp+54h] [rbp-ACh] char v23[8200]; // [rsp+58h] [rbp-A8h] BYREF unsigned int entIndex; // [rsp+2090h] [rbp+1F90h] BYREF EntityInstance = 0i64; v21 = 1024; v22 = 0x80000000; if ( (&EntityInstance & 7) != 0 ) sub_182E7E4D0(); EntityInstance = v23; v19 = 0; sub_182A80FC0(v17, &v18, 0i64); v18 = &CDefaultTypedEntityInstanceFilter<C_BaseEntity>::`vftable'; for ( Ent = sub_182A8B5A0(v17); Ent; Ent = sub_182A8F8F0(v17) ) { v1 = v19; v2 = v21; v3 = v19; if ( v19 != v21 || (v4 = v22, (v22 & 0x40000000) != 0) ) { v9 = EntityInstance; } else { if ( v21 == 0x7FFFFFFF ) { UtlMemory_FailedAllocation(0x7FFFFFFFi64, 1i64); v4 = v22; v2 = v21; } v5 = v2 + 1; v6 = UtlMemory_CalcNewAllocationCount(v2, v4 & 0x3FFFFFFF, (v2 + 1), 8i64); v8 = v6; if ( v6 < v5 ) { if ( v6 || v5 > -1 ) { do { v7 = ((v8 + v5) >> 31); v8 = (v8 + v5) / 2; } while ( v8 < v5 ); } else { v8 = -1; } } LOBYTE(v7) = (v22 & 0xC0000000) == 0; v9 = UtlMemory_Alloc(EntityInstance, v7, 8i64 * v8, 8i64 * v21); EntityInstance = v9; if ( (v22 & 0xC0000000) != 0 ) v22 &= 0x3FFFFFFFu; v1 = v19; v21 = v8; } v19 = v1 + 1; *(v9 + 8 * v3) = Ent; } v10 = v19; if ( v19 > 1 ) { V_qsort(EntityInstance, v19, 8i64, sub_181358FA0); v10 = v19; } EntInstance = EntityInstance; v12 = &EntityInstance[8 * v10]; if ( EntityInstance != v12 ) { do { Entity = *EntInstance; entName = &unk_182FB02FA; if ( *(*(*EntInstance + 16i64) + 24i64) ) entName = *(*(*EntInstance + 16i64) + 24i64); className = *((*(**EntInstance + 352i64))(*EntInstance) + 8); sub_182AA0100(Entity, &entIndex); ConMsg("Ent %5d: class %s name \"%s\"\n", entIndex, className, entName); EntInstance += 8; } while ( EntInstance != v12 ); EntInstance = EntityInstance; } v19 = 0; if ( (v21 & 0x80000000) != 0 || EntInstance == v23 ) { result = v22; } else { if ( EntInstance && (v22 & 0xC0000000) == 0 ) (*(*g_pMemAlloc + 24i64))(g_pMemAlloc, EntInstance); EntInstance = v23; EntityInstance = v23; result = v22 & 0x3FFFFFFF | 0x80000000; v21 = 1024; v22 = result; } if ( (result & 0xC0000000) == 0 ) { if ( EntInstance ) return (*(*g_pMemAlloc + 24i64))(g_pMemAlloc, EntInstance); } return result; }
[Console] Ent 242: class CDOTA_Item_TeleportScroll name "item_tpscroll"
[Console] Ent 16408: class CBaseModelEntity name "divine_ambient"
[Console] Ent 16409: class CPointCamera name "camera_1"
[Console] Ent 16418: class CParticleSystem name ""
for ( i = sub_2A8B710(v17); i; i = sub_2A8FA60(v17) )
{
v1 = v19;
v2 = v21;
v3 = v19;
if ( v19 != v21 || (v4 = v22, (v22 & 0x40000000) != 0) )
{
v9 = (__int64)v20;
}
else
{
if ( v21 == 0x7FFFFFFF )
{
UtlMemory_FailedAllocation(0x7FFFFFFFi64, 1i64);
v4 = v22;
v2 = v21;
}
v5 = v2 + 1;
v6 = UtlMemory_CalcNewAllocationCount(v2, v4 & 0x3FFFFFFF, (unsigned int)(v2 + 1), 8i64);
v8 = v6;
if ( v6 < v5 )
{
if ( v6 || v5 > -1 )
{
do
{
v7 = (unsigned int)((v8 + v5) >> 31);
v8 = (v8 + v5) / 2;
}
while ( v8 < v5 );
}
else
{
v8 = -1;
}
}
LOBYTE(v7) = (v22 & 0xC0000000) == 0;
v9 = UtlMemory_Alloc(v20, v7, 8i64 * v8, 8i64 * (int)v21);
v20 = (char *)v9;
if ( (v22 & 0xC0000000) != 0 )
v22 &= 0x3FFFFFFFu;
v1 = v19;
v21 = v8;
}
v19 = v1 + 1;
*(_QWORD *)(v9 + 8 * v3) = i;
}
v19: The current size (number of valid items stored so far).
v21: The allocated capacity (max elements that can currently be stored).
v20: Pointer to the memory buffer used to store the elements.
for ( i = sub_2A8B710(v17); i; i = sub_2A8FA60(v17) )
if ( !CGameEntitySystem )
return 0i64;
v2 = *a1; // current node
if ( v2 )
{
v3 = *(_QWORD *)(v2 + 0x60); // v3 = current->next
}
else if ( *((_BYTE *)a1 + 0x10) )
{
v3 = *(_QWORD *)(CGameEntitySystem + 0x230 // alternate list (?)
}
else
{
v3 = *(_QWORD *)(CGameEntitySystem + 0x210); // default list (?)
}
unsigned int ShowEnts()
{
// Initialize values
__int64 Ent; // Holds current entity
int v1; // Index into entity list array
__int64 v2, v3; // Misc pointers
int v4, v5, v6, v8, v10; // Temp counters & sizes
__int64 v7, v9; // Temp ptrs
char *EntInstance, *v12; // Iterators over entity array
__int64 Entity; // Actual entity pointer
const char *entName, *className; // Entity name / class
unsigned int result; // Return result
__int64 v17[3]; // Entity iterator struct
void **v18; // Filter virtual table
int v19; // Number of entities found
char *EntityInstance; // Pointer to allocated entity array
unsigned int v21; // Capacity of entity array
int v22; // Allocation flags
char v23[8200]; // Local buffer for entities (1024 entries * 8 bytes)
unsigned int entIndex; // Final entity index
EntityInstance = 0;
v21 = 1024; // Initial capacity
v22 = 0x80000000; // Flag (MSB set means local stack buffer used)
if ((&EntityInstance & 7) != 0) // Alignment check (should be 8-byte aligned)
sub_182E7E4D0(); // (unknown alignment check failure handler)
EntityInstance = v23; // Use stack buffer
v19 = 0; // Reset entity count
// Setup entity iterator: v17 is likely an iterator/context structure
sub_182A80FC0(v17, &v18, 0); // Initialize iterator
v18 = &CDefaultTypedEntityInstanceFilter<C_BaseEntity>::`vftable'; // Set default filter
// ----------- Entity iteration begins -------------------
for (Ent = sub_182A8B5A0(v17); Ent; Ent = sub_182A8F8F0(v17))
{
v1 = v19; // Current count
v2 = v21; // Current capacity
v3 = v19;
// Check if there's room to store another entity
if (v19 != v21 || (v4 = v22, (v22 & 0x40000000) != 0))
{
// If already have space or special flag set
v9 = EntityInstance;
}
else
{
// Not enough space — resize entity array
// Prevent overflow (if max size reached)
if (v21 == 0x7FFFFFFF)
{
UtlMemory_FailedAllocation(0x7FFFFFFF, 1);
v4 = v22;
v2 = v21;
}
v5 = v2 + 1; // New desired count
v6 = UtlMemory_CalcNewAllocationCount(v2, v4 & 0x3FFFFFFF, v2 + 1, 8); // Compute new size
v8 = v6;
if (v6 < v5)
{
// Binary search resize to find a safe capacity
if (v6 || v5 > -1)
{
do
{
v7 = ((v8 + v5) >> 31); // Sign check
v8 = (v8 + v5) / 2;
}
while (v8 < v5);
}
else
{
v8 = -1;
}
}
// Allocate new memory
LOBYTE(v7) = (v22 & 0xC0000000) == 0;
v9 = UtlMemory_Alloc(EntityInstance, v7, 8i64 * v8, 8i64 * v21);
EntityInstance = v9;
// Update flags
if ((v22 & 0xC0000000) != 0)
v22 &= 0x3FFFFFFF;
v1 = v19;
v21 = v8;
}
// Store the entity pointer
v19 = v1 + 1;
*(v9 + 8 * v3) = Ent;
}
v10 = v19;
if (v19 > 1)
{
// Sort the entity list (by pointer or ent index)
V_qsort(EntityInstance, v19, 8, sub_181358FA0);
v10 = v19;
}
// ----------- Print out all stored entities --------------
EntInstance = EntityInstance;
v12 = &EntityInstance[8 * v10];
if (EntityInstance != v12)
{
do
{
Entity = *EntInstance; // Actual entity pointer
// Default name (fallback if null)
entName = &unk_182FB02FA;
// Get entity name
if (*(*(*EntInstance + 0x10i64) + 0x18i64)) // *(ent->m_pEntity + 0x10)->name
entName = *(*(*EntInstance + 0x10i64) + 0x18i64);
// Get class name: (*(vftable + 352)) returns struct, offset 8 has name
className = *((*(**EntInstance + 352i64))(*EntInstance) + 8);
// Get ent index from entity handle
sub_182AA0100(Entity, &entIndex);
// Print out: Ent 12345: class C_Foo name "MyEntity"
ConMsg("Ent %5d: class %s name \"%s\"\n", entIndex, className, entName);
EntInstance += 8; // Next entity
}
while (EntInstance != v12);
EntInstance = EntityInstance; // Restore pointer
}
// ----------- Cleanup memory -----------------------------
v19 = 0;
if ((v21 & 0x80000000) != 0 || EntInstance == v23)
{
// Used stack buffer — no need to free
result = v22;
}
else
{
// Free dynamically allocated memory
if (EntInstance && (v22 & 0xC0000000) == 0)
(*(*g_pMemAlloc + 0x18))(g_pMemAlloc, EntInstance);
// Reset to stack buffer
EntInstance = v23;
EntityInstance = v23;
result = (v22 & 0x3FFFFFFF) | 0x80000000;
v21 = 1024;
v22 = result;
}
// Final cleanup: free again if needed
if ((result & 0xC0000000) == 0)
{
if (EntInstance)
return (*(*g_pMemAlloc + 0x18))(g_pMemAlloc, EntInstance);
}
return result;
}
if index > 16383, it's clientside-only(non-networkable) entities iirc(the server doesn't manage them)(you don't really need them most of the time it's shit like trees decorations etc.)I can't understand the logic behind that. also why entity index goes from 3-digit to 5-digit? what is the purpose of doing this?
C++:[Console] Ent 242: class CDOTA_Item_TeleportScroll name "item_tpscroll" [Console] Ent 16408: class CBaseModelEntity name "divine_ambient" [Console] Ent 16409: class CPointCamera name "camera_1" [Console] Ent 16418: class CParticleSystem name ""
if index > 16383, it's clientside-only(non-networkable) entities iirc(the server doesn't manage them)(you don't really need them most of the time it's shit like trees decorations etc.)
also the iteration in cl_showents is now just like in cl_ent_find, ie entitysystem->FirstIdentity()->m_pNext->m_pNext->m_pNext->...->nullptr (aka GetNextEnt)(CEntityIdentity are linked-list'ed with each other)(this form of iteration also gives you these crappy clientside entities, unlike the previous GetHighestIndex-based iteration which only gave you networkable entities)
you could also just loop through all entities once, fill your own entity-list-thingie with what you need and then hook/monitor entity creation/deletion and reflect the changes in your own list
unless I'm mistaken
0x210 or something for firstidentity, and m_pNext is documented in schema in CEntityIdentityIsn't there a better way to traverse the entity list? I really don't like the linkedlist method.
(Also what's offset for entitysystem->FirstIdentity, 0x10?, and m_pNext is 0x60?)
you sure? mind double-checking?Some creep indices were greater than 16,383 for me. I need their health values for last-hitting.
0x210 or something for firstidentity, and m_pNext is documented in schema in CEntityIdentity
are you sure? mind double-checking?
cuz indices don't even correspond to each other on the client and on the server when they're > 16383
(they do for indices below that, though. and the server(unless I'm mistaken, ofc) uses indices to correlate networkable entities on the client and on the server, ie when your hero gets his hp updated, the server sends "entity at index 123 got its hp updated", and the client updates the hp of the entity at index 123, whichever entity that may be. if they don't match there will be problems. and they don't match for >16383)
Пожалуйста, авторизуйтесь для просмотра ссылки.Пожалуйста, авторизуйтесь для просмотра ссылки." The first 2048 entries are reserved for entities withПожалуйста, авторизуйтесь для просмотра ссылки., which cross the client/server divide "(2048 is from a different game. for dota 2 it appears to be 16384)
Пожалуйста, авторизуйтесь для просмотра ссылки."InПожалуйста, авторизуйтесь для просмотра ссылки., specifically
Пожалуйста, авторизуйтесь для просмотра ссылки., the networked entity limit is 16384Пожалуйста, авторизуйтесь для просмотра ссылки..
Пожалуйста, авторизуйтесь для просмотра ссылки.- max 16384 edicts and 16384 server-only entities"
Посмотреть вложение 307333
(cl_ is client command, without the prefix is the server command)
again, you can iterate once and populate your own list and then just track updates by hooking entity creation/deletion(OnAddEntity/OnRemoveEntity kind-of-thingie)
Проект предоставляет различный материал, относящийся к сфере киберспорта, программирования, ПО для игр, а также позволяет его участникам общаться на многие другие темы. Почта для жалоб: admin@yougame.biz