120 lines
4.2 KiB
C++
120 lines
4.2 KiB
C++
#include "spectators.h"
|
||
#include "../../interfaces/interfaces.h"
|
||
#include "../../hooks/hooks.h"
|
||
#include "../../../../external/imgui/imgui.h"
|
||
#include "../../../cs2/entity/CCSPlayerController/CCSPlayerController.h"
|
||
#include "../visuals/visuals.h"
|
||
#include "../../menu/hud.h"
|
||
#include <vector>
|
||
#include <string>
|
||
#include "../../players/players.h"
|
||
#include "../../../cs2/entity/C_CSPlayerPawn/C_CSPlayerPawn.h"
|
||
|
||
namespace Spectators {
|
||
|
||
bool IsPlayerSpectatingYou(CCSPlayerController* controller, C_CSPlayerPawn* localPlayer) {
|
||
if (!controller || !localPlayer) return false;
|
||
if (controller->IsLocalPlayer()) return false;
|
||
|
||
uintptr_t pObserverServices = *reinterpret_cast<uintptr_t*>(
|
||
reinterpret_cast<uintptr_t>(controller) +
|
||
SchemaFinder::Get(hash_32_fnv1a_const("CCSPlayerController->m_pObserverServices"))
|
||
);
|
||
if (!pObserverServices) return false;
|
||
|
||
CBaseHandle hObserverTarget = *reinterpret_cast<CBaseHandle*>(
|
||
pObserverServices +
|
||
SchemaFinder::Get(hash_32_fnv1a_const("CPlayer_ObserverServices->m_hObserverTarget"))
|
||
);
|
||
if (!hObserverTarget.valid()) return false;
|
||
|
||
g_DebugString = "pObserverServices";
|
||
|
||
// Получаем указатель на pawn, за которым наблюдают
|
||
auto* observerPawn = reinterpret_cast<C_CSPlayerPawn*>(
|
||
I::GameEntity->Instance->Get(hObserverTarget.index())
|
||
);
|
||
if (!observerPawn) return false;
|
||
|
||
g_DebugString = "pObserverServices";
|
||
|
||
g_DebugString = observerPawn->handle().index() + " " + localPlayer->handle().index();
|
||
// Сравниваем указатели
|
||
return observerPawn->handle().index() == localPlayer->handle().index();
|
||
}
|
||
|
||
std::vector<SpectatorInfo> GetSpectators() {
|
||
std::vector<SpectatorInfo> spectators;
|
||
if (!H::oGetLocalPlayer || !I::GameEntity || !I::GameEntity->Instance) {
|
||
g_DebugString = "[Spectators] Не инициализированы (GetSpectators): "
|
||
+ std::string(!H::oGetLocalPlayer ? "oGetLocalPlayer " : "")
|
||
+ std::string(!I::GameEntity ? "GameEntity " : "")
|
||
+ std::string((I::GameEntity && !I::GameEntity->Instance) ? "GameEntity->Instance " : "");
|
||
return spectators;
|
||
}
|
||
C_CSPlayerPawn* localPlayer = H::oGetLocalPlayer(0);
|
||
if (!localPlayer) {
|
||
g_DebugString = "[Spectators] localPlayer nullptr (GetSpectators)";
|
||
return spectators;
|
||
}
|
||
|
||
int maxIdx = I::GameEntity->Instance->GetHighestEntityIndex();
|
||
|
||
for (int i = 1; i <= maxIdx; ++i) {
|
||
auto* entity = I::GameEntity->Instance->Get(i);
|
||
if (!entity) continue;
|
||
SchemaClassInfoData_t* classInfo = nullptr;
|
||
entity->dump_class_info(&classInfo);
|
||
if (!classInfo || strcmp(classInfo->szName, "CCSPlayerController") != 0)
|
||
continue;
|
||
auto* controller = reinterpret_cast<CCSPlayerController*>(entity);
|
||
if (!controller) continue;
|
||
if (!controller->m_hPawn().valid()) continue;
|
||
|
||
if (!IsPlayerSpectatingYou(controller, localPlayer))
|
||
continue;
|
||
|
||
const char* nameStr = controller->m_sSanitizedPlayerName();
|
||
std::string name = (nameStr && strlen(nameStr) > 0) ? nameStr : "Unknown";
|
||
|
||
spectators.emplace_back(name, false, 0, 0);
|
||
}
|
||
return spectators;
|
||
}
|
||
|
||
void RenderPlayersDebugList() {
|
||
ImGui::Begin("Players Debug List", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
|
||
if (!H::oGetLocalPlayer) {
|
||
ImGui::TextColored(ImVec4(1, 0, 0, 1), "[Spectators] oGetLocalPlayer не инициализирован");
|
||
ImGui::End();
|
||
return;
|
||
}
|
||
if (!I::GameEntity) {
|
||
ImGui::TextColored(ImVec4(1, 0, 0, 1), "[Spectators] GameEntity не инициализирован");
|
||
ImGui::End();
|
||
return;
|
||
}
|
||
if (!I::GameEntity->Instance) {
|
||
ImGui::TextColored(ImVec4(1, 0, 0, 1), "[Spectators] GameEntity->Instance не инициализирован");
|
||
ImGui::End();
|
||
return;
|
||
}
|
||
//if (!g_DebugString.empty()) {
|
||
// ImGui::TextColored(ImVec4(1, 0, 0, 1), "%s", g_DebugString.c_str());
|
||
// ImGui::End();
|
||
// return;
|
||
//}
|
||
ImGui::Text("Name | Team | Alive | Spectating You");
|
||
ImGui::Separator();
|
||
auto spectators = GetSpectators();
|
||
for (const auto& spectator : spectators) {
|
||
ImGui::Text("%-20s | %4d | %5s | %s",
|
||
spectator.name.c_str(),
|
||
spectator.team,
|
||
spectator.isAlive ? "yes" : "no",
|
||
"yes"); // Все из GetSpectators наблюдают за вами
|
||
}
|
||
ImGui::End();
|
||
}
|
||
|
||
} // namespace Spectators
|