1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
//|_ _ _. _ ._ |_ _. _ |
//| | (/_ (_| \/ (/_ | | | | (_| (_ |<
#pragma once
#include "csgo.h"
#include "sdk.h"
#include "../conout.h"
struct NETVAR_TABLE {
U32 ptr;
STR<64> name;
};
inline U32 netvar_get_classes( CSGO* csgo ) {
IFACE_ENTRY chl = u_vector_search<IFACE_ENTRY>(
csgo->interfaces,
[]( IFACE_ENTRY* in ) {
return !!strstr( in->name, "VClient0" );
}
);
if( !chl.ptr )
return 0;
U32 chl_vtable = csgo->read<U32>( chl.ptr );
U32 vtable_8 = chl_vtable + 8 * sizeof(U32);
U32 get_allclasses = csgo->read<U32>( vtable_8 );
U32 class_ptr = csgo->read<U32>( csgo->read<U32>( get_allclasses + 0x1 ) );
return class_ptr;
}
inline VECTOR<NETVAR_TABLE> netvar_get_tables( CSGO* csgo, U32 list ) {
static VECTOR<NETVAR_TABLE> tables{};
if( !tables.empty() )
return tables;
U32 ptr = list;
STR<64> net_name;
do {
CSGO_CLIENT_CLASS cclass = csgo->read<CSGO_CLIENT_CLASS>( ptr );
RECV_TABLE table = csgo->read<RECV_TABLE>( (U32)cclass.recv );
csgo->read( (U32)table.table_name, net_name.data, 64 );
tables.push_back( { (U32)cclass.recv, net_name } );
ptr = (U32)cclass.next;
} while( ptr && ptr != list );
return tables;
}
inline U32 netvar_get_table( CSGO* csgo, const char* table_name ) {
static U32 list_ptr = netvar_get_classes( csgo );
static VECTOR<NETVAR_TABLE> tables = netvar_get_tables( csgo, list_ptr );
for( auto& it : tables ) {
if( !strcmp( it.name.data, table_name ) )
return it.ptr;
}
return 0;
}
inline I32 netvar_get_entry( CSGO* csgo, const char* name, U32 table_ptr ) {
I32 ret{};
RECV_TABLE table = csgo->read<RECV_TABLE>( table_ptr );
RECV_PROP* props = (RECV_PROP*)malloc( table.prop_count * sizeof( RECV_PROP ) );
csgo->read( (U32)table.props, props, sizeof( RECV_PROP ) * table.prop_count );
for( I32 i = 0; i < table.prop_count; ++i ) {
RECV_PROP* prop = &props[i];
if( prop->table ) {
RECV_TABLE child = csgo->read<RECV_TABLE>( (U32)prop->table );
if( child.prop_count ) {
U32 tmp = netvar_get_entry( csgo, name, (U32)prop->table );
if( tmp ) ret += prop->offset + tmp;
}
}
STR<64> prop_name;
csgo->read( (U32)prop->varname, prop_name.data, 64 );
if( !!strcmp( prop_name.data, name ) )
continue;
ret += prop->offset;
break;
}
free( props );
return ret;
}
inline I32 netvar_find( CSGO* csgo, const char* table_name, const char* prop ) {
I32 ret;
U32 table = netvar_get_table( csgo, table_name );
if( !table )
return 0;
ret = netvar_get_entry( csgo, prop, table );
return ret;
}
static void csgo_dump_classes( CSGO* csgo ) {
U32 allclasses = netvar_get_classes( csgo );
if( !allclasses )
return;
char* dump = (char*)malloc( 99999 );
memset( dump, 0, 99999 );
strcat( dump, "enum CSGO_CLIENT_CLASS {\n" );
U32 ptr = allclasses;
STR<64> net_name;
do {
CSGO_CLIENT_CLASS cclass = csgo->read<CSGO_CLIENT_CLASS>( ptr );
csgo->read( (U64)cclass.network_name, net_name.data, 64 );
strcat( dump, " " );
strcat( dump, net_name );
strcat( dump, " = " );
strcat( dump, "0x" );
strcat( dump, u_num_to_string_hex( cclass.index ) );
strcat( dump, ",\n" );
ptr = (U32)cclass.next;
} while( ptr && ptr != allclasses );
strcat( dump, "};" );
FILE* f = fopen( "./classes.dump", "w" );
fwrite( dump, strlen( dump ), 1, f );
fclose( f );
free( dump );
}
|