diff --git a/src/Components/Modules/Friends.cpp b/src/Components/Modules/Friends.cpp index b77a983a..ea15a68b 100644 --- a/src/Components/Modules/Friends.cpp +++ b/src/Components/Modules/Friends.cpp @@ -11,6 +11,10 @@ namespace Components std::recursive_mutex Friends::Mutex; std::vector Friends::FriendsList; + Dvar::Var Friends::UIStreamFriendly; + Dvar::Var Friends::CLAnonymous; + Dvar::Var Friends::CLNotifyFriendState; + void Friends::SortIndividualList(std::vector* list) { std::stable_sort(list->begin(), list->end(), [](Friends::Friend const& friend1, Friends::Friend const& friend2) @@ -111,8 +115,8 @@ namespace Components Friends::SortList(); - const auto notify = Dvar::Var("cl_notifyFriendState").get(); - if (gotOnline && (!notify || (notify && !Game::CL_IsCgameInitialized())) && !Dvar::Var("ui_streamFriendly").get()) + const auto notify = Friends::CLNotifyFriendState.get(); + if (gotOnline && (!notify || (notify && !Game::CL_IsCgameInitialized())) && !Friends::UIStreamFriendly.get()) { Game::Material* material = Friends::CreateAvatar(user); Toast::Show(material, entry->name, "is playing IW4x", 3000, [material]() @@ -124,7 +128,7 @@ namespace Components void Friends::UpdateState(bool force) { - if (Dvar::Var("cl_anonymous").get() || Friends::IsInvisible() || !Steam::Enabled()) return; + if (Friends::CLAnonymous.get() || Friends::IsInvisible() || !Steam::Enabled()) return; if (force) { @@ -228,7 +232,7 @@ namespace Components void Friends::SetPresence(const std::string& key, const std::string& value) { - if (Steam::Proxy::ClientFriends && Steam::Proxy::SteamUtils && !Dvar::Var("cl_anonymous").get() && !Friends::IsInvisible() && Steam::Enabled()) + if (Steam::Proxy::ClientFriends && Steam::Proxy::SteamUtils && !Friends::CLAnonymous.get() && !Friends::IsInvisible() && Steam::Enabled()) { Friends::SetRawPresence(key.data(), value.data()); } @@ -576,10 +580,15 @@ namespace Components { Friends::LoggedOn = false; - if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled() || Monitor::IsEnabled()) return; + if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled() || Monitor::IsEnabled()) + return; - Dvar::Register("cl_anonymous", false, Game::DVAR_ARCHIVE, "Enable invisible mode for Steam"); - Dvar::Register("cl_notifyFriendState", true, Game::DVAR_ARCHIVE, "Update friends about current game status"); + Dvar::OnInit([] + { + Friends::UIStreamFriendly = Dvar::Register("ui_streamFriendly", false, Game::DVAR_ARCHIVE, "Stream friendly UI"); + Friends::CLAnonymous = Dvar::Register("cl_anonymous", false, Game::DVAR_ARCHIVE, "Enable invisible mode for Steam"); + Friends::CLNotifyFriendState = Dvar::Register("cl_notifyFriendState", true, Game::DVAR_ARCHIVE, "Update friends about current game status"); + }); Command::Add("addFriend", [](Command::Params* params) { @@ -712,11 +721,11 @@ namespace Components Friends::InitialState = Steam::Proxy::SteamFriends->GetFriendPersonaState(Steam::Proxy::SteamUser_->GetSteamID()); } - if (Dvar::Var("cl_anonymous").get() || Friends::IsInvisible() || !Steam::Enabled()) + if (Friends::CLAnonymous.get() || Friends::IsInvisible() || !Steam::Enabled()) { if (Steam::Proxy::ClientFriends) { - for (auto id : Friends::GetAppIdList()) + for (const auto id : Friends::GetAppIdList()) { Steam::Proxy::ClientFriends.invoke("ClearRichPresence", id); } diff --git a/src/Components/Modules/Friends.hpp b/src/Components/Modules/Friends.hpp index db1ec171..c4d7b602 100644 --- a/src/Components/Modules/Friends.hpp +++ b/src/Components/Modules/Friends.hpp @@ -25,6 +25,10 @@ namespace Components static bool IsInvisible(); + static Dvar::Var UIStreamFriendly; + static Dvar::Var CLAnonymous; + static Dvar::Var CLNotifyFriendState; + private: #pragma pack(push, 4) struct FriendRichPresenceUpdate diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index de055020..d8c1d1f6 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -858,9 +858,6 @@ namespace Components }); #endif - // Dvars - Dvar::Register("ui_streamFriendly", false, Game::DVAR_ARCHIVE, "Stream friendly UI"); - // Debug patches #ifdef DEBUG // ui_debugMode 1 diff --git a/src/Components/Modules/Renderer.cpp b/src/Components/Modules/Renderer.cpp index efa91e94..7eaaabd7 100644 --- a/src/Components/Modules/Renderer.cpp +++ b/src/Components/Modules/Renderer.cpp @@ -502,7 +502,7 @@ namespace Components // } // }); - // Log broken materials + // Log broken materials Utils::Hook(0x0054CAAA, Renderer::StoreGfxBufContextPtrStub1, HOOK_JUMP).install()->quick(); Utils::Hook(0x0054CF8D, Renderer::StoreGfxBufContextPtrStub2, HOOK_JUMP).install()->quick(); diff --git a/src/Components/Modules/Renderer.hpp b/src/Components/Modules/Renderer.hpp index 553dd336..9e43a154 100644 --- a/src/Components/Modules/Renderer.hpp +++ b/src/Components/Modules/Renderer.hpp @@ -18,7 +18,6 @@ namespace Components static void OnDeviceRecoveryEnd(Utils::Slot callback); static void OnDeviceRecoveryBegin(Utils::Slot callback); - private: static void FrameStub(); diff --git a/src/Components/Modules/ServerInfo.cpp b/src/Components/Modules/ServerInfo.cpp index abefa873..cd7d7b6f 100644 --- a/src/Components/Modules/ServerInfo.cpp +++ b/src/Components/Modules/ServerInfo.cpp @@ -4,6 +4,9 @@ namespace Components { ServerInfo::Container ServerInfo::PlayerContainer; + Game::dvar_t** ServerInfo::CGScoreboardHeight; + Game::dvar_t** ServerInfo::CGScoreboardWidth; + unsigned int ServerInfo::GetPlayerCount() { return ServerInfo::PlayerContainer.playerList.size(); @@ -74,22 +77,24 @@ namespace Components void ServerInfo::DrawScoreboardInfo(int localClientNum) { Game::Font_s* font = Game::R_RegisterFont("fonts/bigfont", 0); - void* cxt = Game::ScrPlace_GetActivePlacement(localClientNum); + const auto* cxt = Game::ScrPlace_GetActivePlacement(localClientNum); - std::string addressText = Network::Address(*Game::connectedHost).getString(); - if (addressText == "0.0.0.0:0" || addressText == "loopback") addressText = "Listen Server"; + auto addressText = Network::Address(*Game::connectedHost).getString(); - // get x positions - float fontSize = 0.35f; - float y = (480.0f - Dvar::Var("cg_scoreboardHeight").get()) * 0.5f; - y += Dvar::Var("cg_scoreboardHeight").get() + 6.0f; + if (addressText == "0.0.0.0:0" || addressText == "loopback") + addressText = "Listen Server"; - float x = 320.0f - Dvar::Var("cg_scoreboardWidth").get() * 0.5f; - float x2 = 320.0f + Dvar::Var("cg_scoreboardWidth").get() * 0.5f; + // Get x positions + auto y = (480.0f - (*ServerInfo::CGScoreboardHeight)->current.value) * 0.5f; + y += (*ServerInfo::CGScoreboardHeight)->current.value + 6.0f; - // draw only when stream friendly ui is not enabled - if (!Dvar::Var("ui_streamFriendly").get()) + const auto x = 320.0f - (*ServerInfo::CGScoreboardWidth)->current.value * 0.5f; + const auto x2 = 320.0f + (*ServerInfo::CGScoreboardWidth)->current.value * 0.5f; + + // Draw only when stream friendly ui is not enabled + if (!Friends::UIStreamFriendly.get()) { + constexpr auto fontSize = 0.35f; Game::UI_DrawText(cxt, reinterpret_cast(0x7ED3F8), 0x7FFFFFFF, font, x, y, 0, 0, fontSize, reinterpret_cast(0x747F34), 3); Game::UI_DrawText(cxt, addressText.data(), 0x7FFFFFFF, font, x2 - Game::UI_TextWidth(addressText.data(), 0, font, fontSize), y, 0, 0, fontSize, reinterpret_cast(0x747F34), 3); } @@ -172,7 +177,9 @@ namespace Components ServerInfo::ServerInfo() { ServerInfo::PlayerContainer.currentPlayer = 0; - ServerInfo::PlayerContainer.playerList.clear(); + + ServerInfo::CGScoreboardHeight = reinterpret_cast(0x9FD070); + ServerInfo::CGScoreboardWidth = reinterpret_cast(0x9FD0AC); // Draw IP and hostname on the scoreboard Utils::Hook(0x4FC6EA, ServerInfo::DrawScoreboardStub, HOOK_CALL).install()->quick(); diff --git a/src/Components/Modules/ServerInfo.hpp b/src/Components/Modules/ServerInfo.hpp index 36dd8cf7..0eee5b6b 100644 --- a/src/Components/Modules/ServerInfo.hpp +++ b/src/Components/Modules/ServerInfo.hpp @@ -28,6 +28,9 @@ namespace Components Network::Address target; }; + static Game::dvar_t** CGScoreboardHeight; + static Game::dvar_t** CGScoreboardWidth; + static Container PlayerContainer; static void ServerStatus(UIScript::Token); diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index a4e61251..c2351a23 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -14,6 +14,11 @@ namespace Components std::vector ServerList::VisibleList; + Dvar::Var ServerList::UIServerSelected; + Dvar::Var ServerList::UIServerSelectedMap; + Dvar::Var ServerList::NETServerQueryLimit; + Dvar::Var ServerList::NETServerFrames; + std::vector* ServerList::GetList() { if (ServerList::IsOnlineList()) @@ -154,13 +159,13 @@ namespace Components if (info) { - Dvar::Var("ui_serverSelected").set(true); - Dvar::Var("ui_serverSelectedMap").set(info->mapname); + ServerList::UIServerSelected.set(true); + ServerList::UIServerSelectedMap.set(info->mapname); Dvar::Var("ui_serverSelectedGametype").set(info->gametype); } else { - Dvar::Var("ui_serverSelected").set(false); + ServerList::UIServerSelected.set(false); } } @@ -621,8 +626,11 @@ namespace Components void ServerList::Frame() { static Utils::Time::Interval frameLimit; - int interval = static_cast(1000.0f / Dvar::Var("net_serverFrames").get()); - if (!frameLimit.elapsed(std::chrono::milliseconds(interval))) return; + const auto interval = static_cast(1000.0f / ServerList::NETServerFrames.get()); + + if (!frameLimit.elapsed(std::chrono::milliseconds(interval))) + return; + frameLimit.update(); std::lock_guard _(ServerList::RefreshContainer.mutex); @@ -638,7 +646,7 @@ namespace Components } } - int requestLimit = Dvar::Var("net_serverQueryLimit").get(); + auto requestLimit = ServerList::NETServerQueryLimit.get(); for (unsigned int i = 0; i < ServerList::RefreshContainer.servers.size() && requestLimit > 0; ++i) { ServerList::Container::ServerContainer* server = &ServerList::RefreshContainer.servers[i]; @@ -734,11 +742,15 @@ namespace Components Dvar::OnInit([]() { - Dvar::Register("ui_serverSelected", false, Game::dvar_flag::DVAR_NONE, "Whether a server has been selected in the serverlist"); - Dvar::Register("ui_serverSelectedMap", "mp_afghan", Game::dvar_flag::DVAR_NONE, "Map of the selected server"); + ServerList::UIServerSelected = Dvar::Register("ui_serverSelected", false, + Game::dvar_flag::DVAR_NONE, "Whether a server has been selected in the serverlist"); + ServerList::UIServerSelectedMap = Dvar::Register("ui_serverSelectedMap", "mp_afghan", + Game::dvar_flag::DVAR_NONE, "Map of the selected server"); - Dvar::Register("net_serverQueryLimit", 1, 1, 10, Dedicated::IsEnabled() ? Game::dvar_flag::DVAR_NONE : Game::dvar_flag::DVAR_ARCHIVE, "Amount of server queries per frame"); - Dvar::Register("net_serverFrames", 30, 1, 60, Dedicated::IsEnabled() ? Game::dvar_flag::DVAR_NONE : Game::dvar_flag::DVAR_ARCHIVE, "Amount of server query frames per second"); + ServerList::NETServerQueryLimit = Dvar::Register("net_serverQueryLimit", 1, + 1, 10, Dedicated::IsEnabled() ? Game::dvar_flag::DVAR_NONE : Game::dvar_flag::DVAR_ARCHIVE, "Amount of server queries per frame"); + ServerList::NETServerFrames = Dvar::Register("net_serverFrames", 30, + 1, 60, Dedicated::IsEnabled() ? Game::dvar_flag::DVAR_NONE : Game::dvar_flag::DVAR_ARCHIVE, "Amount of server query frames per second"); }); // Fix ui_netsource dvar @@ -794,6 +806,7 @@ namespace Components UIScript::Add("RefreshFilter", ServerList::UpdateVisibleList); UIScript::Add("RefreshServers", ServerList::Refresh); + UIScript::Add("JoinServer", [](UIScript::Token) { ServerList::ServerInfo* info = ServerList::GetServer(ServerList::CurrentServer); @@ -803,6 +816,7 @@ namespace Components Party::Connect(info->addr); } }); + UIScript::Add("ServerSort", [](UIScript::Token token) { int key = token.get(); @@ -820,6 +834,7 @@ namespace Components Logger::Print("Sorting server list by token: %d\n", ServerList::SortKey); ServerList::SortList(); }); + UIScript::Add("CreateListFavorite", [](UIScript::Token) { ServerList::ServerInfo* info = ServerList::GetCurrentServer(); @@ -829,10 +844,12 @@ namespace Components ServerList::StoreFavourite(info->addr.getString()); } }); + UIScript::Add("CreateFavorite", [](UIScript::Token) { ServerList::StoreFavourite(Dvar::Var("ui_favoriteAddress").get()); }); + UIScript::Add("CreateCurrentServerFavorite", [](UIScript::Token) { if (Game::CL_IsCgameInitialized()) @@ -844,6 +861,7 @@ namespace Components } } }); + UIScript::Add("DeleteFavorite", [](UIScript::Token) { ServerList::ServerInfo* info = ServerList::GetCurrentServer(); @@ -854,17 +872,18 @@ namespace Components }; }); +#ifdef _DEBUG Command::Add("playerCount", [](Command::Params*) { - int count = 0; - for (auto server : ServerList::OnlineList) + auto count = 0; + for (const auto& server : ServerList::OnlineList) { count += server.clients; } Logger::Print("There are %d players playing.\n", count); }); - +#endif // Add required ownerDraws UIScript::AddOwnerDraw(220, ServerList::UpdateSource); UIScript::AddOwnerDraw(253, ServerList::UpdateGameType); diff --git a/src/Components/Modules/ServerList.hpp b/src/Components/Modules/ServerList.hpp index d125f02f..87e4526f 100644 --- a/src/Components/Modules/ServerList.hpp +++ b/src/Components/Modules/ServerList.hpp @@ -138,5 +138,10 @@ namespace Components static std::vector FavouriteList; static std::vector VisibleList; + + static Dvar::Var UIServerSelected; + static Dvar::Var UIServerSelectedMap; + static Dvar::Var NETServerQueryLimit; + static Dvar::Var NETServerFrames; }; } diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index aa0d8869..80610630 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -624,7 +624,7 @@ namespace Game typedef void(__cdecl * Playlist_ParsePlaylists_t)(const char* data); extern Playlist_ParsePlaylists_t Playlist_ParsePlaylists; - typedef Font_s* (__cdecl * R_RegisterFont_t)(const char* asset, int safe); + typedef Font_s*(__cdecl * R_RegisterFont_t)(const char* asset, int safe); extern R_RegisterFont_t R_RegisterFont; typedef void(__cdecl * R_AddCmdDrawText_t)(const char *text, int maxChars, Font_s *font, float x, float y, float xScale, float yScale, float rotation, const float *color, int style); @@ -915,13 +915,13 @@ namespace Game typedef void(__cdecl * UI_DrawHandlePic_t)(/*ScreenPlacement*/void *scrPlace, float x, float y, float w, float h, int horzAlign, int vertAlign, const float *color, Material *material); extern UI_DrawHandlePic_t UI_DrawHandlePic; - typedef ScreenPlacement* (__cdecl * ScrPlace_GetActivePlacement_t)(int localClientNum); + typedef ScreenPlacement*(__cdecl * ScrPlace_GetActivePlacement_t)(int localClientNum); extern ScrPlace_GetActivePlacement_t ScrPlace_GetActivePlacement; typedef int(__cdecl * UI_TextWidth_t)(const char *text, int maxChars, Font_s *font, float scale); extern UI_TextWidth_t UI_TextWidth; - typedef void(__cdecl * UI_DrawText_t)(void* scrPlace, const char *text, int maxChars, Font_s *font, float x, float y, int horzAlign, int vertAlign, float scale, const float *color, int style); + typedef void(__cdecl * UI_DrawText_t)(const ScreenPlacement* scrPlace, const char* text, int maxChars, Font_s* font, float x, float y, int horzAlign, int vertAlign, float scale, const float* color, int style); extern UI_DrawText_t UI_DrawText; typedef Font_s* (__cdecl* UI_GetFontHandle_t)(ScreenPlacement* scrPlace, int fontEnum, float scale);