2007-11-16 15:24:25 +00:00
|
|
|
/***************************************************************************
|
2009-06-01 19:49:16 +00:00
|
|
|
* Copyright (C) 2007-2009 by Lothar May *
|
2007-11-16 15:24:25 +00:00
|
|
|
* *
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
|
* (at your option) any later version. *
|
|
|
|
|
* *
|
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
|
* *
|
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
|
* along with this program; if not, write to the *
|
|
|
|
|
* Free Software Foundation, Inc., *
|
|
|
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include <net/serverlobbythread.h>
|
2009-05-31 19:45:20 +00:00
|
|
|
#include <net/servergame.h>
|
2009-06-18 20:16:22 +00:00
|
|
|
#include <net/serverbanmanager.h>
|
2007-11-16 15:24:25 +00:00
|
|
|
#include <net/serverexception.h>
|
2009-05-10 22:21:20 +00:00
|
|
|
#include <net/senderhelper.h>
|
2007-11-16 15:24:25 +00:00
|
|
|
#include <net/sendercallback.h>
|
2009-08-20 11:42:13 +00:00
|
|
|
#include <net/serverircbotcallback.h>
|
2007-11-16 15:24:25 +00:00
|
|
|
#include <net/receiverhelper.h>
|
|
|
|
|
#include <net/socket_msg.h>
|
2009-08-14 22:05:01 +00:00
|
|
|
#include <net/chatcleanermanager.h>
|
2009-09-19 20:28:30 +00:00
|
|
|
#include <db/serverdbinterface.h>
|
|
|
|
|
#ifdef POKERTH_OFFICIAL_SERVER
|
|
|
|
|
#include <dbclosed/serverdbfactoryinternal.h>
|
|
|
|
|
#else
|
|
|
|
|
#include <db/serverdbfactorygeneric.h>
|
|
|
|
|
#endif
|
2007-11-16 15:24:25 +00:00
|
|
|
#include <core/avatarmanager.h>
|
|
|
|
|
#include <core/loghelper.h>
|
2008-04-21 22:27:15 +00:00
|
|
|
#include <core/openssl_wrapper.h>
|
2009-08-14 22:05:01 +00:00
|
|
|
#include <configfile.h>
|
2007-11-16 15:24:25 +00:00
|
|
|
|
|
|
|
|
#include <fstream>
|
2009-04-10 21:04:08 +00:00
|
|
|
#include <sstream>
|
2007-11-16 15:24:25 +00:00
|
|
|
#include <algorithm>
|
2009-11-15 08:52:17 +00:00
|
|
|
#include <cctype>
|
2007-11-16 15:24:25 +00:00
|
|
|
#include <boost/lambda/lambda.hpp>
|
|
|
|
|
#include <boost/filesystem.hpp>
|
|
|
|
|
#include <boost/bind.hpp>
|
2009-10-11 09:20:17 +00:00
|
|
|
#include <gsasl.h>
|
2007-11-16 15:24:25 +00:00
|
|
|
|
2008-03-06 15:27:31 +00:00
|
|
|
#define SERVER_MAX_NUM_SESSIONS 512 // Maximum number of idle users in lobby.
|
2009-05-10 14:57:51 +00:00
|
|
|
|
2008-03-06 15:27:31 +00:00
|
|
|
#define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day
|
|
|
|
|
#define SERVER_SAVE_STATISTICS_INTERVAL_SEC 60
|
2009-05-10 14:57:51 +00:00
|
|
|
#define SERVER_CHECK_SESSION_TIMEOUTS_INTERVAL_MSEC 500
|
2009-05-31 19:11:59 +00:00
|
|
|
#define SERVER_REMOVE_GAME_INTERVAL_MSEC 500
|
2009-05-10 14:57:51 +00:00
|
|
|
#define SERVER_REMOVE_PLAYER_INTERVAL_MSEC 100
|
2009-12-23 09:53:01 +00:00
|
|
|
#define SERVER_UPDATE_LOGIN_LOCK_INTERVAL_MSEC 1000
|
2009-06-01 19:49:16 +00:00
|
|
|
#define SERVER_PROCESS_SEND_INTERVAL_MSEC 10
|
2009-05-10 14:57:51 +00:00
|
|
|
|
2009-12-23 09:53:01 +00:00
|
|
|
#define SERVER_INIT_LOGIN_CLIENT_LOCK_SEC 30 // Forbid a client to send an additional avatar.
|
2008-03-04 23:47:45 +00:00
|
|
|
|
2009-11-15 09:07:43 +00:00
|
|
|
#define SERVER_INIT_SESSION_TIMEOUT_SEC 60
|
2008-03-06 15:27:31 +00:00
|
|
|
#define SERVER_TIMEOUT_WARNING_REMAINING_SEC 60
|
2008-03-09 23:32:45 +00:00
|
|
|
#define SERVER_SESSION_ACTIVITY_TIMEOUT_SEC 1800 // 30 min, MUST be > SERVER_TIMEOUT_WARNING_REMAINING_SEC
|
|
|
|
|
#define SERVER_SESSION_FORCED_TIMEOUT_SEC 86400 // 1 day, should be quite large.
|
2007-11-16 15:24:25 +00:00
|
|
|
|
2008-03-06 15:27:31 +00:00
|
|
|
|
|
|
|
|
#define SERVER_STATISTICS_FILE_NAME "server_statistics.log"
|
|
|
|
|
#define SERVER_STATISTICS_STR_TOTAL_PLAYERS "TotalNumPlayersLoggedIn"
|
|
|
|
|
#define SERVER_STATISTICS_STR_TOTAL_GAMES "TotalNumGamesCreated"
|
|
|
|
|
#define SERVER_STATISTICS_STR_MAX_GAMES "MaxGamesOpen"
|
|
|
|
|
#define SERVER_STATISTICS_STR_MAX_PLAYERS "MaxPlayersLoggedIn"
|
2008-04-01 21:44:05 +00:00
|
|
|
#define SERVER_STATISTICS_STR_CUR_GAMES "CurGamesOpen"
|
|
|
|
|
#define SERVER_STATISTICS_STR_CUR_PLAYERS "CurPlayersLoggedIn"
|
2007-11-16 15:24:25 +00:00
|
|
|
|
|
|
|
|
using namespace std;
|
2009-05-04 21:11:29 +00:00
|
|
|
using boost::asio::ip::tcp;
|
2007-11-16 15:24:25 +00:00
|
|
|
|
|
|
|
|
|
2009-09-19 20:28:30 +00:00
|
|
|
class InternalServerCallback : public SenderCallback, public SessionDataCallback, public ChatCleanerCallback, public ServerDBCallback
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
public:
|
2009-09-19 20:28:30 +00:00
|
|
|
InternalServerCallback(ServerLobbyThread &server) : m_server(server) {}
|
|
|
|
|
virtual ~InternalServerCallback() {}
|
2007-11-16 15:24:25 +00:00
|
|
|
|
|
|
|
|
virtual void SignalNetError(SessionId /*session*/, int /*errorID*/, int /*osErrorID*/)
|
|
|
|
|
{
|
|
|
|
|
// We just ignore send errors for now, on server side.
|
|
|
|
|
// A serious send error should trigger a read error or a read
|
|
|
|
|
// returning 0 afterwards, and we will handle this error.
|
|
|
|
|
}
|
2009-01-31 22:20:08 +00:00
|
|
|
virtual void SignalSessionTerminated(unsigned session)
|
2009-01-11 20:12:26 +00:00
|
|
|
{
|
2009-02-01 17:21:02 +00:00
|
|
|
m_server.GetSender().SignalSessionTerminated(session);
|
2009-01-11 20:12:26 +00:00
|
|
|
}
|
2009-08-17 09:45:06 +00:00
|
|
|
virtual void SignalChatBotMessage(const string &msg)
|
|
|
|
|
{
|
|
|
|
|
m_server.SendChatBotMsg(msg);
|
|
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
|
2009-09-19 20:28:30 +00:00
|
|
|
virtual void ConnectSuccess()
|
|
|
|
|
{
|
2009-10-24 21:49:11 +00:00
|
|
|
LOG_MSG("Successfully connected to database.");
|
2009-09-19 20:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void ConnectFailed(const string &error)
|
|
|
|
|
{
|
2009-10-24 21:49:11 +00:00
|
|
|
LOG_ERROR("DB connect error: " << error);
|
2009-10-03 17:03:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void QueryError(const std::string &error)
|
|
|
|
|
{
|
2009-10-24 21:49:11 +00:00
|
|
|
LOG_ERROR("DB query error: " << error);
|
2009-09-19 20:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
2009-10-11 12:07:56 +00:00
|
|
|
virtual void PlayerLoginSuccess(unsigned requestId, DB_id dbPlayerId, const std::string &secret)
|
2009-09-24 20:10:40 +00:00
|
|
|
{
|
2009-10-11 12:07:56 +00:00
|
|
|
m_server.UserValid(requestId, dbPlayerId, secret);
|
2009-09-24 20:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void PlayerLoginFailed(unsigned requestId)
|
|
|
|
|
{
|
2009-10-11 12:07:56 +00:00
|
|
|
m_server.UserInvalid(requestId);
|
2009-09-24 20:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2009-10-11 09:20:17 +00:00
|
|
|
virtual void CreateGameSuccess(unsigned requestId, DB_id gameId)
|
2009-09-19 20:28:30 +00:00
|
|
|
{
|
2009-10-03 20:19:51 +00:00
|
|
|
m_server.SetGameDBId((u_int32_t)requestId, gameId);
|
2009-09-19 20:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-24 20:10:40 +00:00
|
|
|
virtual void CreateGameFailed(unsigned requestId)
|
2009-09-19 20:28:30 +00:00
|
|
|
{
|
2009-10-24 21:49:11 +00:00
|
|
|
// TODO maybe handle request id.
|
|
|
|
|
LOG_ERROR("DB create game failed for request " << requestId);
|
2009-09-19 20:28:30 +00:00
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
private:
|
|
|
|
|
ServerLobbyThread &m_server;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2009-11-08 09:48:01 +00:00
|
|
|
ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ServerMode mode, ServerIrcBotCallback &ircBotCb, ConfigFile *playerConfig,
|
|
|
|
|
AvatarManager &avatarManager, boost::shared_ptr<boost::asio::io_service> ioService)
|
2009-10-11 09:20:17 +00:00
|
|
|
: m_ioService(ioService), m_authContext(NULL), m_gui(gui), m_ircBotCb(ircBotCb), m_avatarManager(avatarManager),
|
2009-11-08 09:48:01 +00:00
|
|
|
m_mode(mode), m_playerConfig(playerConfig), m_curGameId(0), m_curUniquePlayerId(0), m_curSessionId(INVALID_SESSION + 1),
|
2009-06-12 15:48:34 +00:00
|
|
|
m_statDataChanged(false), m_removeGameTimer(*ioService), m_removePlayerTimer(*ioService),
|
|
|
|
|
m_sessionTimeoutTimer(*ioService), m_avatarCleanupTimer(*ioService),
|
2009-12-23 09:53:01 +00:00
|
|
|
m_saveStatisticsTimer(*ioService), m_loginLockTimer(*ioService),
|
2009-06-12 15:48:34 +00:00
|
|
|
m_startTime(boost::posix_time::second_clock::local_time())
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-09-19 20:28:30 +00:00
|
|
|
m_internalServerCallback.reset(new InternalServerCallback(*this));
|
|
|
|
|
m_sender.reset(new SenderHelper(*m_internalServerCallback, m_ioService));
|
2007-11-16 15:24:25 +00:00
|
|
|
m_receiver.reset(new ReceiverHelper);
|
2009-06-18 21:32:01 +00:00
|
|
|
m_banManager.reset(new ServerBanManager(m_ioService));
|
2009-09-19 20:28:30 +00:00
|
|
|
m_chatCleanerManager.reset(new ChatCleanerManager(*m_internalServerCallback, m_ioService));
|
|
|
|
|
DBFactory dbFactory;
|
|
|
|
|
m_database = dbFactory.CreateServerDBObject(*m_internalServerCallback, m_ioService);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerLobbyThread::~ServerLobbyThread()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-11-08 09:48:01 +00:00
|
|
|
ServerLobbyThread::Init(const string &logDir)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
// Read previous server statistics.
|
|
|
|
|
if (!logDir.empty())
|
|
|
|
|
{
|
|
|
|
|
boost::filesystem::path logPath(logDir);
|
|
|
|
|
if (!logDir.empty())
|
|
|
|
|
{
|
|
|
|
|
logPath /= SERVER_STATISTICS_FILE_NAME;
|
|
|
|
|
m_statisticsFileName = logPath.directory_string();
|
|
|
|
|
ReadStatisticsFile();
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-09-26 22:10:43 +00:00
|
|
|
m_database->Init("127.0.0.1", "user", "password", "database", "key");
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-01 19:49:16 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SignalTermination()
|
|
|
|
|
{
|
|
|
|
|
Thread::SignalTermination();
|
|
|
|
|
m_ioService->stop();
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
2009-05-04 21:11:29 +00:00
|
|
|
ServerLobbyThread::AddConnection(boost::shared_ptr<tcp::socket> sock)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-05-10 14:57:51 +00:00
|
|
|
// Create a random session id.
|
|
|
|
|
// This id can be used to reconnect to the server if the connection was lost.
|
|
|
|
|
//unsigned sessionId;
|
|
|
|
|
|
|
|
|
|
// TODO: use randomized method.
|
|
|
|
|
//if(!RAND_bytes((unsigned char *)&sessionId, sizeof(sessionId)))
|
|
|
|
|
//{
|
|
|
|
|
// RAND_pseudo_bytes((unsigned char *)&sessionId, sizeof(sessionId));
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
// Create a new session.
|
2009-09-19 20:28:30 +00:00
|
|
|
boost::shared_ptr<SessionData> sessionData(new SessionData(sock, m_curSessionId++, *m_internalServerCallback));
|
2009-05-10 14:57:51 +00:00
|
|
|
m_sessionManager.AddSession(sessionData);
|
|
|
|
|
|
|
|
|
|
LOG_VERBOSE("Accepted connection - session #" << sessionData->GetId() << ".");
|
|
|
|
|
|
|
|
|
|
bool hasClientIp = false;
|
|
|
|
|
if (m_sessionManager.GetRawSessionCount() <= SERVER_MAX_NUM_SESSIONS)
|
|
|
|
|
{
|
|
|
|
|
boost::system::error_code errCode;
|
|
|
|
|
tcp::endpoint clientEndpoint = sock->remote_endpoint(errCode);
|
|
|
|
|
if (!errCode)
|
|
|
|
|
{
|
|
|
|
|
string ipAddress = clientEndpoint.address().to_string(errCode);
|
|
|
|
|
if (!errCode && !ipAddress.empty())
|
|
|
|
|
{
|
|
|
|
|
sessionData->SetClientAddr(ipAddress);
|
|
|
|
|
hasClientIp = true;
|
2009-11-07 23:27:08 +00:00
|
|
|
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_announceMessage;
|
|
|
|
|
AnnounceMessage_t *netAnnounce = &packet->GetMsg()->choice.announceMessage;
|
|
|
|
|
netAnnounce->protocolVersion.major = NET_VERSION_MAJOR;
|
|
|
|
|
netAnnounce->protocolVersion.minor = NET_VERSION_MINOR;
|
|
|
|
|
netAnnounce->latestGameVersion.major = POKERTH_VERSION_MAJOR;
|
|
|
|
|
netAnnounce->latestGameVersion.minor = POKERTH_VERSION_MINOR;
|
|
|
|
|
netAnnounce->latestBetaRevision = POKERTH_BETA_REVISION;
|
2009-11-08 09:48:01 +00:00
|
|
|
switch (m_mode)
|
|
|
|
|
{
|
|
|
|
|
case SERVER_MODE_LAN:
|
|
|
|
|
netAnnounce->serverType = serverType_serverTypeLAN;
|
|
|
|
|
break;
|
|
|
|
|
case SERVER_MODE_INTERNET_NOAUTH:
|
|
|
|
|
netAnnounce->serverType = serverType_serverTypeInternetNoAuth;
|
|
|
|
|
break;
|
|
|
|
|
case SERVER_MODE_INTERNET_AUTH:
|
|
|
|
|
netAnnounce->serverType = serverType_serverTypeInternetAuth;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-11-07 23:27:08 +00:00
|
|
|
GetSender().Send(sessionData, packet);
|
|
|
|
|
|
2009-05-10 14:57:51 +00:00
|
|
|
sock->async_read_some(
|
|
|
|
|
boost::asio::buffer(sessionData->GetReceiveBuffer().recvBuf, RECV_BUF_SIZE),
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::HandleRead,
|
|
|
|
|
this,
|
|
|
|
|
boost::asio::placeholders::error,
|
2009-06-14 22:07:41 +00:00
|
|
|
sessionData->GetId(),
|
2009-05-10 14:57:51 +00:00
|
|
|
boost::asio::placeholders::bytes_transferred));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!hasClientIp)
|
|
|
|
|
{
|
|
|
|
|
// We do not accept sessions if we cannot
|
|
|
|
|
// retrieve the client address.
|
|
|
|
|
SessionError(SessionWrapper(sessionData, boost::shared_ptr<PlayerData>()), ERR_NET_INVALID_SESSION);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Server is full.
|
|
|
|
|
// Gracefully close this session.
|
|
|
|
|
SessionError(SessionWrapper(sessionData, boost::shared_ptr<PlayerData>()), ERR_NET_SERVER_FULL);
|
|
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::ReAddSession(SessionWrapper session, int reason)
|
|
|
|
|
{
|
2009-06-01 19:49:16 +00:00
|
|
|
if (session.sessionData.get() && session.playerData.get())
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_gamePlayerMessage;
|
|
|
|
|
GamePlayerMessage_t *netPlayerMsg = &packet->GetMsg()->choice.gamePlayerMessage;
|
2009-08-04 22:24:31 +00:00
|
|
|
netPlayerMsg->gameId = session.sessionData->GetGameId();
|
2009-08-02 15:11:40 +00:00
|
|
|
netPlayerMsg->gamePlayerNotification.present = gamePlayerNotification_PR_removedFromGame;
|
|
|
|
|
RemovedFromGame_t *removed = &netPlayerMsg->gamePlayerNotification.choice.removedFromGame;
|
|
|
|
|
|
|
|
|
|
switch (reason)
|
|
|
|
|
{
|
|
|
|
|
case NTF_NET_REMOVED_GAME_FULL :
|
|
|
|
|
removed->removedFromGameReason = removedFromGameReason_gameIsFull;
|
|
|
|
|
break;
|
|
|
|
|
case NTF_NET_REMOVED_ALREADY_RUNNING :
|
|
|
|
|
removed->removedFromGameReason = removedFromGameReason_gameIsRunning;
|
|
|
|
|
break;
|
|
|
|
|
case NTF_NET_REMOVED_KICKED :
|
|
|
|
|
removed->removedFromGameReason = removedFromGameReason_kickedFromGame;
|
|
|
|
|
break;
|
|
|
|
|
case NTF_NET_REMOVED_TIMEOUT :
|
|
|
|
|
removed->removedFromGameReason = removedFromGameReason_gameTimeout;
|
|
|
|
|
break;
|
|
|
|
|
case NTF_NET_REMOVED_START_FAILED :
|
|
|
|
|
removed->removedFromGameReason = removedFromGameReason_removedStartFailed;
|
|
|
|
|
break;
|
|
|
|
|
default :
|
|
|
|
|
removed->removedFromGameReason = removedFromGameReason_removedOnRequest;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-06-07 08:51:43 +00:00
|
|
|
GetSender().Send(session.sessionData, packet);
|
2007-11-16 15:24:25 +00:00
|
|
|
|
2009-06-01 19:49:16 +00:00
|
|
|
HandleReAddedSession(session);
|
|
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-05-31 20:14:46 +00:00
|
|
|
ServerLobbyThread::MoveSessionToGame(ServerGame &game, SessionWrapper session)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
// Remove session from the lobby.
|
|
|
|
|
m_sessionManager.RemoveSession(session.sessionData->GetId());
|
|
|
|
|
// Session is now in game state.
|
|
|
|
|
session.sessionData->SetState(SessionData::Game);
|
|
|
|
|
// Store it in the list of game sessions.
|
|
|
|
|
m_gameSessionManager.AddSession(session);
|
2009-05-31 11:00:33 +00:00
|
|
|
// Set the game id of the session.
|
|
|
|
|
session.sessionData->SetGameId(game.GetId());
|
2009-06-20 12:14:06 +00:00
|
|
|
// Add session to the game.
|
|
|
|
|
game.AddSession(session);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::RemoveSessionFromGame(SessionWrapper session)
|
|
|
|
|
{
|
|
|
|
|
// Just remove the session. Only for fatal errors.
|
|
|
|
|
CloseSession(session);
|
2009-05-31 11:00:33 +00:00
|
|
|
session.sessionData->SetGameId(0);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::CloseSession(SessionWrapper session)
|
|
|
|
|
{
|
2009-07-22 20:22:14 +00:00
|
|
|
if (session.sessionData && session.sessionData->GetState() != SessionData::Closed) // Make this call reentrant.
|
|
|
|
|
{
|
|
|
|
|
LOG_VERBOSE("Closing session #" << session.sessionData->GetId() << ".");
|
|
|
|
|
session.sessionData->SetState(SessionData::Closed);
|
2008-03-19 23:39:59 +00:00
|
|
|
|
2009-07-22 20:22:14 +00:00
|
|
|
m_sessionManager.RemoveSession(session.sessionData->GetId());
|
|
|
|
|
m_gameSessionManager.RemoveSession(session.sessionData->GetId());
|
2007-11-16 15:24:25 +00:00
|
|
|
|
2009-08-15 22:20:19 +00:00
|
|
|
if (session.playerData)
|
|
|
|
|
NotifyPlayerLeftLobby(session.playerData->GetUniqueId());
|
2009-07-22 20:22:14 +00:00
|
|
|
// Update stats (if needed).
|
|
|
|
|
UpdateStatisticsNumberOfPlayers();
|
|
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
2008-05-11 21:41:30 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::ResubscribeLobbyMsg(SessionWrapper session)
|
|
|
|
|
{
|
2009-06-01 19:49:16 +00:00
|
|
|
InternalResubscribeMsg(session);
|
2008-05-11 21:41:30 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 22:20:19 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::NotifyPlayerJoinedLobby(unsigned playerId)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> notify = CreateNetPacketPlayerListNew(playerId);
|
|
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), notify, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), notify, SessionData::Game);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::NotifyPlayerLeftLobby(unsigned playerId)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> notify = CreateNetPacketPlayerListLeft(playerId);
|
|
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), notify, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), notify, SessionData::Game);
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::NotifyPlayerJoinedGame(unsigned gameId, unsigned playerId)
|
|
|
|
|
{
|
|
|
|
|
// Send notification to players in lobby.
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_gameListMessage;
|
|
|
|
|
GameListMessage_t *netListMsg = &packet->GetMsg()->choice.gameListMessage;
|
|
|
|
|
netListMsg->gameId = gameId;
|
|
|
|
|
|
|
|
|
|
netListMsg->gameListNotification.present = gameListNotification_PR_gameListPlayerJoined;
|
|
|
|
|
GameListPlayerJoined_t *playerJoined = &netListMsg->gameListNotification.choice.gameListPlayerJoined;
|
|
|
|
|
playerJoined->playerId = playerId;
|
|
|
|
|
|
2009-06-07 08:51:43 +00:00
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::NotifyPlayerLeftGame(unsigned gameId, unsigned playerId)
|
|
|
|
|
{
|
|
|
|
|
// Send notification to players in lobby.
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_gameListMessage;
|
|
|
|
|
GameListMessage_t *netListMsg = &packet->GetMsg()->choice.gameListMessage;
|
|
|
|
|
netListMsg->gameId = gameId;
|
|
|
|
|
|
|
|
|
|
netListMsg->gameListNotification.present = gameListNotification_PR_gameListPlayerLeft;
|
|
|
|
|
GameListPlayerLeft_t *playerLeft = &netListMsg->gameListNotification.choice.gameListPlayerLeft;
|
|
|
|
|
playerLeft->playerId = playerId;
|
|
|
|
|
|
2009-06-07 08:51:43 +00:00
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::NotifyGameAdminChanged(unsigned gameId, unsigned newAdminPlayerId)
|
|
|
|
|
{
|
|
|
|
|
// Send notification to players in lobby.
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_gameListMessage;
|
|
|
|
|
GameListMessage_t *netListMsg = &packet->GetMsg()->choice.gameListMessage;
|
|
|
|
|
netListMsg->gameId = gameId;
|
|
|
|
|
|
|
|
|
|
netListMsg->gameListNotification.present = gameListNotification_PR_gameListAdminChanged;
|
|
|
|
|
GameListAdminChanged_t *adminChanged = &netListMsg->gameListNotification.choice.gameListAdminChanged;
|
|
|
|
|
adminChanged->newAdminPlayerId = newAdminPlayerId;
|
|
|
|
|
|
2009-06-07 08:51:43 +00:00
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::NotifyStartingGame(unsigned gameId)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_STARTED);
|
2009-06-07 08:51:43 +00:00
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::NotifyReopeningGame(unsigned gameId)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(gameId, GAME_MODE_CREATED);
|
2009-06-07 08:51:43 +00:00
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleGameRetrievePlayerInfo(SessionWrapper session, const PlayerInfoRequestMessage_t &playerInfoRequest)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
// Someone within a game requested player info.
|
2009-08-02 15:11:40 +00:00
|
|
|
HandleNetPacketRetrievePlayerInfo(session, playerInfoRequest);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleGameRetrieveAvatar(SessionWrapper session, const AvatarRequestMessage_t &retrieveAvatar)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
// Someone within a game requested an avatar.
|
2009-08-02 15:11:40 +00:00
|
|
|
HandleNetPacketRetrieveAvatar(session, retrieveAvatar);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 14:51:21 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::HandleChatRequest(SessionWrapper session, const ChatRequestMessage_t &chatRequest)
|
|
|
|
|
{
|
|
|
|
|
// Someone within a game sent a lobby message.
|
|
|
|
|
HandleNetPacketChatRequest(session, chatRequest);
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
bool
|
|
|
|
|
ServerLobbyThread::KickPlayerByName(const std::string &playerName)
|
|
|
|
|
{
|
|
|
|
|
bool retVal = false;
|
|
|
|
|
SessionWrapper session = m_sessionManager.GetSessionByPlayerName(playerName);
|
|
|
|
|
if (!session.sessionData.get())
|
|
|
|
|
session = m_gameSessionManager.GetSessionByPlayerName(playerName);
|
|
|
|
|
|
|
|
|
|
if (session.sessionData.get() && session.playerData.get())
|
|
|
|
|
{
|
2008-03-06 15:27:31 +00:00
|
|
|
RemovePlayer(session.playerData->GetUniqueId(), ERR_NET_PLAYER_KICKED);
|
2007-11-16 15:24:25 +00:00
|
|
|
retVal = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-10 21:54:59 +00:00
|
|
|
string
|
|
|
|
|
ServerLobbyThread::GetPlayerIPAddress(const std::string &playerName) const
|
|
|
|
|
{
|
|
|
|
|
string ipAddress;
|
|
|
|
|
SessionWrapper session = m_sessionManager.GetSessionByPlayerName(playerName);
|
|
|
|
|
if (!session.sessionData.get())
|
|
|
|
|
session = m_gameSessionManager.GetSessionByPlayerName(playerName);
|
|
|
|
|
|
|
|
|
|
if (session.sessionData.get() && session.playerData.get())
|
|
|
|
|
ipAddress = session.sessionData->GetClientAddr();
|
|
|
|
|
|
|
|
|
|
return ipAddress;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-06 15:27:31 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::RemovePlayer(unsigned playerId, unsigned errorCode)
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_removePlayerListMutex);
|
|
|
|
|
m_removePlayerList.push_back(RemovePlayerList::value_type(playerId, errorCode));
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-26 13:50:09 +00:00
|
|
|
void
|
2008-12-26 16:47:14 +00:00
|
|
|
ServerLobbyThread::SendGlobalChat(const string &message)
|
2008-12-26 13:50:09 +00:00
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_chatMessage;
|
|
|
|
|
ChatMessage_t *netChat = &packet->GetMsg()->choice.chatMessage;
|
2009-08-15 10:25:13 +00:00
|
|
|
netChat->chatType.present = chatType_PR_chatTypeBroadcast;
|
2009-08-02 15:11:40 +00:00
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&netChat->chatText,
|
|
|
|
|
message.c_str(),
|
|
|
|
|
message.length());
|
|
|
|
|
|
2009-08-15 10:25:13 +00:00
|
|
|
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
2009-08-02 15:11:40 +00:00
|
|
|
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
2008-12-26 13:50:09 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-26 16:47:14 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SendGlobalMsgBox(const string &message)
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_dialogMessage;
|
|
|
|
|
DialogMessage_t *netDialog = &packet->GetMsg()->choice.dialogMessage;
|
|
|
|
|
|
|
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&netDialog->notificationText,
|
|
|
|
|
message.c_str(),
|
|
|
|
|
message.length());
|
2009-08-17 09:45:06 +00:00
|
|
|
m_sessionManager.SendToAllSessions(GetSender(), packet, SessionData::Established);
|
2009-08-02 15:11:40 +00:00
|
|
|
m_gameSessionManager.SendToAllSessions(GetSender(), packet, SessionData::Game);
|
2008-12-26 16:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-17 09:45:06 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SendChatBotMsg(const std::string &message)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_chatMessage;
|
|
|
|
|
ChatMessage_t *netChat = &packet->GetMsg()->choice.chatMessage;
|
|
|
|
|
netChat->chatType.present = chatType_PR_chatTypeBot;
|
|
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&netChat->chatText,
|
|
|
|
|
message.c_str(),
|
|
|
|
|
message.length());
|
|
|
|
|
|
|
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2009-08-20 11:42:13 +00:00
|
|
|
|
|
|
|
|
GetIrcBotCallback().SignalLobbyMessage(
|
|
|
|
|
0,
|
|
|
|
|
"(chat bot)",
|
|
|
|
|
message);
|
2009-08-17 09:45:06 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-17 11:26:03 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::ReconnectChatBot()
|
|
|
|
|
{
|
|
|
|
|
m_chatCleanerManager->ReInit();
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::AddComputerPlayer(boost::shared_ptr<PlayerData> player)
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_computerPlayersMutex);
|
|
|
|
|
m_computerPlayers.insert(PlayerDataMap::value_type(player->GetUniqueId(), player));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::RemoveComputerPlayer(boost::shared_ptr<PlayerData> player)
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_computerPlayersMutex);
|
|
|
|
|
m_computerPlayers.erase(player->GetUniqueId());
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-30 12:07:48 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SendToLobbyPlayer(unsigned playerId, boost::shared_ptr<NetPacket> packet)
|
|
|
|
|
{
|
|
|
|
|
SessionWrapper tmpSession = m_sessionManager.GetSessionByUniquePlayerId(playerId);
|
|
|
|
|
if (tmpSession.sessionData)
|
|
|
|
|
GetSender().Send(tmpSession.sessionData, packet);
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
AvatarManager &
|
|
|
|
|
ServerLobbyThread::GetAvatarManager()
|
|
|
|
|
{
|
|
|
|
|
return m_avatarManager;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerStats
|
|
|
|
|
ServerLobbyThread::GetStats() const
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_statMutex);
|
|
|
|
|
return m_statData;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-28 23:31:34 +00:00
|
|
|
boost::posix_time::ptime
|
|
|
|
|
ServerLobbyThread::GetStartTime() const
|
|
|
|
|
{
|
|
|
|
|
return m_startTime;
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-07 08:51:43 +00:00
|
|
|
SenderHelper &
|
2009-01-31 22:20:08 +00:00
|
|
|
ServerLobbyThread::GetSender()
|
|
|
|
|
{
|
|
|
|
|
assert(m_sender);
|
|
|
|
|
return *m_sender;
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-12 15:48:34 +00:00
|
|
|
boost::asio::io_service &
|
|
|
|
|
ServerLobbyThread::GetIOService()
|
|
|
|
|
{
|
|
|
|
|
assert(m_ioService);
|
|
|
|
|
return *m_ioService;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-03 18:06:56 +00:00
|
|
|
ServerDBInterface &
|
|
|
|
|
ServerLobbyThread::GetDatabase()
|
|
|
|
|
{
|
|
|
|
|
assert(m_database);
|
|
|
|
|
return *m_database;
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-18 20:16:22 +00:00
|
|
|
ServerBanManager &
|
|
|
|
|
ServerLobbyThread::GetBanManager()
|
|
|
|
|
{
|
|
|
|
|
assert(m_banManager);
|
|
|
|
|
return *m_banManager;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
u_int32_t
|
|
|
|
|
ServerLobbyThread::GetNextUniquePlayerId()
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_curUniquePlayerIdMutex);
|
2008-12-26 13:50:09 +00:00
|
|
|
m_curUniquePlayerId++;
|
|
|
|
|
if (m_curUniquePlayerId == 0) // 0 is an invalid id.
|
|
|
|
|
m_curUniquePlayerId++;
|
|
|
|
|
|
|
|
|
|
return m_curUniquePlayerId;
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u_int32_t
|
|
|
|
|
ServerLobbyThread::GetNextGameId()
|
|
|
|
|
{
|
2008-12-26 13:50:09 +00:00
|
|
|
m_curGameId++;
|
|
|
|
|
if (m_curGameId == 0) // 0 is an invalid id.
|
|
|
|
|
m_curGameId++;
|
|
|
|
|
|
|
|
|
|
return m_curGameId;
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::Main()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2009-10-11 09:20:17 +00:00
|
|
|
InitAuthContext();
|
|
|
|
|
|
|
|
|
|
InitChatCleaner();
|
|
|
|
|
// Start database engine.
|
|
|
|
|
m_database->Start();
|
|
|
|
|
// Register all timers.
|
|
|
|
|
RegisterTimers();
|
|
|
|
|
|
2009-06-17 21:22:01 +00:00
|
|
|
boost::asio::io_service::work ioWork(*m_ioService);
|
|
|
|
|
m_ioService->run(); // Will only be aborted asynchronously.
|
2009-06-04 22:13:52 +00:00
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
} catch (const PokerTHException &e)
|
|
|
|
|
{
|
|
|
|
|
GetCallback().SignalNetServerError(e.GetErrorId(), e.GetOsErrorCode());
|
2009-07-12 21:12:55 +00:00
|
|
|
LOG_ERROR("Lobby exception: " << e.what());
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
2009-06-17 21:22:01 +00:00
|
|
|
// Clear all sessions.
|
|
|
|
|
m_sessionManager.Clear();
|
|
|
|
|
m_gameSessionManager.Clear();
|
2009-06-12 15:48:34 +00:00
|
|
|
// Cancel pending timer callbacks.
|
|
|
|
|
CancelTimers();
|
2009-09-26 22:10:43 +00:00
|
|
|
// Stop database engine.
|
|
|
|
|
m_database->Stop();
|
2009-10-11 09:20:17 +00:00
|
|
|
|
|
|
|
|
ClearAuthContext();
|
2009-05-10 14:57:51 +00:00
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
|
2009-05-10 14:57:51 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::RegisterTimers()
|
|
|
|
|
{
|
|
|
|
|
// Remove closed games.
|
2009-06-12 15:48:34 +00:00
|
|
|
m_removeGameTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::milliseconds(SERVER_REMOVE_GAME_INTERVAL_MSEC));
|
|
|
|
|
m_removeGameTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerRemoveGame, shared_from_this(), boost::asio::placeholders::error));
|
2009-05-10 14:57:51 +00:00
|
|
|
// Remove inactive/kicked players.
|
2009-06-12 15:48:34 +00:00
|
|
|
m_removePlayerTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::milliseconds(SERVER_REMOVE_PLAYER_INTERVAL_MSEC));
|
|
|
|
|
m_removePlayerTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerRemovePlayer, shared_from_this(), boost::asio::placeholders::error));
|
2009-05-10 14:57:51 +00:00
|
|
|
// Check the timeout of sessions which have not been initialised.
|
2009-06-12 15:48:34 +00:00
|
|
|
m_sessionTimeoutTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::milliseconds(SERVER_CHECK_SESSION_TIMEOUTS_INTERVAL_MSEC));
|
|
|
|
|
m_sessionTimeoutTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerCheckSessionTimeouts, shared_from_this(), boost::asio::placeholders::error));
|
2009-05-10 14:57:51 +00:00
|
|
|
// Cleanup the avatar cache. Note: Only works if there are no users on the server.
|
2009-06-12 15:48:34 +00:00
|
|
|
m_avatarCleanupTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::seconds(SERVER_CACHE_CLEANUP_INTERVAL_SEC));
|
|
|
|
|
m_avatarCleanupTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerCleanupAvatarCache, shared_from_this(), boost::asio::placeholders::error));
|
2009-05-10 14:57:51 +00:00
|
|
|
// Update the statistics file.
|
2009-06-12 15:48:34 +00:00
|
|
|
m_saveStatisticsTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::seconds(SERVER_SAVE_STATISTICS_INTERVAL_SEC));
|
|
|
|
|
m_saveStatisticsTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerSaveStatisticsFile, shared_from_this(), boost::asio::placeholders::error));
|
2009-05-10 17:53:37 +00:00
|
|
|
// Update the avatar upload locks.
|
2009-12-23 09:53:01 +00:00
|
|
|
m_loginLockTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::milliseconds(SERVER_UPDATE_LOGIN_LOCK_INTERVAL_MSEC));
|
|
|
|
|
m_loginLockTimer.async_wait(
|
2009-06-12 15:48:34 +00:00
|
|
|
boost::bind(
|
2009-12-23 09:53:01 +00:00
|
|
|
&ServerLobbyThread::TimerUpdateClientLoginLock, shared_from_this(), boost::asio::placeholders::error));
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::CancelTimers()
|
|
|
|
|
{
|
|
|
|
|
m_removeGameTimer.cancel();
|
|
|
|
|
m_removePlayerTimer.cancel();
|
|
|
|
|
m_sessionTimeoutTimer.cancel();
|
|
|
|
|
m_avatarCleanupTimer.cancel();
|
|
|
|
|
m_saveStatisticsTimer.cancel();
|
2009-12-23 09:53:01 +00:00
|
|
|
m_loginLockTimer.cancel();
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-10-11 09:20:17 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::InitAuthContext()
|
|
|
|
|
{
|
2009-10-13 21:03:32 +00:00
|
|
|
int res = gsasl_init(&m_authContext);
|
|
|
|
|
if (res != GSASL_OK)
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_GSASL_INIT_FAILED, 0);
|
|
|
|
|
|
|
|
|
|
if (!gsasl_server_support_p(m_authContext, "SCRAM-SHA-1"))
|
|
|
|
|
{
|
|
|
|
|
gsasl_done(m_authContext);
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_GSASL_NO_SCRAM, 0);
|
|
|
|
|
}
|
2009-10-11 09:20:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::ClearAuthContext()
|
|
|
|
|
{
|
2009-10-11 12:07:56 +00:00
|
|
|
gsasl_done(m_authContext);
|
|
|
|
|
m_authContext = NULL;
|
2009-10-11 09:20:17 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-14 22:05:01 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::InitChatCleaner()
|
|
|
|
|
{
|
|
|
|
|
if (m_playerConfig->readConfigInt("UseChatCleaner") != 0)
|
|
|
|
|
{
|
|
|
|
|
m_chatCleanerManager->Init(
|
|
|
|
|
m_playerConfig->readConfigString("ChatCleanerHostAddress"),
|
|
|
|
|
m_playerConfig->readConfigInt("ChatCleanerPort"),
|
|
|
|
|
m_playerConfig->readConfigInt("ChatCleanerUseIpv6") != 0,
|
|
|
|
|
m_playerConfig->readConfigString("ChatCleanerClientAuth"),
|
|
|
|
|
m_playerConfig->readConfigString("ChatCleanerServerAuth"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
2009-06-14 22:07:41 +00:00
|
|
|
ServerLobbyThread::HandleRead(const boost::system::error_code &ec, SessionId sessionId, size_t bytesRead)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-07-30 21:47:30 +00:00
|
|
|
if (ec != boost::asio::error::operation_aborted)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-07-30 21:47:30 +00:00
|
|
|
try
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-07-22 20:48:21 +00:00
|
|
|
// Find the session.
|
|
|
|
|
SessionWrapper session = m_sessionManager.GetSessionById(sessionId);
|
|
|
|
|
if (!session.sessionData)
|
|
|
|
|
session = m_gameSessionManager.GetSessionById(sessionId);
|
|
|
|
|
if (session.sessionData)
|
2009-05-04 21:11:29 +00:00
|
|
|
{
|
2009-07-21 21:40:24 +00:00
|
|
|
ReceiveBuffer &buf = session.sessionData->GetReceiveBuffer();
|
2009-07-30 21:47:30 +00:00
|
|
|
if (!ec)
|
|
|
|
|
{
|
|
|
|
|
if (buf.recvBufUsed + bytesRead > RECV_BUF_SIZE)
|
|
|
|
|
LOG_ERROR("Session " << session.sessionData->GetId() << " - Internal error: Receive buffer overflow!");
|
|
|
|
|
buf.recvBufUsed += bytesRead;
|
|
|
|
|
GetReceiver().ScanPackets(buf);
|
|
|
|
|
bool errorFlag = false;
|
2009-07-21 21:40:24 +00:00
|
|
|
|
2009-07-30 21:47:30 +00:00
|
|
|
while (!buf.receivedPackets.empty())
|
2009-07-21 21:40:24 +00:00
|
|
|
{
|
2009-07-30 21:47:30 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet = buf.receivedPackets.front();
|
|
|
|
|
buf.receivedPackets.pop_front();
|
|
|
|
|
// Retrieve current game, if applicable.
|
|
|
|
|
boost::shared_ptr<ServerGame> game = InternalGetGameFromId(session.sessionData->GetGameId());
|
|
|
|
|
if (game)
|
2009-07-21 21:40:24 +00:00
|
|
|
{
|
2009-07-30 21:47:30 +00:00
|
|
|
// We need to catch game-specific exceptions, so that they do not affect the server.
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
game->HandlePacket(session, packet);
|
|
|
|
|
} catch (const PokerTHException &e)
|
|
|
|
|
{
|
|
|
|
|
LOG_ERROR("Game " << game->GetId() << " - Read handler exception: " << e.what());
|
|
|
|
|
game->RemoveAllSessions();
|
|
|
|
|
errorFlag = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-07-21 21:40:24 +00:00
|
|
|
}
|
2009-07-30 21:47:30 +00:00
|
|
|
else
|
|
|
|
|
HandlePacket(session, packet);
|
|
|
|
|
}
|
|
|
|
|
if (buf.recvBufUsed >= RECV_BUF_SIZE)
|
|
|
|
|
{
|
|
|
|
|
LOG_ERROR("Session " << session.sessionData->GetId() << " - Full receive buf but no valid packet.");
|
|
|
|
|
buf.recvBufUsed = 0;
|
|
|
|
|
}
|
|
|
|
|
if (!errorFlag)
|
|
|
|
|
{
|
|
|
|
|
session.sessionData->GetAsioSocket()->async_read_some(
|
|
|
|
|
boost::asio::buffer(buf.recvBuf + buf.recvBufUsed, RECV_BUF_SIZE - buf.recvBufUsed),
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::HandleRead,
|
|
|
|
|
this,
|
|
|
|
|
boost::asio::placeholders::error,
|
|
|
|
|
sessionId,
|
|
|
|
|
boost::asio::placeholders::bytes_transferred));
|
2009-07-21 21:40:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
2009-07-30 21:47:30 +00:00
|
|
|
else if (ec == boost::asio::error::interrupted || ec == boost::asio::error::try_again)
|
2009-07-21 21:40:24 +00:00
|
|
|
{
|
2009-07-30 22:11:12 +00:00
|
|
|
LOG_ERROR("Session " << sessionId << " - recv interrupted: " << ec);
|
2009-07-21 21:40:24 +00:00
|
|
|
session.sessionData->GetAsioSocket()->async_read_some(
|
|
|
|
|
boost::asio::buffer(buf.recvBuf + buf.recvBufUsed, RECV_BUF_SIZE - buf.recvBufUsed),
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::HandleRead,
|
|
|
|
|
this,
|
|
|
|
|
boost::asio::placeholders::error,
|
|
|
|
|
sessionId,
|
|
|
|
|
boost::asio::placeholders::bytes_transferred));
|
|
|
|
|
}
|
2009-07-30 21:50:50 +00:00
|
|
|
else
|
2009-07-30 21:47:30 +00:00
|
|
|
{
|
2009-07-30 22:11:12 +00:00
|
|
|
LOG_ERROR("Session " << sessionId << " - Connection closed: " << ec);
|
2009-07-30 21:47:30 +00:00
|
|
|
// On error: Close this session.
|
|
|
|
|
boost::shared_ptr<ServerGame> game = InternalGetGameFromId(session.sessionData->GetGameId());
|
|
|
|
|
if (game)
|
|
|
|
|
game->ErrorRemoveSession(session);
|
|
|
|
|
else
|
|
|
|
|
CloseSession(session);
|
|
|
|
|
}
|
2009-07-21 21:40:24 +00:00
|
|
|
}
|
2009-07-30 21:47:30 +00:00
|
|
|
} catch (const exception &e)
|
2009-07-22 20:48:21 +00:00
|
|
|
{
|
2009-07-30 21:47:30 +00:00
|
|
|
LOG_ERROR("Session " << sessionId << " - unhandled exception in HandleRead: " << e.what());
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
2009-05-04 21:11:29 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::HandlePacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet)
|
|
|
|
|
{
|
|
|
|
|
if (session.sessionData && packet)
|
|
|
|
|
{
|
|
|
|
|
if (packet->IsClientActivity())
|
|
|
|
|
session.sessionData->ResetActivityTimer();
|
|
|
|
|
|
|
|
|
|
if (session.sessionData->GetState() == SessionData::Init)
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
if (packet->GetMsg()->present == PokerTHMessage_PR_initMessage)
|
|
|
|
|
HandleNetPacketInit(session, packet->GetMsg()->choice.initMessage);
|
2009-10-18 20:53:58 +00:00
|
|
|
else if (packet->GetMsg()->present == PokerTHMessage_PR_authMessage)
|
|
|
|
|
{
|
|
|
|
|
AuthMessage_t *authMsg = &packet->GetMsg()->choice.authMessage;
|
|
|
|
|
if (authMsg->present == AuthMessage_PR_authClientResponse)
|
|
|
|
|
HandleNetPacketAuthClientResponse(session, authMsg->choice.authClientResponse);
|
|
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_SOCK_INVALID_STATE);
|
|
|
|
|
}
|
2009-08-02 15:11:40 +00:00
|
|
|
else if (packet->GetMsg()->present == PokerTHMessage_PR_avatarReplyMessage)
|
|
|
|
|
{
|
|
|
|
|
AvatarReplyMessage_t *avatarReply = &packet->GetMsg()->choice.avatarReplyMessage;
|
|
|
|
|
if (avatarReply->avatarResult.present == avatarResult_PR_avatarHeader)
|
|
|
|
|
HandleNetPacketAvatarHeader(session, avatarReply->requestId, avatarReply->avatarResult.choice.avatarHeader);
|
|
|
|
|
else if (avatarReply->avatarResult.present == avatarResult_PR_unknownAvatar)
|
|
|
|
|
HandleNetPacketUnknownAvatar(session, avatarReply->requestId, avatarReply->avatarResult.choice.unknownAvatar);
|
|
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_SOCK_INVALID_STATE);
|
|
|
|
|
}
|
2009-05-04 21:11:29 +00:00
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_SOCK_INVALID_STATE);
|
|
|
|
|
}
|
|
|
|
|
else if (session.sessionData->GetState() == SessionData::ReceivingAvatar)
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
if (packet->GetMsg()->present == PokerTHMessage_PR_avatarReplyMessage)
|
|
|
|
|
{
|
|
|
|
|
AvatarReplyMessage_t *avatarReply = &packet->GetMsg()->choice.avatarReplyMessage;
|
|
|
|
|
if (avatarReply->avatarResult.present == avatarResult_PR_avatarData)
|
|
|
|
|
HandleNetPacketAvatarFile(session, avatarReply->requestId, avatarReply->avatarResult.choice.avatarData);
|
|
|
|
|
else if (avatarReply->avatarResult.present == avatarResult_PR_avatarEnd)
|
|
|
|
|
HandleNetPacketAvatarEnd(session, avatarReply->requestId, avatarReply->avatarResult.choice.avatarEnd);
|
|
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_SOCK_INVALID_STATE);
|
|
|
|
|
}
|
2009-05-04 21:11:29 +00:00
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_SOCK_INVALID_STATE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
if (packet->GetMsg()->present == PokerTHMessage_PR_playerInfoRequestMessage)
|
|
|
|
|
HandleNetPacketRetrievePlayerInfo(session, packet->GetMsg()->choice.playerInfoRequestMessage);
|
|
|
|
|
else if (packet->GetMsg()->present == PokerTHMessage_PR_avatarRequestMessage)
|
|
|
|
|
HandleNetPacketRetrieveAvatar(session, packet->GetMsg()->choice.avatarRequestMessage);
|
|
|
|
|
else if (packet->GetMsg()->present == PokerTHMessage_PR_resetTimeoutMessage)
|
2009-05-04 21:11:29 +00:00
|
|
|
{}
|
2009-08-02 15:11:40 +00:00
|
|
|
else if (packet->GetMsg()->present == PokerTHMessage_PR_subscriptionRequestMessage)
|
|
|
|
|
{
|
|
|
|
|
SubscriptionRequestMessage_t *subscriptionRequest = &packet->GetMsg()->choice.subscriptionRequestMessage;
|
|
|
|
|
if (subscriptionRequest->subscriptionAction == subscriptionAction_resubscribeGameList)
|
|
|
|
|
InternalResubscribeMsg(session);
|
|
|
|
|
else
|
|
|
|
|
session.sessionData->ResetWantsLobbyMsg();
|
|
|
|
|
}
|
|
|
|
|
else if (packet->GetMsg()->present == PokerTHMessage_PR_joinGameRequestMessage)
|
|
|
|
|
{
|
|
|
|
|
JoinGameRequestMessage_t *joinRequest = &packet->GetMsg()->choice.joinGameRequestMessage;
|
|
|
|
|
string password;
|
|
|
|
|
if (joinRequest->password)
|
|
|
|
|
password = string((char *)joinRequest->password->buf, joinRequest->password->size);
|
|
|
|
|
if (joinRequest->joinGameAction.present == joinGameAction_PR_joinNewGame)
|
|
|
|
|
HandleNetPacketCreateGame(session, password, joinRequest->joinGameAction.choice.joinNewGame);
|
|
|
|
|
else if (joinRequest->joinGameAction.present == joinGameAction_PR_joinExistingGame)
|
|
|
|
|
HandleNetPacketJoinGame(session, password, joinRequest->joinGameAction.choice.joinExistingGame);
|
|
|
|
|
}
|
2009-08-15 10:25:13 +00:00
|
|
|
else if (packet->GetMsg()->present == PokerTHMessage_PR_chatRequestMessage)
|
|
|
|
|
HandleNetPacketChatRequest(session, packet->GetMsg()->choice.chatRequestMessage);
|
2009-05-04 21:11:29 +00:00
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_SOCK_INVALID_STATE);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const InitMessage_t &initMessage)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2008-03-20 00:06:19 +00:00
|
|
|
LOG_VERBOSE("Received init for session #" << session.sessionData->GetId() << ".");
|
|
|
|
|
|
2009-12-23 09:53:01 +00:00
|
|
|
// Before any other processing, perform some denial of service and
|
|
|
|
|
// brute force attack prevention by checking whether the user recently sent an
|
|
|
|
|
// Init packet.
|
|
|
|
|
bool recentlySentInit = false;
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_timerClientAddressMapMutex);
|
|
|
|
|
if (m_timerClientAddressMap.find(session.sessionData->GetClientAddr()) != m_timerClientAddressMap.end())
|
|
|
|
|
recentlySentInit = true;
|
|
|
|
|
else
|
|
|
|
|
m_timerClientAddressMap[session.sessionData->GetClientAddr()] = boost::timers::portable::microsec_timer();
|
|
|
|
|
}
|
|
|
|
|
if (recentlySentInit)
|
|
|
|
|
{
|
|
|
|
|
SessionError(session, ERR_NET_INIT_BLOCKED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
// Check the protocol version.
|
2009-10-18 20:53:58 +00:00
|
|
|
if (initMessage.requestedVersion.major != NET_VERSION_MAJOR
|
|
|
|
|
|| session.playerData) // Has this session already sent an init?
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
SessionError(session, ERR_NET_VERSION_NOT_SUPPORTED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-02 15:11:40 +00:00
|
|
|
string playerName;
|
|
|
|
|
MD5Buf avatarMD5;
|
2009-11-14 15:04:31 +00:00
|
|
|
bool noAuth = false;
|
2009-11-15 08:41:29 +00:00
|
|
|
bool validGuest = false;
|
2009-10-23 22:21:34 +00:00
|
|
|
if (initMessage.login.present == login_PR_guestLogin)
|
2009-08-02 15:11:40 +00:00
|
|
|
{
|
2009-10-23 22:21:34 +00:00
|
|
|
const GuestLogin_t *guestLogin = &initMessage.login.choice.guestLogin;
|
2009-10-24 21:49:11 +00:00
|
|
|
playerName = STL_STRING_FROM_OCTET_STRING(guestLogin->nickName);
|
2009-11-15 08:41:29 +00:00
|
|
|
// Verify guest player name.
|
|
|
|
|
if (playerName.length() > sizeof(SERVER_GUEST_PLAYER_NAME - 1)
|
|
|
|
|
&& playerName.substr(0, sizeof(SERVER_GUEST_PLAYER_NAME) - 1) == SERVER_GUEST_PLAYER_NAME)
|
|
|
|
|
{
|
|
|
|
|
string guestId(playerName.substr(sizeof(SERVER_GUEST_PLAYER_NAME)));
|
2009-12-28 12:16:52 +00:00
|
|
|
if ((size_t)count_if(guestId.begin(), guestId.end(), ::isdigit) == guestId.size())
|
2009-11-15 08:41:29 +00:00
|
|
|
{
|
|
|
|
|
validGuest = true;
|
|
|
|
|
noAuth = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!validGuest)
|
2009-11-15 09:02:00 +00:00
|
|
|
{
|
2009-11-15 08:41:29 +00:00
|
|
|
SessionError(session, ERR_NET_INVALID_PLAYER_NAME);
|
2009-11-15 09:02:00 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2009-09-19 20:49:17 +00:00
|
|
|
}
|
2009-11-14 15:04:31 +00:00
|
|
|
#ifdef POKERTH_OFFICIAL_SERVER
|
2009-09-19 20:49:17 +00:00
|
|
|
else if (initMessage.login.present == login_PR_authenticatedLogin)
|
|
|
|
|
{
|
|
|
|
|
const AuthenticatedLogin_t *authLogin = &initMessage.login.choice.authenticatedLogin;
|
2009-10-18 20:53:58 +00:00
|
|
|
string inAuthData((const char *)authLogin->clientUserData.buf, authLogin->clientUserData.size);
|
2009-09-19 21:01:51 +00:00
|
|
|
if (authLogin->avatar)
|
2010-03-21 15:30:13 +00:00
|
|
|
memcpy(avatarMD5.GetData(), authLogin->avatar->buf, MD5_DATA_SIZE);
|
2009-10-13 21:52:10 +00:00
|
|
|
session.sessionData->CreateServerAuthSession(m_authContext);
|
2009-10-18 20:53:58 +00:00
|
|
|
if (session.sessionData->AuthStep(1, inAuthData))
|
|
|
|
|
playerName = session.sessionData->AuthGetUser();
|
2009-08-02 15:11:40 +00:00
|
|
|
}
|
2009-11-14 15:04:31 +00:00
|
|
|
#else
|
|
|
|
|
else if (initMessage.login.present == login_PR_unauthenticatedLogin)
|
|
|
|
|
{
|
|
|
|
|
const UnauthenticatedLogin_t *noauthLogin = &initMessage.login.choice.unauthenticatedLogin;
|
|
|
|
|
playerName = STL_STRING_FROM_OCTET_STRING(noauthLogin->nickName);
|
|
|
|
|
if (noauthLogin->avatar)
|
2009-12-28 12:16:52 +00:00
|
|
|
memcpy(avatarMD5.GetData(), noauthLogin->avatar->buf, MD5_DATA_SIZE);
|
2009-11-14 15:04:31 +00:00
|
|
|
noAuth = true;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2009-08-02 15:11:40 +00:00
|
|
|
else
|
2009-11-15 09:02:00 +00:00
|
|
|
{
|
2009-09-26 16:05:35 +00:00
|
|
|
SessionError(session, ERR_NET_INVALID_PASSWORD);
|
2009-11-15 09:02:00 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2009-08-02 15:11:40 +00:00
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
// Check whether the player name is correct.
|
|
|
|
|
// Partly, this is also done in netpacket.
|
|
|
|
|
// However, some disallowed names are checked only here.
|
2009-08-02 15:11:40 +00:00
|
|
|
if (playerName.empty()
|
|
|
|
|
|| playerName[0] == '#'
|
|
|
|
|
|| playerName[0] == ' '
|
|
|
|
|
|| playerName.substr(0, sizeof(SERVER_COMPUTER_PLAYER_NAME) - 1) == SERVER_COMPUTER_PLAYER_NAME)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
SessionError(session, ERR_NET_INVALID_PLAYER_NAME);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check whether this player is already connected.
|
2009-08-02 15:11:40 +00:00
|
|
|
if (IsPlayerConnected(playerName))
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
SessionError(session, ERR_NET_PLAYER_NAME_IN_USE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-07 22:04:38 +00:00
|
|
|
// Check whether the player name is banned.
|
2009-08-02 15:11:40 +00:00
|
|
|
if (GetBanManager().IsPlayerBanned(playerName))
|
2009-04-07 22:04:38 +00:00
|
|
|
{
|
|
|
|
|
SessionError(session, ERR_NET_PLAYER_BANNED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2009-04-11 11:03:22 +00:00
|
|
|
// Check whether the peer IP address is banned.
|
2009-06-18 20:16:22 +00:00
|
|
|
if (GetBanManager().IsIPAddressBanned(session.sessionData->GetClientAddr()))
|
2009-04-11 11:03:22 +00:00
|
|
|
{
|
|
|
|
|
SessionError(session, ERR_NET_PLAYER_BANNED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2009-04-07 22:04:38 +00:00
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
// Create player data object.
|
|
|
|
|
boost::shared_ptr<PlayerData> tmpPlayerData(
|
2010-03-26 21:41:35 +00:00
|
|
|
new PlayerData(GetNextUniquePlayerId(), 0, PLAYER_TYPE_HUMAN, validGuest ? PLAYER_RIGHTS_GUEST : PLAYER_RIGHTS_NORMAL, false));
|
2009-08-02 15:11:40 +00:00
|
|
|
tmpPlayerData->SetName(playerName);
|
2007-11-16 15:24:25 +00:00
|
|
|
tmpPlayerData->SetNetSessionData(session.sessionData);
|
2009-08-02 15:11:40 +00:00
|
|
|
tmpPlayerData->SetAvatarMD5(avatarMD5);
|
2007-11-16 15:24:25 +00:00
|
|
|
|
|
|
|
|
// Set player data for session.
|
|
|
|
|
m_sessionManager.SetSessionPlayerData(session.sessionData->GetId(), tmpPlayerData);
|
|
|
|
|
session.playerData = tmpPlayerData;
|
|
|
|
|
|
2009-11-14 15:04:31 +00:00
|
|
|
if (noAuth)
|
2009-09-19 21:01:51 +00:00
|
|
|
InitAfterLogin(session);
|
2007-11-16 15:24:25 +00:00
|
|
|
else
|
2009-10-18 20:53:58 +00:00
|
|
|
AuthenticatePlayer(session);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::HandleNetPacketAuthClientResponse(SessionWrapper session, const AuthClientResponse_t &clientResponse)
|
|
|
|
|
{
|
|
|
|
|
if (session.sessionData && session.playerData && session.sessionData->AuthGetCurStepNum() == 1)
|
|
|
|
|
{
|
2009-10-24 21:49:11 +00:00
|
|
|
string authData = STL_STRING_FROM_OCTET_STRING(clientResponse.clientResponse);
|
2009-10-18 20:53:58 +00:00
|
|
|
if (session.sessionData->AuthStep(2, authData))
|
|
|
|
|
{
|
|
|
|
|
string outVerification(session.sessionData->AuthGetNextOutMsg());
|
|
|
|
|
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_authMessage;
|
|
|
|
|
AuthMessage_t *netAuth = &packet->GetMsg()->choice.authMessage;
|
|
|
|
|
netAuth->present = AuthMessage_PR_authServerVerification;
|
|
|
|
|
AuthServerVerification_t *verification = &netAuth->choice.authServerVerification;
|
|
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&verification->serverVerification,
|
|
|
|
|
(char *)outVerification.c_str(),
|
|
|
|
|
outVerification.size());
|
|
|
|
|
GetSender().Send(session.sessionData, packet);
|
|
|
|
|
// The last message is only for server verification.
|
|
|
|
|
// We are done now, the user has logged in.
|
|
|
|
|
InitAfterLogin(session);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_NET_INVALID_PASSWORD);
|
|
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketAvatarHeader(SessionWrapper session, unsigned /*requestId*/, const AvatarHeader_t &avatarHeader)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-10-18 20:53:58 +00:00
|
|
|
if (session.playerData)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
if (avatarHeader.avatarSize >= MIN_AVATAR_FILE_SIZE && avatarHeader.avatarSize <= MAX_AVATAR_FILE_SIZE)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<AvatarFile> tmpAvatarFile(new AvatarFile);
|
|
|
|
|
tmpAvatarFile->fileData.reserve(avatarHeader.avatarSize);
|
|
|
|
|
tmpAvatarFile->fileType = static_cast<AvatarFileType>(avatarHeader.avatarType);
|
|
|
|
|
tmpAvatarFile->reportedSize = avatarHeader.avatarSize;
|
2007-11-16 15:24:25 +00:00
|
|
|
// Ignore request id for now.
|
|
|
|
|
|
2009-08-02 15:11:40 +00:00
|
|
|
session.playerData->SetNetAvatarFile(tmpAvatarFile);
|
2007-11-16 15:24:25 +00:00
|
|
|
|
|
|
|
|
// Session is now receiving an avatar.
|
|
|
|
|
session.sessionData->SetState(SessionData::ReceivingAvatar);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_NET_AVATAR_TOO_LARGE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketUnknownAvatar(SessionWrapper session, unsigned /*requestId*/, const UnknownAvatar_t &/*unknownAvatar*/)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
if (session.playerData.get())
|
|
|
|
|
{
|
|
|
|
|
// Free memory (just in case).
|
2009-08-02 15:11:40 +00:00
|
|
|
session.playerData->SetNetAvatarFile(boost::shared_ptr<AvatarFile>());
|
2007-11-16 15:24:25 +00:00
|
|
|
session.playerData->SetAvatarMD5(MD5Buf());
|
|
|
|
|
// Start session.
|
|
|
|
|
EstablishSession(session);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketAvatarFile(SessionWrapper session, unsigned /*requestId*/, const AvatarData_t &avatarData)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
if (session.playerData.get())
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<AvatarFile> tmpAvatar = session.playerData->GetNetAvatarFile();
|
|
|
|
|
if (tmpAvatar.get() && tmpAvatar->fileData.size() + avatarData.avatarBlock.size <= tmpAvatar->reportedSize)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
std::copy(&avatarData.avatarBlock.buf[0], &avatarData.avatarBlock.buf[avatarData.avatarBlock.size], back_inserter(tmpAvatar->fileData));
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, unsigned /*requestId*/, const AvatarEnd_t &/*avatarEnd*/)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
if (session.playerData.get())
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<AvatarFile> tmpAvatar = session.playerData->GetNetAvatarFile();
|
2007-11-16 15:24:25 +00:00
|
|
|
MD5Buf avatarMD5 = session.playerData->GetAvatarMD5();
|
|
|
|
|
if (!avatarMD5.IsZero() && tmpAvatar.get())
|
|
|
|
|
{
|
|
|
|
|
unsigned avatarSize = (unsigned)tmpAvatar->fileData.size();
|
|
|
|
|
if (avatarSize == tmpAvatar->reportedSize)
|
|
|
|
|
{
|
2009-03-01 23:09:14 +00:00
|
|
|
if (!GetAvatarManager().StoreAvatarInCache(avatarMD5, tmpAvatar->fileType, &tmpAvatar->fileData[0], avatarSize, true))
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
session.playerData->SetAvatarMD5(MD5Buf());
|
|
|
|
|
LOG_ERROR("Failed to store avatar in cache directory.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Free memory.
|
2009-08-02 15:11:40 +00:00
|
|
|
session.playerData->SetNetAvatarFile(boost::shared_ptr<AvatarFile>());
|
2009-03-22 00:39:25 +00:00
|
|
|
// Set avatar file name.
|
|
|
|
|
string avatarFileName;
|
|
|
|
|
if (GetAvatarManager().GetAvatarFileName(avatarMD5, avatarFileName))
|
|
|
|
|
session.playerData->SetAvatarFile(avatarFileName);
|
2007-11-16 15:24:25 +00:00
|
|
|
// Init finished - start session.
|
|
|
|
|
EstablishSession(session);
|
2009-04-25 18:33:01 +00:00
|
|
|
LOG_MSG("Client \"" << session.sessionData->GetClientAddr() << "\" uploaded avatar \""
|
|
|
|
|
<< boost::filesystem::path(avatarFileName).file_string() << "\".");
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
SessionError(session, ERR_NET_WRONG_AVATAR_SIZE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketRetrievePlayerInfo(SessionWrapper session, const PlayerInfoRequestMessage_t &playerInfoRequest)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
// Find player in lobby or in a game.
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<PlayerData> tmpPlayer = m_sessionManager.GetSessionByUniquePlayerId(playerInfoRequest.playerId).playerData;
|
2007-11-16 15:24:25 +00:00
|
|
|
if (!tmpPlayer.get())
|
2009-08-02 15:11:40 +00:00
|
|
|
tmpPlayer = m_gameSessionManager.GetSessionByUniquePlayerId(playerInfoRequest.playerId).playerData;
|
2007-11-16 15:24:25 +00:00
|
|
|
if (!tmpPlayer.get())
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_computerPlayersMutex);
|
2009-08-02 15:11:40 +00:00
|
|
|
PlayerDataMap::const_iterator pos = m_computerPlayers.find(playerInfoRequest.playerId);
|
2007-11-16 15:24:25 +00:00
|
|
|
if (pos != m_computerPlayers.end())
|
|
|
|
|
tmpPlayer = pos->second;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_playerInfoReplyMessage;
|
|
|
|
|
PlayerInfoReplyMessage_t *netPlayerInfoReply = &packet->GetMsg()->choice.playerInfoReplyMessage;
|
|
|
|
|
netPlayerInfoReply->playerId = tmpPlayer->GetUniqueId();
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
if (tmpPlayer.get())
|
|
|
|
|
{
|
|
|
|
|
// Send player info to client.
|
2009-08-02 15:11:40 +00:00
|
|
|
netPlayerInfoReply->playerInfoResult.present = playerInfoResult_PR_playerInfoData;
|
|
|
|
|
PlayerInfoData *data = &netPlayerInfoReply->playerInfoResult.choice.playerInfoData;
|
|
|
|
|
|
|
|
|
|
data->isHuman = tmpPlayer->GetType() == PLAYER_TYPE_HUMAN;
|
2010-03-24 15:54:04 +00:00
|
|
|
data->playerRights = static_cast<PlayerInfoRights>(tmpPlayer->GetRights());
|
2009-08-02 15:11:40 +00:00
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&data->playerName,
|
|
|
|
|
tmpPlayer->GetName().c_str(),
|
|
|
|
|
tmpPlayer->GetName().length());
|
|
|
|
|
if (!tmpPlayer->GetAvatarMD5().IsZero())
|
2009-03-22 00:39:25 +00:00
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
data->avatarData = (struct PlayerInfoData::avatarData *)calloc(1, sizeof(struct PlayerInfoData::avatarData));
|
|
|
|
|
data->avatarData->avatarType = static_cast<NetAvatarType_t>(AvatarManager::GetAvatarFileType(tmpPlayer->GetAvatarFile()));
|
|
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&data->avatarData->avatar,
|
2009-12-28 12:16:52 +00:00
|
|
|
(char *)tmpPlayer->GetAvatarMD5().GetData(),
|
2009-08-02 15:11:40 +00:00
|
|
|
MD5_DATA_SIZE);
|
2009-03-22 00:39:25 +00:00
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Unknown player id - notify client.
|
2009-08-02 15:11:40 +00:00
|
|
|
netPlayerInfoReply->playerInfoResult.present = playerInfoResult_PR_unknownPlayerInfo;
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
2009-08-02 15:11:40 +00:00
|
|
|
GetSender().Send(session.sessionData, packet);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketRetrieveAvatar(SessionWrapper session, const AvatarRequestMessage_t &retrieveAvatar)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
bool avatarFound = false;
|
|
|
|
|
|
|
|
|
|
string tmpFile;
|
2009-08-02 15:11:40 +00:00
|
|
|
MD5Buf tmpMD5;
|
2009-12-28 12:16:52 +00:00
|
|
|
memcpy(tmpMD5.GetData(), retrieveAvatar.avatar.buf, MD5_DATA_SIZE);
|
2009-08-02 15:11:40 +00:00
|
|
|
if (GetAvatarManager().GetAvatarFileName(tmpMD5, tmpFile))
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
NetPacketList tmpPackets;
|
2009-08-02 15:11:40 +00:00
|
|
|
if (GetAvatarManager().AvatarFileToNetPackets(tmpFile, retrieveAvatar.requestId, tmpPackets) == 0)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
avatarFound = true;
|
2009-06-07 08:51:43 +00:00
|
|
|
GetSender().Send(session.sessionData, tmpPackets);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
LOG_ERROR("Failed to read avatar file for network transmission.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!avatarFound)
|
|
|
|
|
{
|
|
|
|
|
// Notify client we didn't find the avatar.
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> unknownAvatar(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
unknownAvatar->GetMsg()->present = PokerTHMessage_PR_avatarReplyMessage;
|
|
|
|
|
AvatarReplyMessage_t *netAvatarReply = &unknownAvatar->GetMsg()->choice.avatarReplyMessage;
|
|
|
|
|
netAvatarReply->requestId = retrieveAvatar.requestId;
|
|
|
|
|
netAvatarReply->avatarResult.present = avatarResult_PR_unknownAvatar;
|
|
|
|
|
|
|
|
|
|
GetSender().Send(session.sessionData, unknownAvatar);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketCreateGame(SessionWrapper session, const std::string &password, const JoinNewGame_t &newGame)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2008-03-19 23:39:59 +00:00
|
|
|
LOG_VERBOSE("Creating new game, initiated by session #" << session.sessionData->GetId() << ".");
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
// Create a new game.
|
2009-08-02 15:11:40 +00:00
|
|
|
GameData tmpData;
|
|
|
|
|
NetPacket::GetGameData(&newGame.gameInfo, tmpData);
|
2009-10-03 18:06:56 +00:00
|
|
|
|
2010-03-28 14:53:08 +00:00
|
|
|
if (session.playerData->GetRights() == PLAYER_RIGHTS_GUEST
|
|
|
|
|
&& tmpData.gameType != GAME_TYPE_NORMAL)
|
|
|
|
|
{
|
|
|
|
|
SendJoinGameFailed(session.sessionData, NTF_NET_JOIN_GUEST_FORBIDDEN);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<ServerGame> game(
|
|
|
|
|
new ServerGame(
|
|
|
|
|
shared_from_this(),
|
|
|
|
|
GetNextGameId(),
|
|
|
|
|
STL_STRING_FROM_OCTET_STRING(newGame.gameInfo.gameName),
|
|
|
|
|
password,
|
|
|
|
|
tmpData,
|
|
|
|
|
session.playerData->GetUniqueId(),
|
|
|
|
|
GetGui(),
|
|
|
|
|
m_playerConfig));
|
|
|
|
|
game->Init();
|
2009-06-07 23:25:13 +00:00
|
|
|
|
2010-03-28 14:53:08 +00:00
|
|
|
// Add game to list of games.
|
|
|
|
|
InternalAddGame(game);
|
|
|
|
|
|
|
|
|
|
MoveSessionToGame(*game, session);
|
|
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-08-02 15:11:40 +00:00
|
|
|
ServerLobbyThread::HandleNetPacketJoinGame(SessionWrapper session, const std::string &password, const JoinExistingGame_t &joinGame)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
// Join an existing game.
|
2009-08-02 15:11:40 +00:00
|
|
|
GameMap::iterator pos = m_gameMap.find(joinGame.gameId);
|
2007-11-16 15:24:25 +00:00
|
|
|
|
|
|
|
|
if (pos != m_gameMap.end())
|
|
|
|
|
{
|
2010-03-28 14:53:08 +00:00
|
|
|
bool joinGame = true;
|
2009-05-31 20:14:46 +00:00
|
|
|
ServerGame &game = *pos->second;
|
2010-03-28 14:53:08 +00:00
|
|
|
const GameData &tmpData = game.GetGameData();
|
|
|
|
|
if (session.playerData->GetRights() == PLAYER_RIGHTS_GUEST
|
|
|
|
|
&& tmpData.gameType != GAME_TYPE_NORMAL)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2010-03-28 14:53:08 +00:00
|
|
|
SendJoinGameFailed(session.sessionData, NTF_NET_JOIN_GUEST_FORBIDDEN);
|
|
|
|
|
joinGame = false;
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
2010-03-28 14:53:08 +00:00
|
|
|
else if (!game.CheckPassword(password))
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
SendJoinGameFailed(session.sessionData, NTF_NET_JOIN_INVALID_PASSWORD);
|
2010-03-28 14:53:08 +00:00
|
|
|
joinGame = false;
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
2010-03-28 14:53:08 +00:00
|
|
|
if (joinGame)
|
|
|
|
|
MoveSessionToGame(game, session);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
// TODO do not remove session
|
2007-11-16 15:24:25 +00:00
|
|
|
SessionError(session, ERR_NET_UNKNOWN_GAME);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 10:25:13 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::HandleNetPacketChatRequest(SessionWrapper session, const ChatRequestMessage_t &chatRequest)
|
|
|
|
|
{
|
|
|
|
|
if (chatRequest.chatRequestType.present == chatRequestType_PR_chatRequestTypeLobby && session.playerData)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_chatMessage;
|
|
|
|
|
ChatMessage_t *netChat = &packet->GetMsg()->choice.chatMessage;
|
|
|
|
|
netChat->chatType.present = chatType_PR_chatTypeLobby;
|
|
|
|
|
ChatTypeLobby_t *netLobbyChat = &netChat->chatType.choice.chatTypeLobby;
|
|
|
|
|
netLobbyChat->playerId = session.playerData->GetUniqueId();
|
|
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&netChat->chatText,
|
|
|
|
|
(char *)chatRequest.chatText.buf,
|
|
|
|
|
chatRequest.chatText.size);
|
|
|
|
|
|
2009-08-15 14:51:21 +00:00
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2009-08-20 11:42:13 +00:00
|
|
|
|
|
|
|
|
string chatMsg = STL_STRING_FROM_OCTET_STRING(chatRequest.chatText);
|
|
|
|
|
// Send the message to the chat cleaner bot.
|
2009-08-15 22:32:42 +00:00
|
|
|
m_chatCleanerManager->HandleChatText(
|
2009-08-20 11:42:13 +00:00
|
|
|
session.playerData->GetUniqueId(),
|
|
|
|
|
session.playerData->GetName(),
|
|
|
|
|
chatMsg);
|
|
|
|
|
// Send the message to the irc bot.
|
|
|
|
|
GetIrcBotCallback().SignalLobbyMessage(
|
|
|
|
|
session.playerData->GetUniqueId(),
|
|
|
|
|
session.playerData->GetName(),
|
|
|
|
|
chatMsg);
|
2009-08-15 10:25:13 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-18 20:53:58 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::AuthChallenge(SessionWrapper session, const string &secret)
|
|
|
|
|
{
|
|
|
|
|
if (session.sessionData && session.playerData && session.sessionData->AuthGetCurStepNum() == 1)
|
|
|
|
|
{
|
|
|
|
|
session.playerData->SetPassword(secret); // For later encryption of data.
|
|
|
|
|
session.sessionData->AuthSetPassword(secret); // For this auth session.
|
|
|
|
|
string outChallenge(session.sessionData->AuthGetNextOutMsg());
|
|
|
|
|
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_authMessage;
|
|
|
|
|
AuthMessage_t *netAuth = &packet->GetMsg()->choice.authMessage;
|
|
|
|
|
netAuth->present = AuthMessage_PR_authServerChallenge;
|
|
|
|
|
AuthServerChallenge_t *challenge = &netAuth->choice.authServerChallenge;
|
|
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&challenge->serverChallenge,
|
|
|
|
|
(char *)outChallenge.c_str(),
|
|
|
|
|
outChallenge.size());
|
|
|
|
|
GetSender().Send(session.sessionData, packet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-19 21:01:51 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::InitAfterLogin(SessionWrapper session)
|
|
|
|
|
{
|
2009-09-26 16:14:22 +00:00
|
|
|
if (session.sessionData && session.playerData)
|
2009-09-19 21:01:51 +00:00
|
|
|
{
|
2009-09-26 16:14:22 +00:00
|
|
|
const MD5Buf &avatarMD5 = session.playerData->GetAvatarMD5();
|
|
|
|
|
string avatarFileName;
|
|
|
|
|
if (!avatarMD5.IsZero()
|
|
|
|
|
&& !GetAvatarManager().GetAvatarFileName(avatarMD5, avatarFileName))
|
2009-09-19 21:01:51 +00:00
|
|
|
{
|
2009-12-23 09:53:01 +00:00
|
|
|
RequestPlayerAvatar(session);
|
2009-09-19 21:01:51 +00:00
|
|
|
}
|
|
|
|
|
else
|
2009-09-26 16:14:22 +00:00
|
|
|
{
|
|
|
|
|
if (!avatarFileName.empty())
|
|
|
|
|
session.playerData->SetAvatarFile(avatarFileName);
|
|
|
|
|
EstablishSession(session);
|
|
|
|
|
}
|
2009-09-19 21:01:51 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::EstablishSession(SessionWrapper session)
|
|
|
|
|
{
|
|
|
|
|
if (!session.playerData.get())
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_SESSION, 0);
|
|
|
|
|
// Send ACK to client.
|
2009-08-15 13:43:00 +00:00
|
|
|
boost::shared_ptr<NetPacket> ack(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
ack->GetMsg()->present = PokerTHMessage_PR_initAckMessage;
|
|
|
|
|
InitAckMessage_t *netInitAck = &ack->GetMsg()->choice.initAckMessage;
|
2009-08-02 15:11:40 +00:00
|
|
|
// initAckData.sessionId = session.sessionData->GetId(); // TODO: currently unused.
|
|
|
|
|
netInitAck->yourPlayerId = session.playerData->GetUniqueId();
|
2009-08-15 13:43:00 +00:00
|
|
|
GetSender().Send(session.sessionData, ack);
|
2007-11-16 15:24:25 +00:00
|
|
|
|
2009-08-15 13:43:00 +00:00
|
|
|
// Send the connected players list to the client.
|
|
|
|
|
SendPlayerList(session.sessionData);
|
2007-11-16 15:24:25 +00:00
|
|
|
// Send the game list to the client.
|
|
|
|
|
SendGameList(session.sessionData);
|
|
|
|
|
|
|
|
|
|
// Session is now established.
|
|
|
|
|
session.sessionData->SetState(SessionData::Established);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_statMutex);
|
|
|
|
|
++m_statData.totalPlayersEverLoggedIn;
|
|
|
|
|
m_statDataChanged = true;
|
|
|
|
|
}
|
2009-08-15 13:43:00 +00:00
|
|
|
// Notify all players.
|
2009-08-15 22:20:19 +00:00
|
|
|
NotifyPlayerJoinedLobby(session.playerData->GetUniqueId());
|
2009-08-15 13:43:00 +00:00
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
UpdateStatisticsNumberOfPlayers();
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-19 21:01:51 +00:00
|
|
|
void
|
2009-10-18 20:53:58 +00:00
|
|
|
ServerLobbyThread::AuthenticatePlayer(SessionWrapper session)
|
2009-09-19 21:01:51 +00:00
|
|
|
{
|
2009-10-18 20:53:58 +00:00
|
|
|
if(session.playerData)
|
|
|
|
|
m_database->AsyncPlayerLogin(session.playerData->GetUniqueId(), session.playerData->GetName());
|
2009-09-24 20:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-10-11 12:07:56 +00:00
|
|
|
ServerLobbyThread::UserValid(unsigned playerId, DB_id dbPlayerId, const string &dbSecret)
|
2009-09-24 20:10:40 +00:00
|
|
|
{
|
2009-10-24 21:49:11 +00:00
|
|
|
SessionWrapper tmpSession = m_sessionManager.GetSessionByUniquePlayerId(playerId, true);
|
|
|
|
|
tmpSession.playerData->SetDBId(dbPlayerId);
|
|
|
|
|
this->AuthChallenge(tmpSession, dbSecret);
|
2009-09-24 20:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-10-11 12:07:56 +00:00
|
|
|
ServerLobbyThread::UserInvalid(unsigned playerId)
|
2009-09-24 20:10:40 +00:00
|
|
|
{
|
2009-09-26 16:05:35 +00:00
|
|
|
SessionError(m_sessionManager.GetSessionByUniquePlayerId(playerId, true), ERR_NET_INVALID_PASSWORD);
|
2009-09-19 21:01:51 +00:00
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::RequestPlayerAvatar(SessionWrapper session)
|
|
|
|
|
{
|
|
|
|
|
if (!session.playerData.get())
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_SESSION, 0);
|
|
|
|
|
// Ask the client to send its avatar.
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_avatarRequestMessage;
|
|
|
|
|
AvatarRequestMessage_t *netAvatarRequest = &packet->GetMsg()->choice.avatarRequestMessage;
|
|
|
|
|
netAvatarRequest->requestId = session.playerData->GetUniqueId();
|
|
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&netAvatarRequest->avatar,
|
2009-12-28 12:16:52 +00:00
|
|
|
(char *)session.playerData->GetAvatarMD5().GetData(),
|
2009-08-02 15:11:40 +00:00
|
|
|
MD5_DATA_SIZE);
|
|
|
|
|
GetSender().Send(session.sessionData, packet);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerLobbyThread::TimerRemoveGame(const boost::system::error_code &ec)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
if (!ec)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
// Synchronously remove games which have been closed.
|
|
|
|
|
GameMap::iterator i = m_gameMap.begin();
|
|
|
|
|
GameMap::iterator end = m_gameMap.end();
|
|
|
|
|
while (i != end)
|
|
|
|
|
{
|
|
|
|
|
GameMap::iterator next = i;
|
|
|
|
|
++next;
|
|
|
|
|
boost::shared_ptr<ServerGame> tmpGame = i->second;
|
|
|
|
|
if (!tmpGame->GetSessionManager().HasSessions())
|
|
|
|
|
InternalRemoveGame(tmpGame); // This will delete the game.
|
|
|
|
|
i = next;
|
|
|
|
|
}
|
2009-06-12 16:04:58 +00:00
|
|
|
// Restart timer
|
|
|
|
|
m_removeGameTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::milliseconds(SERVER_REMOVE_GAME_INTERVAL_MSEC));
|
|
|
|
|
m_removeGameTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerRemoveGame, shared_from_this(), boost::asio::placeholders::error));
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerLobbyThread::TimerRemovePlayer(const boost::system::error_code &ec)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
if (!ec)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
boost::mutex::scoped_lock lock(m_removePlayerListMutex);
|
|
|
|
|
|
|
|
|
|
if (!m_removePlayerList.empty())
|
|
|
|
|
{
|
|
|
|
|
RemovePlayerList::iterator i = m_removePlayerList.begin();
|
|
|
|
|
RemovePlayerList::iterator end = m_removePlayerList.end();
|
|
|
|
|
|
|
|
|
|
while (i != end)
|
|
|
|
|
{
|
|
|
|
|
InternalRemovePlayer(i->first, i->second);
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
m_removePlayerList.clear();
|
|
|
|
|
}
|
2009-06-12 16:04:58 +00:00
|
|
|
// Restart timer
|
|
|
|
|
m_removePlayerTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::milliseconds(SERVER_REMOVE_PLAYER_INTERVAL_MSEC));
|
|
|
|
|
m_removePlayerTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerRemovePlayer, shared_from_this(), boost::asio::placeholders::error));
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-12-23 09:53:01 +00:00
|
|
|
ServerLobbyThread::TimerUpdateClientLoginLock(const boost::system::error_code &ec)
|
2009-06-12 15:48:34 +00:00
|
|
|
{
|
|
|
|
|
if (!ec)
|
|
|
|
|
{
|
2009-12-23 09:53:01 +00:00
|
|
|
boost::mutex::scoped_lock lock(m_timerClientAddressMapMutex);
|
2009-06-12 15:48:34 +00:00
|
|
|
|
2009-12-23 09:53:01 +00:00
|
|
|
TimerClientAddressMap::iterator i = m_timerClientAddressMap.begin();
|
|
|
|
|
TimerClientAddressMap::iterator end = m_timerClientAddressMap.end();
|
2008-05-11 21:41:30 +00:00
|
|
|
|
|
|
|
|
while (i != end)
|
|
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
TimerClientAddressMap::iterator next = i;
|
|
|
|
|
++next;
|
2009-12-23 09:53:01 +00:00
|
|
|
if (i->second.elapsed().total_seconds() > SERVER_INIT_LOGIN_CLIENT_LOCK_SEC)
|
|
|
|
|
m_timerClientAddressMap.erase(i);
|
2009-06-12 15:48:34 +00:00
|
|
|
i = next;
|
2008-05-11 21:41:30 +00:00
|
|
|
}
|
2009-06-12 16:04:58 +00:00
|
|
|
// Restart timer
|
2009-12-23 09:53:01 +00:00
|
|
|
m_loginLockTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::milliseconds(SERVER_UPDATE_LOGIN_LOCK_INTERVAL_MSEC));
|
|
|
|
|
m_loginLockTimer.async_wait(
|
2009-06-12 16:04:58 +00:00
|
|
|
boost::bind(
|
2009-12-23 09:53:01 +00:00
|
|
|
&ServerLobbyThread::TimerUpdateClientLoginLock, shared_from_this(), boost::asio::placeholders::error));
|
2008-05-11 21:41:30 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-24 12:56:39 +00:00
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerLobbyThread::TimerCheckSessionTimeouts(const boost::system::error_code &ec)
|
2008-02-24 12:56:39 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
if (!ec)
|
2008-02-24 12:56:39 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
m_sessionManager.ForEach(boost::bind(&ServerLobbyThread::InternalCheckSessionTimeouts, boost::ref(*this), _1));
|
|
|
|
|
m_gameSessionManager.ForEach(boost::bind(&ServerLobbyThread::InternalCheckSessionTimeouts, boost::ref(*this), _1));
|
2009-06-12 16:04:58 +00:00
|
|
|
// Restart timer
|
|
|
|
|
m_sessionTimeoutTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::milliseconds(SERVER_CHECK_SESSION_TIMEOUTS_INTERVAL_MSEC));
|
|
|
|
|
m_sessionTimeoutTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerCheckSessionTimeouts, shared_from_this(), boost::asio::placeholders::error));
|
2008-02-24 12:56:39 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerLobbyThread::TimerCleanupAvatarCache(const boost::system::error_code &ec)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
if (!ec)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
// Only act if there are no sessions.
|
|
|
|
|
if (!m_sessionManager.HasSessions() && !m_gameSessionManager.HasSessions())
|
|
|
|
|
{
|
|
|
|
|
LOG_VERBOSE("Cleaning up avatar cache.");
|
2008-03-19 23:39:59 +00:00
|
|
|
|
2009-06-12 15:48:34 +00:00
|
|
|
m_avatarManager.RemoveOldAvatarCacheEntries();
|
|
|
|
|
}
|
2009-06-12 16:04:58 +00:00
|
|
|
// Restart timer
|
|
|
|
|
m_avatarCleanupTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::seconds(SERVER_CACHE_CLEANUP_INTERVAL_SEC));
|
|
|
|
|
m_avatarCleanupTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerCleanupAvatarCache, shared_from_this(), boost::asio::placeholders::error));
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-01 10:23:44 +00:00
|
|
|
boost::shared_ptr<ServerGame>
|
|
|
|
|
ServerLobbyThread::InternalGetGameFromId(unsigned gameId)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<ServerGame> game;
|
|
|
|
|
if (gameId)
|
|
|
|
|
{
|
|
|
|
|
GameMap::iterator pos = m_gameMap.find(gameId);
|
|
|
|
|
|
|
|
|
|
if (pos != m_gameMap.end())
|
|
|
|
|
game = pos->second;
|
|
|
|
|
}
|
|
|
|
|
return game;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
2009-05-31 20:14:46 +00:00
|
|
|
ServerLobbyThread::InternalAddGame(boost::shared_ptr<ServerGame> game)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
// Add game to list.
|
|
|
|
|
m_gameMap.insert(GameMap::value_type(game->GetId(), game));
|
|
|
|
|
// Notify all players.
|
2009-06-07 08:51:43 +00:00
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), CreateNetPacketGameListNew(*game), SessionData::Game);
|
2007-11-16 15:24:25 +00:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_statMutex);
|
|
|
|
|
++m_statData.totalGamesEverCreated;
|
2008-04-01 21:44:05 +00:00
|
|
|
++m_statData.numberOfGamesOpen;
|
2007-11-16 15:24:25 +00:00
|
|
|
unsigned numGames = static_cast<unsigned>(m_gameMap.size());
|
|
|
|
|
if (numGames > m_statData.maxGamesOpen)
|
|
|
|
|
m_statData.maxGamesOpen = numGames;
|
|
|
|
|
m_statDataChanged = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-05-31 20:14:46 +00:00
|
|
|
ServerLobbyThread::InternalRemoveGame(boost::shared_ptr<ServerGame> game)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2008-04-01 21:44:05 +00:00
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_statMutex);
|
|
|
|
|
if (m_statData.numberOfGamesOpen)
|
|
|
|
|
{
|
|
|
|
|
--m_statData.numberOfGamesOpen;
|
|
|
|
|
m_statDataChanged = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
// Remove game from list.
|
|
|
|
|
m_gameMap.erase(game->GetId());
|
|
|
|
|
// Remove all sessions left in the game.
|
2009-05-31 19:11:59 +00:00
|
|
|
game->ResetComputerPlayerList();
|
2007-11-16 15:24:25 +00:00
|
|
|
game->RemoveAllSessions();
|
2009-06-07 23:25:13 +00:00
|
|
|
game->Exit();
|
2007-11-16 15:24:25 +00:00
|
|
|
// Notify all players.
|
|
|
|
|
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(game->GetId(), GAME_MODE_CLOSED);
|
2009-06-07 08:51:43 +00:00
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2008-03-06 15:27:31 +00:00
|
|
|
ServerLobbyThread::InternalRemovePlayer(unsigned playerId, unsigned errorCode)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-09-26 21:42:04 +00:00
|
|
|
SessionWrapper session = m_sessionManager.GetSessionByUniquePlayerId(playerId, true);
|
2007-11-16 15:24:25 +00:00
|
|
|
if (session.sessionData.get())
|
2008-03-06 15:27:31 +00:00
|
|
|
SessionError(session, errorCode);
|
2007-11-16 15:24:25 +00:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Scan games for the player.
|
|
|
|
|
GameMap::iterator i = m_gameMap.begin();
|
|
|
|
|
GameMap::iterator end = m_gameMap.end();
|
|
|
|
|
|
|
|
|
|
while (i != end)
|
|
|
|
|
{
|
2009-05-31 20:14:46 +00:00
|
|
|
boost::shared_ptr<ServerGame> tmpGame = i->second;
|
2007-11-16 15:24:25 +00:00
|
|
|
if (tmpGame->GetPlayerDataByUniqueId(playerId).get())
|
|
|
|
|
{
|
2008-03-06 15:27:31 +00:00
|
|
|
tmpGame->RemovePlayer(playerId, errorCode);
|
2007-11-16 15:24:25 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-11 21:41:30 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::InternalResubscribeMsg(SessionWrapper session)
|
|
|
|
|
{
|
|
|
|
|
if (!session.sessionData->WantsLobbyMsg())
|
|
|
|
|
{
|
|
|
|
|
session.sessionData->SetWantsLobbyMsg();
|
2009-08-15 13:43:00 +00:00
|
|
|
SendPlayerList(session.sessionData);
|
2008-05-11 21:41:30 +00:00
|
|
|
SendGameList(session.sessionData);
|
2008-05-12 10:50:19 +00:00
|
|
|
// Send new statistics information.
|
2009-08-15 13:43:00 +00:00
|
|
|
/* boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
2009-08-02 15:11:40 +00:00
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_statisticsMessage;
|
|
|
|
|
StatisticsMessage_t *netStatistics = &packet->GetMsg()->choice.statisticsMessage;
|
2008-05-12 10:50:19 +00:00
|
|
|
|
2009-08-02 15:11:40 +00:00
|
|
|
StatisticsData_t *data = (StatisticsData_t *)calloc(1, sizeof(struct StatisticsData));
|
|
|
|
|
data->statisticsType = statisticsType_statNumberOfPlayers;
|
|
|
|
|
data->statisticsValue = m_sessionManager.GetRawSessionCount() + m_gameSessionManager.GetRawSessionCount();
|
|
|
|
|
ASN_SEQUENCE_ADD(&netStatistics->statisticsData.list, data);
|
|
|
|
|
|
2009-08-15 13:43:00 +00:00
|
|
|
GetSender().Send(session.sessionData, packet);*/
|
2008-05-11 21:41:30 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::HandleReAddedSession(SessionWrapper session)
|
|
|
|
|
{
|
|
|
|
|
// Remove session from game session list.
|
|
|
|
|
m_gameSessionManager.RemoveSession(session.sessionData->GetId());
|
|
|
|
|
|
|
|
|
|
if (m_sessionManager.GetRawSessionCount() <= SERVER_MAX_NUM_SESSIONS)
|
|
|
|
|
{
|
|
|
|
|
// Set state (back) to established.
|
|
|
|
|
session.sessionData->SetState(SessionData::Established);
|
2009-05-31 11:00:33 +00:00
|
|
|
session.sessionData->SetGameId(0);
|
2007-11-16 15:24:25 +00:00
|
|
|
// Add session to lobby list.
|
|
|
|
|
m_sessionManager.AddSession(session);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Gracefully close this session.
|
|
|
|
|
SessionError(session, ERR_NET_SERVER_FULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-06 15:27:31 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::InternalCheckSessionTimeouts(SessionWrapper session)
|
2008-03-04 23:47:45 +00:00
|
|
|
{
|
2008-03-06 15:27:31 +00:00
|
|
|
bool closeSession = false;
|
2009-09-26 21:53:18 +00:00
|
|
|
if (session.sessionData.get())
|
2008-03-04 23:47:45 +00:00
|
|
|
{
|
|
|
|
|
if (session.sessionData->GetState() == SessionData::Init && session.sessionData->GetAutoDisconnectTimerElapsedSec() >= SERVER_INIT_SESSION_TIMEOUT_SEC)
|
2008-03-19 23:39:59 +00:00
|
|
|
{
|
|
|
|
|
LOG_VERBOSE("Session init timeout, removing session #" << session.sessionData->GetId() << ".");
|
2008-03-06 15:27:31 +00:00
|
|
|
closeSession = true;
|
2008-03-19 23:39:59 +00:00
|
|
|
}
|
2008-03-04 23:47:45 +00:00
|
|
|
else if (session.sessionData->GetActivityTimerElapsedSec() >= SERVER_SESSION_ACTIVITY_TIMEOUT_SEC - SERVER_TIMEOUT_WARNING_REMAINING_SEC
|
|
|
|
|
&& !session.sessionData->HasActivityNoticeBeenSent())
|
|
|
|
|
{
|
|
|
|
|
session.sessionData->MarkActivityNotice();
|
2009-08-02 15:11:40 +00:00
|
|
|
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_timeoutWarningMessage;
|
|
|
|
|
TimeoutWarningMessage_t *netWarning = &packet->GetMsg()->choice.timeoutWarningMessage;
|
|
|
|
|
netWarning->timeoutReason = timeoutReason_timeoutNoDataReceived;
|
|
|
|
|
netWarning->remainingSeconds = SERVER_TIMEOUT_WARNING_REMAINING_SEC;
|
2009-06-07 08:51:43 +00:00
|
|
|
GetSender().Send(session.sessionData, packet);
|
2008-03-04 23:47:45 +00:00
|
|
|
}
|
|
|
|
|
else if (session.sessionData->GetActivityTimerElapsedSec() >= SERVER_SESSION_ACTIVITY_TIMEOUT_SEC)
|
|
|
|
|
{
|
2008-03-19 23:39:59 +00:00
|
|
|
LOG_VERBOSE("Activity timeout, removing session #" << session.sessionData->GetId() << ".");
|
2008-03-06 15:27:31 +00:00
|
|
|
closeSession = true;
|
2008-03-04 23:47:45 +00:00
|
|
|
}
|
|
|
|
|
else if (session.sessionData->GetAutoDisconnectTimerElapsedSec() >= SERVER_SESSION_FORCED_TIMEOUT_SEC)
|
|
|
|
|
{
|
2008-03-19 23:39:59 +00:00
|
|
|
LOG_VERBOSE("Auto disconnect timeout, removing session #" << session.sessionData->GetId() << ".");
|
2008-03-06 15:27:31 +00:00
|
|
|
closeSession = true;
|
2008-03-04 23:47:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-03-06 15:27:31 +00:00
|
|
|
if (closeSession)
|
2008-03-19 23:39:59 +00:00
|
|
|
{
|
2009-09-26 21:53:18 +00:00
|
|
|
if (session.playerData.get())
|
|
|
|
|
RemovePlayer(session.playerData->GetUniqueId(), ERR_NET_SESSION_TIMED_OUT);
|
|
|
|
|
else
|
|
|
|
|
m_sessionManager.RemoveSession(session.sessionData->GetId());
|
2008-03-19 23:39:59 +00:00
|
|
|
}
|
2008-03-04 23:47:45 +00:00
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SessionError(SessionWrapper session, int errorCode)
|
|
|
|
|
{
|
2009-09-26 16:05:35 +00:00
|
|
|
if (session.sessionData)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
SendError(session.sessionData, errorCode);
|
|
|
|
|
CloseSession(session);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SendError(boost::shared_ptr<SessionData> s, int errorCode)
|
|
|
|
|
{
|
2008-03-19 23:39:59 +00:00
|
|
|
LOG_VERBOSE("Sending error code " << errorCode << " to session #" << s->GetId() << ".");
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_errorMessage;
|
|
|
|
|
ErrorMessage_t *netError = &packet->GetMsg()->choice.errorMessage;
|
|
|
|
|
netError->errorReason = NetPacket::GameErrorToNetError(errorCode);
|
2009-06-07 08:51:43 +00:00
|
|
|
GetSender().Send(s, packet);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SendJoinGameFailed(boost::shared_ptr<SessionData> s, int reason)
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_joinGameReplyMessage;
|
|
|
|
|
JoinGameReplyMessage_t *netJoinReply = &packet->GetMsg()->choice.joinGameReplyMessage;
|
|
|
|
|
netJoinReply->gameId = s->GetGameId();
|
|
|
|
|
|
|
|
|
|
netJoinReply->joinGameResult.present = joinGameResult_PR_joinGameFailed;
|
|
|
|
|
JoinGameFailed_t *joinFailed = &netJoinReply->joinGameResult.choice.joinGameFailed;
|
|
|
|
|
|
|
|
|
|
switch (reason)
|
|
|
|
|
{
|
|
|
|
|
case NTF_NET_JOIN_GAME_FULL :
|
|
|
|
|
joinFailed->joinGameFailureReason = joinGameFailureReason_gameIsFull;
|
|
|
|
|
break;
|
|
|
|
|
case NTF_NET_JOIN_ALREADY_RUNNING :
|
|
|
|
|
joinFailed->joinGameFailureReason = joinGameFailureReason_gameIsRunning;
|
|
|
|
|
break;
|
|
|
|
|
case NTF_NET_JOIN_INVALID_PASSWORD :
|
|
|
|
|
joinFailed->joinGameFailureReason = joinGameFailureReason_invalidPassword;
|
|
|
|
|
break;
|
2010-03-28 14:53:08 +00:00
|
|
|
case NTF_NET_JOIN_GUEST_FORBIDDEN :
|
|
|
|
|
joinFailed->joinGameFailureReason = joinGameFailureReason_notAllowedAsGuest;
|
|
|
|
|
break;
|
2010-03-30 12:07:48 +00:00
|
|
|
case NTF_NET_JOIN_NOT_INVITED :
|
|
|
|
|
joinFailed->joinGameFailureReason = joinGameFailureReason_notInvited;
|
|
|
|
|
break;
|
2009-08-02 15:11:40 +00:00
|
|
|
default :
|
|
|
|
|
joinFailed->joinGameFailureReason = joinGameFailureReason_invalidGame;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-06-07 08:51:43 +00:00
|
|
|
GetSender().Send(s, packet);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 13:43:00 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SendPlayerList(boost::shared_ptr<SessionData> s)
|
|
|
|
|
{
|
|
|
|
|
// Retrieve all player ids.
|
2009-08-15 14:08:48 +00:00
|
|
|
PlayerIdList idList(m_sessionManager.GetPlayerIdList(SessionData::Established));
|
|
|
|
|
PlayerIdList gameIdList(m_gameSessionManager.GetPlayerIdList(SessionData::Game));
|
2009-08-15 13:43:00 +00:00
|
|
|
idList.splice(idList.begin(), gameIdList);
|
|
|
|
|
// Send all player ids to client.
|
|
|
|
|
PlayerIdList::const_iterator i = idList.begin();
|
|
|
|
|
PlayerIdList::const_iterator end = idList.end();
|
|
|
|
|
while (i != end)
|
|
|
|
|
{
|
|
|
|
|
GetSender().Send(s, CreateNetPacketPlayerListNew(*i));
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
void
|
|
|
|
|
ServerLobbyThread::SendGameList(boost::shared_ptr<SessionData> s)
|
|
|
|
|
{
|
|
|
|
|
GameMap::const_iterator game_i = m_gameMap.begin();
|
|
|
|
|
GameMap::const_iterator game_end = m_gameMap.end();
|
|
|
|
|
while (game_i != game_end)
|
|
|
|
|
{
|
2009-06-07 08:51:43 +00:00
|
|
|
GetSender().Send(s, CreateNetPacketGameListNew(*game_i->second));
|
2007-11-16 15:24:25 +00:00
|
|
|
++game_i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::UpdateStatisticsNumberOfPlayers()
|
|
|
|
|
{
|
|
|
|
|
ServerStats stats;
|
|
|
|
|
unsigned curNumberOfPlayersOnServer = m_sessionManager.GetRawSessionCount() + m_gameSessionManager.GetRawSessionCount();
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_statMutex);
|
|
|
|
|
if (curNumberOfPlayersOnServer != m_statData.numberOfPlayersOnServer)
|
|
|
|
|
{
|
|
|
|
|
m_statData.numberOfPlayersOnServer = stats.numberOfPlayersOnServer = curNumberOfPlayersOnServer;
|
|
|
|
|
if (curNumberOfPlayersOnServer > m_statData.maxPlayersLoggedIn)
|
|
|
|
|
m_statData.maxPlayersLoggedIn = curNumberOfPlayersOnServer;
|
|
|
|
|
m_statDataChanged = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Do not send other stats than number of players for now.
|
2009-08-15 13:43:00 +00:00
|
|
|
//BroadcastStatisticsUpdate(stats);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::BroadcastStatisticsUpdate(const ServerStats &stats)
|
|
|
|
|
{
|
|
|
|
|
if (stats.numberOfPlayersOnServer)
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_statisticsMessage;
|
|
|
|
|
StatisticsMessage_t *netStatistics = &packet->GetMsg()->choice.statisticsMessage;
|
2007-11-16 15:24:25 +00:00
|
|
|
|
2009-08-02 15:11:40 +00:00
|
|
|
StatisticsData_t *data = (StatisticsData_t *)calloc(1, sizeof(struct StatisticsData));
|
|
|
|
|
data->statisticsType = statisticsType_statNumberOfPlayers;
|
|
|
|
|
data->statisticsValue = m_sessionManager.GetRawSessionCount() + m_gameSessionManager.GetRawSessionCount();
|
|
|
|
|
ASN_SEQUENCE_ADD(&netStatistics->statisticsData.list, data);
|
|
|
|
|
|
|
|
|
|
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
|
|
|
|
m_gameSessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Game);
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerLobbyThread::ReadStatisticsFile()
|
|
|
|
|
{
|
|
|
|
|
ifstream i(m_statisticsFileName.c_str(), ios_base::in);
|
|
|
|
|
|
|
|
|
|
if (!i.fail() && !i.eof())
|
|
|
|
|
{
|
|
|
|
|
boost::mutex::scoped_lock lock(m_statMutex);
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
string statisticsType;
|
|
|
|
|
unsigned statisticsValue;
|
|
|
|
|
i >> statisticsType;
|
|
|
|
|
i >> statisticsValue;
|
|
|
|
|
if (statisticsType == SERVER_STATISTICS_STR_TOTAL_PLAYERS)
|
|
|
|
|
m_statData.totalPlayersEverLoggedIn = statisticsValue;
|
|
|
|
|
else if (statisticsType == SERVER_STATISTICS_STR_TOTAL_GAMES)
|
|
|
|
|
m_statData.totalGamesEverCreated = statisticsValue;
|
|
|
|
|
else if (statisticsType == SERVER_STATISTICS_STR_MAX_PLAYERS)
|
|
|
|
|
m_statData.maxPlayersLoggedIn = statisticsValue;
|
|
|
|
|
else if (statisticsType == SERVER_STATISTICS_STR_MAX_GAMES)
|
|
|
|
|
m_statData.maxGamesOpen = statisticsValue;
|
2008-04-01 21:44:05 +00:00
|
|
|
// other statistics are non-persistant and not read.
|
2007-11-16 15:24:25 +00:00
|
|
|
} while (!i.fail() && !i.eof());
|
|
|
|
|
m_statDataChanged = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerLobbyThread::TimerSaveStatisticsFile(const boost::system::error_code &ec)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
if (!ec)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
LOG_VERBOSE("Saving statistics.");
|
|
|
|
|
boost::mutex::scoped_lock lock(m_statMutex);
|
|
|
|
|
if (m_statDataChanged)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
ofstream o(m_statisticsFileName.c_str(), ios_base::out | ios_base::trunc);
|
|
|
|
|
if (!o.fail())
|
|
|
|
|
{
|
|
|
|
|
o << SERVER_STATISTICS_STR_TOTAL_PLAYERS " " << m_statData.totalPlayersEverLoggedIn << endl;
|
|
|
|
|
o << SERVER_STATISTICS_STR_TOTAL_GAMES " " << m_statData.totalGamesEverCreated << endl;
|
|
|
|
|
o << SERVER_STATISTICS_STR_MAX_PLAYERS " " << m_statData.maxPlayersLoggedIn << endl;
|
|
|
|
|
o << SERVER_STATISTICS_STR_MAX_GAMES " " << m_statData.maxGamesOpen << endl;
|
|
|
|
|
o << SERVER_STATISTICS_STR_CUR_PLAYERS " " << m_statData.numberOfPlayersOnServer << endl;
|
|
|
|
|
o << SERVER_STATISTICS_STR_CUR_GAMES " " << m_statData.numberOfGamesOpen << endl;
|
|
|
|
|
m_statDataChanged = false;
|
|
|
|
|
}
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
2009-06-12 16:04:58 +00:00
|
|
|
// Restart timer
|
|
|
|
|
m_saveStatisticsTimer.expires_from_now(
|
|
|
|
|
boost::posix_time::seconds(SERVER_SAVE_STATISTICS_INTERVAL_SEC));
|
|
|
|
|
m_saveStatisticsTimer.async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerLobbyThread::TimerSaveStatisticsFile, shared_from_this(), boost::asio::placeholders::error));
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerCallback &
|
|
|
|
|
ServerLobbyThread::GetCallback()
|
|
|
|
|
{
|
|
|
|
|
return m_gui;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-03 20:19:51 +00:00
|
|
|
void
|
2009-10-11 09:20:17 +00:00
|
|
|
ServerLobbyThread::SetGameDBId(u_int32_t gameId, DB_id gameDBId)
|
2009-10-03 20:19:51 +00:00
|
|
|
{
|
|
|
|
|
boost::shared_ptr<ServerGame> game = InternalGetGameFromId(gameId);
|
|
|
|
|
if (game)
|
|
|
|
|
game->SetDBId(gameDBId);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-20 11:42:13 +00:00
|
|
|
ServerIrcBotCallback &
|
|
|
|
|
ServerLobbyThread::GetIrcBotCallback()
|
|
|
|
|
{
|
|
|
|
|
return m_ircBotCb;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
ReceiverHelper &
|
|
|
|
|
ServerLobbyThread::GetReceiver()
|
|
|
|
|
{
|
|
|
|
|
assert(m_receiver.get());
|
|
|
|
|
return *m_receiver;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-19 20:28:30 +00:00
|
|
|
InternalServerCallback &
|
2007-11-16 15:24:25 +00:00
|
|
|
ServerLobbyThread::GetSenderCallback()
|
|
|
|
|
{
|
2009-09-19 20:28:30 +00:00
|
|
|
assert(m_internalServerCallback.get());
|
|
|
|
|
return *m_internalServerCallback;
|
2007-11-16 15:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GuiInterface &
|
|
|
|
|
ServerLobbyThread::GetGui()
|
|
|
|
|
{
|
|
|
|
|
return m_gui;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2009-04-07 22:04:38 +00:00
|
|
|
ServerLobbyThread::IsPlayerConnected(const string &name) const
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
|
|
|
|
bool retVal = false;
|
|
|
|
|
|
|
|
|
|
retVal = m_sessionManager.IsPlayerConnected(name);
|
|
|
|
|
|
|
|
|
|
if (!retVal)
|
|
|
|
|
retVal = m_gameSessionManager.IsPlayerConnected(name);
|
|
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 13:43:00 +00:00
|
|
|
boost::shared_ptr<NetPacket>
|
|
|
|
|
ServerLobbyThread::CreateNetPacketPlayerListNew(unsigned playerId)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_playerListMessage;
|
|
|
|
|
PlayerListMessage_t *netPlayerList = &packet->GetMsg()->choice.playerListMessage;
|
|
|
|
|
netPlayerList->playerId = playerId;
|
|
|
|
|
netPlayerList->playerListNotification = playerListNotification_playerListNew;
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boost::shared_ptr<NetPacket>
|
|
|
|
|
ServerLobbyThread::CreateNetPacketPlayerListLeft(unsigned playerId)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_playerListMessage;
|
|
|
|
|
PlayerListMessage_t *netPlayerList = &packet->GetMsg()->choice.playerListMessage;
|
|
|
|
|
netPlayerList->playerId = playerId;
|
|
|
|
|
netPlayerList->playerListNotification = playerListNotification_playerListLeft;
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
boost::shared_ptr<NetPacket>
|
2009-05-31 20:14:46 +00:00
|
|
|
ServerLobbyThread::CreateNetPacketGameListNew(const ServerGame &game)
|
2007-11-16 15:24:25 +00:00
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_gameListMessage;
|
|
|
|
|
GameListMessage_t *netGameList = &packet->GetMsg()->choice.gameListMessage;
|
|
|
|
|
netGameList->gameId = game.GetId();
|
|
|
|
|
|
|
|
|
|
netGameList->gameListNotification.present = gameListNotification_PR_gameListNew;
|
|
|
|
|
GameListNew_t *gameNew = &netGameList->gameListNotification.choice.gameListNew;
|
|
|
|
|
gameNew->adminPlayerId = game.GetAdminPlayerId();
|
|
|
|
|
gameNew->gameMode = game.IsRunning() ? NetGameMode_gameStarted : NetGameMode_gameCreated;
|
|
|
|
|
NetPacket::SetGameData(game.GetGameData(), &gameNew->gameInfo);
|
|
|
|
|
OCTET_STRING_fromBuf(
|
|
|
|
|
&gameNew->gameInfo.gameName,
|
|
|
|
|
game.GetName().c_str(),
|
|
|
|
|
game.GetName().length());
|
|
|
|
|
gameNew->isPrivate = game.IsPasswordProtected();
|
|
|
|
|
|
|
|
|
|
PlayerIdList tmpList = game.GetPlayerIdList();
|
|
|
|
|
PlayerIdList::const_iterator i = tmpList.begin();
|
|
|
|
|
PlayerIdList::const_iterator end = tmpList.end();
|
|
|
|
|
while (i != end)
|
|
|
|
|
{
|
|
|
|
|
NonZeroId_t *playerId = (NonZeroId_t *)calloc(1, sizeof(NonZeroId_t));
|
|
|
|
|
*playerId = *i;
|
|
|
|
|
ASN_SEQUENCE_ADD(&gameNew->playerIds.list, playerId);
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-16 15:24:25 +00:00
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boost::shared_ptr<NetPacket>
|
|
|
|
|
ServerLobbyThread::CreateNetPacketGameListUpdate(unsigned gameId, GameMode mode)
|
|
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket(NetPacket::Alloc));
|
|
|
|
|
packet->GetMsg()->present = PokerTHMessage_PR_gameListMessage;
|
|
|
|
|
GameListMessage_t *netGameList = &packet->GetMsg()->choice.gameListMessage;
|
|
|
|
|
netGameList->gameId = gameId;
|
|
|
|
|
|
|
|
|
|
netGameList->gameListNotification.present = gameListNotification_PR_gameListUpdate;
|
|
|
|
|
GameListUpdate_t *gameUpdate = &netGameList->gameListNotification.choice.gameListUpdate;
|
|
|
|
|
|
|
|
|
|
gameUpdate->gameMode = mode;
|
2007-11-16 15:24:25 +00:00
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|