good
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
#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
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "../../../../external/imgui/imgui.h"
|
||||
#include "../../../cs2/entity/C_CSPlayerPawn/C_CSPlayerPawn.h"
|
||||
#include "../../../cs2/entity/C_BaseEntity/C_BaseEntity.h"
|
||||
#include "../../config/config.h"
|
||||
#include "../../../cs2/entity/CCSPlayerController/CCSPlayerController.h"
|
||||
|
||||
struct SpectatorInfo {
|
||||
std::string name;
|
||||
bool isLocalPlayer;
|
||||
int team;
|
||||
bool isAlive;
|
||||
|
||||
SpectatorInfo(const std::string& n, bool local, int t, bool alive)
|
||||
: name(n), isLocalPlayer(local), team(t), isAlive(alive) {}
|
||||
};
|
||||
|
||||
namespace Spectators {
|
||||
void RenderSpectatorList();
|
||||
std::vector<SpectatorInfo> GetSpectators();
|
||||
bool IsPlayerSpectatingYou(CCSPlayerController* controller, C_CSPlayerPawn* localPlayer);
|
||||
void RenderPlayersDebugList();
|
||||
}
|
||||
Reference in New Issue
Block a user