summaryrefslogtreecommitdiffstats
path: root/src/Protocol/MojangAPI.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Protocol/MojangAPI.h')
-rw-r--r--src/Protocol/MojangAPI.h226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h
new file mode 100644
index 000000000..fa4c16e4e
--- /dev/null
+++ b/src/Protocol/MojangAPI.h
@@ -0,0 +1,226 @@
+
+// MojangAPI.h
+
+// Declares the cMojangAPI class representing the various API points provided by Mojang's webservices, and a cache for their results
+
+
+
+
+
+#pragma once
+
+#include <time.h>
+
+
+
+
+
+// fwd: ../RankManager.h"
+class cRankManager;
+
+namespace Json
+{
+ class Value;
+}
+
+
+
+
+
+// tolua_begin
+class cMojangAPI
+{
+public:
+ // tolua_end
+
+ cMojangAPI(void);
+ ~cMojangAPI();
+
+ /** Initializes the API; reads the settings from the specified ini file.
+ Loads cached results from disk. */
+ void Start(cIniFile & a_SettingsIni);
+
+ /** Connects to the specified server using SSL, sends the given request and receives the response.
+ Checks Mojang certificates using the hard-coded Starfield root CA certificate.
+ Returns true if all was successful, false on failure. */
+ static bool SecureRequest(const AString & a_ServerName, const AString & a_Request, AString & a_Response);
+
+ /** Normalizes the given UUID to its short form (32 bytes, no dashes, lowercase).
+ Logs a warning and returns empty string if not a UUID.
+ Note: only checks the string's length, not the actual content. */
+ static AString MakeUUIDShort(const AString & a_UUID);
+
+ /** Normalizes the given UUID to its dashed form (36 bytes, 4 dashes, lowercase).
+ Logs a warning and returns empty string if not a UUID.
+ Note: only checks the string's length, not the actual content. */
+ static AString MakeUUIDDashed(const AString & a_UUID);
+
+ /** Converts a player name into a UUID.
+ The UUID will be empty on error.
+ If a_UseOnlyCached is true, the function only consults the cached values.
+ If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking
+ operation, do not use this in world-tick thread!
+ If you have multiple names to resolve, use the GetUUIDsFromPlayerNames() function, it uses a single request for multiple names. */
+ AString GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached = false);
+
+ /** Converts a UUID into a playername.
+ The returned playername will be empty on error.
+ Both short and dashed UUID formats are accepted.
+ Uses both m_UUIDToName and m_UUIDToProfile to search for the value. Uses m_UUIDToProfile for cache.
+ If a_UseOnlyCached is true, the function only consults the cached values.
+ If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking
+ operation, do not use this in world-tick thread! */
+ AString GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached = false);
+
+ /** Converts the player names into UUIDs.
+ a_PlayerName[idx] will be converted to UUID and returned as idx-th value
+ The UUID will be empty on error.
+ If a_UseOnlyCached is true, only the cached values are returned.
+ If a_UseOnlyCached is false, the names not found in the cache are looked up online, which is a blocking
+ operation, do not use this in world-tick thread! */
+ AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName, bool a_UseOnlyCached = false);
+
+ /** Called by the Authenticator to add a PlayerName -> UUID mapping that it has received from
+ authenticating a user. This adds the cache item and "refreshes" it if existing, adjusting its datetime
+ stamp to now. */
+ void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID);
+
+ /** Called by the Authenticator to add a profile that it has received from authenticating a user. Adds
+ the profile to the respective mapping caches and updtes their datetime stamp to now. */
+ void AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties);
+
+ /** Sets the m_RankMgr that is used for name-uuid notifications. Accepts NULL to remove the binding. */
+ void SetRankManager(cRankManager * a_RankManager) { m_RankMgr = a_RankManager; }
+
+protected:
+ /** The thread that periodically checks for stale data and re-queries it from the server. */
+ class cUpdateThread;
+
+
+ /** Holds data for a single player profile. */
+ struct sProfile
+ {
+ AString m_PlayerName; // Case-correct playername
+ AString m_UUID; // Short lowercased UUID
+ AString m_Textures; // The Textures field of the profile properties
+ AString m_TexturesSignature; // The signature of the Textures field of the profile properties
+ Int64 m_DateTime; // UNIXtime of the profile lookup
+
+ /** Default constructor for the container's sake. */
+ sProfile(void) :
+ m_PlayerName(),
+ m_UUID(),
+ m_Textures(),
+ m_TexturesSignature(),
+ m_DateTime(time(NULL))
+ {
+ }
+
+ /** Constructor for the storage creation. */
+ sProfile(
+ const AString & a_PlayerName,
+ const AString & a_UUID,
+ const AString & a_Textures,
+ const AString & a_TexturesSignature,
+ Int64 a_DateTime
+ ) :
+ m_PlayerName(a_PlayerName),
+ m_UUID(a_UUID),
+ m_Textures(a_Textures),
+ m_TexturesSignature(a_TexturesSignature),
+ m_DateTime(a_DateTime)
+ {
+ }
+
+ /** Constructor that parses the values from the Json profile. */
+ sProfile(
+ const AString & a_PlayerName,
+ const AString & a_UUID,
+ const Json::Value & a_Properties,
+ Int64 a_DateTime
+ );
+ };
+ typedef std::map<AString, sProfile> cProfileMap;
+
+
+ /** The server to connect to when converting player names to UUIDs. For example "api.mojang.com". */
+ AString m_NameToUUIDServer;
+
+ /** The URL to use for converting player names to UUIDs, without server part.
+ For example "/profiles/page/1". */
+ AString m_NameToUUIDAddress;
+
+ /** The server to connect to when converting UUID to profile. For example "sessionserver.mojang.com". */
+ AString m_UUIDToProfileServer;
+
+ /** The URL to use for converting UUID to profile, without the server part.
+ Will replace %UUID% with the actual UUID. For example "session/minecraft/profile/%UUID%?unsigned=false". */
+ AString m_UUIDToProfileAddress;
+
+ /** Cache for the Name-to-UUID lookups. The map key is lowercased PlayerName. Protected by m_CSNameToUUID. */
+ cProfileMap m_NameToUUID;
+
+ /** Protects m_NameToUUID against simultaneous multi-threaded access. */
+ cCriticalSection m_CSNameToUUID;
+
+ /** Cache for the Name-to-UUID lookups. The map key is lowercased short UUID. Protected by m_CSUUIDToName. */
+ cProfileMap m_UUIDToName;
+
+ /** Protects m_UUIDToName against simultaneous multi-threaded access. */
+ cCriticalSection m_CSUUIDToName;
+
+ /** Cache for the UUID-to-profile lookups. The map key is lowercased short UUID.
+ Protected by m_CSUUIDToProfile. */
+ cProfileMap m_UUIDToProfile;
+
+ /** Protects m_UUIDToProfile against simultaneous multi-threaded access. */
+ cCriticalSection m_CSUUIDToProfile;
+
+ /** The rank manager that is notified of the name-uuid pairings. May be NULL. Protected by m_CSRankMgr. */
+ cRankManager * m_RankMgr;
+
+ /** Protects m_RankMgr agains simultaneous multi-threaded access. */
+ cCriticalSection m_CSRankMgr;
+
+ /** The thread that periodically updates the stale data in the DB from the Mojang servers. */
+ SharedPtr<cUpdateThread> m_UpdateThread;
+
+
+ /** Loads the caches from a disk storage. */
+ void LoadCachesFromDisk(void);
+
+ /** Saves the caches to a disk storage. */
+ void SaveCachesToDisk(void);
+
+ /** Makes sure all specified names are in the m_PlayerNameToUUID cache. Downloads any missing ones from Mojang API servers.
+ Names that are not valid are not added into the cache.
+ ASSUMEs that a_PlayerNames contains lowercased player names. */
+ void CacheNamesToUUIDs(const AStringVector & a_PlayerNames);
+
+ /** Queries all the specified names and stores them into the m_PlayerNameToUUID cache.
+ Names that are not valid are not added into the cache.
+ ASSUMEs that a_PlayerNames contans lowercased player names.
+ For performance reasons takes a non-const reference and modifies the list given to it, until empty. */
+ void QueryNamesToUUIDs(AStringVector & a_PlayerNames);
+
+ /** Makes sure the specified UUID is in the m_UUIDToProfile cache. If missing, downloads it from Mojang API servers.
+ UUIDs that are not valid will not be added into the cache.
+ ASSUMEs that a_UUID is a lowercased short UUID. */
+ void CacheUUIDToProfile(const AString & a_UUID);
+
+ /** Queries the specified UUID's profile and stores it in the m_UUIDToProfile cache. If already present, updates the cache entry.
+ UUIDs that are not valid will not be added into the cache.
+ ASSUMEs that a_UUID is a lowercased short UUID. */
+ void QueryUUIDToProfile(const AString & a_UUID);
+
+ /** Called for each name-uuid pairing that is discovered.
+ If assigned, notifies the m_RankManager of the event. */
+ void NotifyNameUUID(const AString & a_PlayerName, const AString & a_PlayerUUID);
+
+ /** Updates the stale values in the DB from the Mojang servers. Called from the cUpdateThread, blocks on the HTTPS API calls. */
+ void Update(void);
+} ; // tolua_export
+
+
+
+