+void Client::sendInit(const std::string &playerName)
+{
+ NetworkPacket pkt(TOSERVER_INIT, 1 + 2 + 2 + (1 + playerName.size()));
+
+ // we don't support network compression yet
+ u16 supp_comp_modes = NETPROTO_COMPRESSION_NONE;
+ pkt << (u8) SER_FMT_VER_HIGHEST_READ << (u16) supp_comp_modes;
+ pkt << (u16) CLIENT_PROTOCOL_VERSION_MIN << (u16) CLIENT_PROTOCOL_VERSION_MAX;
+ pkt << playerName;
+
+ Send(&pkt);
+}
+
+void Client::startAuth(AuthMechanism chosen_auth_mechanism)
+{
+ m_chosen_auth_mech = chosen_auth_mechanism;
+
+ switch (chosen_auth_mechanism) {
+ case AUTH_MECHANISM_FIRST_SRP: {
+ // send srp verifier to server
+ NetworkPacket resp_pkt(TOSERVER_FIRST_SRP, 0);
+ char *salt, *bytes_v;
+ std::size_t len_salt, len_v;
+ salt = NULL;
+ getSRPVerifier(getPlayerName(), m_password,
+ &salt, &len_salt, &bytes_v, &len_v);
+ resp_pkt
+ << std::string((char*)salt, len_salt)
+ << std::string((char*)bytes_v, len_v)
+ << (u8)((m_password == "") ? 1 : 0);
+ free(salt);
+ free(bytes_v);
+ Send(&resp_pkt);
+ break;
+ }
+ case AUTH_MECHANISM_SRP:
+ case AUTH_MECHANISM_LEGACY_PASSWORD: {
+ u8 based_on = 1;
+
+ if (chosen_auth_mechanism == AUTH_MECHANISM_LEGACY_PASSWORD) {
+ m_password = translatePassword(getPlayerName(), m_password);
+ based_on = 0;
+ }
+
+ std::string playername_u = lowercase(getPlayerName());
+ m_auth_data = srp_user_new(SRP_SHA256, SRP_NG_2048,
+ getPlayerName().c_str(), playername_u.c_str(),
+ (const unsigned char *) m_password.c_str(),
+ m_password.length(), NULL, NULL);
+ char *bytes_A = 0;
+ size_t len_A = 0;
+ SRP_Result res = srp_user_start_authentication(
+ (struct SRPUser *) m_auth_data, NULL, NULL, 0,
+ (unsigned char **) &bytes_A, &len_A);
+ FATAL_ERROR_IF(res != SRP_OK, "Creating local SRP user failed.");
+
+ NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_A, 0);
+ resp_pkt << std::string(bytes_A, len_A) << based_on;
+ Send(&resp_pkt);
+ break;
+ }
+ case AUTH_MECHANISM_NONE:
+ break; // not handled in this method
+ }
+}
+