13 #include <gpsp/client.h>
15 typedef void (
GPSP::Client::*RequestActionFunc)(
const GameSpy::Parameter&)
const;
17 static std::map<std::string, RequestActionFunc> mRequestActions =
42 std::vector<char> buffer(4096, 0);
44 int recv_size = read(this->_socket, &(buffer[0]), 4096);
53 buffer.resize(recv_size);
55 this->UpdateLastRecievedTime();
57 request = Util::Buffer::ToString(buffer);
59 this->_LogTransaction(
"-->", request);
61 this->onRequest(request);
77 GameSpy::Parameter parameter = GameSpy::Request2Parameter(request);
80 std::string action = parameter[0];
82 auto it = mRequestActions.find(action);
83 if (it != mRequestActions.end())
86 RequestActionFunc func = it->second;
89 (this->*(func))(parameter);
93 Logger::warning(
"action \"" + action +
"\" not implemented!", Server::Type::GPSP);
117 if(parameter.size() != 11 ||
118 !Util::isAscii(parameter[3]) ||
119 !Util::isAscii(parameter[5]))
124 std::string email = parameter[3];
125 std::string password = parameter[5];
128 if(email.size() > 50)
130 email = email.substr(0, 49);
133 Battlefield::Players players;
138 Logger::info(this->GetAddress() +
" --> Nicks ", Server::Type::GPSP);
141 bool correct_password =
false;
142 std::string md5password = Util::MD5hash(password);
145 if(player.GetPassword() == md5password)
147 correct_password =
true;
152 if(players.size() == 0 || !correct_password)
155 std::string response = GameSpy::Parameter2Response({
"nr",
"260",
"ndone",
"",
"final"});
158 this->Send(response);
161 this->_LogTransaction(
"<--", response);
166 GameSpy::Parameter response_parameter = {
"nr",
"0" };
170 std::string uniquenick = player.GetUniquenick();
171 std::string nick = player.GetNick();
176 if(clan.GetClanId() != -1)
178 uniquenick = clan.GetTag() +
" " + uniquenick;
181 response_parameter.push_back(
"nick");
182 response_parameter.push_back(nick);
184 response_parameter.push_back(
"uniquenick");
185 response_parameter.push_back(uniquenick);
187 Logger::info(this->GetAddress() +
" <-- " + uniquenick, Server::Type::GPSP);
190 response_parameter.push_back(
"ndone");
191 response_parameter.push_back(
"");
192 response_parameter.push_back(
"final");
195 std::string response = GameSpy::Parameter2Response(response_parameter);
198 this->Send(response);
201 this->_LogTransaction(
"<--", response);
221 if(parameter.size() != 7 ||
222 !Util::isAscii(parameter[3]))
227 std::string email = Util::tolower(parameter[3]);
229 Logger::info(this->GetAddress() +
" --> Valid: " + email, Server::Type::GPSP);
231 Battlefield::Players players;
232 std::string response;
237 if(players.size() >= 1)
239 response = GameSpy::Parameter2Response({
245 response = GameSpy::Parameter2Response({
250 this->Send(response);
252 this->_LogTransaction(
"<--", response);
278 if(parameter.size() != 17 ||
279 !Util::isAscii(parameter[3]) ||
280 !Util::isAscii(parameter[5]) ||
281 !Util::isAscii(parameter[7]) ||
282 !Util::isAscii(parameter[13]))
289 std::string nick = parameter[3];
290 std::string email = Util::tolower(parameter[5]);
291 std::string password = parameter[7];
292 std::string uniquenick = parameter[13];
295 if(email.size() > 50)
297 email = email.substr(0, 49);
300 Logger::info(this->GetAddress() +
" --> NewUser: " + nick +
", " + uniquenick +
", " + email, Server::Type::GPSP);
304 player.SetUniquenickWithoutClanTag(uniquenick);
305 uniquenick = player.GetUniquenick();
308 if(nick.size() < 3 or uniquenick.size() < 3)
310 std::string response = GameSpy::Parameter2Response({
316 this->Send(response);
318 this->_LogTransaction(
"<--", response);
324 Battlefield::Players players;
331 if(player.GetUniquenick() == uniquenick)
333 std::string response = GameSpy::Parameter2Response({
335 "pid", std::to_string(player.GetProfileId()),
339 this->Send(response);
341 this->_LogTransaction(
"<--", response);
350 new_player.SetNick(nick);
351 new_player.SetEmail(email);
352 new_player.SetUniquenick(uniquenick);
353 new_player.SetPassword(password);
356 if(players.size() >= 1)
359 new_player.SetUserId(players[0].GetUserId());
373 std::string response = GameSpy::Parameter2Response({
375 "pid", std::to_string(new_player.GetProfileId()),
379 this->Send(response);
381 this->_LogTransaction(
"<--", response);
395 if(parameter.size() != 13 ||
396 !Util::isAscii(parameter[9]))
401 std::string uniquenick = parameter[9];
403 Logger::info(this->GetAddress() +
" --> Search: " + uniquenick, Server::Type::GPSP);
406 player.SetUniquenick(uniquenick);
411 std::string response;
412 GameSpy::Parameter response_parameter;
415 if(player.GetProfileId() != -1)
417 response_parameter = {
418 "bsr", std::to_string(player.GetProfileId()),
419 "nick", player.GetNick(),
423 "uniquenick", player.GetUniquenick(),
430 response_parameter.push_back(
"bsrdone");
431 response_parameter.push_back(
"");
432 response_parameter.push_back(
"final");
434 response = GameSpy::Parameter2Response(response_parameter);
436 this->Send(response);
438 this->_LogTransaction(
"<--", response);
445 std::shared_lock<std::shared_mutex> guard(g_settings_mutex);
447 if ((g_logger_mode & Logger::Mode::Development) == 0)
452 bool show_console = (g_settings[
"gpsp"][
"show_requests"].asBool() && direction ==
"-->") ||
453 (g_settings[
"gpsp"][
"show_responses"].asBool() && direction ==
"<--");
455 Logger::info(this->GetAddress() +
" " + direction +
" " + response,
456 Server::Type::GPSP, show_console);
Represents a clan in the Battlefield game.
Represents a player with extended statistics.
bool insertPlayerStats(const Battlefield::Player &player)
Inserts the statistics of a player into the database.
bool queryPlayersByEmail(Battlefield::Players &players, const std::string &email)
Queries players by their email addresses.
bool queryPlayerByUniquenick(Battlefield::Player &player)
Queries a player by their unique nickname.
bool queryPlayersByEmailOrUniquenick(Battlefield::Players &players, const std::string &email, const std::string &uniquenick)
Queries players by their email addresses or unique nicknames.
bool queryClanByProfileId(Battlefield::Clan &clan, const Battlefield::Player &player)
Queries a clan by a player's profile ID.
bool insertPlayer(Battlefield::Player &player)
Inserts a player into the database.
bool queryPlayerNewUserID(Battlefield::Player &player)
Queries a new user ID for a player.
Client class for GPSP protocol.
void _LogTransaction(const std::string &direction, const std::string &response) const
Log a transaction with direction and response.
void requestNicks(const GameSpy::Parameter ¶meter) const
Request nicknames.
void Disconnect()
Disconnect the client.
Client(int socket, struct sockaddr_in address)
Construct a new Client object.
void requestValid(const GameSpy::Parameter ¶meter) const
Request validation.
void requestNewUser(const GameSpy::Parameter ¶meter) const
Request a new user.
void onRequest(const std::string &msg)
Handle incoming requests.
void Listen()
Listen for incoming messages.
void requestSearch(const GameSpy::Parameter ¶meter) const
Search for users.
~Client()
Destroy the Client object.
void UpdateLastRecievedTime()
Updates the last received time to the current system time.
struct sockaddr_in _address
void onClientDisconnect(const Net::Socket &client)
Called when a client disconnects from the server.