4#include <CS2Kit/Sdk/Entity.hpp>
5#include <CS2Kit/Sdk/EntityRender.hpp>
6#include <CS2Kit/Sdk/GameData.hpp>
7#include <CS2Kit/Sdk/GameInterfaces.hpp>
8#include <CS2Kit/Sdk/PlayerController.hpp>
9#include <CS2Kit/Utils/Log.hpp>
12#include <entity2/entityinstance.h>
13#include <mathlib/vector.h>
20PlayerController::PlayerController(
int slot) : _slot(slot)
22 _controller = EntitySystem::Instance().GetPlayerController(slot);
25bool PlayerController::IsValid()
const
27 return _controller !=
nullptr;
30CEntityInstance* PlayerController::GetEntity()
const
35CEntityInstance* PlayerController::GetPawn()
const
40 int offset = SchemaService::Instance().GetOffset(
"CCSPlayerController",
"m_hPlayerPawn");
44 auto hPawn = *
reinterpret_cast<uint32_t*
>(
reinterpret_cast<uint8_t*
>(_controller) + offset);
45 return EntitySystem::Instance().ResolveEntityHandle(hPawn);
48void PlayerController::Kick(
const char* reason)
const
53 auto* engine = GameInterfaces::Instance().Engine;
56 Log::Warn(
"PlayerController::Kick: IVEngineServer2 not available.");
60 engine->DisconnectClient(CPlayerSlot(_slot), NETWORK_DISCONNECT_KICKED, reason);
64T PlayerController::GetField(
const char* className,
const char* fieldName)
const
69 int offset = SchemaService::Instance().GetOffset(className, fieldName);
73 return *
reinterpret_cast<T*
>(
reinterpret_cast<uint8_t*
>(_controller) + offset);
77T PlayerController::GetPawnField(
const char* className,
const char* fieldName)
const
79 auto* pawn = GetPawn();
83 int offset = SchemaService::Instance().GetOffset(className, fieldName);
87 return *
reinterpret_cast<T*
>(
reinterpret_cast<uint8_t*
>(pawn) + offset);
91void PlayerController::SetField(
const char* className,
const char* fieldName,
const T& value)
const
96 int offset = SchemaService::Instance().GetOffset(className, fieldName);
100 *
reinterpret_cast<T*
>(
reinterpret_cast<uint8_t*
>(_controller) + offset) = value;
104void PlayerController::SetPawnField(
const char* className,
const char* fieldName,
const T& value)
const
106 auto* pawn = GetPawn();
110 int offset = SchemaService::Instance().GetOffset(className, fieldName);
114 *
reinterpret_cast<T*
>(
reinterpret_cast<uint8_t*
>(pawn) + offset) = value;
117int PlayerController::GetHealth()
const
119 return GetPawnField<int>(
"CBaseEntity",
"m_iHealth");
122int PlayerController::GetTeam()
const
124 return GetPawnField<int>(
"CBaseEntity",
"m_iTeamNum");
127int PlayerController::GetLifeState()
const
129 return GetPawnField<uint8_t>(
"CBaseEntity",
"m_lifeState");
132bool PlayerController::IsAlive()
const
134 return GetPawn() !=
nullptr && GetLifeState() == 0;
137uint64_t PlayerController::GetButtons()
const
139 return EntitySystem::Instance().GetPlayerButtons(_slot);
142int PlayerController::GetArmor()
const
144 return GetPawnField<int>(
"CCSPlayerPawn",
"m_ArmorValue");
147Vector PlayerController::GetAbsOrigin()
const
149 return GetPawnField<Vector>(
"CBaseEntity",
"m_vecAbsOrigin");
152QAngle PlayerController::GetAbsAngles()
const
154 return GetPawnField<QAngle>(
"CBaseEntity",
"m_angRotation");
157QAngle PlayerController::GetEyeAngles()
const
159 return GetPawnField<QAngle>(
"CCSPlayerPawnBase",
"m_angEyeAngles");
162void PlayerController::Slay()
const
164 auto* pawn = GetPawn();
168 int vtableIndex = GameData::Instance().GetOffset(
"CommitSuicide");
171 Log::Warn(
"PlayerController::Slay: CommitSuicide vtable offset not found.");
175 CallVirtual<void>(vtableIndex, pawn,
false,
true);
178void PlayerController::ChangeTeam(
int team)
const
183 int vtableIndex = GameData::Instance().GetOffset(
"ChangeTeam");
186 Log::Warn(
"PlayerController::ChangeTeam: ChangeTeam vtable offset not found.");
190 CallVirtual<void>(vtableIndex, _controller, team);
193void PlayerController::Respawn()
const
198 int vtableIndex = GameData::Instance().GetOffset(
"Respawn");
201 Log::Warn(
"PlayerController::Respawn: Respawn vtable offset not found.");
205 CallVirtual<void>(vtableIndex, _controller);
208void PlayerController::Teleport(
const Vector* origin,
const QAngle* angles,
const Vector* velocity)
const
210 auto* pawn = GetPawn();
214 int vtableIndex = GameData::Instance().GetOffset(
"Teleport");
217 Log::Warn(
"PlayerController::Teleport: Teleport vtable offset not found.");
221 CallVirtual<void>(vtableIndex, pawn, origin, angles, velocity);
227constexpr size_t PlayerNameBufferSize = 128;
230int PlayerController::GetObserverMode()
const
232 return GetPawnField<uint8_t>(
"CPlayer_ObserverServices",
"m_iObserverMode");
235void PlayerController::SetObserverMode(uint8_t mode)
const
237 SetPawnField<uint8_t>(
"CPlayer_ObserverServices",
"m_iObserverMode", mode);
240std::string PlayerController::GetPlayerName()
const
245 int offset = SchemaService::Instance().GetOffset(
"CBasePlayerController",
"m_iszPlayerName");
249 auto* p =
reinterpret_cast<const char*
>(
reinterpret_cast<uint8_t*
>(_controller) + offset);
251 while (len < PlayerNameBufferSize && p[len] !=
'\0')
253 return std::string(p, len);
256void PlayerController::SetPlayerName(
const std::string& name)
const
261 int offset = SchemaService::Instance().GetOffset(
"CBasePlayerController",
"m_iszPlayerName");
265 auto* dst =
reinterpret_cast<char*
>(
reinterpret_cast<uint8_t*
>(_controller) + offset);
266 std::memset(dst, 0, PlayerNameBufferSize);
267 size_t copyLen = name.size();
268 if (copyLen >= PlayerNameBufferSize)
269 copyLen = PlayerNameBufferSize - 1;
271 std::memcpy(dst, name.data(), copyLen);
274void PlayerController::SetVisible(
bool visible, uint8_t alpha)
const
276 auto* pawn = GetPawn();
280 RenderMode_t mode = visible ? RenderMode_t::Normal : RenderMode_t::TransTexture;
281 uint32_t color = visible ? ColorOpaqueWhite : ((
static_cast<uint32_t
>(alpha) << 24) | 0x00FFFFFFu);
287template int PlayerController::GetField<int>(
const char*,
const char*)
const;
288template uint8_t PlayerController::GetField<uint8_t>(
const char*,
const char*)
const;
289template uint32_t PlayerController::GetField<uint32_t>(
const char*,
const char*)
const;
290template float PlayerController::GetField<float>(
const char*,
const char*)
const;
291template Vector PlayerController::GetField<Vector>(
const char*,
const char*)
const;
292template QAngle PlayerController::GetField<QAngle>(
const char*,
const char*)
const;
294template int PlayerController::GetPawnField<int>(
const char*,
const char*)
const;
295template uint8_t PlayerController::GetPawnField<uint8_t>(
const char*,
const char*)
const;
296template uint32_t PlayerController::GetPawnField<uint32_t>(
const char*,
const char*)
const;
297template float PlayerController::GetPawnField<float>(
const char*,
const char*)
const;
298template Vector PlayerController::GetPawnField<Vector>(
const char*,
const char*)
const;
299template QAngle PlayerController::GetPawnField<QAngle>(
const char*,
const char*)
const;
301template void PlayerController::SetField<int>(
const char*,
const char*,
const int&)
const;
302template void PlayerController::SetField<uint8_t>(
const char*,
const char*,
const uint8_t&)
const;
303template void PlayerController::SetField<uint32_t>(
const char*,
const char*,
const uint32_t&)
const;
304template void PlayerController::SetField<float>(
const char*,
const char*,
const float&)
const;
305template void PlayerController::SetField<Vector>(
const char*,
const char*,
const Vector&)
const;
306template void PlayerController::SetField<QAngle>(
const char*,
const char*,
const QAngle&)
const;
308template void PlayerController::SetPawnField<int>(
const char*,
const char*,
const int&)
const;
309template void PlayerController::SetPawnField<uint8_t>(
const char*,
const char*,
const uint8_t&)
const;
310template void PlayerController::SetPawnField<uint32_t>(
const char*,
const char*,
const uint32_t&)
const;
311template void PlayerController::SetPawnField<float>(
const char*,
const char*,
const float&)
const;
312template void PlayerController::SetPawnField<Vector>(
const char*,
const char*,
const Vector&)
const;
313template void PlayerController::SetPawnField<QAngle>(
const char*,
const char*,
const QAngle&)
const;
void SetEntityRender(CEntityInstance *entity, RenderMode_t mode, uint32_t color)