diff options
Diffstat (limited to 'primedev/masterserver/masterserver.h')
-rw-r--r-- | primedev/masterserver/masterserver.h | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/primedev/masterserver/masterserver.h b/primedev/masterserver/masterserver.h new file mode 100644 index 00000000..570db619 --- /dev/null +++ b/primedev/masterserver/masterserver.h @@ -0,0 +1,199 @@ +#pragma once + +#include "core/convar/convar.h" +#include "server/serverpresence.h" +#include <winsock2.h> +#include <string> +#include <cstring> +#include <future> +#include <unordered_set> + +extern ConVar* Cvar_ns_masterserver_hostname; +extern ConVar* Cvar_ns_curl_log_enable; + +struct RemoteModInfo +{ +public: + std::string Name; + std::string Version; +}; + +class RemoteServerInfo +{ +public: + char id[33]; // 32 bytes + nullterminator + + // server info + char name[64]; + std::string description; + char map[32]; + char playlist[16]; + char region[32]; + std::vector<RemoteModInfo> requiredMods; + + int playerCount; + int maxPlayers; + + // connection stuff + bool requiresPassword; + +public: + RemoteServerInfo( + const char* newId, + const char* newName, + const char* newDescription, + const char* newMap, + const char* newPlaylist, + const char* newRegion, + int newPlayerCount, + int newMaxPlayers, + bool newRequiresPassword); +}; + +struct RemoteServerConnectionInfo +{ +public: + char authToken[32]; + + in_addr ip; + unsigned short port; +}; + +struct MainMenuPromoData +{ +public: + std::string newInfoTitle1; + std::string newInfoTitle2; + std::string newInfoTitle3; + + std::string largeButtonTitle; + std::string largeButtonText; + std::string largeButtonUrl; + int largeButtonImageIndex; + + std::string smallButton1Title; + std::string smallButton1Url; + int smallButton1ImageIndex; + + std::string smallButton2Title; + std::string smallButton2Url; + int smallButton2ImageIndex; +}; + +class MasterServerManager +{ +private: + bool m_bRequestingServerList = false; + bool m_bAuthenticatingWithGameServer = false; + +public: + char m_sOwnServerId[33]; + char m_sOwnServerAuthToken[33]; + char m_sOwnClientAuthToken[33]; + + std::string m_sOwnModInfoJson; + + bool m_bOriginAuthWithMasterServerDone = false; + bool m_bOriginAuthWithMasterServerInProgress = false; + + bool m_bOriginAuthWithMasterServerSuccessful = false; + std::string m_sOriginAuthWithMasterServerErrorCode = ""; + std::string m_sOriginAuthWithMasterServerErrorMessage = ""; + + bool m_bSavingPersistentData = false; + + bool m_bScriptRequestingServerList = false; + bool m_bSuccessfullyConnected = true; + + bool m_bNewgameAfterSelfAuth = false; + bool m_bScriptAuthenticatingWithGameServer = false; + bool m_bSuccessfullyAuthenticatedWithGameServer = false; + std::string m_sAuthFailureReason {}; + + bool m_bHasPendingConnectionInfo = false; + RemoteServerConnectionInfo m_pendingConnectionInfo; + + std::vector<RemoteServerInfo> m_vRemoteServers; + + bool m_bHasMainMenuPromoData = false; + MainMenuPromoData m_sMainMenuPromoData; + + std::optional<RemoteServerInfo> m_currentServer; + std::string m_sCurrentServerPassword; + + std::unordered_set<std::string> m_handledServerConnections; + +public: + MasterServerManager(); + + void ClearServerList(); + void RequestServerList(); + void RequestMainMenuPromos(); + void AuthenticateOriginWithMasterServer(const char* uid, const char* originToken); + void AuthenticateWithOwnServer(const char* uid, const char* playerToken); + void AuthenticateWithServer(const char* uid, const char* playerToken, RemoteServerInfo server, const char* password); + void WritePlayerPersistentData(const char* playerId, const char* pdata, size_t pdataSize); + void ProcessConnectionlessPacketSigreq1(std::string req); +}; + +extern MasterServerManager* g_pMasterServerManager; +extern ConVar* Cvar_ns_masterserver_hostname; + +/** Result returned in the std::future of a MasterServerPresenceReporter::ReportPresence() call. */ +enum class MasterServerReportPresenceResult +{ + // Adding this server to the MS was successful. + Success, + // We failed to add this server to the MS and should retry. + Failed, + // We failed to add this server to the MS and shouldn't retry. + FailedNoRetry, + // We failed to even reach the MS. + FailedNoConnect, + // We failed to add the server because an existing server with the same ip:port exists. + FailedDuplicateServer, +}; + +class MasterServerPresenceReporter : public ServerPresenceReporter +{ +public: + /** Full data returned in the std::future of a MasterServerPresenceReporter::ReportPresence() call. */ + struct ReportPresenceResultData + { + MasterServerReportPresenceResult result; + + std::optional<std::string> id; + std::optional<std::string> serverAuthToken; + }; + + const int MAX_REGISTRATION_ATTEMPTS = 5; + + // Called to initialise the master server presence reporter's state. + void CreatePresence(const ServerPresence* pServerPresence) override; + + // Run on an internal to either add the server to the MS or update it. + void ReportPresence(const ServerPresence* pServerPresence) override; + + // Called when we need to remove the server from the master server. + void DestroyPresence(const ServerPresence* pServerPresence) override; + + // Called every frame. + void RunFrame(double flCurrentTime, const ServerPresence* pServerPresence) override; + +protected: + // Contains the async logic to add the server to the MS. + void InternalAddServer(const ServerPresence* pServerPresence); + + // Contains the async logic to update the server on the MS. + void InternalUpdateServer(const ServerPresence* pServerPresence); + + // The future used for InternalAddServer() calls. + std::future<ReportPresenceResultData> addServerFuture; + + // The future used for InternalAddServer() calls. + std::future<ReportPresenceResultData> updateServerFuture; + + int m_nNumRegistrationAttempts; + + double m_fNextAddServerAttemptTime; +}; |