From 340e743e65034e33980747512f7254eb298d1f6c Mon Sep 17 00:00:00 2001 From: mentolixite Date: Fri, 24 Jun 2022 19:48:03 +0200 Subject: [PATCH] feat(PlayerList): Show self at the top, separated by a divider (#271) Additionally I redesigned how the player service worked. Co-authored-by: Yimura --- .../src/backend/looped/player/spectate.cpp | 4 +- BigBaseV2/src/hooks/receive_net_message.cpp | 3 +- BigBaseV2/src/services/friends_service.cpp | 7 +- BigBaseV2/src/services/friends_service.hpp | 10 +- BigBaseV2/src/services/player_service.cpp | 102 ++++++++---------- BigBaseV2/src/services/player_service.hpp | 68 +++++++----- BigBaseV2/src/views/esp/view_esp.cpp | 13 +-- BigBaseV2/src/views/players/view_players.cpp | 52 +++++---- 8 files changed, 141 insertions(+), 118 deletions(-) diff --git a/BigBaseV2/src/backend/looped/player/spectate.cpp b/BigBaseV2/src/backend/looped/player/spectate.cpp index 8f30f270..37ab300d 100644 --- a/BigBaseV2/src/backend/looped/player/spectate.cpp +++ b/BigBaseV2/src/backend/looped/player/spectate.cpp @@ -8,8 +8,8 @@ namespace big void looped::player_spectate() { - Vehicle vehicle = self::veh; - Ped ped = self::ped; + const auto vehicle = self::veh; + const auto ped = self::ped; if (!g_player_service->get_selected()->is_valid() || !g->player.spectating) { diff --git a/BigBaseV2/src/hooks/receive_net_message.cpp b/BigBaseV2/src/hooks/receive_net_message.cpp index 952d1328..6d79dc99 100644 --- a/BigBaseV2/src/hooks/receive_net_message.cpp +++ b/BigBaseV2/src/hooks/receive_net_message.cpp @@ -34,8 +34,7 @@ namespace big buffer.m_flagBits = 1; rage::netConnection::MessageType msg_type; - player* player = g_player_service->get_by_msg_id(frame->m_msg_id); - + const auto player = g_player_service->get_by_msg_id(frame->m_msg_id); if (player && get_message_type(msg_type, buffer)) { switch (msg_type) diff --git a/BigBaseV2/src/services/friends_service.cpp b/BigBaseV2/src/services/friends_service.cpp index 63f3c172..bf1309ba 100644 --- a/BigBaseV2/src/services/friends_service.cpp +++ b/BigBaseV2/src/services/friends_service.cpp @@ -13,9 +13,12 @@ namespace big g_friends_service = nullptr; } - bool friends_service::is_friend(const std::unique_ptr& plyr) + bool friends_service::is_friend(CNetGamePlayer* net_player) { - const std::uint64_t rockstar_id = plyr->get_net_data()->m_rockstar_id2; + if (net_player == nullptr) + return false; + + const auto rockstar_id = net_player->get_net_data()->m_rockstar_id2; for (std::uint32_t i = 0; i < g_pointers->m_friend_registry->m_friend_count; i++) if (rockstar_id == g_pointers->m_friend_registry->m_friends_list->m_data[i].m_rockstar_id) return true; diff --git a/BigBaseV2/src/services/friends_service.hpp b/BigBaseV2/src/services/friends_service.hpp index dc657a7e..3ba165fe 100644 --- a/BigBaseV2/src/services/friends_service.hpp +++ b/BigBaseV2/src/services/friends_service.hpp @@ -1,5 +1,4 @@ #pragma once -#include "player_service.hpp" namespace big { @@ -7,9 +6,14 @@ namespace big { public: friends_service(); - virtual ~friends_service(); + ~friends_service(); + + friends_service(const friends_service&) = delete; + friends_service(friends_service&&) noexcept = delete; + friends_service& operator=(const friends_service&) = delete; + friends_service& operator=(friends_service&&) noexcept = delete; - static bool is_friend(const std::unique_ptr& plyr); + [[nodiscard]] static bool is_friend(CNetGamePlayer* net_player); }; inline friends_service* g_friends_service{}; diff --git a/BigBaseV2/src/services/player_service.cpp b/BigBaseV2/src/services/player_service.cpp index 1c7985e8..7522b4fa 100644 --- a/BigBaseV2/src/services/player_service.cpp +++ b/BigBaseV2/src/services/player_service.cpp @@ -1,5 +1,5 @@ -#include "gta_util.hpp" #include "friends_service.hpp" +#include "gta_util.hpp" #include "player_service.hpp" namespace big @@ -7,74 +7,74 @@ namespace big player::player(CNetGamePlayer* net_game_player) : m_net_game_player(net_game_player) { - + m_is_friend = friends_service::is_friend(net_game_player); } - CAutomobile* player::get_current_vehicle() + CAutomobile* player::get_current_vehicle() const { - if (CPed* ped = this->get_ped(); ped != nullptr) - if (CAutomobile* vehicle = ped->m_vehicle; vehicle != nullptr) + if (const auto ped = this->get_ped(); ped != nullptr) + if (const auto vehicle = ped->m_vehicle; vehicle != nullptr) return vehicle; return nullptr; } - const char* player::get_name() + const char* player::get_name() const { return m_net_game_player == nullptr ? "" : m_net_game_player->get_name(); } - rage::netPlayerData* player::get_net_data() + rage::netPlayerData* player::get_net_data() const { return m_net_game_player == nullptr ? nullptr : m_net_game_player->get_net_data(); } - CNetGamePlayer* player::get_net_game_player() + CNetGamePlayer* player::get_net_game_player() const { return m_net_game_player; } - CPed* player::get_ped() + CPed* player::get_ped() const { - if (CPlayerInfo* player_info = this->get_player_info(); player_info != nullptr) - if (CPed* ped = player_info->m_ped; ped != nullptr) + if (const auto player_info = this->get_player_info(); player_info != nullptr) + if (const auto ped = player_info->m_ped; ped != nullptr) return ped; return nullptr; } - CPlayerInfo* player::get_player_info() + CPlayerInfo* player::get_player_info() const { if (m_net_game_player != nullptr && m_net_game_player->m_player_info != nullptr) return m_net_game_player->m_player_info; return nullptr; } - uint8_t player::id() + uint8_t player::id() const { return m_net_game_player == nullptr ? -1 : m_net_game_player->m_player_id; } - bool player::is_host() + bool player::is_host() const { return m_net_game_player == nullptr ? false : m_net_game_player->is_host(); } - bool player::is_friend() + bool player::is_friend() const { return m_is_friend; } - bool player::is_valid() + bool player::is_valid() const { return m_net_game_player == nullptr ? false : m_net_game_player->is_valid(); } - bool player::equals(CNetGamePlayer* net_game_player) + bool player::equals(const CNetGamePlayer* net_game_player) const { return net_game_player == m_net_game_player; } - std::string player::to_lowercase_identifier() + std::string player::to_lowercase_identifier() const { std::string lower = this->get_name(); std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); @@ -83,82 +83,70 @@ namespace big } player_service::player_service() + : m_selected_player(m_dummy) { g_player_service = this; - m_dummy_player = new player(nullptr); - - auto network_player_mgr = gta_util::get_network_player_mgr(); + const auto network_player_mgr = gta_util::get_network_player_mgr(); if (!network_player_mgr) return; - auto net_game_player = network_player_mgr->m_local_net_player; - if (!net_game_player) - return; + m_self = &network_player_mgr->m_local_net_player; for (uint16_t i = 0; i < network_player_mgr->m_player_limit; ++i) - { - net_game_player = network_player_mgr->m_player_list[i]; - player_join(net_game_player); - } + player_join(network_player_mgr->m_player_list[i]); } player_service::~player_service() { g_player_service = nullptr; - - delete m_dummy_player; } void player_service::do_cleanup() { - m_selected_player = nullptr; m_players.clear(); } - player* player_service::get_by_name(std::string name) + player_ptr player_service::get_by_name(std::string name) { std::transform(name.begin(), name.end(), name.begin(), ::tolower); - if (auto it = m_players.find(name); it != m_players.end()) - return it->second.get(); + if (const auto it = m_players.find(name); it != m_players.end()) + return it->second; return nullptr; } - player* player_service::get_by_msg_id(uint32_t msg_id) + player_ptr player_service::get_by_msg_id(uint32_t msg_id) const { - std::map>::iterator it; - for (it = m_players.begin(); it != m_players.end(); it++) - { - if (it->second.get()->get_net_game_player()->m_msg_id == msg_id) - return it->second.get(); - } + for (const auto& [name, player] : m_players) + if (player->get_net_game_player()->m_msg_id == msg_id) + return player; return nullptr; } - player* player_service::get_by_host_token(uint64_t token) + player_ptr player_service::get_by_host_token(uint64_t token) const { - std::map>::iterator it; - for (it = m_players.begin(); it != m_players.end(); it++) - { - if (it->second.get()->get_net_data()->m_host_token == token) - return it->second.get(); - } + for (const auto& [name, player] : m_players) + if (player->get_net_data()->m_host_token == token) + return player; return nullptr; } - player* player_service::get_selected() + player_ptr player_service::get_selected() const { - return m_selected_player == nullptr ? m_dummy_player : m_selected_player; + return m_selected_player; + } + + player_ptr player_service::get_self() const + { + return std::make_shared(*m_self); } void player_service::player_join(CNetGamePlayer* net_game_player) { - if (net_game_player == nullptr) return; - - std::unique_ptr plyr = std::make_unique(net_game_player); - plyr->m_is_friend = friends_service::is_friend(plyr); + if (net_game_player == nullptr || net_game_player == *m_self) return; + auto plyr = std::make_shared(net_game_player); m_players.emplace( plyr->to_lowercase_identifier(), std::move(plyr) @@ -169,13 +157,13 @@ namespace big { if (net_game_player == nullptr) return; if (m_selected_player && m_selected_player->equals(net_game_player)) - m_selected_player = nullptr; + m_selected_player = m_dummy; - std::unique_ptr plyr = std::make_unique(net_game_player); + auto plyr = std::make_unique(net_game_player); m_players.erase(plyr->to_lowercase_identifier()); } - void player_service::set_selected(player* plyr) + void player_service::set_selected(player_ptr plyr) { m_selected_player = plyr; } diff --git a/BigBaseV2/src/services/player_service.hpp b/BigBaseV2/src/services/player_service.hpp index dc0ecf43..36faa636 100644 --- a/BigBaseV2/src/services/player_service.hpp +++ b/BigBaseV2/src/services/player_service.hpp @@ -12,54 +12,74 @@ namespace big bool m_is_friend; public: - player(CNetGamePlayer* net_game_player); - virtual ~player() = default; + explicit player(CNetGamePlayer* net_game_player); + ~player() = default; + + player(const player&) = default; + player(player&&) noexcept = default; + player& operator=(const player&) = default; + player& operator=(player&&) noexcept = default; float screen_position_x = -1.f; float screen_position_y = -1.f; - CAutomobile* get_current_vehicle(); - const char* get_name(); - rage::netPlayerData* get_net_data(); - CNetGamePlayer* get_net_game_player(); - CPed* get_ped(); - CPlayerInfo* get_player_info(); + [[nodiscard]] CAutomobile* get_current_vehicle() const; + [[nodiscard]] const char* get_name() const; + [[nodiscard]] rage::netPlayerData* get_net_data() const; + [[nodiscard]] CNetGamePlayer* get_net_game_player() const; + [[nodiscard]] CPed* get_ped() const; + [[nodiscard]] CPlayerInfo* get_player_info() const; - uint8_t id(); + [[nodiscard]] uint8_t id() const; - bool is_friend(); - bool is_host(); - bool is_valid(); + [[nodiscard]] bool is_friend() const; + [[nodiscard]] bool is_host() const; + [[nodiscard]] bool is_valid() const; protected: - bool equals(CNetGamePlayer* net_game_player); + bool equals(const CNetGamePlayer* net_game_player) const; - std::string to_lowercase_identifier(); + [[nodiscard]] std::string to_lowercase_identifier() const; }; - typedef std::map> player_list; + using player_ptr = std::shared_ptr; + using players = std::map; + class player_service final { - player* m_dummy_player{}; - player* m_selected_player = nullptr; + CNetGamePlayer** m_self; + + players m_players; + + player_ptr m_dummy = std::make_shared(nullptr); + player_ptr m_selected_player; public: - player_list m_players; player_service(); - virtual ~player_service(); + ~player_service(); + + player_service(const player_service&) = delete; + player_service(player_service&&) noexcept = delete; + player_service& operator=(const player_service&) = delete; + player_service& operator=(player_service&&) noexcept = delete; void do_cleanup(); - player* get_by_name(std::string name); - player* get_by_msg_id(uint32_t msg_id); - player* get_by_host_token(uint64_t token); - player* get_selected(); + [[nodiscard]] player_ptr get_self() const; + + [[nodiscard]] player_ptr get_by_name(std::string name); + [[nodiscard]] player_ptr get_by_msg_id(uint32_t msg_id) const; + [[nodiscard]] player_ptr get_by_host_token(uint64_t token) const; + [[nodiscard]] player_ptr get_selected() const; void player_join(CNetGamePlayer* net_game_player); void player_leave(CNetGamePlayer* net_game_player); - void set_selected(player* plyr); + players& players() + { return m_players; } + + void set_selected(player_ptr plyr); }; diff --git a/BigBaseV2/src/views/esp/view_esp.cpp b/BigBaseV2/src/views/esp/view_esp.cpp index 66cdc3e8..c5e1be48 100644 --- a/BigBaseV2/src/views/esp/view_esp.cpp +++ b/BigBaseV2/src/views/esp/view_esp.cpp @@ -1,10 +1,9 @@ #include "view_esp.hpp" +#include "gta_util.hpp" #include "pointers.hpp" #include "services/player_service.hpp" #include "util/math.hpp" -#include "gta_util.hpp" #include "util/misc.hpp" -#include "services/context_menu_service.hpp" namespace big { @@ -24,16 +23,14 @@ namespace big if (const auto draw_list = ImGui::GetBackgroundDrawList(); draw_list) { - for (auto& item : g_player_service->m_players) + for (const auto& [_, plyr] : g_player_service->players()) { - const std::unique_ptr& plyr = item.second; - if (g->esp.hide_self && plyr->id() == gta_util::get_network_player_mgr()->m_local_net_player->m_player_id || !plyr->is_valid() || !plyr->get_ped() || !plyr->get_ped()->m_navigation) continue; - rage::fvector3& player_pos = plyr->get_ped()->m_navigation->m_position; + auto& player_pos = plyr->get_ped()->m_navigation->m_position; float screen_x, screen_y; @@ -49,9 +46,9 @@ namespace big const float esp_x = (float)*g_pointers->m_resolution_x * screen_x; const float esp_y = (float)*g_pointers->m_resolution_y * screen_y; - const float esp_side_x = esp_x + (67.5f * multplr); + // const float esp_side_x = esp_x + (67.5f * multplr); // unused? - std::string name_str = ""; + std::string name_str; ImVec2 name_pos = { esp_x - (62.5f * multplr), esp_y - (175.f * multplr) - 20.f }; ImU32 esp_color = g->esp.default_color; diff --git a/BigBaseV2/src/views/players/view_players.cpp b/BigBaseV2/src/views/players/view_players.cpp index c01dccc4..d6825289 100644 --- a/BigBaseV2/src/views/players/view_players.cpp +++ b/BigBaseV2/src/views/players/view_players.cpp @@ -3,6 +3,22 @@ namespace big { + static void player_button(const player_ptr& plyr) + { + if (plyr->is_host()) + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.29f, 0.45f, 0.69f, 1.f)); + + if (ImGui::Button(plyr->get_name(), { ImGui::GetWindowSize().x - 15.f, 0.f })) + { + g_player_service->set_selected(plyr); + g_gui_service->set_selected(tabs::PLAYER); + g->window.switched_view = true; + } + + if (plyr->is_host()) + ImGui::PopStyleColor(); + } + void view::players() { float window_pos = 110.f + g_gui_service->nav_ctr * ImGui::CalcTextSize("W").y + g_gui_service->nav_ctr * ImGui::GetStyle().ItemSpacing.y + g_gui_service->nav_ctr * ImGui::GetStyle().ItemInnerSpacing.y + ImGui::GetStyle().WindowPadding.y; @@ -11,34 +27,30 @@ namespace big ImGui::SetNextWindowPos({ 10.f, window_pos }); if (ImGui::Begin("playerlist", nullptr, window_flags)) { - const auto player_count = g_player_service->m_players.size(); - float window_height = (ImGui::CalcTextSize("A").y + ImGui::GetStyle().ItemInnerSpacing.y * 2 + 6.5f) * player_count; + const auto player_count = g_player_service->players().size() + 1; - window_height = window_height + window_pos > (float)*g_pointers->m_resolution_y - 10.f ? (float)*g_pointers->m_resolution_y - (window_pos + 40.f) : window_height; + // https://github.com/ocornut/imgui/issues/4399 + float window_height = 1.f; + + window_height += (ImGui::CalcTextSize("A").y + ImGui::GetStyle().ItemInnerSpacing.y * 2 + 6.5f) * player_count; + window_height += window_pos > (float)*g_pointers->m_resolution_y - 10.f ? (float)*g_pointers->m_resolution_y - (window_pos + 40.f) : 0; ImGui::PushStyleColor(ImGuiCol_FrameBg, { 0.f, 0.f, 0.f, 0.f }); ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, { 0.f, 0.f, 0.f, 0.f }); - if (ImGui::BeginListBox("##players", { 250.f - ImGui::GetStyle().WindowPadding.x * 2 , window_height })) { - for (auto& item : g_player_service->m_players) - { - const auto& plyr = item.second; - if (plyr->is_host()) - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.29f, 0.45f, 0.69f, 1.f)); - if (ImGui::Button(plyr->get_name(), { ImGui::GetWindowSize().x - 15.f, 0.f })) - { - g_player_service->set_selected(plyr.get()); - g_gui_service->set_selected(tabs::PLAYER); - g->window.switched_view = true; - } - if (plyr->is_host()) - ImGui::PopStyleColor(); - } + + if (ImGui::BeginListBox("##players", { 250.f - ImGui::GetStyle().WindowPadding.x * 2 , window_height })) + { + player_button(g_player_service->get_self()); + + ImGui::Separator(); + + for (const auto& [_, player] : g_player_service->players()) + player_button(player); ImGui::EndListBox(); } ImGui::PopStyleColor(2); - - ImGui::End(); } + ImGui::End(); } }