From 1d7b32b789ae11f36e4cc02ca244fd9572b1bfc0 Mon Sep 17 00:00:00 2001
From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com>
Date: Mon, 27 Jun 2022 16:54:40 +0200
Subject: [PATCH] Preparation work for pylon master server implementation

---
 r5dev/gameui/IBrowser.cpp           | 43 ++++++++++++++---------------
 r5dev/gameui/IBrowser.h             |  6 ++--
 r5dev/networksystem/pylon.cpp       |  2 +-
 r5dev/networksystem/r5net.cpp       | 18 ++++++------
 r5dev/networksystem/r5net.h         |  6 ++--
 r5dev/networksystem/serverlisting.h | 31 ++++++++++++++-------
 r5dev/squirrel/sqinit.cpp           |  4 +--
 7 files changed, 60 insertions(+), 50 deletions(-)

diff --git a/r5dev/gameui/IBrowser.cpp b/r5dev/gameui/IBrowser.cpp
index ee931300..3b4b73c7 100644
--- a/r5dev/gameui/IBrowser.cpp
+++ b/r5dev/gameui/IBrowser.cpp
@@ -90,25 +90,20 @@ void CBrowser::Draw(void)
 
     int nVars = 0;
     ImGui::PushStyleVar(ImGuiStyleVar_Alpha, m_flFadeAlpha);                   nVars++;
-    ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(750, 510));        nVars++;
+    ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(750, 524));        nVars++;
 
     if (!m_bModernTheme)
     {
         ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 1.0f);              nVars++;
     }
 
-    if (!ImGui::Begin(m_pszBrowserTitle, &m_bActivate))
+    if (!ImGui::Begin(m_pszBrowserTitle, &m_bActivate, ImGuiWindowFlags_NoScrollbar))
     {
         ImGui::End();
         ImGui::PopStyleVar(nVars);
         return;
     }
-    ImGui::End();
-
-    ImGui::Begin(m_pszBrowserTitle, NULL, ImGuiWindowFlags_NoScrollbar);
-    {
-        BasePanel();
-    }
+    BasePanel();
     ImGui::End();
     ImGui::PopStyleVar(nVars);
 }
@@ -141,13 +136,13 @@ void CBrowser::Think(void)
 void CBrowser::BasePanel(void)
 {
     ImGui::BeginTabBar("CompMenu");
-    if (ImGui::BeginTabItem("Server Browser"))
+    if (ImGui::BeginTabItem("Browsing"))
     {
         BrowserPanel();
         ImGui::EndTabItem();
     }
 #ifndef CLIENT_DLL
-    if (ImGui::BeginTabItem("Host Server"))
+    if (ImGui::BeginTabItem("Hosting"))
     {
         HostPanel();
         ImGui::EndTabItem();
@@ -194,17 +189,18 @@ void CBrowser::BrowserPanel(void)
     {
         ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 25);
         ImGui::TableSetupColumn("Map", ImGuiTableColumnFlags_WidthStretch, 20);
-        ImGui::TableSetupColumn("Port", ImGuiTableColumnFlags_WidthStretch, 5);
         ImGui::TableSetupColumn("Playlist", ImGuiTableColumnFlags_WidthStretch, 10);
-        ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 5);
+        ImGui::TableSetupColumn("Players", ImGuiTableColumnFlags_WidthStretch, 5);
+        ImGui::TableSetupColumn("Port", ImGuiTableColumnFlags_WidthStretch, 5);
         ImGui::TableHeadersRow();
 
-        for (ServerListing& server : m_vServerList)
+        for (NetGameServer_t& server : m_vServerList)
         {
             const char* pszHostName = server.svServerName.c_str();
             const char* pszHostMap  = server.svMapName.c_str();
             const char* pszHostPort = server.svPort.c_str();
             const char* pszPlaylist = server.svPlaylist.c_str();
+            const char* pszPlayers  = server.svPlaylist.c_str();
 
             if (m_imServerBrowserFilter.PassFilter(pszHostName)
                 || m_imServerBrowserFilter.PassFilter(pszHostMap)
@@ -216,11 +212,14 @@ void CBrowser::BrowserPanel(void)
                 ImGui::TableNextColumn();
                 ImGui::Text(pszHostMap);
 
+                ImGui::TableNextColumn();
+                ImGui::Text(pszPlaylist);
+
                 ImGui::TableNextColumn();
                 ImGui::Text(pszHostPort);
 
                 ImGui::TableNextColumn();
-                ImGui::Text(pszPlaylist);
+                ImGui::Text(pszPlayers);
 
                 ImGui::TableNextColumn();
                 string svConnectBtn = "Connect##";
@@ -338,7 +337,7 @@ void CBrowser::LaunchServer(void)
     * Playlist gets parsed in two instances, first in KeyValues::ParsePlaylists with all the neccessary values.
     * Then when you would normally call launchplaylist which calls StartPlaylist it would cmd call mp_gamemode which parses the gamemode specific part of the playlist..
     */
-    KeyValues_ParsePlaylists(m_Server.svPlaylist.c_str());
+    KeyValues::ParsePlaylists(m_Server.svPlaylist.c_str());
     stringstream ssModeCommand;
     ssModeCommand << "mp_gamemode " << m_Server.svPlaylist;
     ProcessCommand(ssModeCommand.str().c_str());
@@ -392,7 +391,7 @@ void CBrowser::HiddenServersModal(void)
         if (ImGui::Button("Connect", ImVec2(ImGui::GetWindowContentRegionWidth() / 2, 24)))
         {
             m_svHiddenServerRequestMessage.clear();
-            ServerListing server;
+            NetGameServer_t server;
             bool result = g_pR5net->GetServerByToken(server, m_svHiddenServerRequestMessage, m_svHiddenServerToken); // Send token connect request.
             if (!server.svServerName.empty())
             {
@@ -525,7 +524,7 @@ void CBrowser::HostPanel(void)
     }
 
     ImGui::TextColored(ImVec4(1.00f, 0.00f, 0.00f, 1.00f), svServerNameErr.c_str());
-    ImGui::TextColored(m_iv4HostRequestMessageColor, m_svHostRequestMessage.c_str());
+    ImGui::TextColored(m_HostRequestMessageColor, m_svHostRequestMessage.c_str());
     if (!m_svHostToken.empty())
     {
         ImGui::InputText("##ServerHost_HostToken", &m_svHostToken, ImGuiInputTextFlags_ReadOnly);
@@ -587,7 +586,7 @@ void CBrowser::UpdateHostingStatus(void)
     case eHostStatus::NOT_HOSTING:
     {
         m_svHostRequestMessage.clear();
-        m_iv4HostRequestMessageColor = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
+        m_HostRequestMessageColor = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
         break;
     }
     case eHostStatus::HOSTING:
@@ -632,7 +631,7 @@ void CBrowser::SendHostingPostRequest(void)
 #ifndef CLIENT_DLL
     m_svHostToken.clear();
     bool result = g_pR5net->PostServerHost(m_svHostRequestMessage, m_svHostToken,
-        ServerListing
+        NetGameServer_t
         {
             m_Server.svServerName.c_str(),
             string(g_pHostState->m_levelName),
@@ -649,7 +648,7 @@ void CBrowser::SendHostingPostRequest(void)
 
     if (result)
     {
-        m_iv4HostRequestMessageColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f);
+        m_HostRequestMessageColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f);
         stringstream ssMessage;
         ssMessage << "Broadcasting! ";
         if (!m_svHostToken.empty())
@@ -661,7 +660,7 @@ void CBrowser::SendHostingPostRequest(void)
     }
     else
     {
-        m_iv4HostRequestMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
+        m_HostRequestMessageColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
     }
 #endif // !CLIENT_DLL
 }
@@ -693,7 +692,7 @@ void CBrowser::SettingsPanel(void)
             g_pR5net = new R5Net::Client(r5net_matchmaking_hostname->GetString());
         }
     }
-    ImGui::InputText("Netkey", (char*)g_svNetKey.c_str(), ImGuiInputTextFlags_ReadOnly);
+    ImGui::InputText("Netkey", const_cast<char*>(g_svNetKey.c_str()), ImGuiInputTextFlags_ReadOnly);
     if (ImGui::Button("Regenerate Encryption Key"))
     {
         RegenerateEncryptionKey();
diff --git a/r5dev/gameui/IBrowser.h b/r5dev/gameui/IBrowser.h
index e54f79e7..5c88126f 100644
--- a/r5dev/gameui/IBrowser.h
+++ b/r5dev/gameui/IBrowser.h
@@ -74,7 +74,7 @@ public:
     float m_flFadeAlpha = 0.f;
     const char* m_pszBrowserTitle = nullptr;
 
-    vector<ServerListing> m_vServerList;
+    vector<NetGameServer_t> m_vServerList;
     ImGuiTextFilter m_imServerBrowserFilter;
     char m_szServerAddressBuffer[256] = { '\0' };
     char m_szServerEncKeyBuffer[30]   = { '\0' };
@@ -88,10 +88,10 @@ public:
     ////////////////////
     //   Host Server  //
     ////////////////////
-    ServerListing m_Server;
+    NetGameServer_t m_Server;
     string m_svHostRequestMessage;
     string m_svHostToken;
-    ImVec4 m_iv4HostRequestMessageColor = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
+    ImVec4 m_HostRequestMessageColor = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
 
     ////////////////////
     // Private Server //
diff --git a/r5dev/networksystem/pylon.cpp b/r5dev/networksystem/pylon.cpp
index 7e3e820a..a31cef45 100644
--- a/r5dev/networksystem/pylon.cpp
+++ b/r5dev/networksystem/pylon.cpp
@@ -27,7 +27,7 @@ void KeepAliveToPylon()
 		std::string m_szHostRequestMessage = std::string();
 
 		bool result = g_pR5net->PostServerHost(m_szHostRequestMessage, m_szHostToken,
-			ServerListing{
+			NetGameServer_t{
 				hostname->GetString(),
 				std::string(g_pHostState->m_levelName),
 				"",
diff --git a/r5dev/networksystem/r5net.cpp b/r5dev/networksystem/r5net.cpp
index bb0ffd39..e64ecc49 100644
--- a/r5dev/networksystem/r5net.cpp
+++ b/r5dev/networksystem/r5net.cpp
@@ -16,9 +16,9 @@ string R5Net::Client::GetSDKVersion()
 //-----------------------------------------------------------------------------
 // Purpose: returns a vector of hosted servers.
 //-----------------------------------------------------------------------------
-vector<ServerListing> R5Net::Client::GetServersList(string& svOutMessage)
+vector<NetGameServer_t> R5Net::Client::GetServersList(string& svOutMessage)
 {
-    vector<ServerListing> vslList{};
+    vector<NetGameServer_t> vslList{};
 
     nlohmann::json jsRequestBody = nlohmann::json::object();
     jsRequestBody["version"] = GetSDKVersion();
@@ -46,7 +46,7 @@ vector<ServerListing> R5Net::Client::GetServersList(string& svOutMessage)
             for (auto &obj : jsResultBody["servers"])
             {
                 vslList.push_back(
-                    ServerListing{
+                    NetGameServer_t{
                         obj.value("name",""),
                         obj.value("map", ""),
                         obj.value("ip", ""),
@@ -110,7 +110,7 @@ vector<ServerListing> R5Net::Client::GetServersList(string& svOutMessage)
 //			&slServerListing - 
 // Output : Returns true on success, false on failure.
 //-----------------------------------------------------------------------------
-bool R5Net::Client::PostServerHost(string& svOutMessage, string& svOutToken, const ServerListing& slServerListing)
+bool R5Net::Client::PostServerHost(string& svOutMessage, string& svOutToken, const NetGameServer_t& slServerListing)
 {
     nlohmann::json jsRequestBody = nlohmann::json::object();
     jsRequestBody["name"] = slServerListing.svServerName;
@@ -206,7 +206,7 @@ bool R5Net::Client::PostServerHost(string& svOutMessage, string& svOutToken, con
 //			svToken - 
 // Output : Returns true on success, false on failure.
 //-----------------------------------------------------------------------------
-bool R5Net::Client::GetServerByToken(ServerListing& slOutServer, string& svOutMessage, const string& svToken)
+bool R5Net::Client::GetServerByToken(NetGameServer_t& slOutServer, string& svOutMessage, const string& svToken)
 {
     nlohmann::json jsRequestBody = nlohmann::json::object();
     jsRequestBody["token"] = svToken;
@@ -233,7 +233,7 @@ bool R5Net::Client::GetServerByToken(ServerListing& slOutServer, string& svOutMe
 
             if (htResults && jsResultBody["success"].is_boolean() && jsResultBody["success"])
             {
-                slOutServer = ServerListing{
+                slOutServer = NetGameServer_t{
                         jsResultBody["server"].value("name",""),
                         jsResultBody["server"].value("map", ""),
                         jsResultBody["server"].value("ip", ""),
@@ -257,7 +257,7 @@ bool R5Net::Client::GetServerByToken(ServerListing& slOutServer, string& svOutMe
                     svOutMessage = "";
                 }
 
-                slOutServer = ServerListing{};
+                slOutServer = NetGameServer_t{};
                 return false;
             }
         }
@@ -287,7 +287,7 @@ bool R5Net::Client::GetServerByToken(ServerListing& slOutServer, string& svOutMe
         }
 
         svOutMessage = "Failed to reach comp-server. Unknown error code.";
-        slOutServer = ServerListing{};
+        slOutServer = NetGameServer_t{};
         return false;
     }
 
@@ -325,4 +325,4 @@ bool R5Net::Client::GetClientIsBanned(const string& svIpAddress, uint64_t nOrigi
     return false;
 }
 ///////////////////////////////////////////////////////////////////////////////
-R5Net::Client* g_pR5net(new R5Net::Client("r5a-comp-sv.herokuapp.com"));
+R5Net::Client* g_pR5net(new R5Net::Client("127.0.0.1:3000"));
diff --git a/r5dev/networksystem/r5net.h b/r5dev/networksystem/r5net.h
index c958dd62..9305dc2f 100644
--- a/r5dev/networksystem/r5net.h
+++ b/r5dev/networksystem/r5net.h
@@ -11,9 +11,9 @@ namespace R5Net
 			m_HttpClient.set_connection_timeout(10);
 		}
 	
-		vector<ServerListing> GetServersList(string& svOutMessage);
-		bool PostServerHost(string& svOutMessage, string& svOutToken, const ServerListing& slServerListing);
-		bool GetServerByToken(ServerListing& slOutServer, string& svOutMessage, const string& svToken);
+		vector<NetGameServer_t> GetServersList(string& svOutMessage);
+		bool PostServerHost(string& svOutMessage, string& svOutToken, const NetGameServer_t& slServerListing);
+		bool GetServerByToken(NetGameServer_t& slOutServer, string& svOutMessage, const string& svToken);
 		bool GetClientIsBanned(const string& svIpAddress, uint64_t nOriginID, string& svOutErrCl);
 		string GetSDKVersion();
 
diff --git a/r5dev/networksystem/serverlisting.h b/r5dev/networksystem/serverlisting.h
index 1d29b2d7..0799e614 100644
--- a/r5dev/networksystem/serverlisting.h
+++ b/r5dev/networksystem/serverlisting.h
@@ -1,14 +1,25 @@
 #pragma once
 
-struct ServerListing
+
+struct NetGameMod_t
 {
-	std::string svServerName;
-	std::string svMapName = "mp_lobby";
-	std::string svIpAddress;
-	std::string svPort;
-	std::string svPlaylist = "dev_default";
-	bool bHidden{};
-	std::string svRemoteChecksum;
-	std::string svVersion;
-	std::string svEncryptionKey;
+	string m_svPackage;
+	int m_nNumber;
+	bool m_bRequired;
+	string m_svDownloadLink;
+
+	NLOHMANN_DEFINE_TYPE_INTRUSIVE(NetGameMod_t, m_svPackage, m_nNumber, m_bRequired, m_svDownloadLink)
+};
+
+struct NetGameServer_t
+{
+	string svServerName;
+	string svMapName = "mp_lobby";
+	string svPlaylist = "dev_default";
+	string svIpAddress;
+	string svPort;
+	bool bHidden{};
+	string svRemoteChecksum;
+	string svVersion;
+	string svEncryptionKey;
 };
diff --git a/r5dev/squirrel/sqinit.cpp b/r5dev/squirrel/sqinit.cpp
index fc62ce80..9b08b339 100644
--- a/r5dev/squirrel/sqinit.cpp
+++ b/r5dev/squirrel/sqinit.cpp
@@ -283,7 +283,7 @@ namespace VSquirrel
             string svHiddenServerRequestMessage;
             string svToken = sq_getstring(v, 1);
 
-            ServerListing svListing;
+            NetGameServer_t svListing;
             bool result = g_pR5net->GetServerByToken(svListing, svHiddenServerRequestMessage, svToken); // Send szToken connect request.
             if (result)
             {
@@ -301,7 +301,7 @@ namespace VSquirrel
             string svHiddenServerRequestMessage;
             string svToken = sq_getstring(v, 1);
 
-            ServerListing serverListing;
+            NetGameServer_t serverListing;
             bool result = g_pR5net->GetServerByToken(serverListing, svHiddenServerRequestMessage, svToken); // Send szToken connect request.
             if (!serverListing.svServerName.empty())
             {