8 #include "SQLiteCpp/Database.h" 9 #include "SQLiteCpp/Statement.h" 10 #include "../IniFile.h" 11 #include "json/json.h" 12 #include "../mbedTLS++/BlockingSslClientSocket.h" 13 #include "../mbedTLS++/SslConfig.h" 14 #include "../RankManager.h" 15 #include "../OSSupport/IsThread.h" 32 #define DEFAULT_NAME_TO_UUID_SERVER "api.mojang.com" 33 #define DEFAULT_NAME_TO_UUID_ADDRESS "/profiles/minecraft" 34 #define DEFAULT_UUID_TO_PROFILE_SERVER "sessionserver.mojang.com" 35 #define DEFAULT_UUID_TO_PROFILE_ADDRESS "/session/minecraft/profile/%UUID%?unsigned=false" 44 static const char CertString[] =
48 "-----BEGIN CERTIFICATE-----\n" 49 "MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT\n" 50 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i\n" 51 "YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG\n" 52 "EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg\n" 53 "R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9\n" 54 "9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq\n" 55 "fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv\n" 56 "iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU\n" 57 "1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+\n" 58 "bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW\n" 59 "MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA\n" 60 "ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l\n" 61 "uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn\n" 62 "Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS\n" 63 "tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF\n" 64 "PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un\n" 65 "hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV\n" 66 "5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==\n" 67 "-----END CERTIFICATE-----\n\n" 71 "-----BEGIN CERTIFICATE-----\n" 72 "MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV\n" 73 "UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy\n" 74 "dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1\n" 75 "MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx\n" 76 "dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B\n" 77 "AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f\n" 78 "BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A\n" 79 "cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC\n" 80 "AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ\n" 81 "MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm\n" 82 "aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw\n" 83 "ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj\n" 84 "IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF\n" 85 "MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA\n" 86 "A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y\n" 87 "7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh\n" 88 "1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4\n" 89 "-----END CERTIFICATE-----\n\n" 94 "-----BEGIN CERTIFICATE-----\n" 95 "MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n" 96 "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n" 97 "HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs\n" 98 "ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw\n" 99 "MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\n" 100 "b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj\n" 101 "aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp\n" 102 "Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\n" 103 "ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg\n" 104 "nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1\n" 105 "HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N\n" 106 "Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN\n" 107 "dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0\n" 108 "HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO\n" 109 "BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G\n" 110 "CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU\n" 111 "sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3\n" 112 "4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg\n" 113 "8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K\n" 114 "pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\n" 115 "mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n" 116 "-----END CERTIFICATE-----\n\n" 119 "-----BEGIN CERTIFICATE-----\n" 120 "MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n" 121 "MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n" 122 "U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw\n" 123 "NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE\n" 124 "ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp\n" 125 "ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3\n" 126 "DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf\n" 127 "8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN\n" 128 "+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0\n" 129 "X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa\n" 130 "K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA\n" 131 "1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G\n" 132 "A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR\n" 133 "zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0\n" 134 "YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD\n" 135 "bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w\n" 136 "DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3\n" 137 "L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D\n" 138 "eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\n" 139 "xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp\n" 140 "VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n" 141 "WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n" 142 "-----END CERTIFICATE-----\n" 145 static auto X509Cert = [&]()
147 auto Cert = std::make_shared<cX509Cert>();
148 VERIFY(0 == Cert->Parse(CertString,
sizeof(CertString)));
162 static const std::shared_ptr<const cSslConfig> Config = []()
181 const cUUID & a_UUID,
182 const Json::Value & a_Properties,
185 m_PlayerName(a_PlayerName),
188 m_TexturesSignature(),
189 m_DateTime(a_DateTime)
204 if (!a_Properties.isArray())
209 Json::UInt Size = a_Properties.size();
210 for (Json::UInt i = 0; i < Size; i++)
212 const Json::Value & Prop = a_Properties[i];
213 AString PropName = Prop.get(
"name",
"").asString();
214 if (PropName !=
"textures")
218 m_Textures = Prop.get(
"value",
"").asString();
237 super(
"cMojangAPI::cUpdateThread"),
238 m_MojangAPI(a_MojangAPI)
245 m_ShouldTerminate =
true;
267 }
while (!m_ShouldTerminate && !m_evtNotify.
Wait(60 * 60 * 1000));
324 if (!a_UseOnlyCached)
332 cProfileMap::const_iterator itr =
m_NameToUUID.find(lcPlayerName);
338 return itr->second.m_UUID;
353 return itr->second.m_PlayerName;
361 return itr->second.m_PlayerName;
366 if (!a_UseOnlyCached)
384 for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr)
390 if (!a_UseOnlyCached)
397 std::vector<cUUID> res;
398 res.resize(PlayerNames.size());
400 for (AStringVector::const_iterator itr = PlayerNames.begin(), end = PlayerNames.end(); itr != end; ++itr, ++idx)
402 cProfileMap::const_iterator itrN =
m_NameToUUID.find(*itr);
405 res[idx] = itrN->second.m_UUID;
417 Int64 Now = time(
nullptr);
435 Int64 Now = time(
nullptr);
461 if (!Socket.
Connect(a_ServerName, 443))
467 if (!Socket.
Send(a_Request.c_str(), a_Request.size()))
474 unsigned char buf[1024];
478 int ret = Socket.
Receive(buf,
sizeof(buf));
480 if ((ret == MBEDTLS_ERR_SSL_WANT_READ) || (ret == MBEDTLS_ERR_SSL_WANT_WRITE))
483 LOGWARNING(
"%s: SSL reading failed internally", __FUNCTION__);
486 if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
492 LOGWARNING(
"%s: SSL reading failed: -0x%x", __FUNCTION__, -ret);
500 a_Response.append(reinterpret_cast<const char *>(buf), static_cast<size_t>(ret));
515 SQLite::Database db(
"MojangAPI.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
516 db.exec(
"CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)");
517 db.exec(
"CREATE TABLE IF NOT EXISTS UUIDToProfile (UUID, PlayerName, Textures, TexturesSignature, DateTime)");
521 SQLite::Statement stmt(db,
"SELECT PlayerName, UUID, DateTime FROM PlayerNameToUUID");
522 while (stmt.executeStep())
524 AString PlayerName = stmt.getColumn(0);
525 AString StringUUID = stmt.getColumn(1);
526 Int64 DateTime = stmt.getColumn(2);
539 SQLite::Statement stmt(db,
"SELECT PlayerName, UUID, Textures, TexturesSignature, DateTime FROM UUIDToProfile");
540 while (stmt.executeStep())
542 AString PlayerName = stmt.getColumn(0);
543 AString StringUUID = stmt.getColumn(1);
544 AString Textures = stmt.getColumn(2);
545 AString TexturesSignature = stmt.getColumn(2);
546 Int64 DateTime = stmt.getColumn(4);
558 catch (
const SQLite::Exception & ex)
560 LOGINFO(
"Loading MojangAPI cache failed: %s", ex.what());
573 SQLite::Database db(
"MojangAPI.sqlite", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
574 db.exec(
"CREATE TABLE IF NOT EXISTS PlayerNameToUUID (PlayerName, UUID, DateTime)");
575 db.exec(
"CREATE TABLE IF NOT EXISTS UUIDToProfile (UUID, PlayerName, Textures, TexturesSignature, DateTime)");
578 db.exec(
"DELETE FROM PlayerNameToUUID");
579 db.exec(
"DELETE FROM UUIDToProfile");
584 SQLite::Statement stmt(db,
"INSERT INTO PlayerNameToUUID(PlayerName, UUID, DateTime) VALUES (?, ?, ?)");
588 auto & Profile = NameToUUID.second;
589 if (Profile.m_DateTime < LimitDateTime)
594 stmt.bind(1, Profile.m_PlayerName);
595 stmt.bind(2, Profile.m_UUID.ToShortString());
596 stmt.bind(3, Profile.m_DateTime);
604 SQLite::Statement stmt(db,
"INSERT INTO UUIDToProfile(UUID, PlayerName, Textures, TexturesSignature, DateTime) VALUES (?, ?, ?, ?, ?)");
608 auto & Profile = UUIDToProfile.second;
609 if (Profile.m_DateTime < LimitDateTime)
614 stmt.bind(1, Profile.m_UUID.ToShortString());
615 stmt.bind(2, Profile.m_PlayerName);
616 stmt.bind(3, Profile.m_Textures);
617 stmt.bind(4, Profile.m_TexturesSignature);
618 stmt.bind(5, Profile.m_DateTime);
624 catch (
const SQLite::Exception & ex)
626 LOGINFO(
"Saving MojangAPI cache failed: %s", ex.what());
638 NamesToQuery.reserve(a_PlayerNames.size());
641 for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr)
645 NamesToQuery.push_back(*itr);
659 while (!a_NamesToQuery.empty())
664 AStringVector::iterator itr = a_NamesToQuery.begin(), end = a_NamesToQuery.end();
665 for (; (itr != end) && (Count <
MAX_PER_QUERY); ++itr, ++Count)
667 Json::Value req(*itr);
670 a_NamesToQuery.erase(a_NamesToQuery.begin(), itr);
671 Json::FastWriter Writer;
672 AString RequestBody = Writer.write(root);
678 Request +=
"User-Agent: Cuberite\r\n";
679 Request +=
"Connection: close\r\n";
680 Request +=
"Content-Type: application/json\r\n";
681 Request +=
Printf(
"Content-Length: %u\r\n", static_cast<unsigned>(RequestBody.length()));
683 Request += RequestBody;
693 const AString Prefix(
"HTTP/1.1 200 OK");
695 if (Response.compare(0, Prefix.size(), Prefix))
697 LOGINFO(
"%s failed: bad HTTP status line received", __FUNCTION__);
698 LOGD(
"Response: \n%s",
CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
703 size_t idxHeadersEnd = Response.find(
"\r\n\r\n");
704 if (idxHeadersEnd == AString::npos)
706 LOGINFO(
"%s failed: bad HTTP response header received", __FUNCTION__);
707 LOGD(
"Response: \n%s",
CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
710 Response.erase(0, idxHeadersEnd + 4);
714 if (!reader.parse(Response, root,
false) || !root.isArray())
716 LOGWARNING(
"%s failed: Cannot parse received data (NameToUUID) to JSON: \"%s\"", __FUNCTION__, reader.getFormattedErrorMessages().c_str());
717 LOGD(
"Response body:\n%s",
CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
722 Json::Value::UInt JsonCount = root.size();
723 Int64 Now = time(
nullptr);
726 for (Json::Value::UInt idx = 0; idx < JsonCount; ++idx)
728 Json::Value & Val = root[idx];
729 AString JsonName = Val.get(
"name",
"").asString();
731 if (!JsonUUID.
FromString(Val.get(
"id",
"").asString()))
743 for (Json::Value::UInt idx = 0; idx < JsonCount; ++idx)
745 Json::Value & Val = root[idx];
746 AString JsonName = Val.get(
"name",
"").asString();
748 if (!JsonUUID.
FromString(Val.get(
"id",
"").asString()))
788 Request +=
"GET " + Address +
" HTTP/1.0\r\n";
790 Request +=
"User-Agent: Cuberite\r\n";
791 Request +=
"Connection: close\r\n";
792 Request +=
"Content-Length: 0\r\n";
803 const AString Prefix(
"HTTP/1.1 200 OK");
805 if (Response.compare(0, Prefix.size(), Prefix))
807 LOGINFO(
"%s failed: bad HTTP status line received", __FUNCTION__);
808 LOGD(
"Response: \n%s",
CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
813 size_t idxHeadersEnd = Response.find(
"\r\n\r\n");
814 if (idxHeadersEnd == AString::npos)
816 LOGINFO(
"%s failed: bad HTTP response header received", __FUNCTION__);
817 LOGD(
"Response: \n%s",
CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
820 Response.erase(0, idxHeadersEnd + 4);
825 if (!reader.parse(Response, root,
false) || !root.isObject())
827 LOGWARNING(
"%s failed: Cannot parse received data (NameToUUID) to JSON: \"%s\"", __FUNCTION__, reader.getFormattedErrorMessages().c_str());
828 LOGD(
"Response body:\n%s",
CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
848 AString PlayerName = root.get(
"name",
"").asString();
849 if (PlayerName.empty())
854 Json::Value Properties = root.get(
"properties",
"");
855 Int64 Now = time(
nullptr);
899 if (NameToUUID.second.m_DateTime < LimitDateTime)
901 PlayerNames.push_back(NameToUUID.first);
905 if (!PlayerNames.empty())
907 LOG(
"cMojangAPI: Updating name-to-uuid cache for %u names", static_cast<unsigned>(PlayerNames.size()));
912 std::vector<cUUID> ProfileUUIDs;
917 if (UUIDToProfile.second.m_DateTime < LimitDateTime)
919 ProfileUUIDs.push_back(UUIDToProfile.first);
923 if (!ProfileUUIDs.empty())
925 LOG(
"cMojangAPI: Updating uuid-to-profile cache for %u uuids", static_cast<unsigned>(ProfileUUIDs.size()));
926 for (
const auto & UUID : ProfileUUIDs)
void QueryNamesToUUIDs(AStringVector &a_PlayerNames)
Queries all the specified names and stores them into the m_PlayerNameToUUID cache.
AString m_UUIDToProfileAddress
The URL to use for converting UUID to profile, without the server part.
void SetExpectedPeerName(AString a_ExpectedPeerName)
Sets the Expected peer name.
void SaveCachesToDisk(void)
Saves the caches to a disk storage.
void Update(void)
Updates the stale values in the DB from the Mojang servers.
cMojangAPI & m_MojangAPI
The cMojangAPI instance to update.
std::vector< cUUID > GetUUIDsFromPlayerNames(const AStringVector &a_PlayerName, bool a_UseOnlyCached=false)
Converts the player names into UUIDs.
void NotifyNameUUID(const AString &a_PlayerName, const cUUID &a_PlayerUUID)
Called for each name-uuid pairing that is discovered.
const Int64 MAX_AGE
The maximum age for items to be kept in the cache.
std::shared_ptr< cX509Cert > cX509CertPtr
AString ToShortString() const
Converts the UUID to a short form string (i.e without dashes).
void AddPlayerNameToUUIDMapping(const AString &a_PlayerName, const cUUID &a_UUID)
Called by the Authenticator to add a PlayerName -> UUID mapping that it has received from authenticat...
bool FromString(const AString &a_StringUUID)
Tries to interpret the string as a short or long form UUID and assign from it.
Holds data for a single player profile.
cRankManager * m_RankMgr
The rank manager that is notified of the name-uuid pairings.
cCriticalSection m_CSNameToUUID
Protects m_NameToUUID against simultaneous multi-threaded access.
void Start(cSettingsRepositoryInterface &a_Settings, bool a_ShouldAuth)
Initializes the API; reads the settings from the specified ini file.
void CacheNamesToUUIDs(const AStringVector &a_PlayerNames)
Makes sure all specified names are in the m_PlayerNameToUUID cache.
cCriticalSection m_CSUUIDToName
Protects m_UUIDToName against simultaneous multi-threaded access.
AString m_UUIDToProfileServer
The server to connect to when converting UUID to profile.
virtual ~cUpdateThread() override
void NotifyNameUUID(const AString &a_PlayerName, const cUUID &a_UUID)
Called by cMojangAPI whenever the playername-uuid pairing is discovered.
void ReplaceString(AString &iHayStack, const AString &iNeedle, const AString &iReplaceWith)
Replaces each occurence of iNeedle in iHayStack with iReplaceWith.
AString m_NameToUUIDServer
The server to connect to when converting player names to UUIDs.
void AddPlayerProfile(const AString &a_PlayerName, const cUUID &a_UUID, const Json::Value &a_Properties)
Called by the Authenticator to add a profile that it has received from authenticating a user...
void SetSslConfig(std::shared_ptr< const cSslConfig > a_Config)
Set the config to be used by the SSL context.
cEvent m_evtNotify
The event used for notifying that the thread should terminate, as well as timing. ...
sProfile(void)
Default constructor for the container's sake.
static std::shared_ptr< cSslConfig > MakeDefaultConfig(bool a_IsClient)
Creates a new config with some sensible defaults on top of mbedTLS basic settings.
#define DEFAULT_UUID_TO_PROFILE_ADDRESS
std::vector< AString > AStringVector
cUpdateThread(cMojangAPI &a_MojangAPI)
static bool SecureRequest(const AString &a_ServerName, const AString &a_Request, AString &a_Response)
Connects to the specified server using SSL, sends the given request and receives the response...
AString GetPlayerNameFromUUID(const cUUID &a_UUID, bool a_UseOnlyCached=false)
Converts a UUID into a playername.
void Wait(void)
Waits until the event has been set.
static cX509CertPtr GetCACerts(void)
Returns the CA certificates that should be trusted for Mojang-related connections.
AString m_NameToUUIDAddress
The URL to use for converting player names to UUIDs, without server part.
const AString & GetLastErrorText(void) const
Returns the text of the last error that has occurred in this instance.
void LOGINFO(const char *a_Format, fmt::ArgList a_ArgList)
AString & Printf(AString &str, const char *format, fmt::ArgList args)
Output the formatted text into the string.
#define DEFAULT_NAME_TO_UUID_SERVER
void LOGWARNING(const char *a_Format, fmt::ArgList a_ArgList)
virtual AString GetValueSet(const AString &keyname, const AString &valuename, const AString &defValue="")=0
Gets the value; if not found, write the default to the repository.
cUUIDProfileMap m_UUIDToProfile
Cache for the UUID-to-profile lookups.
cUUIDProfileMap m_UUIDToName
Cache for the Name-to-UUID lookups.
void QueryUUIDToProfile(const cUUID &a_UUID)
Queries the specified UUID's profile and stores it in the m_UUIDToProfile cache.
cUUID GetUUIDFromPlayerName(const AString &a_PlayerName, bool a_UseOnlyCached=false)
Converts a player name into a UUID.
std::shared_ptr< cUpdateThread > m_UpdateThread
The thread that periodically updates the stale data in the DB from the Mojang servers.
cCriticalSection m_CSUUIDToProfile
Protects m_UUIDToProfile against simultaneous multi-threaded access.
void LoadCachesFromDisk(void)
Loads the caches from a disk storage.
void LOG(const char *a_Format, fmt::ArgList a_ArgList)
AString & CreateHexDump(AString &a_Out, const void *a_Data, size_t a_Size, size_t a_BytesPerLine)
format binary data this way: 00001234: 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66 1234567890abcd...
static std::shared_ptr< const cSslConfig > GetSslConfig()
Returns the config to be used for secure requests.
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
#define DEFAULT_UUID_TO_PROFILE_SERVER
#define DEFAULT_NAME_TO_UUID_ADDRESS
bool Connect(const AString &a_ServerName, UInt16 a_Port)
Connects to the specified server and performs SSL handshake.
void CacheUUIDToProfile(const cUUID &a_UUID)
Makes sure the specified UUID is in the m_UUIDToProfile cache.
int Receive(void *a_Data, size_t a_MaxBytes)
Receives data from the connection.
virtual void Execute(void) override
This is the main thread entrypoint.
AString StrToLower(const AString &s)
Returns a lower-cased copy of the string.
const int MAX_PER_QUERY
The maximum number of names to send in a single query.
cProfileMap m_NameToUUID
Cache for the Name-to-UUID lookups.
cCriticalSection m_CSRankMgr
Protects m_RankMgr agains simultaneous multi-threaded access.
AString m_TexturesSignature
bool Send(const void *a_Data, size_t a_NumBytes)
Sends the specified data over the connection.