I don't know why they insist on using too many addresses yet.
A single CDatabasePrts address returns pointers to more than 30 interfaces, including CLTClient.
And CLTClient contains virtual functions that return pointers to other interfaces. It is much easier to maintain a vtable than a pattern for several pointers.
DIP Engine
DIP Engine should not be used for wall/chams and the correct name is vertex_buffer_controller::render not dip engine, the correct way is to hook inside cd3d_skel_mesh::render as it receives a model_instance * argument containing entity information, if you compare it with some entity (character) in the world, you can do perfect wallhack.
SendToServer
SendToServer is in the CLTClient vtable
Code:
std::uint32_t __thiscall CLTClient::SendToServer(CLTClient *this, CLTMessage_Write_Client *pMsg, std::uint32_t flags)
WeaponSet
The correct name is CharInfo, and inside it there is a pointer to CItemListMgr that contains members that inform the equipped item, such as the weapon for example.
LTClientDLL
LTClientDLL is just a pointer that points to CLTClient (inside Engine.exe)
LTCSBase
CLTClient is derived from ILTCSBase which is an abstract class, so it has no pointer and there is no pointer to ILTCSBase.
Code:
CLTClient : ILTClient : ILTCSBase : IBase
RemoteKill
RemoteKill is patched, there is a server side intersect segment.
The only way to do that is by looking at how the ID130 and ID100 work that are used in the send to server.
"PushToConsole"
Code:
struct ncon_var_track
{
std::uint32_t m_init;
float m_val;
char m_str_val[ 0x1C ];
};
auto size{ sizeof( ncon_var_track ) };
Most of these addresses are actually a struct called ncon_var_track.
And most are one after the other, that means you can do the following:
Code:
class dummy_con_vars
{
public:
ncon_var_track *m_player_gravity;
ncon_var_track *m_in_air_accel_multiplier;
ncon_var_track *m_slide_to_stop_time;
ncon_var_track *m_max_push_y_velocity;
ncon_var_track *m_base_move_accel;
ncon_var_track *m_start_accel;
ncon_var_track *m_max_accel;
ncon_var_track *m_accel_inc;
ncon_var_track *m_walk_vel;
ncon_var_track *m_frun_vel;
ncon_var_track *m_brun_vel;
ncon_var_track *m_srun_vel;
ncon_var_track *m_srun_vel;
ncon_var_track *m_jump_vel;
ncon_var_track *m_duck_vel;
ncon_var_track *m_workaround_stuck_at_wall;
};
auto vars{ reinterpret_cast< dummy_con_vars* >( addr_player_gravity ) };
//
vars->m_player_gravity->m_val = 0.0f;
Most of these other pointers are unnecessary and some can be obtained through instances in other classes. So there is no reason to create a pattern for all these addresses, it is very tiring.