pseudoclasses

This commit is contained in:
nullifiedcat 2017-11-23 13:21:37 +03:00
parent 2efb08752b
commit 7cf5ec4230
16 changed files with 147 additions and 85 deletions

View File

@ -108,6 +108,7 @@
#include "backpacktf.hpp"
#include "sharedobj.hpp"
#include "init.hpp"
#include "reclasses/reclasses.hpp"
#include "copypasted/Netvar.h"
#include "copypasted/CSignature.h"

View File

@ -25,54 +25,51 @@ constexpr platform PLATFORM = platform::PLATFORM_UNSUPPORTED;
#endif
struct offsets {
static constexpr uint32_t undefined = std::numeric_limits<uint32_t>::max();
static constexpr uint32_t PlatformOffset(uint32_t offset_linux, uint32_t offset_windows, uint32_t offset_osx) {
uint32_t result = -1;
switch (PLATFORM) {
case platform::PLATFORM_LINUX:
result = offset_linux; break;
case platform::PLATFORM_WINDOWS:
result = offset_windows; break;
case platform::PLATFORM_OSX:
result = offset_osx; break;
}
// pCompileError.
//static_assert(result != -1, "No offset defined for this platform!");
return result;
}
static constexpr uint32_t GetUserCmd() { return PlatformOffset(8, -1, -1); }
static constexpr uint32_t ShouldDraw() { return PlatformOffset(136, -1, -1); }
static constexpr uint32_t DrawModelExecute() { return PlatformOffset(19, -1, -1); }
static constexpr uint32_t GetClientName() { return PlatformOffset(44, -1, -1); }
static constexpr uint32_t ProcessSetConVar() { return PlatformOffset(4, -1, -1); }
static constexpr uint32_t ProcessGetCvarValue() { return PlatformOffset(29, -1, -1); }
static constexpr uint32_t GetFriendPersonaName() { return PlatformOffset(7, -1, -1); }
static constexpr uint32_t CreateMove() { return PlatformOffset(22, -1, -1); }
static constexpr uint32_t PaintTraverse() { return PlatformOffset(42, -1, -1); }
static constexpr uint32_t OverrideView() { return PlatformOffset(17, -1, -1); }
static constexpr uint32_t FrameStageNotify() { return PlatformOffset(35, -1, -1); }
static constexpr uint32_t DispatchUserMessage() { return PlatformOffset(36, -1, -1); }
static constexpr uint32_t CanPacket() { return PlatformOffset(57, -1, -1); }
static constexpr uint32_t SendNetMsg() { return PlatformOffset(41, -1, -1); }
static constexpr uint32_t Shutdown() { return PlatformOffset(37, -1, -1); }
static constexpr uint32_t IN_KeyEvent() { return PlatformOffset(20, -1, -1); }
static constexpr uint32_t HandleInputEvent() { return PlatformOffset(78, -1, -1); }
static constexpr uint32_t LevelInit() { return PlatformOffset(23, -1, -1); }
static constexpr uint32_t LevelShutdown() { return PlatformOffset(24, -1, -1); }
static constexpr uint32_t BeginFrame() { return PlatformOffset(5, -1, -1); }
static constexpr uint32_t FireGameEvent() { return PlatformOffset(2, -1, -1); }
static constexpr uint32_t FireEvent() { return PlatformOffset(8, 0, 0); }
static constexpr uint32_t FireEventClientSide() { return PlatformOffset(9, 0, 0); }
static constexpr uint32_t PlatformOffset(uint32_t offset_linux, uint32_t offset_windows, uint32_t offset_osx) {
uint32_t result = undefined;
switch (PLATFORM) {
case platform::PLATFORM_LINUX:
result = offset_linux; break;
case platform::PLATFORM_WINDOWS:
result = offset_windows; break;
case platform::PLATFORM_OSX:
result = offset_osx; break;
}
// pCompileError.
//static_assert(result != -1, "No offset defined for this platform!");
return result;
}
static constexpr uint32_t GetUserCmd() { return PlatformOffset(8, -1, -1); }
static constexpr uint32_t ShouldDraw() { return PlatformOffset(136, -1, -1); }
static constexpr uint32_t DrawModelExecute() { return PlatformOffset(19, -1, -1); }
static constexpr uint32_t GetClientName() { return PlatformOffset(44, -1, -1); }
static constexpr uint32_t ProcessSetConVar() { return PlatformOffset(4, -1, -1); }
static constexpr uint32_t ProcessGetCvarValue() { return PlatformOffset(29, -1, -1); }
static constexpr uint32_t GetFriendPersonaName() { return PlatformOffset(7, -1, -1); }
static constexpr uint32_t CreateMove() { return PlatformOffset(22, -1, -1); }
static constexpr uint32_t PaintTraverse() { return PlatformOffset(42, -1, -1); }
static constexpr uint32_t OverrideView() { return PlatformOffset(17, -1, -1); }
static constexpr uint32_t FrameStageNotify() { return PlatformOffset(35, -1, -1); }
static constexpr uint32_t DispatchUserMessage() { return PlatformOffset(36, -1, -1); }
static constexpr uint32_t CanPacket() { return PlatformOffset(57, -1, -1); }
static constexpr uint32_t SendNetMsg() { return PlatformOffset(41, -1, -1); }
static constexpr uint32_t Shutdown() { return PlatformOffset(37, -1, -1); }
static constexpr uint32_t IN_KeyEvent() { return PlatformOffset(20, -1, -1); }
static constexpr uint32_t HandleInputEvent() { return PlatformOffset(78, -1, -1); }
static constexpr uint32_t LevelInit() { return PlatformOffset(23, -1, -1); }
static constexpr uint32_t LevelShutdown() { return PlatformOffset(24, -1, -1); }
static constexpr uint32_t BeginFrame() { return PlatformOffset(5, -1, -1); }
static constexpr uint32_t FireGameEvent() { return PlatformOffset(2, -1, -1); }
static constexpr uint32_t FireEvent() { return PlatformOffset(8, 0, 0); }
static constexpr uint32_t FireEventClientSide() { return PlatformOffset(9, 0, 0); }
static constexpr uint32_t GetSlot() { return PlatformOffset(395, 0, 395); }
static constexpr uint32_t GetProjectileSpeed() { return PlatformOffset(534, 0, 534); }
static constexpr uint32_t GetProjectileGravity() { return PlatformOffset(534, 0, 534); }
static constexpr uint32_t DoSwingTrace() { return PlatformOffset(522, 0, 522); }
static constexpr uint32_t AreRandomCritsEnabled() { return PlatformOffset(466, 0, 466); }
static constexpr uint32_t AreRandomCritsEnabled() { return PlatformOffset(466, 0, 466); }
static constexpr uint32_t lastoutgoingcommand() { return PlatformOffset(19228, -1, -1); }
static constexpr uint32_t m_nOutSequenceNr() { return PlatformOffset(8, -1, -1); }
static constexpr uint32_t m_NetChannel() { return PlatformOffset(196, -1, -1); }
static constexpr uint32_t lastoutgoingcommand() { return PlatformOffset(19228, -1, -1); }
static constexpr uint32_t m_nOutSequenceNr() { return PlatformOffset(8, -1, -1); }
static constexpr uint32_t m_NetChannel() { return PlatformOffset(196, -1, -1); }
};

View File

@ -7,13 +7,23 @@
#pragma once
class C_BaseCombatWeapon : public IClientEntity
class C_BaseCombatWeapon
{
public:
inline int GetSlot()
inline static bool IsBaseCombatWeapon(IClientEntity *self)
{
typedef int(*fn_t)(C_BaseCombatWeapon *);
return vfunc<fn_t>(this, 395, 0)(this);
typedef bool(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(190, offsets::undefined, 190), 0)(self);
}
inline static int GetSlot(IClientEntity *self)
{
typedef int(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(395, offsets::undefined, 395), 0)(self);
}
inline static const char *GetPrintName(IClientEntity *self)
{
typedef const char *(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(398, offsets::undefined, 398), 0)(self);
}
};

View File

@ -0,0 +1,30 @@
/*
* C_TFWeaponBase.hpp
*
* Created on: Nov 23, 2017
* Author: nullifiedcat
*/
#pragma once
class C_TFWeaponBase : public C_BaseCombatWeapon
{
public:
inline static IClientEntity *GetOwnerViaInterface(IClientEntity *self)
{
typedef IClientEntity *(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(451, offsets::undefined, 451), 0)(self);
}
inline static bool UsesPrimaryAmmo(IClientEntity *self)
{
typedef bool(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(447, offsets::undefined, 447), 0)(self);
}
inline static bool HasPrimaryAmmo(IClientEntity *self)
{
typedef bool(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(317, offsets::undefined, 317), 0)(self);
}
};

View File

@ -7,10 +7,19 @@
#pragma once
class C_TFWeaponBaseGun : public C_BaseCombatWeapon
class C_TFWeaponBaseGun : public C_TFWeaponBase
{
public:
inline static float GetProjectileSpeed(IClientEntity *self)
{
typedef float(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(534, offsets::undefined, 534), 0)(self);
}
inline static float GetProjectileGravity(IClientEntity *self)
{
typedef float(*fn_t)(IClientEntity *);
return vfunc<fn_t>(self, offsets::PlatformOffset(535, offsets::undefined, 535), 0)(self);
}
};

View File

@ -0,0 +1,20 @@
/*
* C_TFWeaponBaseMelee.hpp
*
* Created on: Nov 23, 2017
* Author: nullifiedcat
*/
#pragma once
class C_TFWeaponBaseMelee: public C_TFWeaponBase
{
public:
inline static bool DoSwingTrace(IClientEntity *self, trace_t *trace)
{
typedef bool(*fn_t)(IClientEntity *, trace_t *);
return vfunc<fn_t>(self, offsets::PlatformOffset(522, offsets::undefined, 522), 0)(self, trace);
}
};

View File

@ -13,6 +13,8 @@ namespace re
{
#include "C_BaseCombatWeapon.hpp"
#include "C_TFWeaponBase.hpp"
#include "C_TFWeaponBaseMelee.hpp"
#include "C_TFWeaponBaseGun.hpp"

View File

@ -22,7 +22,8 @@ void CreateMove() {
static auto IsBehindAndFacingTarget_addr = gSignatures.GetClientSignature("55 89 E5 57 56 53 83 EC 2C 8B 45 08 8B 5D 08 C1 E0 0C");
static auto IsBehindAndFacingTarget = reinterpret_cast<IsBehindAndFacingTarget_t>(IsBehindAndFacingTarget_addr);
if (vfunc<bool(*)(IClientEntity*, trace_t*)>(weapon, offsets::DoSwingTrace())(weapon, &trace)) {
if (re::C_TFWeaponBaseMelee::DoSwingTrace(weapon, &trace))
{
if (trace.m_pEnt && reinterpret_cast<IClientEntity*>(trace.m_pEnt)->GetClientClass()->m_ClassID == RCC_PLAYER) {
if (NET_INT(trace.m_pEnt, netvar.iTeamNum) != g_pLocalPlayer->team) {
if (IsBehindAndFacingTarget(weapon, reinterpret_cast<IClientEntity*>(trace.m_pEnt)))

View File

@ -866,7 +866,7 @@ void _FASTCALL ProcessEntity(CachedEntity* ent) {
CachedEntity* weapon = ENTITY(widx);
if (CE_GOOD(weapon)) {
if (show_weapon) {
const char* weapon_name = vfunc<const char*(*)(IClientEntity*)>(RAW_ENT(weapon), 398, 0)(RAW_ENT(weapon));
const char* weapon_name = re::C_BaseCombatWeapon::GetPrintName(RAW_ENT(weapon));
if (weapon_name) AddEntityString(ent, std::string(weapon_name));
}
}

View File

@ -236,12 +236,12 @@ void DoWalking() {
if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon())) {
// IsBaseCombatWeapon()
if (vfunc<bool(*)(IClientEntity*)>(RAW_ENT(g_pLocalPlayer->weapon()), 190, 0)(RAW_ENT(g_pLocalPlayer->weapon())) &&
vfunc<bool(*)(IClientEntity*)>(owner_weapon, 190, 0)(owner_weapon)) {
if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(RAW_ENT(g_pLocalPlayer->weapon())) &&
re::C_BaseCombatWeapon::IsBaseCombatWeapon(owner_weapon)) {
// Get the players slot numbers and store in some vars
int my_slot = vfunc<int(*)(IClientEntity*)>(RAW_ENT(g_pLocalPlayer->weapon()), 395, 0)(RAW_ENT(g_pLocalPlayer->weapon()));
int owner_slot = vfunc<int(*)(IClientEntity*)>(owner_weapon, 395, 0)(owner_weapon);
int my_slot = re::C_BaseCombatWeapon::GetSlot(RAW_ENT(g_pLocalPlayer->weapon()));
int owner_slot = re::C_BaseCombatWeapon::GetSlot(owner_weapon);
// If the local player is a medic and user settings allow, then keep the medigun out
if (g_pLocalPlayer->clazz == tf_medic && always_medigun) {

View File

@ -389,7 +389,7 @@ void DrawText() {
if (!debug_info) return;
if (CE_GOOD(g_pLocalPlayer->weapon())) {
AddSideString(format("Slot: ", vfunc<int(*)(IClientEntity*)>(RAW_ENT(g_pLocalPlayer->weapon()), 395, 0)(RAW_ENT(g_pLocalPlayer->weapon()))));
AddSideString(format("Slot: ", re::C_BaseCombatWeapon::GetSlot(RAW_ENT(g_pLocalPlayer->weapon()))));
AddSideString(format("Taunt Concept: ", CE_INT(LOCAL_E, netvar.m_iTauntConcept)));
AddSideString(format("Taunt Index: ", CE_INT(LOCAL_E, netvar.m_iTauntIndex)));
AddSideString(format("Sequence: ", CE_INT(LOCAL_E, netvar.m_nSequence)));

View File

@ -164,7 +164,7 @@ void FrameStageNotify(int stage) {
my_weapon = CE_INT(g_pLocalPlayer->entity, netvar.hActiveWeapon);
my_weapon_ptr = g_IEntityList->GetClientEntity(my_weapon & 0xFFF);
if (!my_weapon_ptr) return;
if (!vfunc<bool(*)(IClientEntity*)>(my_weapon_ptr, 190, 0)(my_weapon_ptr)) return;
if (!re::C_BaseCombatWeapon::IsBaseCombatWeapon(my_weapon_ptr)) return;
for (int i = 0; i < 4; i++) {
handle = weapon_list[i];
eid = handle & 0xFFF;
@ -174,7 +174,7 @@ void FrameStageNotify(int stage) {
if (!entity) continue;
// TODO IsBaseCombatWeapon
// or TODO PlatformOffset
if (!vfunc<bool(*)(IClientEntity*)>(entity, 190, 0)(entity)) continue;
if (!re::C_BaseCombatWeapon::IsBaseCombatWeapon(entity)) continue;
if ((my_weapon_ptr != last_weapon_out) || !cookie.Check()) {
GetModifier(NET_INT(entity, netvar.iItemDefinitionIndex)).Apply(eid);
}
@ -349,7 +349,7 @@ void def_attribute_modifier::Apply(int entity) {
ent = g_IEntityList->GetClientEntity(entity);
if (!ent) return;
if (!vfunc<bool(*)(IClientEntity*)>(ent, 190, 0)(ent)) return;
if (!re::C_BaseCombatWeapon::IsBaseCombatWeapon(ent)) return;
if (defidx_redirect && NET_INT(ent, netvar.iItemDefinitionIndex) != defidx_redirect) {
NET_INT(ent, netvar.iItemDefinitionIndex) = defidx_redirect;
if (show_debug_info)

View File

@ -189,18 +189,15 @@ using state::nodes;
using state::node_good;
bool HasLowAmmo() {
// 0x13D = CBaseCombatWeapon::HasPrimaryAmmo()
// 190 = IsBaseCombatWeapon
// 1C1 = C_TFWeaponBase::UsesPrimaryAmmo()
int *weapon_list = (int*)((unsigned)(RAW_ENT(LOCAL_E)) + netvar.hMyWeapons);
for (int i = 0; weapon_list[i]; i++) {
int handle = weapon_list[i];
int eid = handle & 0xFFF;
if (eid >= 32 && eid <= HIGHEST_ENTITY) {
IClientEntity* weapon = g_IEntityList->GetClientEntity(eid);
if (weapon and vfunc<bool(*)(IClientEntity*)>(weapon, 190, 0)(weapon) and
vfunc<bool(*)(IClientEntity*)>(weapon, 0x1C1, 0)(weapon) and
not vfunc<bool(*)(IClientEntity*)>(weapon, 0x13D, 0)(weapon)) {
if (weapon and re::C_BaseCombatWeapon::IsBaseCombatWeapon(weapon) and
re::C_TFWeaponBase::UsesPrimaryAmmo(weapon) and
not re::C_TFWeaponBase::HasPrimaryAmmo(weapon)) {
return true;
}
}
@ -704,8 +701,8 @@ void UpdateSlot() {
if (CE_GOOD(LOCAL_E) && CE_GOOD(LOCAL_W) && !g_pLocalPlayer->life_state && ms > 1000) {
IClientEntity* weapon = RAW_ENT(LOCAL_W);
// IsBaseCombatWeapon()
if (vfunc<bool(*)(IClientEntity*)>(weapon, 190, 0)(weapon)) {
int slot = vfunc<int(*)(IClientEntity*)>(weapon, 395, 0)(weapon);
if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(weapon)) {
int slot = re::C_BaseCombatWeapon::GetSlot(weapon);
if (slot != int(force_slot) - 1) {
hack::ExecuteCommand(format("slot", int(force_slot)));
}

View File

@ -467,7 +467,7 @@ weaponmode GetWeaponMode() {
}
weapon = (ENTITY(weapon_handle & 0xFFF));
if (CE_BAD(weapon)) return weaponmode::weapon_invalid;
slot = vfunc<int(*)(IClientEntity*)>(RAW_ENT(g_pLocalPlayer->weapon()), 395, 0)(RAW_ENT(g_pLocalPlayer->weapon()));
slot = re::C_BaseCombatWeapon::GetSlot(RAW_ENT(weapon));
if (slot == 2) return weaponmode::weapon_melee;
if (slot > 2) {
return weaponmode::weapon_pda;
@ -526,7 +526,7 @@ bool GetProjectileData(CachedEntity* weapon, float& speed, float& gravity) {
rspeed = 1100.0f;
} else if (weapon->m_iClassID == CL_CLASS(CTFGrenadeLauncher)) {
IF_GAME (IsTF2()) {
rspeed = vfunc<GetProjectileData*>(RAW_ENT(weapon), 527)(RAW_ENT(weapon));
rspeed = re::C_TFWeaponBaseGun::GetProjectileSpeed(RAW_ENT(g_pLocalPlayer->weapon()));
// TODO Wrong grenade launcher gravity
rgrav = 0.5f;
} else IF_GAME (IsTF2C()) {
@ -534,8 +534,8 @@ bool GetProjectileData(CachedEntity* weapon, float& speed, float& gravity) {
rgrav = 0.5f;
}
} else if (weapon->m_iClassID == CL_CLASS(CTFCompoundBow)) {
rspeed = vfunc<GetProjectileData*>(RAW_ENT(weapon), 527)(RAW_ENT(weapon));
rgrav = vfunc<GetProjectileData*>(RAW_ENT(weapon), 528)(RAW_ENT(weapon));
rspeed = re::C_TFWeaponBaseGun::GetProjectileSpeed(RAW_ENT(g_pLocalPlayer->weapon()));
rgrav = re::C_TFWeaponBaseGun::GetProjectileGravity(RAW_ENT(g_pLocalPlayer->weapon()));
} else if (weapon->m_iClassID == CL_CLASS(CTFBat_Wood)) {
rspeed = 3000.0f;
rgrav = 0.5f;

View File

@ -74,8 +74,9 @@ void EffectChams::EndRenderChams() {
rgba_t EffectChams::ChamsColor(IClientEntity* entity) {
CachedEntity* ent = ENTITY(entity->entindex());
if (CE_BAD(ent)) return colors::white;
if (vfunc<bool(*)(IClientEntity*)>(entity, 0xBE, 0)(entity)) {
IClientEntity* owner = vfunc<IClientEntity*(*)(IClientEntity*)>(entity, 0x1C3, 0)(entity);
if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(entity))
{
IClientEntity* owner = re::C_TFWeaponBase::GetOwnerViaInterface(entity);
if (owner) {
return ChamsColor(owner);
}
@ -149,7 +150,7 @@ void EffectChams::RenderChamsRecursive(IClientEntity* entity) {
attach = g_IEntityList->GetClientEntity(*(int*)((uintptr_t)entity + netvar.m_Collision - 24) & 0xFFF);
while (attach && passes++ < 32) {
if (attach->ShouldDraw()) {
if (entity->GetClientClass()->m_ClassID == RCC_PLAYER && vfunc<bool(*)(IClientEntity*)>(attach, 190, 0)(attach)) {
if (entity->GetClientClass()->m_ClassID == RCC_PLAYER && re::C_BaseCombatWeapon::IsBaseCombatWeapon(attach)) {
if (weapons_white) {
rgba_t mod_original;
g_IVRenderView->GetColorModulation(mod_original.rgba);

View File

@ -190,8 +190,8 @@ rgba_t EffectGlow::GlowColor(IClientEntity* entity) {
ent = ENTITY(entity->entindex());
if (CE_BAD(ent)) return colors::white;
if (ent == hacks::shared::aimbot::CurrentTarget()) return colors::pink;
if (vfunc<bool(*)(IClientEntity*)>(entity, 0xBE, 0)(entity)) {
owner = vfunc<IClientEntity*(*)(IClientEntity*)>(entity, 0x1C3, 0)(entity);
if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(entity)) {
owner = re::C_TFWeaponBase::GetOwnerViaInterface(entity);
if (owner) {
return GlowColor(owner);
}
@ -219,12 +219,6 @@ bool EffectGlow::ShouldRenderGlow(IClientEntity* entity) {
if (entity->entindex() < 0) return false;
ent = ENTITY(entity->entindex());
if (CE_BAD(ent)) return false;
/*if (weapons && vfunc<bool(*)(IClientEntity*)>(entity, 0xBE, 0)(entity)) {
IClientEntity* owner = vfunc<IClientEntity*(*)(IClientEntity*)>(entity, 0x1C3, 0)(entity);
if (owner) {
return ShouldRenderChams(owner);
}
}*/
switch (ent->m_Type) {
case ENTITY_BUILDING:
if (!buildings) return false;
@ -333,7 +327,7 @@ void EffectGlow::DrawEntity(IClientEntity* entity) {
attach = g_IEntityList->GetClientEntity(*(int*)((uintptr_t)entity + netvar.m_Collision - 24) & 0xFFF);
while (attach && passes++ < 32) {
if (attach->ShouldDraw()) {
if (weapons_white && entity->GetClientClass()->m_ClassID == RCC_PLAYER && vfunc<bool(*)(IClientEntity*)>(attach, 190, 0)(attach)) {
if (weapons_white && entity->GetClientClass()->m_ClassID == RCC_PLAYER && re::C_BaseCombatWeapon::IsBaseCombatWeapon(attach)) {
rgba_t mod_original;
g_IVRenderView->GetColorModulation(mod_original.rgba);
g_IVRenderView->SetColorModulation(colors::white);