From 44090244bc078e927035c4f12e8dd04d150d85d1 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 3 May 2022 00:17:31 -0500 Subject: [PATCH 1/8] use X Labs master server, node fallback --- src/Components/Modules/Dedicated.cpp | 2 -- src/Components/Modules/Node.cpp | 2 ++ src/Components/Modules/ServerList.cpp | 47 ++++++++++++++++++--------- src/Components/Modules/ServerList.hpp | 3 ++ 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp index b56e9ccb..6043607a 100644 --- a/src/Components/Modules/Dedicated.cpp +++ b/src/Components/Modules/Dedicated.cpp @@ -374,7 +374,6 @@ namespace Components } }); -#ifdef USE_LEGACY_SERVER_LIST // Heartbeats Scheduler::Once(Dedicated::Heartbeat); Scheduler::OnFrame([]() @@ -387,7 +386,6 @@ namespace Components Dedicated::Heartbeat(); } }); -#endif Dvar::OnInit([]() { diff --git a/src/Components/Modules/Node.cpp b/src/Components/Modules/Node.cpp index 50797f93..e08a597a 100644 --- a/src/Components/Modules/Node.cpp +++ b/src/Components/Modules/Node.cpp @@ -114,6 +114,7 @@ namespace Components void Node::StoreNodes(bool force) { + if (ServerList::useMasterServer) return; if (Dedicated::IsEnabled() && Dvar::Var("sv_lanOnly").get()) return; static Utils::Time::Interval interval; @@ -167,6 +168,7 @@ namespace Components void Node::RunFrame() { + if (ServerList::useMasterServer) return; if (Dedicated::IsEnabled() && Dvar::Var("sv_lanOnly").get()) return; if (!Dedicated::IsEnabled() && *Game::clcState > 0) diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 586c61e6..9e0099f4 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -19,6 +19,8 @@ namespace Components Dvar::Var ServerList::NETServerQueryLimit; Dvar::Var ServerList::NETServerFrames; + bool ServerList::useMasterServer = true; + std::vector* ServerList::GetList() { if (ServerList::IsOnlineList()) @@ -274,22 +276,31 @@ namespace Components } else if (ServerList::IsOnlineList()) { -#ifdef USE_LEGACY_SERVER_LIST - ServerList::RefreshContainer.awatingList = true; - ServerList::RefreshContainer.awaitTime = Game::Sys_Milliseconds(); + const auto masterPort = Dvar::Var("masterPort").get(); + const auto masterServerName = Dvar::Var("masterServerName").get(); - int masterPort = Dvar::Var("masterPort").get(); - const char* masterServerName = Dvar::Var("masterServerName").get(); + Game::netadr_t masterServerAddr; + if (ServerList::GetMasterServer(masterServerAddr)) + { + Logger::Print("A valid master server was found at %s:%u\n", masterServerName, masterPort); - ServerList::RefreshContainer.host = Network::Address(Utils::String::VA("%s:%u", masterServerName, masterPort)); + ServerList::RefreshContainer.awatingList = true; + ServerList::RefreshContainer.awaitTime = Game::Sys_Milliseconds(); - Logger::Print("Sending serverlist request to master: %s:%u\n", masterServerName, masterPort); + ServerList::RefreshContainer.host = Network::Address(Utils::String::VA("%s:%u", masterServerName, masterPort)); - Network::SendCommand(ServerList::RefreshContainer.host, "getservers", Utils::String::VA("IW4 %i full empty", PROTOCOL)); - //Network::SendCommand(ServerList::RefreshContainer.Host, "getservers", "0 full empty"); -#else - Node::Synchronize(); -#endif + Logger::Print("Sending serverlist request to master\n"); + Network::SendCommand(ServerList::RefreshContainer.host, "getservers", Utils::String::VA("IW4 %i full empty", PROTOCOL)); + } + else + { + // this should only be getting called if no master server is found or reached + Logger::Print("No valid master server was found, using node as fallback\n"); + + useMasterServer = false; + + Node::Synchronize(); + } } else if (ServerList::IsFavouriteList()) { @@ -733,6 +744,14 @@ namespace Components } } + bool ServerList::GetMasterServer(Game::netadr_t& address) + { + auto masterPort = Dvar::Var("masterPort").get(); + auto masterServerName = Dvar::Var("masterServerName").get(); + + return Game::NET_StringToAdr(Utils::String::VA("%s:%u"), &address); + } + ServerList::ServerList() { ServerList::OnlineList.clear(); @@ -792,11 +811,9 @@ namespace Components }); // Set default masterServerName + port and save it -#ifdef USE_LEGACY_SERVER_LIST - Utils::Hook::Set(0x60AD92, "127.0.0.1"); + Utils::Hook::Set(0x60AD92, "master.xlabs.dev"); Utils::Hook::Set(0x60AD90, Game::dvar_flag::DVAR_ARCHIVE); // masterServerName Utils::Hook::Set(0x60ADC6, Game::dvar_flag::DVAR_ARCHIVE); // masterPort -#endif // Add server list feeder UIFeeder::Add(2.0f, ServerList::GetServerCount, ServerList::GetServerText, ServerList::SelectServer); diff --git a/src/Components/Modules/ServerList.hpp b/src/Components/Modules/ServerList.hpp index 87e4526f..43f7c534 100644 --- a/src/Components/Modules/ServerList.hpp +++ b/src/Components/Modules/ServerList.hpp @@ -50,6 +50,9 @@ namespace Components static void UpdateVisibleInfo(); + static bool GetMasterServer(Game::netadr_t& address); + static bool useMasterServer; + private: enum Column { From 102e8862f2583d37de6ac3213b5b3d0755d663d6 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 3 May 2022 01:34:57 -0500 Subject: [PATCH 2/8] fix stutter, use node as fallback, add toasts --- src/Components/Modules/Node.cpp | 2 +- src/Components/Modules/ServerList.cpp | 38 +++++++++++++++++---------- src/Components/Modules/ServerList.hpp | 2 ++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/Components/Modules/Node.cpp b/src/Components/Modules/Node.cpp index e08a597a..69465959 100644 --- a/src/Components/Modules/Node.cpp +++ b/src/Components/Modules/Node.cpp @@ -248,7 +248,7 @@ namespace Components if (list.isnode() && (!list.port() || list.port() == address.getPort())) { - if (!Dedicated::IsEnabled() && ServerList::IsOnlineList() && list.protocol() == PROTOCOL) + if (!Dedicated::IsEnabled() && ServerList::IsOnlineList() && !ServerList::useMasterServer && list.protocol() == PROTOCOL) { NODE_LOG("Inserting %s into the serverlist\n", address.getCString()); ServerList::InsertRequest(address); diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 9e0099f4..77134ffe 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -282,7 +282,8 @@ namespace Components Game::netadr_t masterServerAddr; if (ServerList::GetMasterServer(masterServerAddr)) { - Logger::Print("A valid master server was found at %s:%u\n", masterServerName, masterPort); + Toast::Show("cardicon_headshot", "", "Fetching servers...", 3000); + useMasterServer = true; ServerList::RefreshContainer.awatingList = true; ServerList::RefreshContainer.awaitTime = Game::Sys_Milliseconds(); @@ -292,15 +293,6 @@ namespace Components Logger::Print("Sending serverlist request to master\n"); Network::SendCommand(ServerList::RefreshContainer.host, "getservers", Utils::String::VA("IW4 %i full empty", PROTOCOL)); } - else - { - // this should only be getting called if no master server is found or reached - Logger::Print("No valid master server was found, using node as fallback\n"); - - useMasterServer = false; - - Node::Synchronize(); - } } else if (ServerList::IsFavouriteList()) { @@ -581,8 +573,7 @@ namespace Components void ServerList::SortList() { // Only sort when the serverlist is open - Game::menuDef_t* menu = Game::Menus_FindByName(Game::uiContext, "pc_join_unranked"); - if (!menu || !Game::Menu_IsVisible(Game::uiContext, menu)) return; + if (!IsServerListOpen()) return; std::stable_sort(ServerList::VisibleList.begin(), ServerList::VisibleList.end(), [](const unsigned int &server1, const unsigned int &server2) -> bool { @@ -648,12 +639,22 @@ namespace Components if (ServerList::RefreshContainer.awatingList) { - // Check if we haven't got a response within 10 seconds + // Stop counting if we are out of the server browser menu + if (!IsServerListOpen()) + { + ServerList::RefreshContainer.awatingList = false; + } + + // Check if we haven't got a response within 5 seconds if (Game::Sys_Milliseconds() - ServerList::RefreshContainer.awaitTime > 5000) { ServerList::RefreshContainer.awatingList = false; Logger::Print("We haven't received a response from the master within %d seconds!\n", (Game::Sys_Milliseconds() - ServerList::RefreshContainer.awaitTime) / 1000); + Toast::Show("cardicon_headshot", "^1Error", "Failed to reach master server, using node servers instead.", 5000); + + useMasterServer = false; + Node::Synchronize(); } } @@ -749,7 +750,16 @@ namespace Components auto masterPort = Dvar::Var("masterPort").get(); auto masterServerName = Dvar::Var("masterServerName").get(); - return Game::NET_StringToAdr(Utils::String::VA("%s:%u"), &address); + return Game::NET_StringToAdr(Utils::String::VA("%s:%u", masterServerName, masterPort), &address); + } + + bool ServerList::IsServerListOpen() + { + Game::menuDef_t* menu = Game::Menus_FindByName(Game::uiContext, "pc_join_unranked"); + if (!menu) + return false; + + return Game::Menu_IsVisible(Game::uiContext, menu); } ServerList::ServerList() diff --git a/src/Components/Modules/ServerList.hpp b/src/Components/Modules/ServerList.hpp index 43f7c534..98c927a9 100644 --- a/src/Components/Modules/ServerList.hpp +++ b/src/Components/Modules/ServerList.hpp @@ -146,5 +146,7 @@ namespace Components static Dvar::Var UIServerSelectedMap; static Dvar::Var NETServerQueryLimit; static Dvar::Var NETServerFrames; + + static bool IsServerListOpen(); }; } From a0345bcdbeffb0d76c59af5462de9c039ed519b5 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 3 May 2022 01:38:51 -0500 Subject: [PATCH 3/8] don't refresh browser on updating filter... ... because this only causes a refresh if there are no servers to even begin with and the chance of that happening is kinda slim if we catch servers really fast. this also prevents 2 calls to Refresh right as you open a empty server browser. :stuck_out_tongue: --- src/Components/Modules/ServerList.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 77134ffe..3972c11e 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -207,13 +207,6 @@ namespace Components auto list = ServerList::GetList(); if (!list) return; - // Refresh entirely, if there is no entry in the list - if (list->empty()) - { - ServerList::Refresh(UIScript::Token()); - return; - } - bool ui_browserShowFull = Dvar::Var("ui_browserShowFull").get(); bool ui_browserShowEmpty = Dvar::Var("ui_browserShowEmpty").get(); int ui_browserShowHardcore = Dvar::Var("ui_browserKillcam").get(); From 000ad98408ea1543e33e681b9c85cf1fa1f3f4f7 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 3 May 2022 01:40:24 -0500 Subject: [PATCH 4/8] title for toast --- src/Components/Modules/ServerList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 3972c11e..d190809f 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -275,7 +275,7 @@ namespace Components Game::netadr_t masterServerAddr; if (ServerList::GetMasterServer(masterServerAddr)) { - Toast::Show("cardicon_headshot", "", "Fetching servers...", 3000); + Toast::Show("cardicon_headshot", "Server Browser", "Fetching servers...", 3000); useMasterServer = true; ServerList::RefreshContainer.awatingList = true; From 4e234e88ef4a11f3214177b7121ec5ee93fd73d6 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 3 May 2022 01:55:30 -0500 Subject: [PATCH 5/8] allow storing of nodes whenever --- src/Components/Modules/Node.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Components/Modules/Node.cpp b/src/Components/Modules/Node.cpp index 69465959..60d1d18b 100644 --- a/src/Components/Modules/Node.cpp +++ b/src/Components/Modules/Node.cpp @@ -114,7 +114,6 @@ namespace Components void Node::StoreNodes(bool force) { - if (ServerList::useMasterServer) return; if (Dedicated::IsEnabled() && Dvar::Var("sv_lanOnly").get()) return; static Utils::Time::Interval interval; From 00ac17c9015a8f82109a1c52ea51fa79fb1fb15e Mon Sep 17 00:00:00 2001 From: m Date: Tue, 3 May 2022 02:01:54 -0500 Subject: [PATCH 6/8] remove useless dvar fetching --- src/Components/Modules/ServerList.cpp | 9 +++------ src/Components/Modules/ServerList.hpp | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index d190809f..1b8bf202 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -273,7 +273,7 @@ namespace Components const auto masterServerName = Dvar::Var("masterServerName").get(); Game::netadr_t masterServerAddr; - if (ServerList::GetMasterServer(masterServerAddr)) + if (ServerList::GetMasterServer(masterServerName, masterPort, masterServerAddr)) { Toast::Show("cardicon_headshot", "Server Browser", "Fetching servers...", 3000); useMasterServer = true; @@ -738,12 +738,9 @@ namespace Components } } - bool ServerList::GetMasterServer(Game::netadr_t& address) + bool ServerList::GetMasterServer(const char* ip, int port, Game::netadr_t& address) { - auto masterPort = Dvar::Var("masterPort").get(); - auto masterServerName = Dvar::Var("masterServerName").get(); - - return Game::NET_StringToAdr(Utils::String::VA("%s:%u", masterServerName, masterPort), &address); + return Game::NET_StringToAdr(Utils::String::VA("%s:%u", ip, port), &address); } bool ServerList::IsServerListOpen() diff --git a/src/Components/Modules/ServerList.hpp b/src/Components/Modules/ServerList.hpp index 98c927a9..22754f7b 100644 --- a/src/Components/Modules/ServerList.hpp +++ b/src/Components/Modules/ServerList.hpp @@ -50,7 +50,7 @@ namespace Components static void UpdateVisibleInfo(); - static bool GetMasterServer(Game::netadr_t& address); + static bool GetMasterServer(const char* ip, int port, Game::netadr_t& address); static bool useMasterServer; private: From e63132b29b68fee6f114ce99e6317a38e2d40bbd Mon Sep 17 00:00:00 2001 From: m Date: Tue, 3 May 2022 04:10:48 -0500 Subject: [PATCH 7/8] changes --- src/Components/Modules/ServerList.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index 1b8bf202..cfab4f6d 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -566,7 +566,7 @@ namespace Components void ServerList::SortList() { // Only sort when the serverlist is open - if (!IsServerListOpen()) return; + if (!ServerList::IsServerListOpen()) return; std::stable_sort(ServerList::VisibleList.begin(), ServerList::VisibleList.end(), [](const unsigned int &server1, const unsigned int &server2) -> bool { @@ -633,7 +633,7 @@ namespace Components if (ServerList::RefreshContainer.awatingList) { // Stop counting if we are out of the server browser menu - if (!IsServerListOpen()) + if (!ServerList::IsServerListOpen()) { ServerList::RefreshContainer.awatingList = false; } @@ -745,7 +745,7 @@ namespace Components bool ServerList::IsServerListOpen() { - Game::menuDef_t* menu = Game::Menus_FindByName(Game::uiContext, "pc_join_unranked"); + auto* menu = Game::Menus_FindByName(Game::uiContext, "pc_join_unranked"); if (!menu) return false; @@ -811,7 +811,7 @@ namespace Components }); // Set default masterServerName + port and save it - Utils::Hook::Set(0x60AD92, "master.xlabs.dev"); + Utils::Hook::Set(0x60AD92, "master.xlabs.dev"); Utils::Hook::Set(0x60AD90, Game::dvar_flag::DVAR_ARCHIVE); // masterServerName Utils::Hook::Set(0x60ADC6, Game::dvar_flag::DVAR_ARCHIVE); // masterPort From 736d3a0e2453e32fed689a599eba85f13e7c03d2 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 3 May 2022 11:35:53 -0500 Subject: [PATCH 8/8] log failures to resolve address also adds toast to let the user know a error occured :D --- src/Components/Modules/ServerList.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp index cfab4f6d..d6af313a 100644 --- a/src/Components/Modules/ServerList.cpp +++ b/src/Components/Modules/ServerList.cpp @@ -272,20 +272,25 @@ namespace Components const auto masterPort = Dvar::Var("masterPort").get(); const auto masterServerName = Dvar::Var("masterServerName").get(); + // Check if our dvars can properly convert to a address Game::netadr_t masterServerAddr; - if (ServerList::GetMasterServer(masterServerName, masterPort, masterServerAddr)) + if (!ServerList::GetMasterServer(masterServerName, masterPort, masterServerAddr)) { - Toast::Show("cardicon_headshot", "Server Browser", "Fetching servers...", 3000); - useMasterServer = true; - - ServerList::RefreshContainer.awatingList = true; - ServerList::RefreshContainer.awaitTime = Game::Sys_Milliseconds(); - - ServerList::RefreshContainer.host = Network::Address(Utils::String::VA("%s:%u", masterServerName, masterPort)); - - Logger::Print("Sending serverlist request to master\n"); - Network::SendCommand(ServerList::RefreshContainer.host, "getservers", Utils::String::VA("IW4 %i full empty", PROTOCOL)); + Logger::Print("Could not resolve address for %s:%u", masterServerName, masterPort); + Toast::Show("cardicon_headshot", "^1Error", Utils::String::VA("Could not resolve address for %s:%u", masterServerName, masterPort), 5000); + return; } + + Toast::Show("cardicon_headshot", "Server Browser", "Fetching servers...", 3000); + + useMasterServer = true; + + ServerList::RefreshContainer.awatingList = true; + ServerList::RefreshContainer.awaitTime = Game::Sys_Milliseconds(); + ServerList::RefreshContainer.host = Network::Address(Utils::String::VA("%s:%u", masterServerName, masterPort)); + + Logger::Print("Sending serverlist request to master\n"); + Network::SendCommand(ServerList::RefreshContainer.host, "getservers", Utils::String::VA("IW4 %i full empty", PROTOCOL)); } else if (ServerList::IsFavouriteList()) {