Horizon Official Technical Documentation
Horizon::Auth::AuthClientInterface Class Reference

#include <AuthClientInterface.hpp>

+ Inheritance diagram for Horizon::Auth::AuthClientInterface:
+ Collaboration diagram for Horizon::Auth::AuthClientInterface:

Public Member Functions

 AuthClientInterface (std::shared_ptr< AuthSession > session)
 
 ~AuthClientInterface ()
 
bool process_login (std::string username, std::string hash, uint16_t version, uint16_t client_type)
 
bool client_login_otp_response ()
 
- Public Member Functions inherited from Horizon::ClientInterface< AuthSession >
 ClientInterface (std::shared_ptr< AuthSession > s)
 
 ~ClientInterface ()
 
std::shared_ptr< AuthSession > get_session ()
 
void set_session (std::shared_ptr< AuthSession > s)
 

Constructor & Destructor Documentation

◆ AuthClientInterface()

AuthClientInterface::AuthClientInterface ( std::shared_ptr< AuthSession session)
41{
42
43}
ClientInterface(std::shared_ptr< AuthSession > s)
Definition: ClientInterface.hpp:40

◆ ~AuthClientInterface()

AuthClientInterface::~AuthClientInterface ( )
46{
47
48}

Member Function Documentation

◆ client_login_otp_response()

bool AuthClientInterface::client_login_otp_response ( )
187{
189 pkt.deliver();
190 return true;
191}
Main object for the aegis packet: AC_LOGIN_OTP.
Definition: TransmittedPackets.hpp:673
std::shared_ptr< AuthSession > get_session()
Definition: ClientInterface.hpp:43

References Horizon::Auth::AC_LOGIN_OTP::deliver(), and Horizon::ClientInterface< AuthSession >::get_session().

+ Here is the call graph for this function:

◆ process_login()

bool AuthClientInterface::process_login ( std::string  username,
std::string  hash,
uint16_t  version,
uint16_t  client_type 
)
51{
54 int pos = 0;
55 char block_date[20]{ 0 };
56
57 if (((pos = username.find("_m")) || (pos = username.find("_f"))) && pos != std::string::npos) {
59
60 if (username.find("_m")) {
61 username = username.substr(0, pos);
62 gender = ACCOUNT_GENDER_MALE;
63 }
64 else if (username.find("_f")) {
65 username = username.substr(0, pos);
66 gender = ACCOUNT_GENDER_FEMALE;
67 }
68
69 std::vector<unsigned char> salt;
70 std::vector<unsigned char> hash;
71
72 auto conn = sAuth->get_database_connection();
73 try {
74 boost::mysql::statement stmt = conn->prepare_statement("SELECT * FROM `game_accounts` WHERE `username` = ?");
75 auto b1 = stmt.bind(username);
76 boost::mysql::results results;
77 conn->execute(b1, results);
78
79 if (results.rows().empty()) {
80 HLog(info) << "Recieved connection request for unknown account '" << username << "'.";
81
82 HLog(info) << "Creating a new account for user '" << username << "' with password '" << password << "'.";
83
84 sAuth->generate_salt(salt);
85
86 sAuth->hash_password(password, salt, hash);
87
88 try {
89 boost::mysql::statement stmt = conn->prepare_statement("INSERT INTO `game_accounts` (`username`, `hash`, `salt`, `email`, `birth_date`, `gender`, `group_id`, `state`, `login_count`, `last_login`, `last_ip`, `character_slots`, `pincode`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
90 auto b2 = stmt.bind(username, hash, salt, "a@a.com", "0000-00-00", gender == ACCOUNT_GENDER_MALE ? "M" : (gender == ACCOUNT_GENDER_FEMALE ? "F" : "NA"), 0, (int)ACCOUNT_STATE_NONE, 1, boost::mysql::date::now(), get_session()->get_socket()->remote_ip_address(), 3, "0000");
91 boost::mysql::results results2;
92 conn->execute(b2, results2);
93 uint32_t aid = results2.last_insert_id();
94 acal.deliver(aid, aid, 0, gender);
95
96 stmt = conn->prepare_statement("REPLACE INTO `session_data` (`auth_code`, `game_account_id`, `client_version`, `client_type`, `character_slots`, `group_id`, `connect_time`, `current_server`) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
97 auto b3 = stmt.bind(results2.last_insert_id(), aid, PACKET_VERSION, client_type, 3, 0, std::time(nullptr), "A");
98 boost::mysql::results results3;
99 conn->execute(b3, results3);
100
101 HLog(info) << "Session (" << aid << ") has been initiated.";
102 HLog(info) << "Request for authorization of account '" << username << "' (" << aid << ")" << " has been granted.";
103 }
104 catch (std::exception& error) {
105 HLog(error) << error.what();
106 acrl.deliver(login_error_codes::ERR_SESSION_CONNECTED, block_date, 0);
107 return false;
108 }
109 return true;
110 }
111 }
112 catch (std::exception& error) {
113 HLog(error) << error.what();
114 }
115
116 acrl.deliver(login_error_codes::ERR_SESSION_CONNECTED, block_date, 0);
117 return false;
118 }
119
120 try
121 {
122 auto conn = sAuth->get_database_connection();
123 boost::mysql::statement stmt = conn->prepare_statement("SELECT * FROM `game_accounts` WHERE `username` = ?");
124 auto b1 = stmt.bind(username);
125 boost::mysql::results results;
126 conn->execute(b1, results);
127
128 if (results.rows().empty()) {
129 HLog(info) << "Recieved connection request for unknown account '" << username << "'.";
130 acrl.deliver(login_error_codes::ERR_UNREGISTERED_ID, block_date, 0);
131 return false;
132 }
133
134 std::vector<unsigned char> hash(results.rows()[0][2].as_blob().begin(), results.rows()[0][2].as_blob().end());
135 std::vector<unsigned char> salt(results.rows()[0][3].as_blob().begin(), results.rows()[0][3].as_blob().end());
136
137 std::vector<unsigned char> hash_check;
138
139 sAuth->hash_password(password, salt, hash_check);
140
141 // compare salt_vec with salt and hash_vec with hash
142 if (hash_check != hash) {
143 HLog(info) << "Incorrect password for account '" << username << "' with password '" << password << "'.";
144 acrl.deliver(login_error_codes::ERR_INCORRECT_PASSWORD, block_date, 0);
145 return false;
146 }
147
148 uint32_t aid = results.rows()[0][0].as_uint64();
149 uint32_t group_id = results.rows()[0][6].as_int64();
150 uint32_t gender = results.rows()[0][4].as_string().compare("M") == 0 ? 0 : 1;
151
152 stmt = conn->prepare_statement("SELECT * FROM `session_data` WHERE `game_account_id` = ?");
153 auto b2 = stmt.bind(aid);
154 boost::mysql::results r2;
155 conn->execute(b2, r2);
156
157 if (!r2.rows().empty()) {
158 acrl.deliver(login_error_codes::ERR_SESSION_CONNECTED, block_date, 0);
159 return false;
160 }
161 else {
162 stmt = conn->prepare_statement("INSERT INTO `session_data` (`auth_code`, `game_account_id`, `client_version`, `client_type`, `character_slots`, `group_id`, `connect_time`, `current_server`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
163 auto b3 = stmt.bind(aid, aid, PACKET_VERSION, client_type, 3, 0, std::time(nullptr), "A");
164 boost::mysql::results r3;
165 conn->execute(b3, r3);
166
167 HLog(info) << "Session (" << aid << ") has been initiated.";
168 }
169
170 acal.deliver(aid, aid, group_id, gender);
171
172 HLog(info) << "Request for authorization of account '" << username << "' (" << aid << ")" << " has been granted.";
173 }
174 catch (boost::mysql::error_with_diagnostics &err) {
175 HLog(error) << err.what();
176 return false;
177 }
178 catch (std::exception& err) {
179 HLog(error) << err.what();
180 return false;
181 }
182
183 return true;
184}
#define sAuth
Definition: Auth.hpp:131
@ ACCOUNT_STATE_NONE
Definition: Database.hpp:41
game_account_gender_type
Definition: Database.hpp:33
@ ACCOUNT_GENDER_MALE
Definition: Database.hpp:34
@ ACCOUNT_GENDER_NONE
Definition: Database.hpp:36
@ ACCOUNT_GENDER_FEMALE
Definition: Database.hpp:35
#define PACKET_VERSION
Definition: Horizon.hpp:46
#define HLog(type)
Definition: Logger.hpp:122
Main object for the aegis packet: AC_ACCEPT_LOGIN.
Definition: TransmittedPackets.hpp:104
Main object for the aegis packet: AC_REFUSE_LOGIN.
Definition: TransmittedPackets.hpp:881

References ACCOUNT_GENDER_FEMALE, ACCOUNT_GENDER_MALE, ACCOUNT_GENDER_NONE, ACCOUNT_STATE_NONE, Horizon::Auth::AC_ACCEPT_LOGIN::deliver(), Horizon::Auth::AC_REFUSE_LOGIN::deliver(), Horizon::Auth::ERR_INCORRECT_PASSWORD, Horizon::Auth::ERR_SESSION_CONNECTED, Horizon::Auth::ERR_UNREGISTERED_ID, Horizon::ClientInterface< AuthSession >::get_session(), HLog, PACKET_VERSION, and sAuth.

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: