diff --git a/engine/server/application/ConnectionServer/src/shared/ClientConnection.cpp b/engine/server/application/ConnectionServer/src/shared/ClientConnection.cpp index 0151f093..e4090172 100755 --- a/engine/server/application/ConnectionServer/src/shared/ClientConnection.cpp +++ b/engine/server/application/ConnectionServer/src/shared/ClientConnection.cpp @@ -301,9 +301,9 @@ void ClientConnection::handleClientIdMessage(const ClientIdMsg &msg) { bool cont = false; StationId apiSuid = 0; const std::string clientIP = getRemoteAddress(); - const std::string sess = sessionId; + const std::string sess = sessionId; - webAPI api(sessURL); + webAPI api(sessURL); // add our data api.addJsonData("session_key", sess); @@ -317,13 +317,13 @@ void ClientConnection::handleClientIdMessage(const ClientIdMsg &msg) { int expired = api.getNullableValue("expired"); std::string apiUser = api.getString("user_name"); std::string apiIP = api.getString("ip"); - - if (apiIP == clientIP && expired == 0) { + + if (apiIP == clientIP && expired == 0) { m_suid = apiSuid; cont = true; } } - } + } if (!cont) { LOG("ClientDisconnect", ("SUID %d (%d) passed a bad token to the connections erver. Disconnecting.", m_suid, apiSuid)); diff --git a/engine/server/application/ConnectionServer/src/shared/ConnectionServer.cpp b/engine/server/application/ConnectionServer/src/shared/ConnectionServer.cpp index 18a42389..7e7f5783 100755 --- a/engine/server/application/ConnectionServer/src/shared/ConnectionServer.cpp +++ b/engine/server/application/ConnectionServer/src/shared/ConnectionServer.cpp @@ -57,107 +57,85 @@ #include "sharedFoundation/CrcConstexpr.hpp" // ====================================================================== -namespace ConnectionServerNamespace -{ - ConnectionServer * s_connectionServer = 0; - NetworkSetupData * s_clientServiceSetup = 0; +namespace ConnectionServerNamespace { + ConnectionServer *s_connectionServer = 0; + NetworkSetupData *s_clientServiceSetup = 0; - const std::string SCENE_NAME_TUTORIAL = "tutorial"; - const std::string SCENE_NAME_FALCON_PREFIX = "space_npe_falcon"; + const std::string SCENE_NAME_TUTORIAL = "tutorial"; + const std::string SCENE_NAME_FALCON_PREFIX = "space_npe_falcon"; }; using namespace ConnectionServerNamespace; // ====================================================================== -ConnectionServer & ConnectionServer::instance() -{ - return *s_connectionServer; +ConnectionServer &ConnectionServer::instance() { + return *s_connectionServer; } //----------------------------------------------------------------------- -ConnectionServer::ConnectionServer() : - MessageDispatch::Receiver(), - chatService(0), - customerService(0), - clientServicePrivate(0), - clientServicePublic(0), - gameService(0), - loginServerKeys(0), - done(false), - m_id(0), - m_metricsData(0), - centralConnection(0), - chatServers(), - customerServiceServers(), - clientMap(), - connectedMap(), - gameServerMap(), - freeTrials(), - networkBarrier(0), - pingSocket(new UdpSock), - m_recoverTime(0), - m_pingTrafficNumBytes(0), - m_recoveringClientList() -{ - if (s_clientServiceSetup == 0) - s_clientServiceSetup = new NetworkSetupData; +ConnectionServer::ConnectionServer() + : MessageDispatch::Receiver(), chatService(0), customerService(0), clientServicePrivate(0), + clientServicePublic(0), gameService(0), loginServerKeys(0), done(false), m_id(0), m_metricsData(0), + centralConnection(0), chatServers(), customerServiceServers(), clientMap(), connectedMap(), gameServerMap(), + freeTrials(), networkBarrier(0), pingSocket(new UdpSock), m_recoverTime(0), m_pingTrafficNumBytes(0), + m_recoveringClientList() { + if (s_clientServiceSetup == 0) { + s_clientServiceSetup = new NetworkSetupData; + } - s_clientServiceSetup->maxOutstandingPackets = ConfigConnectionServer::getClientMaxOutstandingPackets(); - s_clientServiceSetup->maxRawPacketSize = ConfigConnectionServer::getClientMaxRawPacketSize(); - s_clientServiceSetup->maxConnections = ConfigConnectionServer::getClientMaxConnections(); - s_clientServiceSetup->fragmentSize = ConfigConnectionServer::getClientFragmentSize(); - s_clientServiceSetup->maxDataHoldTime = ConfigConnectionServer::getClientMaxDataHoldTime(); - s_clientServiceSetup->hashTableSize = ConfigConnectionServer::getClientHashTableSize(); - s_clientServiceSetup->port = ConfigConnectionServer::getClientServicePortPublic(); - s_clientServiceSetup->maxConnectionsPerIP = ConfigConnectionServer::getMaxConnectionsPerIP(); - s_clientServiceSetup->compress = ConfigConnectionServer::getCompressClientNetworkTraffic(); - s_clientServiceSetup->useTcp = false; + s_clientServiceSetup->maxOutstandingPackets = ConfigConnectionServer::getClientMaxOutstandingPackets(); + s_clientServiceSetup->maxRawPacketSize = ConfigConnectionServer::getClientMaxRawPacketSize(); + s_clientServiceSetup->maxConnections = ConfigConnectionServer::getClientMaxConnections(); + s_clientServiceSetup->fragmentSize = ConfigConnectionServer::getClientFragmentSize(); + s_clientServiceSetup->maxDataHoldTime = ConfigConnectionServer::getClientMaxDataHoldTime(); + s_clientServiceSetup->hashTableSize = ConfigConnectionServer::getClientHashTableSize(); + s_clientServiceSetup->port = ConfigConnectionServer::getClientServicePortPublic(); + s_clientServiceSetup->maxConnectionsPerIP = ConfigConnectionServer::getMaxConnectionsPerIP(); + s_clientServiceSetup->compress = ConfigConnectionServer::getCompressClientNetworkTraffic(); + s_clientServiceSetup->useTcp = false; - loginServerKeys = new KeyServer(20); + loginServerKeys = new KeyServer(20); - Address a("", ConfigConnectionServer::getPingPort()); - IGNORE_RETURN(pingSocket->bind(a)); + Address a("", ConfigConnectionServer::getPingPort()); + IGNORE_RETURN(pingSocket->bind(a)); } //----------------------------------------------------------------------- -ConnectionServer::~ConnectionServer() -{ - delete pingSocket; - pingSocket = 0; +ConnectionServer::~ConnectionServer() { + delete pingSocket; + pingSocket = 0; - delete loginServerKeys; - loginServerKeys = 0; + delete loginServerKeys; + loginServerKeys = 0; - centralConnection = 0; + centralConnection = 0; - chatServers.clear(); + chatServers.clear(); - customerServiceServers.clear(); + customerServiceServers.clear(); - connectedMap.clear(); + connectedMap.clear(); - clientServicePublic = 0; - clientServicePrivate = 0; - chatService = 0; - customerService = 0; - gameService = 0; - gameServerMap.clear(); - freeTrials.clear(); - delete s_clientServiceSetup; + clientServicePublic = 0; + clientServicePrivate = 0; + chatService = 0; + customerService = 0; + gameService = 0; + gameServerMap.clear(); + freeTrials.clear(); + delete s_clientServiceSetup; } //----------------------------------------------------------------------- -const CustomerServiceConnection * ConnectionServer::getCustomerServiceConnection() -{ - if (!instance().customerServiceServers.empty()) - { - return (*(instance().customerServiceServers.begin())); - } - return nullptr; +const CustomerServiceConnection *ConnectionServer::getCustomerServiceConnection() { + if (!instance().customerServiceServers.empty()) { + return (*(instance().customerServiceServers.begin())); + } + return nullptr; } //----------------------------------------------------------------------- @@ -167,239 +145,223 @@ const CustomerServiceConnection * ConnectionServer::getCustomerServiceConnection // be waiting on a different gameserver, or they could be in the process // of being validated -void ConnectionServer::addGameConnection(unsigned long gameServerId, GameConnection* gc) -{ - static ConnectionServer & cs = instance(); +void ConnectionServer::addGameConnection(unsigned long gameServerId, GameConnection *gc) { + static ConnectionServer &cs = instance(); - cs.gameServerMap[gameServerId] = gc;//@todo check for dupe - // find characters pending for THIS gameserver - SuidMap::iterator i; - for (i = cs.connectedMap.begin(); i != cs.connectedMap.end(); ++i) - { - ClientConnection * c = (*i).second; - if (!c->getHasBeenSentToGameServer()) - IGNORE_RETURN(c->sendToGameServer()); - } + cs.gameServerMap[gameServerId] = gc;//@todo check for dupe + // find characters pending for THIS gameserver + SuidMap::iterator i; + for (i = cs.connectedMap.begin(); i != cs.connectedMap.end(); ++i) { + ClientConnection *c = (*i).second; + if (!c->getHasBeenSentToGameServer()) { + IGNORE_RETURN(c->sendToGameServer()); + } + } } //----------------------------------------------------------------------- -bool ConnectionServer::decryptToken(const KeyShare::Token & token, uint32 & stationUserId, bool & secure, std::string & accountName) -{ - static ConnectionServer & cs = instance(); +bool +ConnectionServer::decryptToken(const KeyShare::Token &token, uint32 &stationUserId, bool &secure, std::string &accountName) { + static ConnectionServer &cs = instance(); - //Also the sizeof(int) is likewise magic from the session api - uint32 len = sizeof(uint32) + sizeof(bool) + MAX_ACCOUNT_NAME_LENGTH + 1; - unsigned char * keyBuffer = new unsigned char[len]; - unsigned char * keyBufferPointer = keyBuffer; - memset(keyBuffer, 0, len); + //Also the sizeof(int) is likewise magic from the session api + uint32 len = sizeof(uint32) + sizeof(bool) + MAX_ACCOUNT_NAME_LENGTH + 1; + unsigned char *keyBuffer = new unsigned char[len]; + unsigned char *keyBufferPointer = keyBuffer; + memset(keyBuffer, 0, len); - bool retval = cs.loginServerKeys->decipherToken(token, keyBuffer, len); + bool retval = cs.loginServerKeys->decipherToken(token, keyBuffer, len); - if (!retval) - return retval; + if (!retval) { + return retval; + } - char *tmpBuffer = new char[MAX_ACCOUNT_NAME_LENGTH + 1]; - memset(tmpBuffer, 0, MAX_ACCOUNT_NAME_LENGTH + 1); + char *tmpBuffer = new char[MAX_ACCOUNT_NAME_LENGTH + 1]; + memset(tmpBuffer, 0, MAX_ACCOUNT_NAME_LENGTH + 1); - memcpy(&stationUserId, keyBufferPointer, sizeof(uint32)); - keyBufferPointer += sizeof(uint32); - memcpy(&secure, keyBufferPointer, sizeof(bool)); - keyBufferPointer += sizeof(bool); - memcpy(tmpBuffer, keyBufferPointer, MAX_ACCOUNT_NAME_LENGTH); - accountName = tmpBuffer; - delete[] tmpBuffer; - delete[] keyBuffer; - return retval; + memcpy(&stationUserId, keyBufferPointer, sizeof(uint32)); + keyBufferPointer += sizeof(uint32); + memcpy(&secure, keyBufferPointer, sizeof(bool)); + keyBufferPointer += sizeof(bool); + memcpy(tmpBuffer, keyBufferPointer, MAX_ACCOUNT_NAME_LENGTH); + accountName = tmpBuffer; + delete[] tmpBuffer; + delete[] keyBuffer; + return retval; } -bool ConnectionServer::decryptToken(const KeyShare::Token & token, char* sessionKey, StationId & stationId) -{ - static ConnectionServer & cs = instance(); +bool ConnectionServer::decryptToken(const KeyShare::Token &token, char *sessionKey, StationId &stationId) { + static ConnectionServer &cs = instance(); - uint32 len = apiSessionIdWidth + sizeof(StationId); - unsigned char * keyBuffer = new unsigned char[len + 1]; - unsigned char * keyBufferPointer = keyBuffer; - memset(keyBuffer, 0, sizeof(*keyBuffer)); + uint32 len = apiSessionIdWidth + sizeof(StationId); + unsigned char *keyBuffer = new unsigned char[len + 1]; + unsigned char *keyBufferPointer = keyBuffer; + memset(keyBuffer, 0, sizeof(*keyBuffer)); - bool retval = cs.loginServerKeys->decipherToken(token, keyBuffer, len); + bool retval = cs.loginServerKeys->decipherToken(token, keyBuffer, len); - if (!retval) - return retval; + if (!retval) { + return retval; + } - memcpy(sessionKey, keyBufferPointer, len); - keyBufferPointer += apiSessionIdWidth; - memcpy(&stationId, keyBufferPointer, sizeof(StationId)); - delete[] keyBuffer; - return retval; + memcpy(sessionKey, keyBufferPointer, len); + keyBufferPointer += apiSessionIdWidth; + memcpy(&stationId, keyBufferPointer, sizeof(StationId)); + delete[] keyBuffer; + return retval; } //----------------------------------------------------------------------- -const Service * ConnectionServer::getChatService() -{ - static ConnectionServer & cs = instance(); - return cs.chatService; +const Service *ConnectionServer::getChatService() { + static ConnectionServer &cs = instance(); + return cs.chatService; } //----------------------------------------------------------------------- -const Service * ConnectionServer::getCustomerService() -{ - static ConnectionServer & cs = instance(); - return cs.customerService; +const Service *ConnectionServer::getCustomerService() { + static ConnectionServer &cs = instance(); + return cs.customerService; } //----------------------------------------------------------------------- -Service * ConnectionServer::getClientServicePrivate() -{ - static ConnectionServer & cs = instance(); - return cs.clientServicePrivate; +Service *ConnectionServer::getClientServicePrivate() { + static ConnectionServer &cs = instance(); + return cs.clientServicePrivate; } //----------------------------------------------------------------------- -Service * ConnectionServer::getClientServicePublic() -{ - static ConnectionServer & cs = instance(); - return cs.clientServicePublic; +Service *ConnectionServer::getClientServicePublic() { + static ConnectionServer &cs = instance(); + return cs.clientServicePublic; } //----------------------------------------------------------------------- -KeyShare::Token ConnectionServer::makeToken(const unsigned char * newData, const uint32 dataLen) -{ - static ConnectionServer & cs = instance(); - return cs.loginServerKeys->makeToken(newData, dataLen); +KeyShare::Token ConnectionServer::makeToken(const unsigned char *newData, const uint32 dataLen) { + static ConnectionServer &cs = instance(); + return cs.loginServerKeys->makeToken(newData, dataLen); } //----------------------------------------------------------------------- -void ConnectionServer::pushKey(const KeyShare::Key & newKey) -{ - static ConnectionServer & cs = instance(); - cs.loginServerKeys->pushKey(newKey); +void ConnectionServer::pushKey(const KeyShare::Key &newKey) { + static ConnectionServer &cs = instance(); + cs.loginServerKeys->pushKey(newKey); } //----------------------------------------------------------------------- -void ConnectionServer::addNewClient(ClientConnection* cconn, const NetworkId &oid, GameConnection* gconn, const std::string &, bool sendToStarport) -{ - static ConnectionServer & cs = instance(); - ClientMap::iterator i = cs.clientMap.find(oid); - if (i != cs.clientMap.end()) - { - if (cconn->getClient()) - { - WARNING_STRICT_FATAL(true, ("Client already connected, attempting to drop old one\n")); - dropClient(cconn, "Duplicate Login"); - return; - } - else - { - // stale connection in map - cs.removeFromClientMap(oid); - } - } +void +ConnectionServer::addNewClient(ClientConnection *cconn, const NetworkId &oid, GameConnection *gconn, const std::string &, bool sendToStarport) { + static ConnectionServer &cs = instance(); + ClientMap::iterator i = cs.clientMap.find(oid); + if (i != cs.clientMap.end()) { + if (cconn->getClient()) { + WARNING_STRICT_FATAL(true, ("Client already connected, attempting to drop old one\n")); + dropClient(cconn, "Duplicate Login"); + return; + } else { + // stale connection in map + cs.removeFromClientMap(oid); + } + } - // Create a new entry in the client map - cs.addToClientMap(oid, cconn); + // Create a new entry in the client map + cs.addToClientMap(oid, cconn); - // Get the client that was just created - Client * newClient = cs.getClient(oid); - NOT_NULL(newClient); + // Get the client that was just created + Client *newClient = cs.getClient(oid); + NOT_NULL(newClient); - // select a chat server connection for the client - // if non exists, then the client will be notified when - // one starts - if (!cs.chatServers.empty()) - { - //ChatServerConnection * c = (*chatServers.begin()); - // find chat server with least load - size_t max = 0xFFFFFFFF; - ChatServerConnection * candidate = 0; - std::set::const_iterator iter; - for (iter = cs.chatServers.begin(); iter != cs.chatServers.end(); ++iter) - { - if ((*iter)->getClients().size() <= max) - { - candidate = (*iter); - max = (*iter)->getClients().size(); - } - } - if (candidate) - newClient->setChatConnection(candidate); - } + // select a chat server connection for the client + // if non exists, then the client will be notified when + // one starts + if (!cs.chatServers.empty()) { + //ChatServerConnection * c = (*chatServers.begin()); + // find chat server with least load + size_t max = 0xFFFFFFFF; + ChatServerConnection *candidate = 0; + std::set::const_iterator iter; + for (iter = cs.chatServers.begin(); iter != cs.chatServers.end(); ++iter) { + if ((*iter)->getClients().size() <= max) { + candidate = (*iter); + max = (*iter)->getClients().size(); + } + } + if (candidate) { + newClient->setChatConnection(candidate); + } + } - // select a cs server connection for the client - // if non exists, then the client will be notified when - // one starts - if (!cs.customerServiceServers.empty()) - { - //ChatServerConnection * c = (*chatServers.begin()); - // find chat server with least load - size_t max = 0xFFFFFFFF; - CustomerServiceConnection * candidate = 0; - std::set::const_iterator iter; - for (iter = cs.customerServiceServers.begin(); iter != cs.customerServiceServers.end(); ++iter) - { - if ((*iter)->getClients().size() <= max) - { - candidate = (*iter); - max = (*iter)->getClients().size(); - } - } - if (candidate) - newClient->setCustomerServiceConnection(candidate); - } + // select a cs server connection for the client + // if non exists, then the client will be notified when + // one starts + if (!cs.customerServiceServers.empty()) { + //ChatServerConnection * c = (*chatServers.begin()); + // find chat server with least load + size_t max = 0xFFFFFFFF; + CustomerServiceConnection *candidate = 0; + std::set::const_iterator iter; + for (iter = cs.customerServiceServers.begin(); iter != cs.customerServiceServers.end(); ++iter) { + if ((*iter)->getClients().size() <= max) { + candidate = (*iter); + max = (*iter)->getClients().size(); + } + } + if (candidate) { + newClient->setCustomerServiceConnection(candidate); + } + } - //send the game server a message about this client. - static const std::string loginTrace("TRACE_LOGIN"); - LOG(loginTrace, ("NewClient(%d, %s, %s)", cconn->getSUID(), oid.getValueString().c_str(), cconn->getAccountName().c_str())); - NewClient m(oid, cconn->getAccountName(), cconn->getRemoteAddress(), cconn->getIsSecure(), false, cconn->getSUID(), nullptr, cconn->getGameFeatures(), cconn->getSubscriptionFeatures(), cconn->getEntitlementTotalTime(), cconn->getEntitlementEntitledTime(), cconn->getEntitlementTotalTimeSinceLastLogin(), cconn->getEntitlementEntitledTimeSinceLastLogin(), cconn->getBuddyPoints(), cconn->getConsumedRewardEvents(), cconn->getClaimedRewardItems(), cconn->isUsingAdminLogin(), cconn->getCanSkipTutorial(), sendToStarport); - gconn->send(m, true); - //@todo move this to ClientConnection.cpp + //send the game server a message about this client. + static const std::string loginTrace("TRACE_LOGIN"); + LOG(loginTrace, ("NewClient(%d, %s, %s)", cconn->getSUID(), oid.getValueString().c_str(), cconn->getAccountName().c_str())); + NewClient m(oid, cconn->getAccountName(), cconn->getRemoteAddress(), cconn->getIsSecure(), false, cconn->getSUID(), nullptr, cconn->getGameFeatures(), cconn->getSubscriptionFeatures(), cconn->getEntitlementTotalTime(), cconn->getEntitlementEntitledTime(), cconn->getEntitlementTotalTimeSinceLastLogin(), cconn->getEntitlementEntitledTimeSinceLastLogin(), cconn->getBuddyPoints(), cconn->getConsumedRewardEvents(), cconn->getClaimedRewardItems(), cconn->isUsingAdminLogin(), cconn->getCanSkipTutorial(), sendToStarport); + gconn->send(m, true); + //@todo move this to ClientConnection.cpp } //----------------------------------------------------------------------- -void ConnectionServer::dropClient(ClientConnection * conn, const std::string& description) -{ - DEBUG_FATAL(!conn, ("Cannot call dropClient with nullptr connection")); - if (!conn) //lint !e774 // boolean within 'if' always evaluates to False //suppresed because this is only relevant in DEBUG builds - return; +void ConnectionServer::dropClient(ClientConnection *conn, const std::string &description) { + DEBUG_FATAL(!conn, ("Cannot call dropClient with nullptr connection")); + if (!conn) { //lint !e774 // boolean within 'if' always evaluates to False //suppresed because this is only relevant in DEBUG builds + return; + } - static ConnectionServer & cs = instance(); - //Client dropped. Tell game server if they've logged in. - LOG("ClientDisconnect", ("Dropping client for SUID %d\n", conn->getSUID())); - LOG("CustomerService", ("Login:%s Dropped Reason: %s. Character: %s (%s). Play time: %s. Active play time: %s", ClientConnection::describeAccount(conn).c_str(), description.c_str(), conn->getCharacterName().c_str(), conn->getCharacterId().getValueString().c_str(), conn->getPlayTimeDuration().c_str(), conn->getActivePlayTimeDuration().c_str())); + static ConnectionServer &cs = instance(); + //Client dropped. Tell game server if they've logged in. + LOG("ClientDisconnect", ("Dropping client for SUID %d\n", conn->getSUID())); + LOG("CustomerService", ("Login:%s Dropped Reason: %s. Character: %s (%s). Play time: %s. Active play time: %s", ClientConnection::describeAccount(conn).c_str(), description.c_str(), conn->getCharacterName().c_str(), conn->getCharacterId().getValueString().c_str(), conn->getPlayTimeDuration().c_str(), conn->getActivePlayTimeDuration().c_str())); - Client *client = conn->getClient(); - if (client) - { - DropClient msg(client->getNetworkId()); - GameConnection* gconn = client->getGameConnection(); - //Don't worry about sending a message to a non-existant game server - if (gconn) - gconn->send(msg, true); - else - DEBUG_REPORT_LOG(true, ("Could not find game server to drop this client\n")); + Client *client = conn->getClient(); + if (client) { + DropClient msg(client->getNetworkId()); + GameConnection *gconn = client->getGameConnection(); + //Don't worry about sending a message to a non-existant game server + if (gconn) { + gconn->send(msg, true); + } else { + DEBUG_REPORT_LOG(true, ("Could not find game server to drop this client\n")); + } - // Remove the entry from the client map - cs.removeFromClientMap(client->getNetworkId()); - } - else - { - //If they aren't connected to the game yet, they're probably on the pending list. - //@todo ensure we don't need to send a cleanup message to central + // Remove the entry from the client map + cs.removeFromClientMap(client->getNetworkId()); + } else { + //If they aren't connected to the game yet, they're probably on the pending list. + //@todo ensure we don't need to send a cleanup message to central // removePendingCharacter(conn->getSUID()); - } + } - // Remove entry from the connected map - cs.removeFromConnectedMap(conn->getSUID()); + // Remove entry from the connected map + cs.removeFromConnectedMap(conn->getSUID()); - conn->disconnect(); + conn->disconnect(); } //----------------------------------------------------------------------- @@ -416,708 +378,629 @@ void ConnectionServer::dropClient(ClientConnection * conn, const std::string& de //----------------------------------------------------------------------- -void ConnectionServer::addConnectedClient(uint32 suid, ClientConnection* conn) -{ - static ConnectionServer & cs = instance(); - cs.addToConnectedMap(suid, conn); +void ConnectionServer::addConnectedClient(uint32 suid, ClientConnection *conn) { + static ConnectionServer &cs = instance(); + cs.addToConnectedMap(suid, conn); } //----------------------------------------------------------------------- -ClientConnection* ConnectionServer::getClientConnection(const uint32 suid) -{ - static ConnectionServer & cs = instance(); - ClientConnection * result = 0; - SuidMap::const_iterator i = cs.connectedMap.find(suid); - if (i != cs.connectedMap.end()) - { - result = (*i).second; - } - return result; +ClientConnection *ConnectionServer::getClientConnection(const uint32 suid) { + static ConnectionServer &cs = instance(); + ClientConnection *result = 0; + SuidMap::const_iterator i = cs.connectedMap.find(suid); + if (i != cs.connectedMap.end()) { + result = (*i).second; + } + return result; } // ---------------------------------------------------------------------- -const Service * ConnectionServer::getGameService() -{ - static ConnectionServer & cs = instance(); - return cs.gameService; +const Service *ConnectionServer::getGameService() { + static ConnectionServer &cs = instance(); + return cs.gameService; } // ---------------------------------------------------------------------- -GameConnection* ConnectionServer::getGameConnection(const std::string &sceneName) -{ - static ConnectionServer & cs = instance(); - GameServerMap::iterator i = cs.gameServerMap.begin(); - for (; i != cs.gameServerMap.end(); ++i) - { - if (sceneName == (*i).second->getSceneName()) - { - return (*i).second; - } - } - return nullptr; +GameConnection *ConnectionServer::getGameConnection(const std::string &sceneName) { + static ConnectionServer &cs = instance(); + GameServerMap::iterator i = cs.gameServerMap.begin(); + for (; i != cs.gameServerMap.end(); ++i) { + if (sceneName == (*i).second->getSceneName()) { + return (*i).second; + } + } + return nullptr; } // ---------------------------------------------------------------------- -void ConnectionServer::handleConnectionServerIdMessage(const ConnectionServerId & m) -{ - // Connection established with central server. Set everything up. - m_id = m.getId(); +void ConnectionServer::handleConnectionServerIdMessage(const ConnectionServerId &m) { + // Connection established with central server. Set everything up. + m_id = m.getId(); - const Service * const servicePrivate = getClientServicePrivate(); - const Service * const servicePublic = getClientServicePublic(); - FATAL(servicePrivate == nullptr && servicePublic == nullptr, ("No client service is active!")); + const Service *const servicePrivate = getClientServicePrivate(); + const Service *const servicePublic = getClientServicePublic(); + FATAL(servicePrivate == nullptr && servicePublic == nullptr, ("No client service is active!")); - const Service * const g = getGameService(); - FATAL(g == nullptr, ("No game service is active!")); - const Service * const c = getChatService(); - const Service * const cs = getCustomerService(); - const uint16 pingPort = getPingPort(); + const Service *const g = getGameService(); + FATAL(g == nullptr, ("No game service is active!")); + const Service *const c = getChatService(); + const Service *const cs = getCustomerService(); + const uint16 pingPort = getPingPort(); - if ((servicePrivate != nullptr || servicePublic != nullptr) && g != nullptr) //lint !e774 // always evaluates to false // suppresed because the FATAL macro triggers this lint warning - { - uint16 chatPort = 0; - uint16 csPort = 0; - if (c) - { - chatPort = c->getBindPort(); - } + if ((servicePrivate != nullptr || servicePublic != nullptr) && g != + nullptr) //lint !e774 // always evaluates to false // suppresed because the FATAL macro triggers this lint warning + { + uint16 chatPort = 0; + uint16 csPort = 0; + if (c) { + chatPort = c->getBindPort(); + } - if (cs) - { - csPort = cs->getBindPort(); - } + if (cs) { + csPort = cs->getBindPort(); + } - uint16 publicPort = 0; - if (servicePublic) - { - publicPort = servicePublic->getBindPort(); - } + uint16 publicPort = 0; + if (servicePublic) { + publicPort = servicePublic->getBindPort(); + } - uint16 privatePort = 0; - if (servicePrivate) - { - privatePort = servicePrivate->getBindPort(); - } + uint16 privatePort = 0; + if (servicePrivate) { + privatePort = servicePrivate->getBindPort(); + } - std::string clientServicePublicBindAddress = ConfigConnectionServer::getPublicBindAddress(); - if (clientServicePublicBindAddress.empty()) - { - clientServicePublicBindAddress = NetworkHandler::getHostName(); - } + std::string clientServicePublicBindAddress = ConfigConnectionServer::getPublicBindAddress(); + if (clientServicePublicBindAddress.empty()) { + clientServicePublicBindAddress = NetworkHandler::getHostName(); + } - NOT_NULL(gameService); - NOT_NULL(chatService); - NOT_NULL(customerService); + NOT_NULL(gameService); + NOT_NULL(chatService); + NOT_NULL(customerService); - const NewCentralConnectionServer ncs(gameService->getBindAddress(), clientServicePublicBindAddress, chatService->getBindAddress(), customerService->getBindAddress(), privatePort, publicPort, g->getBindPort(), chatPort, csPort, pingPort, ConfigConnectionServer::getConnectionServerNumber()); - sendToCentralProcess(ncs); - } - else - { - FATAL(true, ("Error in connection server startup")); - } + const NewCentralConnectionServer ncs(gameService->getBindAddress(), clientServicePublicBindAddress, chatService->getBindAddress(), customerService->getBindAddress(), privatePort, publicPort, g->getBindPort(), chatPort, csPort, pingPort, ConfigConnectionServer::getConnectionServerNumber()); + sendToCentralProcess(ncs); + } else { + FATAL(true, ("Error in connection server startup")); + } } // ---------------------------------------------------------------------- -void ConnectionServer::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message) -{ - // it's reasonably safe to cast, message type verified - // determine message type - - const uint32 messageType = message.getType(); +void +ConnectionServer::receiveMessage(const MessageDispatch::Emitter &source, const MessageDispatch::MessageBase &message) { + // it's reasonably safe to cast, message type verified + // determine message type - switch(messageType) { - case constcrc("GameConnectionOpened") : - { - DEBUG_REPORT_LOG(true, ("Game Connection opened\n")); - break; - } - case constcrc("GameConnectionClosed") : - { - //@todo handle case where game server drops and we have users connected to it. - //Drop all connected clients. - const GameConnection & downConnection = static_cast(source); - DEBUG_REPORT_LOG(true, ("Game Server connection went down. Dropping clients.\n")); - //remove Game Conection from list + const uint32 messageType = message.getType(); - PseudoClientConnection::gameConnectionClosed(&downConnection); + switch (messageType) { + case constcrc("GameConnectionOpened") : { + DEBUG_REPORT_LOG(true, ("Game Connection opened\n")); + break; + } + case constcrc("GameConnectionClosed") : { + //@todo handle case where game server drops and we have users connected to it. + //Drop all connected clients. + const GameConnection &downConnection = static_cast(source); + DEBUG_REPORT_LOG(true, ("Game Server connection went down. Dropping clients.\n")); + //remove Game Conection from list - GameServerMap::iterator j = gameServerMap.find(downConnection.getGameServerId()); - if (j != gameServerMap.end()) - { - gameServerMap.erase(j); - } - break; - } - case constcrc("CentralConnectionOpened") : - { - DEBUG_REPORT_LOG(true, ("Opened connection with central\n")); - centralConnection = const_cast(static_cast(&source));//lint !e826 // info: Suspiscious pointer-to-pointer conversion (area too small) + PseudoClientConnection::gameConnectionClosed(&downConnection); - if (ConfigConnectionServer::getStartPublicServer()) - { - s_clientServiceSetup->port = ConfigConnectionServer::getClientServicePortPublic(); - s_clientServiceSetup->maxConnectionsPerIP = ConfigConnectionServer::getMaxConnectionsPerIP(); - clientServicePublic = new Service(ConnectionAllocator(), *s_clientServiceSetup); - } + GameServerMap::iterator j = gameServerMap.find(downConnection.getGameServerId()); + if (j != gameServerMap.end()) { + gameServerMap.erase(j); + } + break; + } + case constcrc("CentralConnectionOpened") : { + DEBUG_REPORT_LOG(true, ("Opened connection with central\n")); + centralConnection = const_cast(static_cast(&source));//lint !e826 // info: Suspiscious pointer-to-pointer conversion (area too small) - s_clientServiceSetup->port = ConfigConnectionServer::getClientServicePortPrivate(); - s_clientServiceSetup->maxConnectionsPerIP = 0; - clientServicePrivate = new Service(ConnectionAllocator(), *s_clientServiceSetup); + if (ConfigConnectionServer::getStartPublicServer()) { + s_clientServiceSetup->port = ConfigConnectionServer::getClientServicePortPublic(); + s_clientServiceSetup->maxConnectionsPerIP = ConfigConnectionServer::getMaxConnectionsPerIP(); + clientServicePublic = new Service(ConnectionAllocator(), *s_clientServiceSetup); + } - connectToMessage("ClientConnectionOpened"); - connectToMessage("ClientConnectionClosed"); - break; - } - case constcrc("CentralConnectionClosed") : - { - centralConnection = const_cast(static_cast(&source));//lint !e826 // info: Suspiscious pointer-to-pointer conversion (area too small) - setDone("CentralConnectionClosed: %s", centralConnection ? centralConnection->getDisconnectReason().c_str() : ""); - centralConnection = 0; - DEBUG_REPORT_LOG(true, ("CentralDied. So we will too\n")); - //@todo Drop all pending clients. - break; - } - case constcrc("ClientConnectionOpened") : - { - DEBUG_REPORT_LOG(true, ("Opened connection with client\n")); - break; - } - case constcrc("ClientConnectionClosed") : - { - DEBUG_REPORT_LOG(true, ("Client is Dropping connection\n")); - ClientConnection * cconn = const_cast(static_cast(&source));//lint !e826 // info: Suspiscious pointer-to-pointer conversion (area too small) + s_clientServiceSetup->port = ConfigConnectionServer::getClientServicePortPrivate(); + s_clientServiceSetup->maxConnectionsPerIP = 0; + clientServicePrivate = new Service(ConnectionAllocator(), *s_clientServiceSetup); - //tell CentralServer - if (centralConnection) - { - GenericValueTypeMessage const msg("ClientConnectionClosed", cconn->getSUID()); - centralConnection->send(msg, true); - } + connectToMessage("ClientConnectionOpened"); + connectToMessage("ClientConnectionClosed"); + break; + } + case constcrc("CentralConnectionClosed") : { + centralConnection = const_cast(static_cast(&source));//lint !e826 // info: Suspiscious pointer-to-pointer conversion (area too small) + setDone("CentralConnectionClosed: %s", centralConnection ? centralConnection->getDisconnectReason().c_str() + : ""); + centralConnection = 0; + DEBUG_REPORT_LOG(true, ("CentralDied. So we will too\n")); + //@todo Drop all pending clients. + break; + } + case constcrc("ClientConnectionOpened") : { + DEBUG_REPORT_LOG(true, ("Opened connection with client\n")); + break; + } + case constcrc("ClientConnectionClosed") : { + DEBUG_REPORT_LOG(true, ("Client is Dropping connection\n")); + ClientConnection *cconn = const_cast(static_cast(&source));//lint !e826 // info: Suspiscious pointer-to-pointer conversion (area too small) - //Client dropped. Tell game server if they've logged in. - Client *client = cconn->getClient(); - if (client) - { - DropClient msg(client->getNetworkId()); - GameConnection* gconn = client->getGameConnection(); - //Don't worry about sending a message to a non-existant game server - if (gconn) - gconn->send(msg, true); + //tell CentralServer + if (centralConnection) { + GenericValueTypeMessage const msg("ClientConnectionClosed", cconn->getSUID()); + centralConnection->send(msg, true); + } - // Remove the entry from the client map - removeFromClientMap(client->getNetworkId()); - } - else - { - // TODO: wtf is this? @Darth, fix it! - //If they aren't connected to the game yet, they're probably on the pending list. - //removePendingCharacter(cconn->getSUID()); - } - removeFromConnectedMap(cconn->getSUID()); - break; - } - case constcrc("ConnectionServerId") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - ConnectionServerId m(ri); - handleConnectionServerIdMessage(m); - break; - } - case constcrc("ConnectionKeyPush") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - ConnectionKeyPush pk(ri); - loginServerKeys->pushKey(pk.getKey()); - break; - } - case constcrc("LoginKeyPush") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const LoginKeyPush k(ri); - loginServerKeys->pushKey(k.getKey()); - break; - } - case constcrc("CharacterListMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const CharacterListMessage msg(ri); - WARNING_STRICT_FATAL(true, ("CharacterListMessage is deprecated on the ConnectionServer -- fix whoever is sending it.\n")); - break; - } - case constcrc("ConnectionCreateCharacterSuccess") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const ConnectionCreateCharacterSuccess msg(ri); - LOG("TraceCharacterCreation", ("Received ConnectionCreateCharacterSuccess for %d", msg.getStationId())); - ClientConnection* const client = getClientConnection(msg.getStationId()); - if (client) - { - const ClientCreateCharacterSuccess m(msg.getNetworkId()); - client->send(m, true); - } - else - { - LOG("CustomerService", ("CharacterTransfer: Trying to deliver ConnectionCreateCharacterSuccess to PsuedoClientConnection(%d)", msg.getStationId())); - PseudoClientConnection::tryToDeliverMessageTo(static_cast(msg.getStationId()), static_cast(message).getByteStream()); - } - break; - } - case constcrc("ConnectionCreateCharacterFailed") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const ConnectionCreateCharacterFailed msg(ri); - ClientConnection* client = getClientConnection(msg.getStationId()); - if (client) - { - client->setHasRequestedCharacterCreate(false); + //Client dropped. Tell game server if they've logged in. + Client *client = cconn->getClient(); + if (client) { + DropClient msg(client->getNetworkId()); + GameConnection *gconn = client->getGameConnection(); + //Don't worry about sending a message to a non-existant game server + if (gconn) { + gconn->send(msg, true); + } - ClientCreateCharacterFailed m(msg.getName(), msg.getErrorMessage()); //lint !e1013 !e1055 !e746 (Symbol 'getErrorMessage' not a member of class 'const ConnectionCreateCharacterFailed') // supressed because it IS a member of that class. //lint !e1055 //lint !e746 - client->send(m, true); - } - else - { - PseudoClientConnection::tryToDeliverMessageTo(static_cast(msg.getStationId()), static_cast(message).getByteStream()); - } - break; - } - case constcrc("NewCharacterCreated") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - ClientConnection* client = getClientConnection(msg.getValue()); - if (client) - { - // don't allow this client to request another character create; - // this will forced the client to disconnect and reconnect at which time - // a check will be done (taking the newly created character into account) - // to see if the client is allowed to create another character on this account - client->setHasCreatedCharacter(true); - } - break; - } - case constcrc("RandomNameResponse") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - RandomNameResponse connMsg(ri); + // Remove the entry from the client map + removeFromClientMap(client->getNetworkId()); + } else { + // TODO: wtf is this? @Darth, fix it! + //If they aren't connected to the game yet, they're probably on the pending list. + //removePendingCharacter(cconn->getSUID()); + } + removeFromConnectedMap(cconn->getSUID()); + break; + } + case constcrc("ConnectionServerId") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ConnectionServerId m(ri); + handleConnectionServerIdMessage(m); + break; + } + case constcrc("ConnectionKeyPush") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ConnectionKeyPush pk(ri); + loginServerKeys->pushKey(pk.getKey()); + break; + } + case constcrc("LoginKeyPush") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const LoginKeyPush k(ri); + loginServerKeys->pushKey(k.getKey()); + break; + } + case constcrc("CharacterListMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const CharacterListMessage msg(ri); + WARNING_STRICT_FATAL(true, ("CharacterListMessage is deprecated on the ConnectionServer -- fix whoever is sending it.\n")); + break; + } + case constcrc("ConnectionCreateCharacterSuccess") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const ConnectionCreateCharacterSuccess msg(ri); + LOG("TraceCharacterCreation", ("Received ConnectionCreateCharacterSuccess for %d", msg.getStationId())); + ClientConnection *const client = getClientConnection(msg.getStationId()); + if (client) { + const ClientCreateCharacterSuccess m(msg.getNetworkId()); + client->send(m, true); + } else { + LOG("CustomerService", ("CharacterTransfer: Trying to deliver ConnectionCreateCharacterSuccess to PsuedoClientConnection(%d)", msg.getStationId())); + PseudoClientConnection::tryToDeliverMessageTo(static_cast(msg.getStationId()), static_cast(message).getByteStream()); + } + break; + } + case constcrc("ConnectionCreateCharacterFailed") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const ConnectionCreateCharacterFailed msg(ri); + ClientConnection *client = getClientConnection(msg.getStationId()); + if (client) { + client->setHasRequestedCharacterCreate(false); - ClientConnection* cconn = getClientConnection(connMsg.getStationId()); - ClientRandomNameResponse cnr(connMsg.getCreatureTemplate(), connMsg.getName(), connMsg.getErrorMessage());//lint !e1013 (Symbol 'getErrorMessage' not a member of class 'RandomNameResponse') // supressed because it IS a member of that class. - if (cconn) - cconn->send(cnr, true); - - break; - } - case constcrc("VerifyAndLockNameResponse") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - VerifyAndLockNameResponse connMsg(ri); + ClientCreateCharacterFailed m(msg.getName(), msg.getErrorMessage()); //lint !e1013 !e1055 !e746 (Symbol 'getErrorMessage' not a member of class 'const ConnectionCreateCharacterFailed') // supressed because it IS a member of that class. //lint !e1055 //lint !e746 + client->send(m, true); + } else { + PseudoClientConnection::tryToDeliverMessageTo(static_cast(msg.getStationId()), static_cast(message).getByteStream()); + } + break; + } + case constcrc("NewCharacterCreated") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + ClientConnection *client = getClientConnection(msg.getValue()); + if (client) { + // don't allow this client to request another character create; + // this will forced the client to disconnect and reconnect at which time + // a check will be done (taking the newly created character into account) + // to see if the client is allowed to create another character on this account + client->setHasCreatedCharacter(true); + } + break; + } + case constcrc("RandomNameResponse") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + RandomNameResponse connMsg(ri); - ClientConnection* cconn = getClientConnection(connMsg.getStationId()); - ClientVerifyAndLockNameResponse cvalnr(connMsg.getCharacterName(), connMsg.getErrorMessage()); - if (cconn) - cconn->send(cvalnr, true); - - break; - } - case constcrc("ChatServerConnectionOpened") : - { - ChatServerConnection * c = const_cast(static_cast(&source));//lint !e826 suspiscious pointer-to-pointer conversion // suppressed, you bet it is - IGNORE_RETURN(chatServers.insert(c)); - break; - } - case constcrc("ChatServerConnectionClosed") : - { - ChatServerConnection * c = const_cast(static_cast(&source));//lint !e826 suspiscious pointer-to-pointer conversion // suppressed, you bet it is - std::set::iterator f = chatServers.find(c); - if (f != chatServers.end()) - { - // migrate players that were on this chat server - // to another chat server + ClientConnection *cconn = getClientConnection(connMsg.getStationId()); + ClientRandomNameResponse cnr(connMsg.getCreatureTemplate(), connMsg.getName(), connMsg.getErrorMessage());//lint !e1013 (Symbol 'getErrorMessage' not a member of class 'RandomNameResponse') // supressed because it IS a member of that class. + if (cconn) { + cconn->send(cnr, true); + } - // now remove the server from the set - chatServers.erase(f); - if (!chatServers.empty()) - { - std::set::iterator ic = chatServers.begin(); + break; + } + case constcrc("VerifyAndLockNameResponse") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + VerifyAndLockNameResponse connMsg(ri); - const std::set & clients = c->getClients(); - std::set::const_iterator i; - for (i = clients.begin(); i != clients.end(); ++i) - { - ChatServerConnection * newConn = (*ic); - Client * cl = (*i); - cl->setChatConnection(newConn); - ++ic; - if (ic == chatServers.end()) - ic = chatServers.begin(); - } - } - else - { - const std::set & clients = c->getClients(); - std::set::const_iterator i; - for (i = clients.begin(); i != clients.end(); ++i) - { - (*i)->setChatConnection(nullptr); - } - } - } - break; - } - case constcrc("CustomerServiceConnectionOpened") : - { - CustomerServiceConnection * c = const_cast(static_cast(&source));//lint !e826 suspiscious pointer-to-pointer conversion // suppressed, you bet it is - IGNORE_RETURN(customerServiceServers.insert(c)); - break; - } - case constcrc("CustomerServiceConnectionClosed") : - { - CustomerServiceConnection * c = const_cast(static_cast(&source));//lint !e826 suspiscious pointer-to-pointer conversion // suppressed, you bet it is - std::set::iterator f = customerServiceServers.find(c); - if (f != customerServiceServers.end()) - { - // migrate players that were on this chat server - // to another chat server + ClientConnection *cconn = getClientConnection(connMsg.getStationId()); + ClientVerifyAndLockNameResponse cvalnr(connMsg.getCharacterName(), connMsg.getErrorMessage()); + if (cconn) { + cconn->send(cvalnr, true); + } - // now remove the server from the set - customerServiceServers.erase(f); - if (!customerServiceServers.empty()) - { - std::set::iterator ic = customerServiceServers.begin(); + break; + } + case constcrc("ChatServerConnectionOpened") : { + ChatServerConnection *c = const_cast(static_cast(&source));//lint !e826 suspiscious pointer-to-pointer conversion // suppressed, you bet it is + IGNORE_RETURN(chatServers.insert(c)); + break; + } + case constcrc("ChatServerConnectionClosed") : { + ChatServerConnection *c = const_cast(static_cast(&source));//lint !e826 suspiscious pointer-to-pointer conversion // suppressed, you bet it is + std::set::iterator f = chatServers.find(c); + if (f != chatServers.end()) { + // migrate players that were on this chat server + // to another chat server - const std::set & clients = c->getClients(); - std::set::const_iterator i; - for (i = clients.begin(); i != clients.end(); ++i) - { - CustomerServiceConnection * newConn = (*ic); - Client * cl = (*i); - cl->setCustomerServiceConnection(newConn); - ++ic; - if (ic == customerServiceServers.end()) - ic = customerServiceServers.begin(); - } - } - else - { - const std::set & clients = c->getClients(); - std::set::const_iterator i; - for (i = clients.begin(); i != clients.end(); ++i) - { - (*i)->setCustomerServiceConnection(nullptr); - } - } - } - break; - } - case constcrc("GameServerForLoginMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const GameServerForLoginMessage msg(ri); + // now remove the server from the set + chatServers.erase(f); + if (!chatServers.empty()) { + std::set::iterator ic = chatServers.begin(); - ClientConnection* client = getClientConnection(msg.getStationId()); + const std::set &clients = c->getClients(); + std::set::const_iterator i; + for (i = clients.begin(); i != clients.end(); ++i) { + ChatServerConnection *newConn = (*ic); + Client *cl = (*i); + cl->setChatConnection(newConn); + ++ic; + if (ic == chatServers.end()) { + ic = chatServers.begin(); + } + } + } else { + const std::set &clients = c->getClients(); + std::set::const_iterator i; + for (i = clients.begin(); i != clients.end(); ++i) { + (*i)->setChatConnection(nullptr); + } + } + } + break; + } + case constcrc("CustomerServiceConnectionOpened") : { + CustomerServiceConnection *c = const_cast(static_cast(&source));//lint !e826 suspiscious pointer-to-pointer conversion // suppressed, you bet it is + IGNORE_RETURN(customerServiceServers.insert(c)); + break; + } + case constcrc("CustomerServiceConnectionClosed") : { + CustomerServiceConnection *c = const_cast(static_cast(&source));//lint !e826 suspiscious pointer-to-pointer conversion // suppressed, you bet it is + std::set::iterator f = customerServiceServers.find(c); + if (f != customerServiceServers.end()) { + // migrate players that were on this chat server + // to another chat server - // see if the client is for the same character as the login message. - // this is required to prevent admin login via the CS Tool from - // disconnecting other characters logged in from the same account - // (but not the same character) as the character we're administratively - // logging in. - bool clientIsForSameCharacterId = false; - if (client) - { - clientIsForSameCharacterId = client->getCharacterId() == msg.getCharacterId(); - } + // now remove the server from the set + customerServiceServers.erase(f); + if (!customerServiceServers.empty()) { + std::set::iterator ic = customerServiceServers.begin(); - bool handledByPseudoClient = false; - // if the character id in the message doesn't match the character id for - // the existing client, it may be for a pseudoclient. Check, and if so, - // handle there. - if (!clientIsForSameCharacterId) - { - PseudoClientConnection * pcc = PseudoClientConnection::getPseudoClientConnection(msg.getCharacterId()); - // hand off to the PCC only if we do have a pseudoclient, and either we don't have a client, or - // the pseudoclient has a tool id, telling us that it's for cs tool login. - if (pcc && ((!client) || (pcc->getTransferCharacterData().getCSToolId() > 0))) - { - handledByPseudoClient = true; - bool result; - result = PseudoClientConnection::tryToDeliverMessageTo(msg.getStationId(), static_cast(message).getByteStream()); - UNREF(result); - DEBUG_REPORT_LOG(!result, ("Received GameServerForLoginMessage for %lu, who was not connected.\n", msg.getStationId())); - } - } + const std::set &clients = c->getClients(); + std::set::const_iterator i; + for (i = clients.begin(); i != clients.end(); ++i) { + CustomerServiceConnection *newConn = (*ic); + Client *cl = (*i); + cl->setCustomerServiceConnection(newConn); + ++ic; + if (ic == customerServiceServers.end()) { + ic = customerServiceServers.begin(); + } + } + } else { + const std::set &clients = c->getClients(); + std::set::const_iterator i; + for (i = clients.begin(); i != clients.end(); ++i) { + (*i)->setCustomerServiceConnection(nullptr); + } + } + } + break; + } + case constcrc("GameServerForLoginMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const GameServerForLoginMessage msg(ri); - if (client && (!handledByPseudoClient)) - { - static const std::string loginTrace("TRACE_LOGIN"); - LOG(loginTrace, ("GameServerForLoginMessage(%d, %s)", client->getSUID(), client->getCharacterId().getValueString().c_str())); - client->handleGameServerForLoginMessage(msg.getServer()); - } - break; - } - case constcrc("ValidateCharacterForLoginReplyMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const ValidateCharacterForLoginReplyMessage msg(ri); + ClientConnection *client = getClientConnection(msg.getStationId()); - ClientConnection* cconn = getClientConnection(msg.getSuid()); - if (!cconn) - DEBUG_REPORT_LOG(true, ("Received ValidateCharacterForLoginReplyMessage for account %lu, which is no longer connected.\n", msg.getSuid())); - else - { - cconn->onCharacterValidated(msg.getApproved(), msg.getCharacterId(), Unicode::wideToNarrow(msg.getCharacterName()), msg.getContainerId(), msg.getScene(), msg.getCoordinates()); - } - break; - } - case constcrc("ValidateAccountReplyMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const ValidateAccountReplyMessage msg(ri); + // see if the client is for the same character as the login message. + // this is required to prevent admin login via the CS Tool from + // disconnecting other characters logged in from the same account + // (but not the same character) as the character we're administratively + // logging in. + bool clientIsForSameCharacterId = false; + if (client) { + clientIsForSameCharacterId = client->getCharacterId() == msg.getCharacterId(); + } - ClientConnection* cconn = getClientConnection(msg.getStationId()); - if (!cconn) - DEBUG_REPORT_LOG(true, ("Received ValidateAccountReplyMessage for account %lu, which is no longer connected.\n", msg.getStationId())); - else - { - cconn->onIdValidated(msg.getCanLogin(), msg.getCanCreateRegular(), msg.getCanCreateJedi(), msg.getCanSkipTutorial(), msg.getConsumedRewardEvents(), msg.getClaimedRewardItems()); - } - break; - } - case constcrc("SetConnectionServerPublic") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - SetConnectionServerPublic p(ri);//lint !e40 !e522 !e10 // Undeclared identifier 'SetConnectionServerPublic' // suppressed because it IS declared - bool statusChanged = false; - DEBUG_REPORT_LOG(true, ("Conn Server: attempting to chang status\n")); - if (p.getIsPublic())//lint !e40 !e1013 !e10 // Undeclared identifier 'p' // suppressed because it IS declared - { - if (!clientServicePublic) - { - statusChanged = true; - } - } - else - { - delete clientServicePublic; - clientServicePublic = 0; - statusChanged = true; - } + bool handledByPseudoClient = false; + // if the character id in the message doesn't match the character id for + // the existing client, it may be for a pseudoclient. Check, and if so, + // handle there. + if (!clientIsForSameCharacterId) { + PseudoClientConnection *pcc = PseudoClientConnection::getPseudoClientConnection(msg.getCharacterId()); + // hand off to the PCC only if we do have a pseudoclient, and either we don't have a client, or + // the pseudoclient has a tool id, telling us that it's for cs tool login. + if (pcc && ((!client) || (pcc->getTransferCharacterData().getCSToolId() > 0))) { + handledByPseudoClient = true; + bool result; + result = PseudoClientConnection::tryToDeliverMessageTo(msg.getStationId(), static_cast(message).getByteStream()); + UNREF(result); + DEBUG_REPORT_LOG(!result, ("Received GameServerForLoginMessage for %lu, who was not connected.\n", msg.getStationId())); + } + } - if (statusChanged && centralConnection) - { - const Service * publicService = getClientServicePublic(); - const Service * privateService = getClientServicePrivate(); - if (publicService || privateService) - { - uint16 publicServicePort = 0; - uint16 privateServicePort = 0; - if (publicService) - { - publicServicePort = publicService->getBindPort(); - } - if (privateService) - { - privateServicePort = privateService->getBindPort(); - } - const UpdateConnectionServerStatus ucs(publicServicePort, privateServicePort); - centralConnection->send(ucs, true); - } - } - break; - }//lint !e529 // Symbol 'ri' not subsequently referenced // suppressed because it IS referenced. I think lint is very confused for some reason. - case constcrc("ProfilerOperationMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - ProfilerOperationMessage msg(ri); - unsigned int processId = msg.getProcessId(); - if (!processId) - Profiler::handleOperation(msg.getOperation().c_str()); - - break; - } - case constcrc("ExcommunicateGameServerMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - ExcommunicateGameServerMessage msg(ri); + if (client && (!handledByPseudoClient)) { + static const std::string loginTrace("TRACE_LOGIN"); + LOG(loginTrace, ("GameServerForLoginMessage(%d, %s)", client->getSUID(), client->getCharacterId().getValueString().c_str())); + client->handleGameServerForLoginMessage(msg.getServer()); + } + break; + } + case constcrc("ValidateCharacterForLoginReplyMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const ValidateCharacterForLoginReplyMessage msg(ri); - LOG("GameGameConnect", ("Told to drop connection to %lu by Central", msg.getServerId())); + ClientConnection *cconn = getClientConnection(msg.getSuid()); + if (!cconn) { + DEBUG_REPORT_LOG(true, ("Received ValidateCharacterForLoginReplyMessage for account %lu, which is no longer connected.\n", msg.getSuid())); + } else { + cconn->onCharacterValidated(msg.getApproved(), msg.getCharacterId(), Unicode::wideToNarrow(msg.getCharacterName()), msg.getContainerId(), msg.getScene(), msg.getCoordinates()); + } + break; + } + case constcrc("ValidateAccountReplyMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const ValidateAccountReplyMessage msg(ri); - GameConnection *conn = getGameConnection(msg.getServerId()); - if (conn) - conn->disconnect(); - - break; - } - case constcrc("CntrlSrvDropDupeConns") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); + ClientConnection *cconn = getClientConnection(msg.getStationId()); + if (!cconn) { + DEBUG_REPORT_LOG(true, ("Received ValidateAccountReplyMessage for account %lu, which is no longer connected.\n", msg.getStationId())); + } else { + cconn->onIdValidated(msg.getCanLogin(), msg.getCanCreateRegular(), msg.getCanCreateJedi(), msg.getCanSkipTutorial(), msg.getConsumedRewardEvents(), msg.getClaimedRewardItems()); + } + break; + } + case constcrc("SetConnectionServerPublic") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + SetConnectionServerPublic p(ri);//lint !e40 !e522 !e10 // Undeclared identifier 'SetConnectionServerPublic' // suppressed because it IS declared + bool statusChanged = false; + DEBUG_REPORT_LOG(true, ("Conn Server: attempting to chang status\n")); + if (p.getIsPublic())//lint !e40 !e1013 !e10 // Undeclared identifier 'p' // suppressed because it IS declared + { + if (!clientServicePublic) { + statusChanged = true; + } + } else { + delete clientServicePublic; + clientServicePublic = 0; + statusChanged = true; + } - ClientConnection* client = getClientConnection(msg.getValue().first); - if (client && !client->isUsingAdminLogin() && !client->getIsSecure()) - { - std::string s = "New Connection on galaxy "; - s += msg.getValue().second; + if (statusChanged && centralConnection) { + const Service *publicService = getClientServicePublic(); + const Service *privateService = getClientServicePrivate(); + if (publicService || privateService) { + uint16 publicServicePort = 0; + uint16 privateServicePort = 0; + if (publicService) { + publicServicePort = publicService->getBindPort(); + } + if (privateService) { + privateServicePort = privateService->getBindPort(); + } + const UpdateConnectionServerStatus ucs(publicServicePort, privateServicePort); + centralConnection->send(ucs, true); + } + } + break; + }//lint !e529 // Symbol 'ri' not subsequently referenced // suppressed because it IS referenced. I think lint is very confused for some reason. + case constcrc("ProfilerOperationMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ProfilerOperationMessage msg(ri); + unsigned int processId = msg.getProcessId(); + if (!processId) { + Profiler::handleOperation(msg.getOperation().c_str()); + } - dropClient(client, s); - } - break; - } - } + break; + } + case constcrc("ExcommunicateGameServerMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ExcommunicateGameServerMessage msg(ri); + + LOG("GameGameConnect", ("Told to drop connection to %lu by Central", msg.getServerId())); + + GameConnection *conn = getGameConnection(msg.getServerId()); + if (conn) { + conn->disconnect(); + } + + break; + } + case constcrc("CntrlSrvDropDupeConns") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + + ClientConnection *client = getClientConnection(msg.getValue().first); + if (client && !client->isUsingAdminLogin() && !client->getIsSecure()) { + std::string s = "New Connection on galaxy "; + s += msg.getValue().second; + + dropClient(client, s); + } + break; + } + } } //----------------------------------------------------------------------- -void ConnectionServer::install() -{ - s_connectionServer = new ConnectionServer; +void ConnectionServer::install() { + s_connectionServer = new ConnectionServer; - char tmp[128] = { "\0" }; - IGNORE_RETURN(snprintf(tmp, sizeof(tmp), "ConnectionServer:%d", Os::getProcessId())); - SetupSharedLog::install(tmp); - s_connectionServer->setupConnections(); - s_connectionServer->m_metricsData = new ConnectionServerMetricsData; - MetricsManager::install(s_connectionServer->m_metricsData, true, "ConnectionServer", "", ConfigConnectionServer::getConnectionServerNumber()); - DataTableManager::install(); - AdminAccountManager::install(ConfigConnectionServer::getAdminAccountDataTable()); + char tmp[128] = {"\0"}; + IGNORE_RETURN(snprintf(tmp, sizeof(tmp), "ConnectionServer:%d", Os::getProcessId())); + SetupSharedLog::install(tmp); + s_connectionServer->setupConnections(); + s_connectionServer->m_metricsData = new ConnectionServerMetricsData; + MetricsManager::install(s_connectionServer->m_metricsData, true, "ConnectionServer", "", ConfigConnectionServer::getConnectionServerNumber()); + DataTableManager::install(); + AdminAccountManager::install(ConfigConnectionServer::getAdminAccountDataTable()); } //----------------------------------------------------------------------- -void ConnectionServer::remove() -{ - MetricsManager::remove(); - delete s_connectionServer->m_metricsData; - s_connectionServer->m_metricsData = 0; +void ConnectionServer::remove() { + MetricsManager::remove(); + delete s_connectionServer->m_metricsData; + s_connectionServer->m_metricsData = 0; - // explicitly delete all connections that were setup from setupConnections rather than letting - // Connection::remove do it. There are connections that require a valid s_connectionServer which is deleted - // and set to nullptr. - s_connectionServer->unsetupConnections(); + // explicitly delete all connections that were setup from setupConnections rather than letting + // Connection::remove do it. There are connections that require a valid s_connectionServer which is deleted + // and set to nullptr. + s_connectionServer->unsetupConnections(); - SetupSharedLog::remove(); + SetupSharedLog::remove(); - delete s_connectionServer; - s_connectionServer = 0; + delete s_connectionServer; + s_connectionServer = 0; } //----------------------------------------------------------------------- -void ConnectionServer::run(void) -{ - static const bool shouldSleep = ConfigConnectionServer::getShouldSleep(); - static ConnectionServer & cserver = instance(); - DEBUG_FATAL(!cserver.m_metricsData, ("Connection server not installed properly")); +void ConnectionServer::run(void) { + static const bool shouldSleep = ConfigConnectionServer::getShouldSleep(); + static ConnectionServer &cserver = instance(); + DEBUG_FATAL(!cserver.m_metricsData, ("Connection server not installed properly")); - unsigned long startTime = Clock::timeMs(); - Clock::setFrameRateLimit(50.0f); + unsigned long startTime = Clock::timeMs(); + Clock::setFrameRateLimit(50.0f); - LOG("ServerStartup", ("ConnectionServer starting on %s", NetworkHandler::getHostName().c_str())); - while (!cserver.done) - { - PROFILER_AUTO_BLOCK_DEFINE("main loop"); + LOG("ServerStartup", ("ConnectionServer starting on %s", NetworkHandler::getHostName().c_str())); + while (!cserver.done) { + PROFILER_AUTO_BLOCK_DEFINE("main loop"); - //bool barrierReached = true; + //bool barrierReached = true; - do - { - { - PROFILER_AUTO_BLOCK_DEFINE("Os::update"); - if (!Os::update()) - cserver.setDone("Os condition (Parent pid change)"); - } + do { + { + PROFILER_AUTO_BLOCK_DEFINE("Os::update"); + if (!Os::update()) { + cserver.setDone("Os condition (Parent pid change)"); + } + } - { - PROFILER_AUTO_BLOCK_DEFINE("NetworkHandler::update1"); - NetworkHandler::update(); - } + { + PROFILER_AUTO_BLOCK_DEFINE("NetworkHandler::update1"); + NetworkHandler::update(); + } - { - GenericValueTypeMessage > const syncStampMessage("SetSyncStamp", std::make_pair(static_cast(UdpMisc::LocalSyncStampShort()), static_cast(UdpMisc::LocalSyncStampLong()))); - GameServerMap::iterator end = cserver.gameServerMap.end(); - for (GameServerMap::iterator iter = cserver.gameServerMap.begin(); iter != end; ++iter) - iter->second->send(syncStampMessage, true); - } + { + GenericValueTypeMessage > const syncStampMessage("SetSyncStamp", std::make_pair(static_cast(UdpMisc::LocalSyncStampShort()), static_cast(UdpMisc::LocalSyncStampLong()))); + GameServerMap::iterator end = cserver.gameServerMap.end(); + for (GameServerMap::iterator iter = cserver.gameServerMap.begin(); iter != end; ++iter) { + iter->second->send(syncStampMessage, true); + } + } - { - PROFILER_AUTO_BLOCK_DEFINE("NetworkHandler::dispatch"); - NetworkHandler::dispatch(); - } + { + PROFILER_AUTO_BLOCK_DEFINE("NetworkHandler::dispatch"); + NetworkHandler::dispatch(); + } - { - PROFILER_AUTO_BLOCK_DEFINE("update"); - cserver.update(); - } + { + PROFILER_AUTO_BLOCK_DEFINE("update"); + cserver.update(); + } - { - PROFILER_AUTO_BLOCK_DEFINE("NetworkHandler::update2"); - NetworkHandler::update(); - } + { + PROFILER_AUTO_BLOCK_DEFINE("NetworkHandler::update2"); + NetworkHandler::update(); + } - { - PROFILER_AUTO_BLOCK_DEFINE("MetricsManager::update"); - unsigned long curTime = Clock::timeMs(); - MetricsManager::update(static_cast(curTime - startTime)); - startTime = curTime; - } + { + PROFILER_AUTO_BLOCK_DEFINE("MetricsManager::update"); + unsigned long curTime = Clock::timeMs(); + MetricsManager::update(static_cast(curTime - startTime)); + startTime = curTime; + } - if (shouldSleep) - { - PROFILER_AUTO_BLOCK_DEFINE("Os::sleep"); - Os::sleep(1); - } - } while (!cserver.done); + if (shouldSleep) { + PROFILER_AUTO_BLOCK_DEFINE("Os::sleep"); + Os::sleep(1); + } + } while (!cserver.done); - NetworkHandler::clearBytesThisFrame(); + NetworkHandler::clearBytesThisFrame(); - cserver.updateRecoveringClientList(static_cast(Clock::frameTime()*1000.0f)); - } + cserver.updateRecoveringClientList(static_cast(Clock::frameTime() * 1000.0f)); + } } // ---------------------------------------------------------------------- /** * Invoked every frame to do whatever updates are needed */ -void ConnectionServer::update() -{ - if (centralConnection) - { - static Timer t(5.0f); - if (t.updateZero(Clock::frameTime())) - { - // Update the population on the central server - updatePopulationOnCentralServer(); +void ConnectionServer::update() { + if (centralConnection) { + static Timer t(5.0f); + if (t.updateZero(Clock::frameTime())) { + // Update the population on the central server + updatePopulationOnCentralServer(); - if (getNumberOfClients() >= ConfigConnectionServer::getMaxClients() - 1) - { - //@todo need an Alert here - WARNING(true, ("We've reached maximum client capacity on a connection server with %d clients", getNumberOfClients())); - } - } - } + if (getNumberOfClients() >= ConfigConnectionServer::getMaxClients() - 1) { + //@todo need an Alert here + WARNING(true, ("We've reached maximum client capacity on a connection server with %d clients", getNumberOfClients())); + } + } + } - /*if (m_sessionApiClient) - { - m_sessionApiClient->update(); - }*/ + /*if (m_sessionApiClient) + { + m_sessionApiClient->update(); + }*/ - static const int ping_throttle_max = 1024; + static const int ping_throttle_max = 1024; - static char buffer[4]; + static char buffer[4]; - for (int throttle = 0; pingSocket->canRecv() && throttle < ping_throttle_max; ++throttle) - { - Address addr; - const uint32 count = pingSocket->recvFrom(addr, buffer, 4); - m_pingTrafficNumBytes += static_cast(count); - if (m_pingTrafficNumBytes < 0) - m_pingTrafficNumBytes = 0; - IGNORE_RETURN(pingSocket->sendTo(addr, buffer, count)); - } + for (int throttle = 0; pingSocket->canRecv() && throttle < ping_throttle_max; ++throttle) { + Address addr; + const uint32 count = pingSocket->recvFrom(addr, buffer, 4); + m_pingTrafficNumBytes += static_cast(count); + if (m_pingTrafficNumBytes < 0) { + m_pingTrafficNumBytes = 0; + } + IGNORE_RETURN(pingSocket->sendTo(addr, buffer, count)); + } } // ---------------------------------------------------------------------- @@ -1128,487 +1011,430 @@ void ConnectionServer::update() * is OK and we don't do anything. If no game server takes authority for them, * we drop them and force them to log in again. */ -void ConnectionServer::updateRecoveringClientList(uint elapsedTime) -{ - if (!m_recoveringClientList.empty()) - { - m_recoverTime += elapsedTime; +void ConnectionServer::updateRecoveringClientList(uint elapsedTime) { + if (!m_recoveringClientList.empty()) { + m_recoverTime += elapsedTime; - static std::set listPlayersDropped; - for (RecoveringClientListType::iterator i = m_recoveringClientList.begin(); i != m_recoveringClientList.end();) - { - if (m_recoverTime > i->first) - { - Client *client = getClient(i->second); - if (client) - { - if (client->getGameConnection()) - DEBUG_REPORT_LOG(true, ("Player %s recovered from a server crash and will not be dropped.\n", i->second.getValueString().c_str())); - else - { - LOG("Network", ("Dropping player %s because game server crashed and no other server took authority.\n", i->second.getValueString().c_str())); - dropClient(client->getClientConnection(), "Game Server Crash"); + static std::set listPlayersDropped; + for (RecoveringClientListType::iterator i = m_recoveringClientList.begin(); + i != m_recoveringClientList.end();) { + if (m_recoverTime > i->first) { + Client *client = getClient(i->second); + if (client) { + if (client->getGameConnection()) { + DEBUG_REPORT_LOG(true, ("Player %s recovered from a server crash and will not be dropped.\n", i->second.getValueString().c_str())); + } else { + LOG("Network", ("Dropping player %s because game server crashed and no other server took authority.\n", i->second.getValueString().c_str())); + dropClient(client->getClientConnection(), "Game Server Crash"); - IGNORE_RETURN(listPlayersDropped.insert(i->second)); - } - } - i = m_recoveringClientList.erase(i); - } - else - ++i; - } + IGNORE_RETURN(listPlayersDropped.insert(i->second)); + } + } + i = m_recoveringClientList.erase(i); + } else { + ++i; + } + } - if (!listPlayersDropped.empty()) - { - GenericValueTypeMessage > const m("PlayerDroppedFromGameServerCrash", listPlayersDropped); + if (!listPlayersDropped.empty()) { + GenericValueTypeMessage > const m("PlayerDroppedFromGameServerCrash", listPlayersDropped); - // let one of the game server know that we dropped the player(s) due to a game server crash - GameConnection * const anyGameConnection = getAnyGameConnection(); - if (anyGameConnection) - anyGameConnection->send(m, true); + // let one of the game server know that we dropped the player(s) due to a game server crash + GameConnection *const anyGameConnection = getAnyGameConnection(); + if (anyGameConnection) { + anyGameConnection->send(m, true); + } - // let CentralServer know that we dropped the player(s) due to a game server crash - sendToCentralProcess(m); + // let CentralServer know that we dropped the player(s) due to a game server crash + sendToCentralProcess(m); - listPlayersDropped.clear(); - } + listPlayersDropped.clear(); + } - if (m_recoveringClientList.empty()) - m_recoverTime = 0; // prevent rollover and other problems I don't want to worry about - } + if (m_recoveringClientList.empty()) { + m_recoverTime = 0; + } // prevent rollover and other problems I don't want to worry about + } } // ---------------------------------------------------------------------- -void ConnectionServer::addRecoveringClient(const NetworkId& networkId) -{ - instance().m_recoveringClientList.push_back(std::pair(static_cast(instance().m_recoverTime) + ConfigConnectionServer::getCrashRecoveryTimeout(), networkId));//lint !e737 !e713 !e1703 !e1025 // going nuts over unsigned/signed conversion and type mismatch on template +void ConnectionServer::addRecoveringClient(const NetworkId &networkId) { + instance().m_recoveringClientList.push_back(std::pair(static_cast(instance().m_recoverTime) + + ConfigConnectionServer::getCrashRecoveryTimeout(), networkId));//lint !e737 !e713 !e1703 !e1025 // going nuts over unsigned/signed conversion and type mismatch on template } // ---------------------------------------------------------------------- -void ConnectionServer::unsetupConnections() -{ - // remove all ClientConnection objects so when Connection::remove() is called we don't crash since - // ConnectionServer no longer exists - while (!instance().connectedMap.empty()) - { - SuidMap::iterator i = instance().connectedMap.begin(); - if (i != instance().connectedMap.end()) - { - ClientConnection * c = (*i).second; - uint32 suid = (*i).first; - IGNORE_RETURN(instance().connectedMap.erase(suid)); - if (c) - { - ConnectionServer::dropClient(c, "ConnectionServer shutting down."); - delete c; - } - } - } +void ConnectionServer::unsetupConnections() { + // remove all ClientConnection objects so when Connection::remove() is called we don't crash since + // ConnectionServer no longer exists + while (!instance().connectedMap.empty()) { + SuidMap::iterator i = instance().connectedMap.begin(); + if (i != instance().connectedMap.end()) { + ClientConnection *c = (*i).second; + uint32 suid = (*i).first; + IGNORE_RETURN(instance().connectedMap.erase(suid)); + if (c) { + ConnectionServer::dropClient(c, "ConnectionServer shutting down."); + delete c; + } + } + } - if (customerService) - { - delete customerService; - customerService = 0; - } + if (customerService) { + delete customerService; + customerService = 0; + } - if (chatService) - { - delete chatService; - chatService = 0; - } + if (chatService) { + delete chatService; + chatService = 0; + } - if (centralConnection) - { - delete centralConnection; - centralConnection = 0; - } + if (centralConnection) { + delete centralConnection; + centralConnection = 0; + } - if (gameService) - { - delete gameService; - gameService = 0; - } + if (gameService) { + delete gameService; + gameService = 0; + } } //----------------------------------------------------------------------- -void ConnectionServer::setupConnections() -{ - // set up message connections - connectToMessage("ConnectionGameServerConnect"); - connectToMessage("SetConnectionServerPublic"); +void ConnectionServer::setupConnections() { + // set up message connections + connectToMessage("ConnectionGameServerConnect"); + connectToMessage("SetConnectionServerPublic"); - // set up port to listen for clients, central, and game servers + // set up port to listen for clients, central, and game servers - connectToMessage("CentralConnectionOpened"); - connectToMessage("CentralConnectionClosed"); + connectToMessage("CentralConnectionOpened"); + connectToMessage("CentralConnectionClosed"); - NetworkSetupData setup; - setup.port = ConfigConnectionServer::getGameServicePort(); - setup.bindInterface = ConfigConnectionServer::getGameServiceBindInterface(); - setup.maxConnections = 1000; + NetworkSetupData setup; + setup.port = ConfigConnectionServer::getGameServicePort(); + setup.bindInterface = ConfigConnectionServer::getGameServiceBindInterface(); + setup.maxConnections = 1000; - gameService = new Service(ConnectionAllocator(), setup); - connectToMessage("GameConnectionOpened"); - connectToMessage("GameConnectionClosed"); + gameService = new Service(ConnectionAllocator(), setup); + connectToMessage("GameConnectionOpened"); + connectToMessage("GameConnectionClosed"); - // connect to central server - centralConnection = new CentralConnection(ConfigConnectionServer::getCentralServerAddress(), ConfigConnectionServer::getCentralServerPort()); + // connect to central server + centralConnection = new CentralConnection(ConfigConnectionServer::getCentralServerAddress(), ConfigConnectionServer::getCentralServerPort()); - setup.port = 0; - setup.bindInterface = ConfigConnectionServer::getChatServiceBindInterface(); - chatService = new Service(ConnectionAllocator(), setup); - connectToMessage("ChatServerConnectionOpened"); - connectToMessage("ChatServerConnectionClosed"); + setup.port = 0; + setup.bindInterface = ConfigConnectionServer::getChatServiceBindInterface(); + chatService = new Service(ConnectionAllocator(), setup); + connectToMessage("ChatServerConnectionOpened"); + connectToMessage("ChatServerConnectionClosed"); - setup.bindInterface = ConfigConnectionServer::getCustomerServiceBindInterface(); - customerService = new Service(ConnectionAllocator(), setup); - connectToMessage("CustomerServiceConnectionOpened"); - connectToMessage("CustomerServiceConnectionClosed"); + setup.bindInterface = ConfigConnectionServer::getCustomerServiceBindInterface(); + customerService = new Service(ConnectionAllocator(), setup); + connectToMessage("CustomerServiceConnectionOpened"); + connectToMessage("CustomerServiceConnectionClosed"); - connectToMessage("ConnectionServerId"); - connectToMessage("ConnectionKeyPush"); - connectToMessage("LoginKeyPush"); - connectToMessage("CharacterListMessage"); + connectToMessage("ConnectionServerId"); + connectToMessage("ConnectionKeyPush"); + connectToMessage("LoginKeyPush"); + connectToMessage("CharacterListMessage"); - //Create Characters Messages - connectToMessage("ClientCreateCharacter"); - connectToMessage("ConnectionCreateCharacterSuccess"); - connectToMessage("ConnectionCreateCharacterFailed"); - connectToMessage("NewCharacterCreated"); - connectToMessage("GameServerForLoginMessage"); + //Create Characters Messages + connectToMessage("ClientCreateCharacter"); + connectToMessage("ConnectionCreateCharacterSuccess"); + connectToMessage("ConnectionCreateCharacterFailed"); + connectToMessage("NewCharacterCreated"); + connectToMessage("GameServerForLoginMessage"); - // name query messages - connectToMessage("ClientRandomNameRequest"); // from client - connectToMessage("RandomNameResponse"); // from game server + // name query messages + connectToMessage("ClientRandomNameRequest"); // from client + connectToMessage("RandomNameResponse"); // from game server - connectToMessage("ClientVerifyAndLockNameRequest"); // from client - connectToMessage("VerifyAndLockNameResponse"); // from game server + connectToMessage("ClientVerifyAndLockNameRequest"); // from client + connectToMessage("VerifyAndLockNameResponse"); // from game server - connectToMessage("ValidateCharacterForLoginReplyMessage"); - connectToMessage("ValidateAccountReplyMessage"); + connectToMessage("ValidateCharacterForLoginReplyMessage"); + connectToMessage("ValidateAccountReplyMessage"); - connectToMessage("ProfilerOperationMessage"); - connectToMessage("CentralConnectionClosed"); - connectToMessage("CentralConnectionOpened"); - connectToMessage("ChunkCompleteMessage"); - connectToMessage("FrameEndMessage"); - connectToMessage("GameConnectionClosed"); - connectToMessage("GameGameServerConnect"); - connectToMessage("GameServerReadyMessage"); - connectToMessage("GameServerUniverseLoadedMessage"); - connectToMessage("PersistedPlayerMessage"); - connectToMessage("PreloadListMessage"); - connectToMessage("PreloadRequestCompleteMessage"); - connectToMessage("ProfilerOperationMessage"); - connectToMessage("RequestGameServerForLoginMessage"); - connectToMessage("RequestSceneTransfer"); - connectToMessage("ShutdownMessage"); - connectToMessage("TaskConnectionOpened"); - connectToMessage("UnloadedPlayerMessage"); - connectToMessage("WatcherConnectionClosed"); - connectToMessage("WatcherConnectionOpened"); - connectToMessage("ExcommunicateGameServerMessage"); - connectToMessage("CntrlSrvDropDupeConns"); + connectToMessage("ProfilerOperationMessage"); + connectToMessage("CentralConnectionClosed"); + connectToMessage("CentralConnectionOpened"); + connectToMessage("ChunkCompleteMessage"); + connectToMessage("FrameEndMessage"); + connectToMessage("GameConnectionClosed"); + connectToMessage("GameGameServerConnect"); + connectToMessage("GameServerReadyMessage"); + connectToMessage("GameServerUniverseLoadedMessage"); + connectToMessage("PersistedPlayerMessage"); + connectToMessage("PreloadListMessage"); + connectToMessage("PreloadRequestCompleteMessage"); + connectToMessage("ProfilerOperationMessage"); + connectToMessage("RequestGameServerForLoginMessage"); + connectToMessage("RequestSceneTransfer"); + connectToMessage("ShutdownMessage"); + connectToMessage("TaskConnectionOpened"); + connectToMessage("UnloadedPlayerMessage"); + connectToMessage("WatcherConnectionClosed"); + connectToMessage("WatcherConnectionOpened"); + connectToMessage("ExcommunicateGameServerMessage"); + connectToMessage("CntrlSrvDropDupeConns"); } //---------------------------------------------------------------------- -uint16 ConnectionServer::getPingPort() -{ - static ConnectionServer & cs = instance(); - return cs.pingSocket->getBindAddress().getHostPort(); +uint16 ConnectionServer::getPingPort() { + static ConnectionServer &cs = instance(); + return cs.pingSocket->getBindAddress().getHostPort(); } //----------------------------------------------------------------------- -Client* ConnectionServer::getClient(const NetworkId & oid) -{ - static ConnectionServer & cs = instance(); - ClientMap::const_iterator iter = cs.clientMap.find(oid); - if (iter != cs.clientMap.end()) - return (*iter).second; - return 0; +Client *ConnectionServer::getClient(const NetworkId &oid) { + static ConnectionServer &cs = instance(); + ClientMap::const_iterator iter = cs.clientMap.find(oid); + if (iter != cs.clientMap.end()) { + return (*iter).second; + } + return 0; } //----------------------------------------------------------------------- -const ConnectionServer::ClientMap & ConnectionServer::getClientMap() -{ - return instance().clientMap; +const ConnectionServer::ClientMap &ConnectionServer::getClientMap() { + return instance().clientMap; } //----------------------------------------------------------------------- -GameConnection* ConnectionServer::getGameConnection(uint32 gameServerId) -{ - static ConnectionServer & cs = instance(); - const GameServerMap::const_iterator i = cs.gameServerMap.find(gameServerId); - if (i != cs.gameServerMap.end()) - return (*i).second; +GameConnection *ConnectionServer::getGameConnection(uint32 gameServerId) { + static ConnectionServer &cs = instance(); + const GameServerMap::const_iterator i = cs.gameServerMap.find(gameServerId); + if (i != cs.gameServerMap.end()) { + return (*i).second; + } - return nullptr; + return nullptr; } //----------------------------------------------------------------------- -GameConnection* ConnectionServer::getAnyGameConnection() -{ - static ConnectionServer & cs = instance(); - if (!cs.gameServerMap.empty()) - return cs.gameServerMap.begin()->second; +GameConnection *ConnectionServer::getAnyGameConnection() { + static ConnectionServer &cs = instance(); + if (!cs.gameServerMap.empty()) { + return cs.gameServerMap.begin()->second; + } - return nullptr; + return nullptr; } //----------------------------------------------------------------------- -int ConnectionServer::getPingTrafficNumBytes() -{ - static ConnectionServer & cs = instance(); - return cs.m_pingTrafficNumBytes; +int ConnectionServer::getPingTrafficNumBytes() { + static ConnectionServer &cs = instance(); + return cs.m_pingTrafficNumBytes; } //----------------------------------------------------------------------- -int ConnectionServer::getNumberOfClients() -{ - static ConnectionServer & cs = instance(); - return static_cast(cs.connectedMap.size()); +int ConnectionServer::getNumberOfClients() { + static ConnectionServer &cs = instance(); + return static_cast(cs.connectedMap.size()); } //----------------------------------------------------------------------- -int ConnectionServer::getNumberOfFreeTrials() -{ - static ConnectionServer & cs = instance(); - return static_cast(cs.freeTrials.size()); +int ConnectionServer::getNumberOfFreeTrials() { + static ConnectionServer &cs = instance(); + return static_cast(cs.freeTrials.size()); } //----------------------------------------------------------------------- -int ConnectionServer::getNumberOfGameServers() -{ - static ConnectionServer & cs = instance(); - return static_cast(cs.gameServerMap.size()); +int ConnectionServer::getNumberOfGameServers() { + static ConnectionServer &cs = instance(); + return static_cast(cs.gameServerMap.size()); } //----------------------------------------------------------------------- -void ConnectionServer::removeConnectedCharacter(uint32 suid) -{ - static ConnectionServer & cs = instance(); - cs.removeFromConnectedMap(suid); +void ConnectionServer::removeConnectedCharacter(uint32 suid) { + static ConnectionServer &cs = instance(); + cs.removeFromConnectedMap(suid); } //----------------------------------------------------------------------- -void ConnectionServer::sendToCentralProcess(const GameNetworkMessage & msg) -{ - static ConnectionServer & cs = instance(); - if (cs.centralConnection) - cs.centralConnection->send(msg, true); - else - WARNING(true, ("Connection tried to send a message Central, but there is no Central Connection")); +void ConnectionServer::sendToCentralProcess(const GameNetworkMessage &msg) { + static ConnectionServer &cs = instance(); + if (cs.centralConnection) { + cs.centralConnection->send(msg, true); + } else { + WARNING(true, ("Connection tried to send a message Central, but there is no Central Connection")); + } } //----------------------------------------------------------------------- -CentralConnection * ConnectionServer::getCentralConnection() -{ - static ConnectionServer & cs = instance(); - return cs.centralConnection; +CentralConnection *ConnectionServer::getCentralConnection() { + static ConnectionServer &cs = instance(); + return cs.centralConnection; } //----------------------------------------------------------------------- -void ConnectionServer::installSessionValidation() -{ - /*int i = 0; - std::vector sessionServers; - int const numberOfSessionServers = ConfigConnectionServer::getNumberOfSessionServers(); - for (i = 0; i < numberOfSessionServers; ++i) - { - char const * const p = ConfigConnectionServer::getSessionServer(i); - if (p) - { - REPORT_LOG(true, ("Using session server %s\n", p)); - sessionServers.push_back(p); - } - } +void ConnectionServer::installSessionValidation() { + /*int i = 0; + std::vector sessionServers; + int const numberOfSessionServers = ConfigConnectionServer::getNumberOfSessionServers(); + for (i = 0; i < numberOfSessionServers; ++i) + { + char const * const p = ConfigConnectionServer::getSessionServer(i); + if (p) + { + REPORT_LOG(true, ("Using session server %s\n", p)); + sessionServers.push_back(p); + } + } - // if there were none specified, use defaults - FATAL(i == 0, ("No session servers specified for session API")); - m_sessionApiClient = new SessionApiClient(&sessionServers[0], i);*/ - return; + // if there were none specified, use defaults + FATAL(i == 0, ("No session servers specified for session API")); + m_sessionApiClient = new SessionApiClient(&sessionServers[0], i);*/ + return; } // ---------------------------------------------------------------------- -void ConnectionServer::addToClientMap(const NetworkId &oid, ClientConnection* cconn) -{ - Client * newClient = new Client(cconn, oid); +void ConnectionServer::addToClientMap(const NetworkId &oid, ClientConnection *cconn) { + Client *newClient = new Client(cconn, oid); - clientMap[oid] = newClient; + clientMap[oid] = newClient; - //associate the ClientConnection object. - cconn->setClient(newClient); + //associate the ClientConnection object. + cconn->setClient(newClient); } // ---------------------------------------------------------------------- -void ConnectionServer::removeFromClientMap(const NetworkId &oid) -{ - ClientMap::iterator i = clientMap.find(oid); - if (i != clientMap.end()) - { - clientMap.erase(i); - } +void ConnectionServer::removeFromClientMap(const NetworkId &oid) { + ClientMap::iterator i = clientMap.find(oid); + if (i != clientMap.end()) { + clientMap.erase(i); + } } //----------------------------------------------------------------------- -void ConnectionServer::addToConnectedMap(uint32 suid, ClientConnection* cconn) -{ - SuidMap::iterator i = connectedMap.find(suid); - if (i == connectedMap.end()) - { - connectedMap[suid] = cconn; - } - else - { - WARNING_STRICT_FATAL(true, ("Attepting to add duplicate connected chatacter")); - connectedMap[suid] = cconn; - } +void ConnectionServer::addToConnectedMap(uint32 suid, ClientConnection *cconn) { + SuidMap::iterator i = connectedMap.find(suid); + if (i == connectedMap.end()) { + connectedMap[suid] = cconn; + } else { + WARNING_STRICT_FATAL(true, ("Attepting to add duplicate connected chatacter")); + connectedMap[suid] = cconn; + } - if (((cconn->getSubscriptionFeatures() & ClientSubscriptionFeature::FreeTrial) != 0) - && ((cconn->getSubscriptionFeatures() & ClientSubscriptionFeature::Base) == 0)) - { - freeTrials.insert(suid); - } + if (((cconn->getSubscriptionFeatures() & ClientSubscriptionFeature::FreeTrial) != 0) && + ((cconn->getSubscriptionFeatures() & ClientSubscriptionFeature::Base) == 0)) { + freeTrials.insert(suid); + } - // Update the population on the CentralServer immediately - // since we are trying to avoid people "rushing" the server - updatePopulationOnCentralServer(); + // Update the population on the CentralServer immediately + // since we are trying to avoid people "rushing" the server + updatePopulationOnCentralServer(); } // ---------------------------------------------------------------------- -void ConnectionServer::removeFromConnectedMap(uint32 suid) -{ - SuidMap::iterator i = connectedMap.find(suid); - if (i != connectedMap.end()) - { - connectedMap.erase(i); - } +void ConnectionServer::removeFromConnectedMap(uint32 suid) { + SuidMap::iterator i = connectedMap.find(suid); + if (i != connectedMap.end()) { + connectedMap.erase(i); + } - FreeTrialsSet::iterator j = freeTrials.find(suid); - if (j != freeTrials.end()) - { - freeTrials.erase(j); - } + FreeTrialsSet::iterator j = freeTrials.find(suid); + if (j != freeTrials.end()) { + freeTrials.erase(j); + } - // We could update the CentralServer population but people - // leaving the server are not as important as people connecting - // and so we will wait for update() to handle things + // We could update the CentralServer population but people + // leaving the server are not as important as people connecting + // and so we will wait for update() to handle things } // ---------------------------------------------------------------------- -void ConnectionServer::updatePopulationOnCentralServer() -{ - if (centralConnection) - { - // Total number of clients and how many of those are free trials - const int numPlayers = getNumberOfClients(); - const int numFreeTrial = getNumberOfFreeTrials(); +void ConnectionServer::updatePopulationOnCentralServer() { + if (centralConnection) { + // Total number of clients and how many of those are free trials + const int numPlayers = getNumberOfClients(); + const int numFreeTrial = getNumberOfFreeTrials(); - // We are concerned about too many people piling up at the beginning - // of the tutorial, so count how many players could be a problem - int numPlayersEmptyScene = 0; - int numPlayersTutorialScene = 0; - int numPlayersFalconScene = 0; + // We are concerned about too many people piling up at the beginning + // of the tutorial, so count how many players could be a problem + int numPlayersEmptyScene = 0; + int numPlayersTutorialScene = 0; + int numPlayersFalconScene = 0; - // Walk through the clients and evaluate what scene they are in - SuidMap::const_iterator i; - for (i = connectedMap.begin(); i != connectedMap.end(); ++i) - { - const ClientConnection * const conn = (*i).second; - const Client * const client = conn->getClient(); + // Walk through the clients and evaluate what scene they are in + SuidMap::const_iterator i; + for (i = connectedMap.begin(); i != connectedMap.end(); ++i) { + const ClientConnection *const conn = (*i).second; + const Client *const client = conn->getClient(); - if (client && client->getGameConnection()) - { - const std::string& scene = client->getGameConnection()->getSceneName(); + if (client && client->getGameConnection()) { + const std::string &scene = client->getGameConnection()->getSceneName(); - if (scene.empty()) - { - numPlayersEmptyScene += 1; - } - else if (scene == SCENE_NAME_TUTORIAL) - { - numPlayersTutorialScene += 1; - } - else if (scene.substr(0, SCENE_NAME_FALCON_PREFIX.length()) == SCENE_NAME_FALCON_PREFIX) - { - numPlayersFalconScene += 1; - } - } - else - { - numPlayersEmptyScene += 1; - } - } + if (scene.empty()) { + numPlayersEmptyScene += 1; + } else if (scene == SCENE_NAME_TUTORIAL) { + numPlayersTutorialScene += 1; + } else if (scene.substr(0, SCENE_NAME_FALCON_PREFIX.length()) == SCENE_NAME_FALCON_PREFIX) { + numPlayersFalconScene += 1; + } + } else { + numPlayersEmptyScene += 1; + } + } - const UpdatePlayerCountMessage msg(false, numPlayers, numFreeTrial, numPlayersEmptyScene, numPlayersTutorialScene, numPlayersFalconScene); - centralConnection->send(msg, true); - } + const UpdatePlayerCountMessage msg(false, numPlayers, numFreeTrial, numPlayersEmptyScene, numPlayersTutorialScene, numPlayersFalconScene); + centralConnection->send(msg, true); + } } // ---------------------------------------------------------------------- -SessionApiClient* ConnectionServer::getSessionApiClient() -{ - // this is causing crashes when ConnectionServer is shutdown and something calls this function - // because instance() returns 0. - //if (s_connectionServer) - //{ - // return instance().m_sessionApiClient; - //} - //else - //{ - return 0; - //} +SessionApiClient *ConnectionServer::getSessionApiClient() { + // this is causing crashes when ConnectionServer is shutdown and something calls this function + // because instance() returns 0. + //if (s_connectionServer) + //{ + // return instance().m_sessionApiClient; + //} + //else + //{ + return 0; + //} } // ---------------------------------------------------------------------- -void ConnectionServer::setDone(char const *reasonfmt, ...) -{ - if (!done) - { - char reason[1024]; - va_list ap; - va_start(ap, reasonfmt); - IGNORE_RETURN(_vsnprintf(reason, sizeof(reason), reasonfmt, ap));//lint !e530 Symbol 'ap' not initialized - reason[sizeof(reason) - 1] = '\0'; +void ConnectionServer::setDone(char const *reasonfmt, ...) { + if (!done) { + char reason[1024]; + va_list ap; + va_start(ap, reasonfmt); + IGNORE_RETURN(_vsnprintf(reason, sizeof(reason), reasonfmt, ap));//lint !e530 Symbol 'ap' not initialized + reason[sizeof(reason) - 1] = '\0'; - LOG( - "ServerShutdown", - ( - "ConnectionServer (pid %d) shutdown, reason: %s", - static_cast(Os::getProcessId()), - reason)); + LOG("ServerShutdown", ("ConnectionServer (pid %d) shutdown, reason: %s", static_cast(Os::getProcessId()), reason)); - REPORT_LOG( - true, - ( - "ConnectionServer (pid %d) shutdown, reason: %s\n", - static_cast(Os::getProcessId()), - reason)); + REPORT_LOG(true, ("ConnectionServer (pid %d) shutdown, reason: %s\n", static_cast(Os::getProcessId()), reason)); - done = true; - va_end(ap); - } + done = true; + va_end(ap); + } } // ====================================================================== diff --git a/engine/server/application/LoginServer/src/shared/ClientConnection.cpp b/engine/server/application/LoginServer/src/shared/ClientConnection.cpp index 55bd2094..a6c1ead7 100755 --- a/engine/server/application/LoginServer/src/shared/ClientConnection.cpp +++ b/engine/server/application/LoginServer/src/shared/ClientConnection.cpp @@ -27,18 +27,10 @@ using namespace StellaBellum; //----------------------------------------------------------------------- -ClientConnection::ClientConnection(UdpConnectionMT *u, TcpClient *t) : - ServerConnection(u, t), - m_clientId(0), - m_isValidated(false), - m_isSecure(false), - m_adminLevel(-1), - m_stationId(0), - m_requestedAdminSuid(0), - m_gameBits(0), - m_subscriptionBits(0), - m_waitingForCharacterLoginDeletion(false), - m_waitingForCharacterClusterDeletion(false) { +ClientConnection::ClientConnection(UdpConnectionMT *u, TcpClient *t) + : ServerConnection(u, t), m_clientId(0), m_isValidated(false), m_isSecure(false), m_adminLevel(-1), + m_stationId(0), m_requestedAdminSuid(0), m_gameBits(0), m_subscriptionBits(0), + m_waitingForCharacterLoginDeletion(false), m_waitingForCharacterClusterDeletion(false) { } //----------------------------------------------------------------------- @@ -52,18 +44,17 @@ void ClientConnection::onConnectionClosed() { // client has disconnected if (m_stationId) { DEBUG_REPORT_LOG(true, ("Client %lu disconnected\n", m_stationId)); - LOG("LoginClientConnection", - ("onConnectionClosed() for stationId (%lu) at IP (%s)", m_stationId, getRemoteAddress().c_str())); + LOG("LoginClientConnection", ("onConnectionClosed() for stationId (%lu) at IP (%s)", m_stationId, getRemoteAddress().c_str())); } LoginServer::getInstance().removeClient(m_clientId); - /* if ((ConfigLoginServer::getValidateStationKey() || ConfigLoginServer::getDoSessionLogin()) && !m_isValidated) { - SessionApiClient *session = LoginServer::getInstance().getSessionApiClient(); - if (session) { - session->dropClient(this); - } - }*/ + /* if ((ConfigLoginServer::getValidateStationKey() || ConfigLoginServer::getDoSessionLogin()) && !m_isValidated) { + SessionApiClient *session = LoginServer::getInstance().getSessionApiClient(); + if (session) { + session->dropClient(this); + } + }*/ } @@ -73,8 +64,7 @@ void ClientConnection::onConnectionOpened() { m_clientId = LoginServer::getInstance().addClient(*this); setOverflowLimit(ConfigLoginServer::getClientOverflowLimit()); - LOG("LoginClientConnection", - ("onConnectionOpened() for stationId (%lu) at IP (%s)", m_stationId, getRemoteAddress().c_str())); + LOG("LoginClientConnection", ("onConnectionOpened() for stationId (%lu) at IP (%s)", m_stationId, getRemoteAddress().c_str())); } //----------------------------------------------------------------------- @@ -100,8 +90,7 @@ void ClientConnection::onReceive(const Archive::ByteStream &message) { // send the client the server "now" Epoch time so that the // client has an idea of how much difference there is between // the client's Epoch time and the server Epoch time - GenericValueTypeMessage const serverNowEpochTime( - "ServerNowEpochTime", static_cast(::time(nullptr))); + GenericValueTypeMessage const serverNowEpochTime("ServerNowEpochTime", static_cast(::time(nullptr))); send(serverNowEpochTime, true); LoginClientId id(ri); @@ -135,16 +124,13 @@ void ClientConnection::onReceive(const Archive::ByteStream &message) { } case constcrc("DeleteCharacterMessage") : { DeleteCharacterMessage msg(ri); - std::vector::const_iterator f = std::find(m_charactersPendingDeletion.begin(), - m_charactersPendingDeletion.end(), - msg.getCharacterId()); + std::vector::const_iterator f = std::find(m_charactersPendingDeletion.begin(), m_charactersPendingDeletion.end(), msg.getCharacterId()); if ((m_waitingForCharacterLoginDeletion || m_waitingForCharacterClusterDeletion) && f != m_charactersPendingDeletion.end()) { DeleteCharacterReplyMessage reply(DeleteCharacterReplyMessage::rc_ALREADY_IN_PROGRESS); send(reply, true); } else { - if (LoginServer::getInstance().deleteCharacter(msg.getClusterId(), msg.getCharacterId(), - getStationId())) { + if (LoginServer::getInstance().deleteCharacter(msg.getClusterId(), msg.getCharacterId(), getStationId())) { m_waitingForCharacterLoginDeletion = true; m_waitingForCharacterClusterDeletion = true; m_charactersPendingDeletion.push_back(msg.getCharacterId()); @@ -156,8 +142,7 @@ void ClientConnection::onReceive(const Archive::ByteStream &message) { break; } } - } - catch (const Archive::ReadException &readException) { + } catch (const Archive::ReadException &readException) { WARNING(true, ("Archive read error (%s) on message from client. Disconnecting client.", readException.what())); disconnect(); } @@ -233,8 +218,8 @@ void ClientConnection::validateClient(const std::string &id, const std::string & std::string child(i.second); if (!child.empty()) { - REPORT_LOG((parent_id != child_id), - ("\tchild of %s (%i) is %s (%i) \n", parentAccount.c_str(), parent_id, child.c_str(), child_id)); + REPORT_LOG((parent_id != + child_id), ("\tchild of %s (%i) is %s (%i) \n", parentAccount.c_str(), parent_id, child.c_str(), child_id)); // insert all related accounts, if not already there, into the db if (parent_id != child_id) { @@ -245,8 +230,7 @@ void ClientConnection::validateClient(const std::string &id, const std::string & } } - LOG("LoginClientConnection", - ("validateClient() for stationId (%i) at IP (%s), id (%s)", user_id, getRemoteAddress().c_str(), uname.c_str())); + LOG("LoginClientConnection", ("validateClient() for stationId (%i) at IP (%s), id (%s)", user_id, getRemoteAddress().c_str(), uname.c_str())); m_stationId = user_id; @@ -264,16 +248,14 @@ void ClientConnection::validateClient(const std::string &id, const std::string & void ClientConnection::onCharacterDeletedFromLoginDatabase(const NetworkId &characterId) { m_waitingForCharacterLoginDeletion = false; if (!m_waitingForCharacterClusterDeletion) { - std::vector::iterator f = std::find(m_charactersPendingDeletion.begin(), - m_charactersPendingDeletion.end(), characterId); + std::vector::iterator f = std::find(m_charactersPendingDeletion.begin(), m_charactersPendingDeletion.end(), characterId); if (f != m_charactersPendingDeletion.end()) { m_charactersPendingDeletion.erase(f); } DeleteCharacterReplyMessage reply(DeleteCharacterReplyMessage::rc_OK); send(reply, true); - LOG("CustomerService", - ("Player:deleted character %s for stationId %u at IP: %s", characterId.getValueString().c_str(), m_stationId, getRemoteAddress().c_str())); + LOG("CustomerService", ("Player:deleted character %s for stationId %u at IP: %s", characterId.getValueString().c_str(), m_stationId, getRemoteAddress().c_str())); } } @@ -282,8 +264,7 @@ void ClientConnection::onCharacterDeletedFromLoginDatabase(const NetworkId &char void ClientConnection::onCharacterDeletedFromCluster(const NetworkId &characterId) { m_waitingForCharacterClusterDeletion = false; if (!m_waitingForCharacterLoginDeletion) { - std::vector::iterator f = std::find(m_charactersPendingDeletion.begin(), - m_charactersPendingDeletion.end(), characterId); + std::vector::iterator f = std::find(m_charactersPendingDeletion.begin(), m_charactersPendingDeletion.end(), characterId); if (f != m_charactersPendingDeletion.end()) { m_charactersPendingDeletion.erase(f); @@ -292,8 +273,7 @@ void ClientConnection::onCharacterDeletedFromCluster(const NetworkId &characterI DeleteCharacterReplyMessage reply(DeleteCharacterReplyMessage::rc_OK); send(reply, true); - LOG("CustomerService", - ("Player:deleted character %s for stationId %u at IP: %s", characterId.getValueString().c_str(), m_stationId, getRemoteAddress().c_str())); + LOG("CustomerService", ("Player:deleted character %s for stationId %u at IP: %s", characterId.getValueString().c_str(), m_stationId, getRemoteAddress().c_str())); } } diff --git a/engine/server/application/LoginServer/src/shared/LoginServer.cpp b/engine/server/application/LoginServer/src/shared/LoginServer.cpp index 2082af76..0df5fc58 100755 --- a/engine/server/application/LoginServer/src/shared/LoginServer.cpp +++ b/engine/server/application/LoginServer/src/shared/LoginServer.cpp @@ -78,43 +78,36 @@ //----------------------------------------------------------------------- -namespace LoginServerNamespace -{ - struct ConnectionServerEntryLessThan : public std::binary_function - { - bool operator()(const LoginServer::ConnectionServerEntry & x, const LoginServer::ConnectionServerEntry & y) const; - }; //lint !e1509 // (base class destructor for class 'binary_function' is not virtual -- Effective C++ #14) // binary_function defines 3 typedefs required for the Adaptable Binary Function concept, The destructor is generated by the compiler and beyond our control +namespace LoginServerNamespace { + struct ConnectionServerEntryLessThan + : public std::binary_function { + bool operator()(const LoginServer::ConnectionServerEntry &x, const LoginServer::ConnectionServerEntry &y) const; + }; //lint !e1509 // (base class destructor for class 'binary_function' is not virtual -- Effective C++ #14) // binary_function defines 3 typedefs required for the Adaptable Binary Function concept, The destructor is generated by the compiler and beyond our control - enum - { - WORLD_COUNT_CHANNEL, - CLUSTER_COUNT_CHANNEL - }; + enum { + WORLD_COUNT_CHANNEL, CLUSTER_COUNT_CHANNEL + }; - // Very simple function to determine if a "threshold" has been crossed - bool hasCrossedThreshold(int thresholdValue, int oldValue, int newValue) - { - bool result = false; + // Very simple function to determine if a "threshold" has been crossed + bool hasCrossedThreshold(int thresholdValue, int oldValue, int newValue) { + bool result = false; - if ((oldValue < thresholdValue) && (newValue >= thresholdValue)) - { - // Crossed over the threshold - result = true; - } - else if ((oldValue >= thresholdValue) && (newValue < thresholdValue)) - { - // Crossed back down under the threshold - result = true; - } + if ((oldValue < thresholdValue) && (newValue >= thresholdValue)) { + // Crossed over the threshold + result = true; + } else if ((oldValue >= thresholdValue) && (newValue < thresholdValue)) { + // Crossed back down under the threshold + result = true; + } - return result; - } + return result; + } - // for testing purpose when not using session authentication, store - // the account feature Ids here, which will get cleared (obviously) - // when the LoginServer is restarted - std::map > s_nonSessionTestingAccountSwgFeatureIds; - std::map > s_nonSessionTestingAccountSwgTcgFeatureIds; + // for testing purpose when not using session authentication, store + // the account feature Ids here, which will get cleared (obviously) + // when the LoginServer is restarted + std::map > s_nonSessionTestingAccountSwgFeatureIds; + std::map > s_nonSessionTestingAccountSwgTcgFeatureIds; } //----------------------------------------------------------------------- @@ -123,136 +116,119 @@ using namespace LoginServerNamespace; //----------------------------------------------------------------------- -bool ConnectionServerEntryLessThan::operator()(const LoginServer::ConnectionServerEntry &x, const LoginServer::ConnectionServerEntry &y) const -{ - return x.numClients < y.numClients; +bool +ConnectionServerEntryLessThan::operator()(const LoginServer::ConnectionServerEntry &x, const LoginServer::ConnectionServerEntry &y) const { + return x.numClients < y.numClients; } //----------------------------------------------------------------------- -LoginServer::LoginServer() : - Singleton(), - MessageDispatch::Receiver(), - done(false), - m_centralService(nullptr), - clientService(0), - pingService(0), - keyServer(0), - m_clientMap(), - m_clusterList(), - m_validatedClientMap(), - m_clusterStatusChanged(false), - m_soeMonitor(0) -{ - NetworkSetupData setup; - setup.port = ConfigLoginServer::getClientServicePort(); - setup.maxConnections = ConfigLoginServer::getMaxClients(); - setup.maxConnectionsPerIP = ConfigLoginServer::getMaxConnectionsPerIP(); - setup.oldestUnacknowledgedTimeout = 30000; - setup.keepAliveDelay = 45000; - setup.compress = ConfigLoginServer::getCompressClientNetworkTraffic(); - setup.useTcp = false; +LoginServer::LoginServer() + : Singleton(), MessageDispatch::Receiver(), done(false), m_centralService(nullptr), + clientService(0), pingService(0), keyServer(0), m_clientMap(), m_clusterList(), m_validatedClientMap(), + m_clusterStatusChanged(false), m_soeMonitor(0) { + NetworkSetupData setup; + setup.port = ConfigLoginServer::getClientServicePort(); + setup.maxConnections = ConfigLoginServer::getMaxClients(); + setup.maxConnectionsPerIP = ConfigLoginServer::getMaxConnectionsPerIP(); + setup.oldestUnacknowledgedTimeout = 30000; + setup.keepAliveDelay = 45000; + setup.compress = ConfigLoginServer::getCompressClientNetworkTraffic(); + setup.useTcp = false; - clientService = new Service(ConnectionAllocator(), setup); - setup.compress = false; + clientService = new Service(ConnectionAllocator(), setup); + setup.compress = false; - setup.port = ConfigLoginServer::getPingServicePort(); - pingService = new Service(ConnectionAllocator(), setup); - setup.useTcp = true; + setup.port = ConfigLoginServer::getPingServicePort(); + pingService = new Service(ConnectionAllocator(), setup); + setup.useTcp = true; - if (ConfigLoginServer::getDevelopmentMode()) - { - setup.port = ConfigLoginServer::getCentralServicePort(); - m_centralService = new Service(ConnectionAllocator(), setup); - } + if (ConfigLoginServer::getDevelopmentMode()) { + setup.port = ConfigLoginServer::getCentralServicePort(); + m_centralService = new Service(ConnectionAllocator(), setup); + } - // only start the customer tool connection listener if the port is set (defaults to 0) - setup.port = ConfigLoginServer::getCSToolPort(); - if (setup.port) - { - m_CSService = new Service(ConnectionAllocator(), setup); - } + // only start the customer tool connection listener if the port is set (defaults to 0) + setup.port = ConfigLoginServer::getCSToolPort(); + if (setup.port) { + m_CSService = new Service(ConnectionAllocator(), setup); + } - // set up message connections - connectToMessage("ClaimRewardsMessage"); - connectToMessage("ConnectionClosed"); - connectToMessage("ConnectionServerDown"); //Sent to login from central when connection server goes down - connectToMessage("LoginClusterName"); - connectToMessage("LoginClusterName2"); - connectToMessage("LoginConnectionServerAddress"); //Sent to login from central after reconnecting. - connectToMessage("LoginCreateCharacterMessage"); - connectToMessage("LoginRestoreCharacterMessage"); - connectToMessage("LoginUpgradeAccountMessage"); - connectToMessage("PreloadFinishedMessage"); - connectToMessage("PurgeCompleteMessage"); - connectToMessage("RenameCharacterMessage"); - connectToMessage("TransferRequestMoveValidation"); - connectToMessage("TransferReplyNameValidation"); - connectToMessage("TransferLoginCharacterToDestinationServer"); - connectToMessage("UpdateLoginConnectionServerStatus"); - connectToMessage("UpdatePlayerCountMessage"); - connectToMessage("ValidateAccountMessage"); - connectToMessage("CntrlSrvDropDupeConns"); - connectToMessage("OccupyUnlockedSlotReq"); - connectToMessage("VacateUnlockedSlotReq"); - connectToMessage("SwapUnlockedSlotReq"); - connectToMessage("AdjustAccountFeatureIdRequest"); - connectToMessage("AccountFeatureIdRequest"); - connectToMessage("FeatureIdTransactionRequest"); - connectToMessage("FeatureIdTransactionSyncUpdate"); - keyServer = new KeyServer; + // set up message connections + connectToMessage("ClaimRewardsMessage"); + connectToMessage("ConnectionClosed"); + connectToMessage("ConnectionServerDown"); //Sent to login from central when connection server goes down + connectToMessage("LoginClusterName"); + connectToMessage("LoginClusterName2"); + connectToMessage("LoginConnectionServerAddress"); //Sent to login from central after reconnecting. + connectToMessage("LoginCreateCharacterMessage"); + connectToMessage("LoginRestoreCharacterMessage"); + connectToMessage("LoginUpgradeAccountMessage"); + connectToMessage("PreloadFinishedMessage"); + connectToMessage("PurgeCompleteMessage"); + connectToMessage("RenameCharacterMessage"); + connectToMessage("TransferRequestMoveValidation"); + connectToMessage("TransferReplyNameValidation"); + connectToMessage("TransferLoginCharacterToDestinationServer"); + connectToMessage("UpdateLoginConnectionServerStatus"); + connectToMessage("UpdatePlayerCountMessage"); + connectToMessage("ValidateAccountMessage"); + connectToMessage("CntrlSrvDropDupeConns"); + connectToMessage("OccupyUnlockedSlotReq"); + connectToMessage("VacateUnlockedSlotReq"); + connectToMessage("SwapUnlockedSlotReq"); + connectToMessage("AdjustAccountFeatureIdRequest"); + connectToMessage("AccountFeatureIdRequest"); + connectToMessage("FeatureIdTransactionRequest"); + connectToMessage("FeatureIdTransactionSyncUpdate"); + keyServer = new KeyServer; } //----------------------------------------------------------------------- -LoginServer::~LoginServer() -{ - delete keyServer; +LoginServer::~LoginServer() { + delete keyServer; } //----------------------------------------------------------------------- -int LoginServer::addClient(ClientConnection & client) -{ - DEBUG_FATAL(client.getIsValidated(), ("Tried to add an already validated client?!")); - //Perhaps add a debug only check to make sure a client connection isn't in twice...I'm not sure how that could happen. +int LoginServer::addClient(ClientConnection &client) { + DEBUG_FATAL(client.getIsValidated(), ("Tried to add an already validated client?!")); + //Perhaps add a debug only check to make sure a client connection isn't in twice...I'm not sure how that could happen. - static int nextClientId = 0; - int tmp = ++nextClientId; - m_clientMap[tmp] = &client; - return tmp; + static int nextClientId = 0; + int tmp = ++nextClientId; + m_clientMap[tmp] = &client; + return tmp; } //----------------------------------------------------------------------- -ClientConnection* LoginServer::getValidatedClient(const StationId& clientId) -{ - std::map::iterator i = m_validatedClientMap.find(clientId); - if (i == m_validatedClientMap.end()) - return 0; - return i->second; +ClientConnection *LoginServer::getValidatedClient(const StationId &clientId) { + std::map::iterator i = m_validatedClientMap.find(clientId); + if (i == m_validatedClientMap.end()) { + return 0; + } + return i->second; } //----------------------------------------------------------------------- -ClientConnection* LoginServer::getUnvalidatedClient(int clientId) -{ - WARNING_STRICT_FATAL(clientId == 0, ("Tried to get an unvalidated client with client id == 0")); - std::map::iterator i = m_clientMap.find(clientId); - if (i == m_clientMap.end()) - return 0; - WARNING_STRICT_FATAL(i->second->getIsValidated(), ("Returning validated client from call to getUnvalidatedClient()")); - return i->second; +ClientConnection *LoginServer::getUnvalidatedClient(int clientId) { + WARNING_STRICT_FATAL(clientId == 0, ("Tried to get an unvalidated client with client id == 0")); + std::map::iterator i = m_clientMap.find(clientId); + if (i == m_clientMap.end()) { + return 0; + } + WARNING_STRICT_FATAL(i->second->getIsValidated(), ("Returning validated client from call to getUnvalidatedClient()")); + return i->second; } //----------------------------------------------------------------------- -void LoginServer::removeClient(int clientId) -{ - std::map::iterator i = m_clientMap.find(clientId); - if (i != m_clientMap.end()) - { - if (i->second->getIsValidated()) - { +void LoginServer::removeClient(int clientId) { + std::map::iterator i = m_clientMap.find(clientId); + if (i != m_clientMap.end()) { + if (i->second->getIsValidated()) { IGNORE_RETURN(m_validatedClientMap.erase(i->second->getStationId())); } IGNORE_RETURN(m_clientMap.erase(clientId)); @@ -261,780 +237,692 @@ void LoginServer::removeClient(int clientId) //----------------------------------------------------------------------- -void LoginServer::installSessionValidation() -{ - /*int i = 0; - std::vector sessionServers; +void LoginServer::installSessionValidation() { + /*int i = 0; + std::vector sessionServers; - int numberOfSessionServers = ConfigLoginServer::getNumberOfSessionServers(); - for (i = 0; i < numberOfSessionServers; ++i) - { - char const * const p = ConfigLoginServer::getSessionServer(i); - if (p) - { - REPORT_LOG(true, ("Using session server %s\n", p)); - sessionServers.push_back(p); - } - } + int numberOfSessionServers = ConfigLoginServer::getNumberOfSessionServers(); + for (i = 0; i < numberOfSessionServers; ++i) + { + char const * const p = ConfigLoginServer::getSessionServer(i); + if (p) + { + REPORT_LOG(true, ("Using session server %s\n", p)); + sessionServers.push_back(p); + } + } - // if there were none specified, use defaults - FATAL(i == 0, ("No session servers specified for session API")); + // if there were none specified, use defaults + FATAL(i == 0, ("No session servers specified for session API")); - m_sessionApiClient = new SessionApiClient(&sessionServers[0], i);*/ + m_sessionApiClient = new SessionApiClient(&sessionServers[0], i);*/ - return; + return; } //----------------------------------------------------------------------- -bool LoginServer::deleteCharacter(uint32 clusterId, NetworkId const & characterId, StationId suid) -{ - const ClusterListEntry *cle = findClusterById(clusterId); - if (cle) - { - if (cle->m_centralServerConnection) - { - ServerDeleteCharacterMessage smsg(suid, characterId, 0); - cle->m_centralServerConnection->send(smsg, true); +bool LoginServer::deleteCharacter(uint32 clusterId, NetworkId const &characterId, StationId suid) { + const ClusterListEntry *cle = findClusterById(clusterId); + if (cle) { + if (cle->m_centralServerConnection) { + ServerDeleteCharacterMessage smsg(suid, characterId, 0); + cle->m_centralServerConnection->send(smsg, true); - ClientConnection* target = getValidatedClient(suid); - if (target) - { - target->onCharacterDeletedFromCluster(characterId); - } + ClientConnection *target = getValidatedClient(suid); + if (target) { + target->onCharacterDeletedFromCluster(characterId); + } - DatabaseConnection::getInstance().deleteCharacter(clusterId, characterId, suid); - return true; - } - else - { - DEBUG_REPORT_LOG(true, ("User %lu requested deleting character %s on cluster %lu, but the cluster is not currently connected.\n", suid, characterId.getValueString().c_str(), clusterId)); - return false; - } - } - else - { - DEBUG_REPORT_LOG(true, ("User %lu requested deleting character %s on cluster %lu, but we have no cluster with that number.\n", suid, characterId.getValueString().c_str(), clusterId)); - return false; - } + DatabaseConnection::getInstance().deleteCharacter(clusterId, characterId, suid); + return true; + } else { + DEBUG_REPORT_LOG(true, ("User %lu requested deleting character %s on cluster %lu, but the cluster is not currently connected.\n", suid, characterId.getValueString().c_str(), clusterId)); + return false; + } + } else { + DEBUG_REPORT_LOG(true, ("User %lu requested deleting character %s on cluster %lu, but we have no cluster with that number.\n", suid, characterId.getValueString().c_str(), clusterId)); + return false; + } } //----------------------------------------------------------------------- -const KeyShare::Key & LoginServer::getCurrentKey(void) const -{ - return keyServer->getKey(0); +const KeyShare::Key &LoginServer::getCurrentKey(void) const { + return keyServer->getKey(0); } //----------------------------------------------------------------------- -SessionApiClient * LoginServer::getSessionApiClient() -{ - return m_sessionApiClient; +SessionApiClient *LoginServer::getSessionApiClient() { + return m_sessionApiClient; } //----------------------------------------------------------------------- -KeyShare::Token LoginServer::makeToken(const unsigned char * const data, const uint32 dataLen) const -{ - return keyServer->makeToken(data, dataLen); +KeyShare::Token LoginServer::makeToken(const unsigned char *const data, const uint32 dataLen) const { + return keyServer->makeToken(data, dataLen); } //----------------------------------------------------------------------- -void LoginServer::pushAllKeys(CentralServerConnection * targetGameServer) const -{ - for (int i = static_cast(keyServer->getKeyCount()) - 1; i >= 0; i--) - { - LoginKeyPush pk(keyServer->getKey(static_cast(i))); - targetGameServer->send(pk, true); - } +void LoginServer::pushAllKeys(CentralServerConnection *targetGameServer) const { + for (int i = static_cast(keyServer->getKeyCount()) - 1; i >= 0; i--) { + LoginKeyPush pk(keyServer->getKey(static_cast(i))); + targetGameServer->send(pk, true); + } } //----------------------------------------------------------------------- -void LoginServer::pushKeyToAllServers(void) -{ - KeyShare::Key k = keyServer->getKey(0); - CentralServerConnection * c; +void LoginServer::pushKeyToAllServers(void) { + KeyShare::Key k = keyServer->getKey(0); + CentralServerConnection *c; - LoginKeyPush msg(k); + LoginKeyPush msg(k); - unsigned char s[128]; - memcpy(s, k.value, 16); //lint !e64 !e119 !e534 // not sure where lint is finding a memcpy(void *, int) prototype - DEBUG_REPORT_LOG(true, ("Key Exchange ->: ")); - for (int x = 0; x < 16; x++) - { - DEBUG_REPORT_LOG(true, ("[%3i]", s[x])); - } - DEBUG_REPORT_LOG(true, ("\n")); + unsigned char s[128]; + memcpy(s, k.value, 16); //lint !e64 !e119 !e534 // not sure where lint is finding a memcpy(void *, int) prototype + DEBUG_REPORT_LOG(true, ("Key Exchange ->: ")); + for (int x = 0; x < 16; x++) { + DEBUG_REPORT_LOG(true, ("[%3i]", s[x])); + } + DEBUG_REPORT_LOG(true, ("\n")); - for (ClusterListType::const_iterator i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - c = (*i)->m_centralServerConnection; - if (c) - { - c->send(msg, true); - } - } + for (ClusterListType::const_iterator i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + c = (*i)->m_centralServerConnection; + if (c) { + c->send(msg, true); + } + } } // ---------------------------------------------------------------------- -void LoginServer::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message) -{ - // determine message type - const uint32 messageType = message.getType(); +void LoginServer::receiveMessage(const MessageDispatch::Emitter &source, const MessageDispatch::MessageBase &message) { + // determine message type + const uint32 messageType = message.getType(); - switch(messageType) { - case constcrc("LoginClusterName") : - case constcrc("LoginClusterName2") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const LoginClusterName msg(ri); - if (msg.getClusterName().length() > 0) - { - CentralServerConnection * connection = const_cast(safe_cast(&source)); - DEBUG_REPORT_LOG(true, ("Cluster connection %s opened\n", msg.getClusterName().c_str())); - ClusterListEntry *cle = nullptr; - if (ConfigLoginServer::getDevelopmentMode()) { - // in this mode, we trust the name sent by the cluster - cle = findClusterByName(msg.getClusterName()); + switch (messageType) { + case constcrc("LoginClusterName") : + case constcrc("LoginClusterName2") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const LoginClusterName msg(ri); + if (msg.getClusterName().length() > 0) { + CentralServerConnection *connection = const_cast(safe_cast(&source)); + DEBUG_REPORT_LOG(true, ("Cluster connection %s opened\n", msg.getClusterName().c_str())); + ClusterListEntry *cle = nullptr; + if (ConfigLoginServer::getDevelopmentMode()) { + // in this mode, we trust the name sent by the cluster + cle = findClusterByName(msg.getClusterName()); #ifdef _DEBUG - // if in debug mode, we dynamically add clusters we don't know about - // DO NOT USE ON PRODUCTION! This is where other servers are getting hijacked. - if (!cle) - { - cle = addCluster(msg.getClusterName()); - } + // if in debug mode, we dynamically add clusters we don't know about + // DO NOT USE ON PRODUCTION! This is where other servers are getting hijacked. + if (!cle) + { + cle = addCluster(msg.getClusterName()); + } #endif - } - else - { - // in this mode, the cluster name has to match what we were expecting - cle = findClusterByConnection(connection); - if (!cle) - DEBUG_FATAL(true, ("PROGRAMMER BUG: Got a connection from %s:%hu, which we weren't expecting. Cluster name is \"%s\".\n", connection->getRemoteAddress().c_str(), connection->getRemotePort(), msg.getClusterName().c_str())); - else - if (msg.getClusterName() != cle->m_clusterName) - { - WARNING(true, ("Server %i is named \"%s\" in the database. The server at the specified address (%s:%hu) reports its name as \"%s\". It will not be allowed in the service. Either the name in the database or the name in Central's config file should be corrected.\n", cle->m_clusterId, cle->m_clusterName.c_str(), connection->getRemoteAddress().c_str(), connection->getRemotePort(), msg.getClusterName().c_str())); - disconnectCluster(*cle, true, false); - cle = nullptr; - } - } + } else { + // in this mode, the cluster name has to match what we were expecting + cle = findClusterByConnection(connection); + if (!cle) { + DEBUG_FATAL(true, ("PROGRAMMER BUG: Got a connection from %s:%hu, which we weren't expecting. Cluster name is \"%s\".\n", connection->getRemoteAddress().c_str(), connection->getRemotePort(), msg.getClusterName().c_str())); + } else if (msg.getClusterName() != cle->m_clusterName) { + WARNING(true, ("Server %i is named \"%s\" in the database. The server at the specified address (%s:%hu) reports its name as \"%s\". It will not be allowed in the service. Either the name in the database or the name in Central's config file should be corrected.\n", cle->m_clusterId, cle->m_clusterName.c_str(), connection->getRemoteAddress().c_str(), connection->getRemotePort(), msg.getClusterName().c_str())); + disconnectCluster(*cle, true, false); + cle = nullptr; + } + } - if (cle) - { - cle->m_timeZone = msg.getTimeZone(); - cle->m_centralServerConnection = connection; - cle->m_connected = true; - pushAllKeys(connection); + if (cle) { + cle->m_timeZone = msg.getTimeZone(); + cle->m_centralServerConnection = connection; + cle->m_connected = true; + pushAllKeys(connection); - if (cle->m_clusterId == 0) - { - DEBUG_FATAL(!ConfigLoginServer::getDevelopmentMode(), ("Programmer bug: cle->m_clusterId was 0 in non-development mode. The code before this line should have prevented this.\n")); - DEBUG_REPORT_LOG(true, ("Cluster was not on the list. Adding it to the database.\n")); - DatabaseConnection::getInstance().registerNewCluster(msg.getClusterName(), connection->getRemoteAddress()); - } - else - cle->m_centralServerConnection->setClusterId(cle->m_clusterId); + if (cle->m_clusterId == 0) { + DEBUG_FATAL(!ConfigLoginServer::getDevelopmentMode(), ("Programmer bug: cle->m_clusterId was 0 in non-development mode. The code before this line should have prevented this.\n")); + DEBUG_REPORT_LOG(true, ("Cluster was not on the list. Adding it to the database.\n")); + DatabaseConnection::getInstance().registerNewCluster(msg.getClusterName(), connection->getRemoteAddress()); + } else { + cle->m_centralServerConnection->setClusterId(cle->m_clusterId); + } - m_clusterStatusChanged = true; + m_clusterStatusChanged = true; - // tell the cluster its cluster id - if (cle->m_clusterId > 0) - { - GenericValueTypeMessage const msgClusterId("ClusterId", cle->m_clusterId); - cle->m_centralServerConnection->send(msgClusterId, true); - } + // tell the cluster its cluster id + if (cle->m_clusterId > 0) { + GenericValueTypeMessage const msgClusterId("ClusterId", cle->m_clusterId); + cle->m_centralServerConnection->send(msgClusterId, true); + } - // tell the cluster about its locked and secret state - GenericValueTypeMessage > const msgState("UpdateClusterLockedAndSecretState", std::make_pair(cle->m_locked, cle->m_secret)); - cle->m_centralServerConnection->send(msgState, true); - } - } - break; - } - case constcrc("LoginConnectionServerAddress") : - { - const CentralServerConnection * cs = safe_cast(&source); - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + // tell the cluster about its locked and secret state + GenericValueTypeMessage > const msgState("UpdateClusterLockedAndSecretState", std::make_pair(cle->m_locked, cle->m_secret)); + cle->m_centralServerConnection->send(msgState, true); + } + } + break; + } + case constcrc("LoginConnectionServerAddress") : { + const CentralServerConnection *cs = safe_cast(&source); + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - LoginConnectionServerAddress m(ri); //lint !e1774 !e826onServerEntry entry; - ConnectionServerEntry entry; - entry.clientServiceAddress = Address(Address(m.getClientServiceAddress(), 0).getSockAddr4()).getHostAddress(); - entry.clientServicePortPrivate = m.getClientServicePortPrivate(); - entry.clientServicePortPublic = m.getClientServicePortPublic(); - entry.id = m.getId(); - entry.numClients = m.getNumClients(); - entry.pingPort = m.getPingPort(); + LoginConnectionServerAddress m(ri); //lint !e1774 !e826onServerEntry entry; + ConnectionServerEntry entry; + entry.clientServiceAddress = Address(Address(m.getClientServiceAddress(), 0).getSockAddr4()).getHostAddress(); + entry.clientServicePortPrivate = m.getClientServicePortPrivate(); + entry.clientServicePortPublic = m.getClientServicePortPublic(); + entry.id = m.getId(); + entry.numClients = m.getNumClients(); + entry.pingPort = m.getPingPort(); - DEBUG_REPORT_LOG(true, ("ConnectionServer Reconnect - address from connection server (%s), address after conversion (%s)\n", m.getClientServiceAddress().c_str(), entry.clientServiceAddress.c_str())); + DEBUG_REPORT_LOG(true, ("ConnectionServer Reconnect - address from connection server (%s), address after conversion (%s)\n", m.getClientServiceAddress().c_str(), entry.clientServiceAddress.c_str())); - ClusterListEntry *cle = findClusterByConnection(cs); - if (cle) - { - WARNING_STRICT_FATAL(!cle->m_centralServerConnection, ("Got reconnect for connection server with no central! Cluster %s\n", cs->getClusterName().c_str())); - std::vector::iterator i = std::find(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), entry); - if (i == cle->m_connectionServers.end()) - { - cle->m_connectionServers.push_back(entry); - m_clusterStatusChanged = true; - } - else - { - *i = entry; - } + ClusterListEntry *cle = findClusterByConnection(cs); + if (cle) { + WARNING_STRICT_FATAL(!cle->m_centralServerConnection, ("Got reconnect for connection server with no central! Cluster %s\n", cs->getClusterName().c_str())); + std::vector::iterator i = std::find(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), entry); + if (i == cle->m_connectionServers.end()) { + cle->m_connectionServers.push_back(entry); + m_clusterStatusChanged = true; + } else { + *i = entry; + } - std::sort(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), ConnectionServerEntryLessThan()); - } - else - WARNING_STRICT_FATAL(true, ("Programmer bug: Got LoginConnectionServerAddress from a cluster that wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); - break; - } - case constcrc("PreloadFinishedMessage") : - { - const CentralServerConnection * cs = safe_cast(&source); - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - PreloadFinishedMessage msg(ri); + std::sort(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), ConnectionServerEntryLessThan()); + } else { + WARNING_STRICT_FATAL(true, ("Programmer bug: Got LoginConnectionServerAddress from a cluster that wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); + } + break; + } + case constcrc("PreloadFinishedMessage") : { + const CentralServerConnection *cs = safe_cast(&source); + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + PreloadFinishedMessage msg(ri); - ClusterListEntry *cle = findClusterByConnection(cs); - if (cle) - { - if (msg.getFinished()) - { - REPORT_LOG(true, ("Cluster %s is ready for players.\n", cle->m_clusterName.c_str())); - if (!cle->m_readyForPlayers) - { - cle->m_readyForPlayers = true; - m_clusterStatusChanged = true; - } - } - else - { - REPORT_LOG(true, ("Cluster %s is not ready for players.\n", cle->m_clusterName.c_str())); - if (cle->m_readyForPlayers) - { - cle->m_readyForPlayers = false; - m_clusterStatusChanged = true; - PurgeManager::onClusterNoLongerReady(cle->m_clusterId); - } - } - } - else - WARNING_STRICT_FATAL(true, ("Programmer bug: Got PreloadFinishedMessage from a cluster that wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); - - break; - } - case constcrc("ConnectionServerDown") : - { - const CentralServerConnection * centralConnection = safe_cast(&source); - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - ConnectionServerDown c(ri); //lint !e1774 !e826 - ClusterListEntry *cle = findClusterByConnection(centralConnection); - if (cle) - { - DEBUG_REPORT_LOG(true, ("Lost a connection server %d for %s.\n", c.getId(), cle->m_clusterName.c_str())); + ClusterListEntry *cle = findClusterByConnection(cs); + if (cle) { + if (msg.getFinished()) { + REPORT_LOG(true, ("Cluster %s is ready for players.\n", cle->m_clusterName.c_str())); + if (!cle->m_readyForPlayers) { + cle->m_readyForPlayers = true; + m_clusterStatusChanged = true; + } + } else { + REPORT_LOG(true, ("Cluster %s is not ready for players.\n", cle->m_clusterName.c_str())); + if (cle->m_readyForPlayers) { + cle->m_readyForPlayers = false; + m_clusterStatusChanged = true; + PurgeManager::onClusterNoLongerReady(cle->m_clusterId); + } + } + } else { + WARNING_STRICT_FATAL(true, ("Programmer bug: Got PreloadFinishedMessage from a cluster that wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); + } - std::vector::iterator iter = cle->m_connectionServers.begin(); - bool found = false; - for (; iter != cle->m_connectionServers.end(); ++iter) - { - if (iter->id == c.getId()) - { - IGNORE_RETURN(cle->m_connectionServers.erase(iter)); - std::sort(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), ConnectionServerEntryLessThan()); - found = true; - break; - } - } - DEBUG_REPORT_LOG(!found, ("Tried to remove a connection server that wasn't in our list.\n")); - m_clusterStatusChanged = true; - } - else - WARNING_STRICT_FATAL(true, ("Programmer bug: Got ConnectionServerDown from a cluster that wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); - - break; - } - case constcrc("ConnectionClosed") : - { - const CentralServerConnection *c = dynamic_cast(&source); - if (c) - { - ClusterListEntry *cle = findClusterByConnection(c); - if (cle) - { - DEBUG_REPORT_LOG(true, ("Cluster connection %s closed.\n", c->getClusterName().c_str())); - disconnectCluster(*cle, false, true); - } - else - WARNING_STRICT_FATAL(true, ("Programmer bug: Cluster disconnected but it wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); - } - break; - } - case constcrc("ValidateAccountMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - ValidateAccountMessage msg(ri); + break; + } + case constcrc("ConnectionServerDown") : { + const CentralServerConnection *centralConnection = safe_cast(&source); + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ConnectionServerDown c(ri); //lint !e1774 !e826 + ClusterListEntry *cle = findClusterByConnection(centralConnection); + if (cle) { + DEBUG_REPORT_LOG(true, ("Lost a connection server %d for %s.\n", c.getId(), cle->m_clusterName.c_str())); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().getAccountValidationData(msg.getStationId(), conn->getClusterId(), msg.getTrack(), msg.getSubscriptionBits()); - else - WARNING_STRICT_FATAL(true, ("Expect ValidateAccountMessage's to only come from CentralServers.\n")); - break; - } - case constcrc("CntrlSrvDropDupeConns") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); + std::vector::iterator iter = cle->m_connectionServers.begin(); + bool found = false; + for (; iter != cle->m_connectionServers.end(); ++iter) { + if (iter->id == c.getId()) { + IGNORE_RETURN(cle->m_connectionServers.erase(iter)); + std::sort(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), ConnectionServerEntryLessThan()); + found = true; + break; + } + } + DEBUG_REPORT_LOG(!found, ("Tried to remove a connection server that wasn't in our list.\n")); + m_clusterStatusChanged = true; + } else { + WARNING_STRICT_FATAL(true, ("Programmer bug: Got ConnectionServerDown from a cluster that wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); + } - sendToAllClusters(msg, dynamic_cast(&source)); - break; - } - case constcrc("AdjustAccountFeatureIdRequest") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - AdjustAccountFeatureIdRequest const msg(ri); + break; + } + case constcrc("ConnectionClosed") : { + const CentralServerConnection *c = dynamic_cast(&source); + if (c) { + ClusterListEntry *cle = findClusterByConnection(c); + if (cle) { + DEBUG_REPORT_LOG(true, ("Cluster connection %s closed.\n", c->getClusterName().c_str())); + disconnectCluster(*cle, false, true); + } else { + WARNING_STRICT_FATAL(true, ("Programmer bug: Cluster disconnected but it wasn't on the list. Probably indicates we aren't tracking connections properly.\n")); + } + } + break; + } + case constcrc("ValidateAccountMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ValidateAccountMessage msg(ri); - if (m_sessionApiClient) - { - // on a session authenticated cluster, this request should have been serviced by the ConnectionServer - } - else - { - // for testing purpose when not using session authentication, store - // the account feature Ids locally in memory, which will get cleared - // (obviously) when the LoginServer is restarted - std::map > * nonSessionTestingAccountFeatureIds = nullptr; - if (msg.getGameCode() == PlatformGameCode::SWG) - nonSessionTestingAccountFeatureIds = &s_nonSessionTestingAccountSwgFeatureIds; - else if (msg.getGameCode() == PlatformGameCode::SWGTCG) - nonSessionTestingAccountFeatureIds = &s_nonSessionTestingAccountSwgTcgFeatureIds; + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().getAccountValidationData(msg.getStationId(), conn->getClusterId(), msg.getTrack(), msg.getSubscriptionBits()); + } else { + WARNING_STRICT_FATAL(true, ("Expect ValidateAccountMessage's to only come from CentralServers.\n")); + } + break; + } + case constcrc("CntrlSrvDropDupeConns") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); - int currentFeatureIdCount = 0; - int updatedFeatureIdCount = 0; - if (nonSessionTestingAccountFeatureIds) - { - std::map & accountFeatureIds = (*nonSessionTestingAccountFeatureIds)[msg.getTargetStationId()]; - std::map::const_iterator accountFeatureId = accountFeatureIds.find(msg.getFeatureId()); - if (accountFeatureId != accountFeatureIds.end()) - currentFeatureIdCount = accountFeatureId->second; + sendToAllClusters(msg, dynamic_cast(&source)); + break; + } + case constcrc("AdjustAccountFeatureIdRequest") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + AdjustAccountFeatureIdRequest const msg(ri); - updatedFeatureIdCount = std::max(0, currentFeatureIdCount + msg.getAdjustment()); - if (updatedFeatureIdCount > 0) - { - accountFeatureIds[msg.getFeatureId()] = updatedFeatureIdCount; - } - else - { - IGNORE_RETURN(accountFeatureIds.erase(msg.getFeatureId())); - if (accountFeatureIds.empty()) - IGNORE_RETURN(nonSessionTestingAccountFeatureIds->erase(msg.getTargetStationId())); - } - } + if (m_sessionApiClient) { + // on a session authenticated cluster, this request should have been serviced by the ConnectionServer + } else { + // for testing purpose when not using session authentication, store + // the account feature Ids locally in memory, which will get cleared + // (obviously) when the LoginServer is restarted + std::map > *nonSessionTestingAccountFeatureIds = nullptr; + if (msg.getGameCode() == PlatformGameCode::SWG) { + nonSessionTestingAccountFeatureIds = &s_nonSessionTestingAccountSwgFeatureIds; + } else if (msg.getGameCode() == PlatformGameCode::SWGTCG) { + nonSessionTestingAccountFeatureIds = &s_nonSessionTestingAccountSwgTcgFeatureIds; + } - // CS log SWG TCG account feature grant or SWG account feature grant for reward item trade in - if (nonSessionTestingAccountFeatureIds && !msg.getTargetPlayerDescription().empty() && msg.getTargetItem().isValid() && !msg.getTargetItemDescription().empty()) - { - if (msg.getGameCode() == PlatformGameCode::SWGTCG) - LOG("CustomerService", ("TcgRedemption: %s redeemed %s for SWGTCG account feature Id %lu (%d -> %d)", msg.getTargetPlayerDescription().c_str(), msg.getTargetItemDescription().c_str(), msg.getFeatureId(), currentFeatureIdCount, updatedFeatureIdCount)); - else if (msg.getGameCode() == PlatformGameCode::SWG) - LOG("CustomerService", ("VeteranRewards: %s traded in %s for SWG account feature Id %lu (%d -> %d)", msg.getTargetPlayerDescription().c_str(), msg.getTargetItemDescription().c_str(), msg.getFeatureId(), currentFeatureIdCount, updatedFeatureIdCount)); - } + int currentFeatureIdCount = 0; + int updatedFeatureIdCount = 0; + if (nonSessionTestingAccountFeatureIds) { + std::map &accountFeatureIds = (*nonSessionTestingAccountFeatureIds)[msg.getTargetStationId()]; + std::map::const_iterator accountFeatureId = accountFeatureIds.find(msg.getFeatureId()); + if (accountFeatureId != accountFeatureIds.end()) { + currentFeatureIdCount = accountFeatureId->second; + } - const CentralServerConnection * conn = dynamic_cast(&source); - if (conn) - { - AdjustAccountFeatureIdResponse const rsp(msg.getRequestingPlayer(), msg.getGameServer(), msg.getTargetPlayer(), msg.getTargetPlayerDescription(), msg.getTargetStationId(), msg.getTargetItem(), msg.getTargetItemDescription(), msg.getGameCode(), msg.getFeatureId(), currentFeatureIdCount, updatedFeatureIdCount, (nonSessionTestingAccountFeatureIds ? RESULT_SUCCESS : RESULT_CANCELLED), false); - sendToCluster(conn->getClusterId(), rsp); - } - } - break; - } - case constcrc("AccountFeatureIdRequest") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - AccountFeatureIdRequest const msg(ri); + updatedFeatureIdCount = std::max(0, currentFeatureIdCount + msg.getAdjustment()); + if (updatedFeatureIdCount > 0) { + accountFeatureIds[msg.getFeatureId()] = updatedFeatureIdCount; + } else { + IGNORE_RETURN(accountFeatureIds.erase(msg.getFeatureId())); + if (accountFeatureIds.empty()) { + IGNORE_RETURN(nonSessionTestingAccountFeatureIds->erase(msg.getTargetStationId())); + } + } + } - if (m_sessionApiClient) - { - // on a session authenticated cluster, this request should have been serviced by the ConnectionServer - } - else - { - // for testing purpose when not using session authentication, store - // the account feature Ids locally in memory, which will get cleared - // (obviously) when the LoginServer is restarted - std::map > * nonSessionTestingAccountFeatureIds = nullptr; - if (msg.getGameCode() == PlatformGameCode::SWG) - nonSessionTestingAccountFeatureIds = &s_nonSessionTestingAccountSwgFeatureIds; - else if (msg.getGameCode() == PlatformGameCode::SWGTCG) - nonSessionTestingAccountFeatureIds = &s_nonSessionTestingAccountSwgTcgFeatureIds; + // CS log SWG TCG account feature grant or SWG account feature grant for reward item trade in + if (nonSessionTestingAccountFeatureIds && !msg.getTargetPlayerDescription().empty() && + msg.getTargetItem().isValid() && !msg.getTargetItemDescription().empty()) { + if (msg.getGameCode() == PlatformGameCode::SWGTCG) { + LOG("CustomerService", ("TcgRedemption: %s redeemed %s for SWGTCG account feature Id %lu (%d -> %d)", msg.getTargetPlayerDescription().c_str(), msg.getTargetItemDescription().c_str(), msg.getFeatureId(), currentFeatureIdCount, updatedFeatureIdCount)); + } else if (msg.getGameCode() == PlatformGameCode::SWG) { + LOG("CustomerService", ("VeteranRewards: %s traded in %s for SWG account feature Id %lu (%d -> %d)", msg.getTargetPlayerDescription().c_str(), msg.getTargetItemDescription().c_str(), msg.getFeatureId(), currentFeatureIdCount, updatedFeatureIdCount)); + } + } - static std::map const empty; - std::map const * accountFeatureIds = ∅ + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + AdjustAccountFeatureIdResponse const rsp(msg.getRequestingPlayer(), msg.getGameServer(), msg.getTargetPlayer(), msg.getTargetPlayerDescription(), msg.getTargetStationId(), msg.getTargetItem(), msg.getTargetItemDescription(), msg.getGameCode(), msg.getFeatureId(), currentFeatureIdCount, updatedFeatureIdCount, (nonSessionTestingAccountFeatureIds + ? RESULT_SUCCESS + : RESULT_CANCELLED), false); + sendToCluster(conn->getClusterId(), rsp); + } + } + break; + } + case constcrc("AccountFeatureIdRequest") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + AccountFeatureIdRequest const msg(ri); - if (nonSessionTestingAccountFeatureIds) - { - std::map >::const_iterator iterFind = nonSessionTestingAccountFeatureIds->find(msg.getTargetStationId()); - if (iterFind != nonSessionTestingAccountFeatureIds->end()) - accountFeatureIds = &(iterFind->second); - } + if (m_sessionApiClient) { + // on a session authenticated cluster, this request should have been serviced by the ConnectionServer + } else { + // for testing purpose when not using session authentication, store + // the account feature Ids locally in memory, which will get cleared + // (obviously) when the LoginServer is restarted + std::map > *nonSessionTestingAccountFeatureIds = nullptr; + if (msg.getGameCode() == PlatformGameCode::SWG) { + nonSessionTestingAccountFeatureIds = &s_nonSessionTestingAccountSwgFeatureIds; + } else if (msg.getGameCode() == PlatformGameCode::SWGTCG) { + nonSessionTestingAccountFeatureIds = &s_nonSessionTestingAccountSwgTcgFeatureIds; + } - const CentralServerConnection * conn = dynamic_cast(&source); - if (conn) - { - static std::map const empty; - AccountFeatureIdResponse const rsp(msg.getRequester(), msg.getGameServer(), msg.getTarget(), msg.getTargetStationId(), msg.getGameCode(), msg.getRequestReason(), RESULT_SUCCESS, false, *accountFeatureIds, empty); - sendToCluster(conn->getClusterId(), rsp); - } - } - break; - } - case constcrc("FeatureIdTransactionRequest") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - FeatureIdTransactionRequest const fitr(ri); + static std::map const empty; + std::map const *accountFeatureIds = ∅ - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().featureIdTransactionRequest(conn->getClusterId(), fitr.getStationId(), fitr.getPlayer(), fitr.getGameServer()); - break; - } - case constcrc("FeatureIdTransactionSyncUpdate") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - FeatureIdTransactionSyncUpdate const fitsu(ri); + if (nonSessionTestingAccountFeatureIds) { + std::map < uint32, std::map < uint32, int > > ::const_iterator + iterFind = nonSessionTestingAccountFeatureIds->find(msg.getTargetStationId()); + if (iterFind != nonSessionTestingAccountFeatureIds->end()) { + accountFeatureIds = &(iterFind->second); + } + } - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().featureIdTransactionSyncUpdate(conn->getClusterId(), fitsu.getStationId(), fitsu.getPlayer(), fitsu.getItemId(), fitsu.getAdjustment()); - break; - } - case constcrc("TransferRequestMoveValidation") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - const TransferRequestMoveValidation request(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + static std::map const empty; + AccountFeatureIdResponse const rsp(msg.getRequester(), msg.getGameServer(), msg.getTarget(), msg.getTargetStationId(), msg.getGameCode(), msg.getRequestReason(), RESULT_SUCCESS, false, *accountFeatureIds, empty); + sendToCluster(conn->getClusterId(), rsp); + } + } + break; + } + case constcrc("FeatureIdTransactionRequest") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + FeatureIdTransactionRequest const fitr(ri); - TransferReplyMoveValidation::TransferReplyMoveValidationResult result = TransferReplyMoveValidation::TRMVR_can_create_regular_character; + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().featureIdTransactionRequest(conn->getClusterId(), fitr.getStationId(), fitr.getPlayer(), fitr.getGameServer()); + } + break; + } + case constcrc("FeatureIdTransactionSyncUpdate") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + FeatureIdTransactionSyncUpdate const fitsu(ri); - ClusterListEntry * cle = findClusterByName(request.getDestinationGalaxy()); - if (!cle) - { - result = TransferReplyMoveValidation::TRMVR_destination_galaxy_invalid; - } - else if (!cle->m_centralServerConnection) - { - result = TransferReplyMoveValidation::TRMVR_destination_galaxy_not_connected; - } - else if (!cle->m_readyForPlayers) - { - result = TransferReplyMoveValidation::TRMVR_destination_galaxy_in_loading; - } + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().featureIdTransactionSyncUpdate(conn->getClusterId(), fitsu.getStationId(), fitsu.getPlayer(), fitsu.getItemId(), fitsu.getAdjustment()); + } + break; + } + case constcrc("TransferRequestMoveValidation") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + const TransferRequestMoveValidation request(ri); - if (result == TransferReplyMoveValidation::TRMVR_can_create_regular_character) - { - // check with DB to see if account is allowed to create character on the destination galaxy - LOG("CustomerService", ("CharacterTransfer: Received TransferRequestMoveValidation : %s (character template id %lu) on %s to %s on %s. Forwarding request to Login Database.", request.getSourceCharacter().c_str(), request.getSourceCharacterTemplateId(), request.getSourceGalaxy().c_str(), request.getDestinationCharacter().c_str(), request.getDestinationGalaxy().c_str())); - DatabaseConnection::getInstance().getAccountValidationData(request, cle->m_centralServerConnection->getClusterId()); - } - else - { - // send failure back to originating server - TransferReplyMoveValidation reply(request.getTransferRequestSource(), request.getTrack(), request.getSourceStationId(), request.getDestinationStationId(), request.getSourceGalaxy(), request.getDestinationGalaxy(), request.getSourceCharacter(), request.getSourceCharacterId(), request.getSourceCharacterTemplateId(), request.getDestinationCharacter(), request.getCustomerLocalizedLanguage(), result); - const CentralServerConnection * conn = dynamic_cast(&source); - if (conn) - { - ClusterListEntry * sourceEntry = findClusterById(conn->getClusterId()); - if (sourceEntry && sourceEntry->m_centralServerConnection) - { - sourceEntry->m_centralServerConnection->send(reply, true); - } - } - } - break; - } - case constcrc("TransferReplyNameValidation") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const replyNameValidation(ri); + TransferReplyMoveValidation::TransferReplyMoveValidationResult result = TransferReplyMoveValidation::TRMVR_can_create_regular_character; - const CentralServerConnection * conn = dynamic_cast(&source); - if (conn) - { - ClusterListEntry * cle = findClusterByName(replyNameValidation.getValue().second.getSourceGalaxy()); - if (cle && cle->m_centralServerConnection) - { - LOG("CustomerService", ("CharacterTransfer: Received TransferReplyNameValidation from destination galaxy CentralServer, forwarding to source galaxy CentralServer : %s", replyNameValidation.getValue().second.toString().c_str())); - cle->m_centralServerConnection->send(replyNameValidation, true); - } - } - break; - } - case constcrc("TransferLoginCharacterToDestinationServer") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const login(ri); + ClusterListEntry *cle = findClusterByName(request.getDestinationGalaxy()); + if (!cle) { + result = TransferReplyMoveValidation::TRMVR_destination_galaxy_invalid; + } else if (!cle->m_centralServerConnection) { + result = TransferReplyMoveValidation::TRMVR_destination_galaxy_not_connected; + } else if (!cle->m_readyForPlayers) { + result = TransferReplyMoveValidation::TRMVR_destination_galaxy_in_loading; + } - const CentralServerConnection * conn = dynamic_cast(&source); - if (conn) - { - ClusterListEntry * cle = findClusterByName(login.getValue().getDestinationGalaxy()); - if (cle && cle->m_centralServerConnection) - { - LOG("CustomerService", ("CharacterTransfer: Received TransferLoginCharacterToDestinationServer from source galaxy CentralServer, forwarding to destination galaxy CentralServer : %s", login.getValue().toString().c_str())); - cle->m_centralServerConnection->send(login, true); - } - } - break; - } - case constcrc("UpdateLoginConnectionServerStatus") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - UpdateLoginConnectionServerStatus msg(ri); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - { - ClusterListEntry *cle = findClusterByConnection(conn); - if (cle) - { - std::vector::iterator i = cle->m_connectionServers.begin(); - for (; i != cle->m_connectionServers.end(); ++i) - { - if (i->id == msg.getId()) - { - i->clientServicePortPublic = msg.getPublicPort(); - i->clientServicePortPrivate = msg.getPrivatePort(); - i->numClients = msg.getPlayerCount(); - break; - } - } - std::sort(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), ConnectionServerEntryLessThan()); - } - } - break; - } - case constcrc("UpdatePlayerCountMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - UpdatePlayerCountMessage msg(ri); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - { - ClusterListEntry *cle = findClusterByConnection(conn); - if (cle) - { - const int tutorialPlayerCount = (msg.getEmptySceneCount() + msg.getTutorialSceneCount() + msg.getFalconSceneCount()); + if (result == TransferReplyMoveValidation::TRMVR_can_create_regular_character) { + // check with DB to see if account is allowed to create character on the destination galaxy + LOG("CustomerService", ("CharacterTransfer: Received TransferRequestMoveValidation : %s (character template id %lu) on %s to %s on %s. Forwarding request to Login Database.", request.getSourceCharacter().c_str(), request.getSourceCharacterTemplateId(), request.getSourceGalaxy().c_str(), request.getDestinationCharacter().c_str(), request.getDestinationGalaxy().c_str())); + DatabaseConnection::getInstance().getAccountValidationData(request, cle->m_centralServerConnection->getClusterId()); + } else { + // send failure back to originating server + TransferReplyMoveValidation reply(request.getTransferRequestSource(), request.getTrack(), request.getSourceStationId(), request.getDestinationStationId(), request.getSourceGalaxy(), request.getDestinationGalaxy(), request.getSourceCharacter(), request.getSourceCharacterId(), request.getSourceCharacterTemplateId(), request.getDestinationCharacter(), request.getCustomerLocalizedLanguage(), result); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + ClusterListEntry *sourceEntry = findClusterById(conn->getClusterId()); + if (sourceEntry && sourceEntry->m_centralServerConnection) { + sourceEntry->m_centralServerConnection->send(reply, true); + } + } + } + break; + } + case constcrc("TransferReplyNameValidation") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const replyNameValidation(ri); - // We only want to update the clients if some "threshold" has been crossed - if ((cle->m_notRecommendedCentral != msg.getLoadedRecently()) - || hasCrossedThreshold(cle->m_onlineTutorialLimit, cle->m_numTutorialPlayers, tutorialPlayerCount) - || hasCrossedThreshold(cle->m_onlineFreeTrialLimit, cle->m_numFreeTrialPlayers, msg.getFreeTrialCount()) - || hasCrossedThreshold(cle->m_onlinePlayerLimit, cle->m_numPlayers, msg.getCount())) - { - m_clusterStatusChanged = true; - } + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + ClusterListEntry *cle = findClusterByName(replyNameValidation.getValue().second.getSourceGalaxy()); + if (cle && cle->m_centralServerConnection) { + LOG("CustomerService", ("CharacterTransfer: Received TransferReplyNameValidation from destination galaxy CentralServer, forwarding to source galaxy CentralServer : %s", replyNameValidation.getValue().second.toString().c_str())); + cle->m_centralServerConnection->send(replyNameValidation, true); + } + } + break; + } + case constcrc("TransferLoginCharacterToDestinationServer") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const login(ri); - cle->m_numPlayers = msg.getCount(); - cle->m_numFreeTrialPlayers = msg.getFreeTrialCount(); - cle->m_notRecommendedCentral = msg.getLoadedRecently(); - cle->m_numTutorialPlayers = tutorialPlayerCount; - } - } - break; - } - case constcrc("RenameCharacterMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - RenameCharacterMessage msg(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + ClusterListEntry *cle = findClusterByName(login.getValue().getDestinationGalaxy()); + if (cle && cle->m_centralServerConnection) { + LOG("CustomerService", ("CharacterTransfer: Received TransferLoginCharacterToDestinationServer from source galaxy CentralServer, forwarding to destination galaxy CentralServer : %s", login.getValue().toString().c_str())); + cle->m_centralServerConnection->send(login, true); + } + } + break; + } + case constcrc("UpdateLoginConnectionServerStatus") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + UpdateLoginConnectionServerStatus msg(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + ClusterListEntry *cle = findClusterByConnection(conn); + if (cle) { + std::vector::iterator i = cle->m_connectionServers.begin(); + for (; i != cle->m_connectionServers.end(); ++i) { + if (i->id == msg.getId()) { + i->clientServicePortPublic = msg.getPublicPort(); + i->clientServicePortPrivate = msg.getPrivatePort(); + i->numClients = msg.getPlayerCount(); + break; + } + } + std::sort(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), ConnectionServerEntryLessThan()); + } + } + break; + } + case constcrc("UpdatePlayerCountMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + UpdatePlayerCountMessage msg(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + ClusterListEntry *cle = findClusterByConnection(conn); + if (cle) { + const int tutorialPlayerCount = (msg.getEmptySceneCount() + msg.getTutorialSceneCount() + + msg.getFalconSceneCount()); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().renameCharacter(conn->getClusterId(), msg.getCharacterId(), msg.getNewName(), nullptr); - else - WARNING_STRICT_FATAL(true, ("Got RenameCharacterMessage from something other than CentralServerConnection.\n")); - - break; - } - case constcrc("LoginCreateCharacterMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - LoginCreateCharacterMessage msg(ri); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().createCharacter(conn->getClusterId(), msg.getStationId(), msg.getCharacterName(), msg.getCharacterObjectId(), msg.getTemplateId(), msg.getJedi()); - - break; - } - case constcrc("LoginRestoreCharacterMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - LoginRestoreCharacterMessage msg(ri); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().restoreCharacter(conn->getClusterId(), msg.getWhoRequested(), msg.getAccount(), msg.getCharacterName(), msg.getCharacterId(), msg.getTemplateId(), msg.getJedi()); - - break; - } - case constcrc("LoginUpgradeAccountMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - LoginUpgradeAccountMessage *msg = new LoginUpgradeAccountMessage(ri); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().upgradeAccount(msg, conn->getClusterId()); - - break; - } - case constcrc("ClaimRewardsMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - ClaimRewardsMessage const * msg = new ClaimRewardsMessage(ri); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - { - // current restriction is that once per account event or item cannot require a "consuming" account feature id - // TODO: looks like this is where vet rewards are consumed...the one per account thing, here - session auth may be enough? - uint32 const requiredAccountFeatureId = msg->getAccountFeatureId(); - bool const consumeAccountFeatureId = msg->getConsumeAccountFeatureId(); - if ((msg->getConsumeEvent() || msg->getConsumeItem()) && (requiredAccountFeatureId > 0) && consumeAccountFeatureId) - { - ClaimRewardsReplyMessage const rsp(msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getRewardItem(), requiredAccountFeatureId, consumeAccountFeatureId, 0, 0, false); - sendToCluster(conn->getClusterId(), rsp); - delete msg; - } - else if (requiredAccountFeatureId > 0) - { - if (m_sessionApiClient) - { - /*if (consumeAccountFeatureId) - { - // request session/Platform to update the account feature id - // SessionApiClient will own (and delete) msg - m_sessionApiClient->handleClaimRewardsMessage(conn->getClusterId(), msg); - } - else - { - LoginAPI::Feature oldFeature; - oldFeature.SetID(requiredAccountFeatureId); - oldFeature.SetData(msg->getAccountFeatureIdOldValue()); + // We only want to update the clients if some "threshold" has been crossed + if ((cle->m_notRecommendedCentral != msg.getLoadedRecently()) || + hasCrossedThreshold(cle->m_onlineTutorialLimit, cle->m_numTutorialPlayers, tutorialPlayerCount) || + hasCrossedThreshold(cle->m_onlineFreeTrialLimit, cle->m_numFreeTrialPlayers, msg.getFreeTrialCount()) || + hasCrossedThreshold(cle->m_onlinePlayerLimit, cle->m_numPlayers, msg.getCount())) { + m_clusterStatusChanged = true; + } - LoginAPI::Feature newFeature; - newFeature.SetID(requiredAccountFeatureId); - newFeature.SetData(msg->getAccountFeatureIdNewValue()); + cle->m_numPlayers = msg.getCount(); + cle->m_numFreeTrialPlayers = msg.getFreeTrialCount(); + cle->m_notRecommendedCentral = msg.getLoadedRecently(); + cle->m_numTutorialPlayers = tutorialPlayerCount; + } + } + break; + } + case constcrc("RenameCharacterMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + RenameCharacterMessage msg(ri); - DatabaseConnection::getInstance().claimRewards(conn->getClusterId(), msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getConsumeEvent(), msg->getRewardItem(), msg->getConsumeItem(), requiredAccountFeatureId, false, oldFeature.GetConsumeCount(), newFeature.GetConsumeCount()); - delete msg; - }*/ - } - else - { - // for testing purpose when not using session authentication, store - // the account feature Ids locally in memory, which will get cleared - // (obviously) when the LoginServer is restarted - std::map & accountFeatureIds = s_nonSessionTestingAccountSwgFeatureIds[msg->getStationId()]; - std::map::const_iterator accountFeatureId = accountFeatureIds.find(requiredAccountFeatureId); - int currentFeatureIdCount = 0; - if (accountFeatureId != accountFeatureIds.end()) - currentFeatureIdCount = accountFeatureId->second; + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().renameCharacter(conn->getClusterId(), msg.getCharacterId(), msg.getNewName(), nullptr); + } else { + WARNING_STRICT_FATAL(true, ("Got RenameCharacterMessage from something other than CentralServerConnection.\n")); + } - if (currentFeatureIdCount <= 0) - { - // fail because account doesn't have required feature id - IGNORE_RETURN(accountFeatureIds.erase(requiredAccountFeatureId)); - if (accountFeatureIds.empty()) - IGNORE_RETURN(s_nonSessionTestingAccountSwgFeatureIds.erase(msg->getStationId())); + break; + } + case constcrc("LoginCreateCharacterMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoginCreateCharacterMessage msg(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().createCharacter(conn->getClusterId(), msg.getStationId(), msg.getCharacterName(), msg.getCharacterObjectId(), msg.getTemplateId(), msg.getJedi()); + } - ClaimRewardsReplyMessage rsp(msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getRewardItem(), requiredAccountFeatureId, consumeAccountFeatureId, 0, 0, false); - sendToCluster(conn->getClusterId(), rsp); - } - else - { - // account has required feature id so claim is success, so update feature id for claim - int const updatedFeatureIdCount = (consumeAccountFeatureId ? std::max(0, currentFeatureIdCount - 1) : currentFeatureIdCount); + break; + } + case constcrc("LoginRestoreCharacterMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoginRestoreCharacterMessage msg(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().restoreCharacter(conn->getClusterId(), msg.getWhoRequested(), msg.getAccount(), msg.getCharacterName(), msg.getCharacterId(), msg.getTemplateId(), msg.getJedi()); + } - if (consumeAccountFeatureId) - { - if (updatedFeatureIdCount > 0) - { - accountFeatureIds[requiredAccountFeatureId] = updatedFeatureIdCount; - } - else - { - IGNORE_RETURN(accountFeatureIds.erase(requiredAccountFeatureId)); - if (accountFeatureIds.empty()) - IGNORE_RETURN(s_nonSessionTestingAccountSwgFeatureIds.erase(msg->getStationId())); - } - } + break; + } + case constcrc("LoginUpgradeAccountMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoginUpgradeAccountMessage *msg = new LoginUpgradeAccountMessage(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().upgradeAccount(msg, conn->getClusterId()); + } - // if feature id updated successfully, record transaction - DatabaseConnection::getInstance().claimRewards(conn->getClusterId(), msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getConsumeEvent(), msg->getRewardItem(), msg->getConsumeItem(), requiredAccountFeatureId, consumeAccountFeatureId, currentFeatureIdCount, updatedFeatureIdCount); - } + break; + } + case constcrc("ClaimRewardsMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ClaimRewardsMessage const *msg = new ClaimRewardsMessage(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + // current restriction is that once per account event or item cannot require a "consuming" account feature id + // TODO: looks like this is where vet rewards are consumed...the one per account thing, here - session auth may be enough? + uint32 const requiredAccountFeatureId = msg->getAccountFeatureId(); + bool const consumeAccountFeatureId = msg->getConsumeAccountFeatureId(); + if ((msg->getConsumeEvent() || msg->getConsumeItem()) && (requiredAccountFeatureId > 0) && + consumeAccountFeatureId) { + ClaimRewardsReplyMessage const rsp(msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getRewardItem(), requiredAccountFeatureId, consumeAccountFeatureId, 0, 0, false); + sendToCluster(conn->getClusterId(), rsp); + delete msg; + } else if (requiredAccountFeatureId > 0) { + if (m_sessionApiClient) { + /*if (consumeAccountFeatureId) + { + // request session/Platform to update the account feature id + // SessionApiClient will own (and delete) msg + m_sessionApiClient->handleClaimRewardsMessage(conn->getClusterId(), msg); + } + else + { + LoginAPI::Feature oldFeature; + oldFeature.SetID(requiredAccountFeatureId); + oldFeature.SetData(msg->getAccountFeatureIdOldValue()); - delete msg; - } - } - else - { - DatabaseConnection::getInstance().claimRewards(conn->getClusterId(), msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getConsumeEvent(), msg->getRewardItem(), msg->getConsumeItem(), 0, false, 0, 0); - delete msg; - } - } - else - { - delete msg; - } - - break; - } - case constcrc("PurgeCompleteMessage") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage msg(ri); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - PurgeManager::handlePurgeCompleteOnCluster(msg.getValue(), conn->getClusterId()); - else - WARNING_STRICT_FATAL(true, ("Programmer bug: got PurgeCompleteMessage from something that couldn't be cast to a CentralServerConnection")); - - break; - } - case constcrc("OccupyUnlockedSlotReq") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, uint32> > const occupyUnlockedSlotReq(ri); + LoginAPI::Feature newFeature; + newFeature.SetID(requiredAccountFeatureId); + newFeature.SetData(msg->getAccountFeatureIdNewValue()); - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().occupyUnlockedSlot(conn->getClusterId(), static_cast(occupyUnlockedSlotReq.getValue().first.first), occupyUnlockedSlotReq.getValue().first.second, occupyUnlockedSlotReq.getValue().second); - - break; - } - case constcrc("VacateUnlockedSlotReq") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, uint32> > const vacateUnlockedSlotReq(ri); + DatabaseConnection::getInstance().claimRewards(conn->getClusterId(), msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getConsumeEvent(), msg->getRewardItem(), msg->getConsumeItem(), requiredAccountFeatureId, false, oldFeature.GetConsumeCount(), newFeature.GetConsumeCount()); + delete msg; + }*/ + } else { + // for testing purpose when not using session authentication, store + // the account feature Ids locally in memory, which will get cleared + // (obviously) when the LoginServer is restarted + std::map &accountFeatureIds = s_nonSessionTestingAccountSwgFeatureIds[msg->getStationId()]; + std::map::const_iterator accountFeatureId = accountFeatureIds.find(requiredAccountFeatureId); + int currentFeatureIdCount = 0; + if (accountFeatureId != accountFeatureIds.end()) { + currentFeatureIdCount = accountFeatureId->second; + } - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().vacateUnlockedSlot(conn->getClusterId(), static_cast(vacateUnlockedSlotReq.getValue().first.first), vacateUnlockedSlotReq.getValue().first.second, vacateUnlockedSlotReq.getValue().second); - - break; - } - case constcrc("SwapUnlockedSlotReq") : - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, std::pair > > const swapUnlockedSlotReq(ri); + if (currentFeatureIdCount <= 0) { + // fail because account doesn't have required feature id + IGNORE_RETURN(accountFeatureIds.erase(requiredAccountFeatureId)); + if (accountFeatureIds.empty()) { + IGNORE_RETURN(s_nonSessionTestingAccountSwgFeatureIds.erase(msg->getStationId())); + } - const CentralServerConnection *conn = dynamic_cast(&source); - if (conn) - DatabaseConnection::getInstance().swapUnlockedSlot(conn->getClusterId(), static_cast(swapUnlockedSlotReq.getValue().first.first), swapUnlockedSlotReq.getValue().first.second, swapUnlockedSlotReq.getValue().second.second, swapUnlockedSlotReq.getValue().second.first); - - break; - } - } + ClaimRewardsReplyMessage rsp(msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getRewardItem(), requiredAccountFeatureId, consumeAccountFeatureId, 0, 0, false); + sendToCluster(conn->getClusterId(), rsp); + } else { + // account has required feature id so claim is success, so update feature id for claim + int const updatedFeatureIdCount = (consumeAccountFeatureId ? std::max(0, + currentFeatureIdCount - + 1) + : currentFeatureIdCount); + + if (consumeAccountFeatureId) { + if (updatedFeatureIdCount > 0) { + accountFeatureIds[requiredAccountFeatureId] = updatedFeatureIdCount; + } else { + IGNORE_RETURN(accountFeatureIds.erase(requiredAccountFeatureId)); + if (accountFeatureIds.empty()) { + IGNORE_RETURN(s_nonSessionTestingAccountSwgFeatureIds.erase(msg->getStationId())); + } + } + } + + // if feature id updated successfully, record transaction + DatabaseConnection::getInstance().claimRewards(conn->getClusterId(), msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getConsumeEvent(), msg->getRewardItem(), msg->getConsumeItem(), requiredAccountFeatureId, consumeAccountFeatureId, currentFeatureIdCount, updatedFeatureIdCount); + } + + delete msg; + } + } else { + DatabaseConnection::getInstance().claimRewards(conn->getClusterId(), msg->getGameServer(), msg->getStationId(), msg->getPlayer(), msg->getRewardEvent(), msg->getConsumeEvent(), msg->getRewardItem(), msg->getConsumeItem(), 0, false, 0, 0); + delete msg; + } + } else { + delete msg; + } + + break; + } + case constcrc("PurgeCompleteMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + PurgeManager::handlePurgeCompleteOnCluster(msg.getValue(), conn->getClusterId()); + } else { + WARNING_STRICT_FATAL(true, ("Programmer bug: got PurgeCompleteMessage from something that couldn't be cast to a CentralServerConnection")); + } + + break; + } + case constcrc("OccupyUnlockedSlotReq") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < uint32, NetworkId >, uint32 > > + const occupyUnlockedSlotReq(ri); + + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().occupyUnlockedSlot(conn->getClusterId(), static_cast(occupyUnlockedSlotReq.getValue().first.first), occupyUnlockedSlotReq.getValue().first.second, occupyUnlockedSlotReq.getValue().second); + } + + break; + } + case constcrc("VacateUnlockedSlotReq") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < uint32, NetworkId >, uint32 > > + const vacateUnlockedSlotReq(ri); + + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().vacateUnlockedSlot(conn->getClusterId(), static_cast(vacateUnlockedSlotReq.getValue().first.first), vacateUnlockedSlotReq.getValue().first.second, vacateUnlockedSlotReq.getValue().second); + } + + break; + } + case constcrc("SwapUnlockedSlotReq") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < uint32, NetworkId >, std::pair < uint32, NetworkId > > > + const swapUnlockedSlotReq(ri); + + const CentralServerConnection *conn = dynamic_cast(&source); + if (conn) { + DatabaseConnection::getInstance().swapUnlockedSlot(conn->getClusterId(), static_cast(swapUnlockedSlotReq.getValue().first.first), swapUnlockedSlotReq.getValue().first.second, swapUnlockedSlotReq.getValue().second.second, swapUnlockedSlotReq.getValue().second.first); + } + + break; + } + } } // ---------------------------------------------------------------------- @@ -1044,523 +932,476 @@ void LoginServer::receiveMessage(const MessageDispatch::Emitter & source, const * Also, flag whether character creation is allowed. * @see DatabaseConnection::getAccountValidationData */ -void LoginServer::validateAccount(const StationId& stationId, uint32 clusterId, uint32 subscriptionBits, bool canCreateRegular, bool canCreateJedi, bool canSkipTutorial, unsigned int track, std::vector > const & consumedRewardEvents, std::vector > const & claimedRewardItems) -{ - bool canLogin = false; +void +LoginServer::validateAccount(const StationId &stationId, uint32 clusterId, uint32 subscriptionBits, bool canCreateRegular, bool canCreateJedi, bool canSkipTutorial, unsigned int track, std::vector > const &consumedRewardEvents, std::vector > const &claimedRewardItems) { + bool canLogin = false; - ClusterListEntry *cle = findClusterById(clusterId); - if (cle && cle->m_centralServerConnection) - { - // Check login rights - // code to restrict logins based on "internal only", geographic rules, etc., goes here - // allow logins unless the cluster is full - bool clientIsInternal = false; - ClientConnection *conn = getValidatedClient(stationId); - if (conn) - { - clientIsInternal = AdminAccountManager::isInternalIp(conn->getRemoteAddress()); - } + ClusterListEntry *cle = findClusterById(clusterId); + if (cle && cle->m_centralServerConnection) { + // Check login rights + // code to restrict logins based on "internal only", geographic rules, etc., goes here + // allow logins unless the cluster is full + bool clientIsInternal = false; + ClientConnection *conn = getValidatedClient(stationId); + if (conn) { + clientIsInternal = AdminAccountManager::isInternalIp(conn->getRemoteAddress()); + } - if (clientIsInternal && ConfigLoginServer::getInternalBypassOnlineLimit()) - { - canLogin = true; - } - else if (cle->m_numPlayers <= cle->m_onlinePlayerLimit) - { - canLogin = true; + if (clientIsInternal && ConfigLoginServer::getInternalBypassOnlineLimit()) { + canLogin = true; + } else if (cle->m_numPlayers <= cle->m_onlinePlayerLimit) { + canLogin = true; - // Check cluster npe user limit - if (cle->m_numTutorialPlayers > cle->m_onlineTutorialLimit) - { - canLogin = false; - } - } + // Check cluster npe user limit + if (cle->m_numTutorialPlayers > cle->m_onlineTutorialLimit) { + canLogin = false; + } + } - if (!canLogin) - { - canCreateRegular = false; - canCreateJedi = false; - canSkipTutorial = false; - } + if (!canLogin) { + canCreateRegular = false; + canCreateJedi = false; + canSkipTutorial = false; + } - // check if we want to allow skip tutorial to all - if (ConfigLoginServer::getAllowSkipTutorialToAll()) - canSkipTutorial = true; + // check if we want to allow skip tutorial to all + if (ConfigLoginServer::getAllowSkipTutorialToAll()) { + canSkipTutorial = true; + } - ValidateAccountReplyMessage msg(stationId, canLogin, canCreateRegular, canCreateJedi, canSkipTutorial, track, consumedRewardEvents, claimedRewardItems); - cle->m_centralServerConnection->send(msg, true); - } + ValidateAccountReplyMessage msg(stationId, canLogin, canCreateRegular, canCreateJedi, canSkipTutorial, track, consumedRewardEvents, claimedRewardItems); + cle->m_centralServerConnection->send(msg, true); + } } //----------------------------------------------------------------------- -void LoginServer::validateAccountForTransfer(const TransferRequestMoveValidation & request, uint32 clusterId, uint32 sourceCharacterTemplateId, bool canCreateRegular, bool canCreateJedi) -{ - UNREF(canCreateJedi); +void +LoginServer::validateAccountForTransfer(const TransferRequestMoveValidation &request, uint32 clusterId, uint32 sourceCharacterTemplateId, bool canCreateRegular, bool canCreateJedi) { + UNREF(canCreateJedi); - // if transfer request was made with console god command, always allow - // the character to be created on the destination galaxy; we assume - // the user of the console god command knows that he's doing with regard - // to making sure that the destination galaxy would not end up with too many - // characters on the account on the destination galaxy - if (!canCreateRegular && (request.getTransferRequestSource() == TransferRequestMoveValidation::TRS_console_god_command)) - { - LOG("CustomerService", ("CharacterTransfer: Account Validation request for %s on %s to %s on %s is complete. Even though canCreateRegular=false, we are setting canCreateRegular=true because this request came from the console god command.", request.getSourceCharacter().c_str(), request.getSourceGalaxy().c_str(), request.getDestinationCharacter().c_str(), request.getDestinationGalaxy().c_str())); - canCreateRegular = true; - } + // if transfer request was made with console god command, always allow + // the character to be created on the destination galaxy; we assume + // the user of the console god command knows that he's doing with regard + // to making sure that the destination galaxy would not end up with too many + // characters on the account on the destination galaxy + if (!canCreateRegular && + (request.getTransferRequestSource() == TransferRequestMoveValidation::TRS_console_god_command)) { + LOG("CustomerService", ("CharacterTransfer: Account Validation request for %s on %s to %s on %s is complete. Even though canCreateRegular=false, we are setting canCreateRegular=true because this request came from the console god command.", request.getSourceCharacter().c_str(), request.getSourceGalaxy().c_str(), request.getDestinationCharacter().c_str(), request.getDestinationGalaxy().c_str())); + canCreateRegular = true; + } - LOG("CustomerService", ("CharacterTransfer: Account Validation request for %s on %s to %s on %s is complete. Sending response to CentralServer", request.getSourceCharacter().c_str(), request.getSourceGalaxy().c_str(), request.getDestinationCharacter().c_str(), request.getDestinationGalaxy().c_str())); + LOG("CustomerService", ("CharacterTransfer: Account Validation request for %s on %s to %s on %s is complete. Sending response to CentralServer", request.getSourceCharacter().c_str(), request.getSourceGalaxy().c_str(), request.getDestinationCharacter().c_str(), request.getDestinationGalaxy().c_str())); - // if this request came from a game server and the validation fails, send - // response to the source galaxy so an error message can be displayed to the user - if ((request.getTransferRequestSource() != TransferRequestMoveValidation::TRS_transfer_server) && !canCreateRegular) - { - ClusterListEntry * sourceGalaxyCle = findClusterByName(request.getSourceGalaxy()); - if (sourceGalaxyCle && sourceGalaxyCle->m_centralServerConnection) - { - clusterId = sourceGalaxyCle->m_centralServerConnection->getClusterId(); - } - } + // if this request came from a game server and the validation fails, send + // response to the source galaxy so an error message can be displayed to the user + if ((request.getTransferRequestSource() != TransferRequestMoveValidation::TRS_transfer_server) && + !canCreateRegular) { + ClusterListEntry *sourceGalaxyCle = findClusterByName(request.getSourceGalaxy()); + if (sourceGalaxyCle && sourceGalaxyCle->m_centralServerConnection) { + clusterId = sourceGalaxyCle->m_centralServerConnection->getClusterId(); + } + } - ClusterListEntry * cle = findClusterById(clusterId); - if (cle && cle->m_centralServerConnection) - { - TransferReplyMoveValidation response(request.getTransferRequestSource(), request.getTrack(), request.getSourceStationId(), request.getDestinationStationId(), request.getSourceGalaxy(), request.getDestinationGalaxy(), request.getSourceCharacter(), request.getSourceCharacterId(), sourceCharacterTemplateId, request.getDestinationCharacter(), request.getCustomerLocalizedLanguage(), (canCreateRegular ? TransferReplyMoveValidation::TRMVR_can_create_regular_character : TransferReplyMoveValidation::TRMVR_cannot_create_regular_character)); - cle->m_centralServerConnection->send(response, true); - } + ClusterListEntry *cle = findClusterById(clusterId); + if (cle && cle->m_centralServerConnection) { + TransferReplyMoveValidation response(request.getTransferRequestSource(), request.getTrack(), request.getSourceStationId(), request.getDestinationStationId(), request.getSourceGalaxy(), request.getDestinationGalaxy(), request.getSourceCharacter(), request.getSourceCharacterId(), sourceCharacterTemplateId, request.getDestinationCharacter(), request.getCustomerLocalizedLanguage(), (canCreateRegular + ? TransferReplyMoveValidation::TRMVR_can_create_regular_character + : TransferReplyMoveValidation::TRMVR_cannot_create_regular_character)); + cle->m_centralServerConnection->send(response, true); + } } //----------------------------------------------------------------------- -void LoginServer::run(void) -{ - NetworkHandler::install(); +void LoginServer::run(void) { + NetworkHandler::install(); #ifdef _DEBUG - LoginServerRemoteDebugSetup::install(); + LoginServerRemoteDebugSetup::install(); #endif - DatabaseConnection::getInstance().connect(); - DatabaseConnection::getInstance().requestClusterList(); - SetupSharedLog::install("LoginServer"); - ConsoleManager::install(); - DataTableManager::install(); - AdminAccountManager::install(ConfigLoginServer::getAdminAccountDataTable()); + DatabaseConnection::getInstance().connect(); + DatabaseConnection::getInstance().requestClusterList(); + SetupSharedLog::install("LoginServer"); + ConsoleManager::install(); + DataTableManager::install(); + AdminAccountManager::install(ConfigLoginServer::getAdminAccountDataTable()); - unsigned long limit = 20; - unsigned long startTime; - unsigned long totalTime = 0; + unsigned long limit = 20; + unsigned long startTime; + unsigned long totalTime = 0; - // load authentication data and bind the monitor to the port - const int port = ConfigLoginServer::getMetricsListenerPort(); - CMonitorAPI *mon = nullptr; + // load authentication data and bind the monitor to the port + const int port = ConfigLoginServer::getMetricsListenerPort(); + CMonitorAPI *mon = nullptr; - if (port) { - mon = new CMonitorAPI("metricsAuthentication.cfg", ConfigLoginServer::getMetricsListenerPort()); - getInstance().m_soeMonitor = mon; - const char *masterChannel = "Population"; - mon->add(masterChannel, WORLD_COUNT_CHANNEL); - std::string host = NetworkHandler::getHostName().c_str(); - size_t dotPos = host.find("."); - if (dotPos != host.npos) { - host = host.substr(0, dotPos - 1); - } - char tmpBuf[1024]; - IGNORE_RETURN(snprintf(tmpBuf, sizeof(tmpBuf), "LoginServer version %s on %s", ApplicationVersion::getInternalVersion(), host - .c_str())); - mon->setDescription(WORLD_COUNT_CHANNEL, tmpBuf); + if (port) { + mon = new CMonitorAPI("metricsAuthentication.cfg", ConfigLoginServer::getMetricsListenerPort()); + getInstance().m_soeMonitor = mon; + const char *masterChannel = "Population"; + mon->add(masterChannel, WORLD_COUNT_CHANNEL); + std::string host = NetworkHandler::getHostName().c_str(); + size_t dotPos = host.find("."); + if (dotPos != host.npos) { + host = host.substr(0, dotPos - 1); + } + char tmpBuf[1024]; + IGNORE_RETURN(snprintf(tmpBuf, sizeof(tmpBuf), "LoginServer version %s on %s", ApplicationVersion::getInternalVersion(), host.c_str())); + mon->setDescription(WORLD_COUNT_CHANNEL, tmpBuf); - mon->add("Galaxies", CLUSTER_COUNT_CHANNEL); - } + mon->add("Galaxies", CLUSTER_COUNT_CHANNEL); + } - while (!getInstance().done) - { - startTime = Clock::timeMs(); - IGNORE_RETURN(Os::update()); - if (getInstance().keyServer->update()) - { - getInstance().pushKeyToAllServers(); - } - NetworkHandler::dispatch(); - do - { - Os::sleep(1); - NetworkHandler::update(); - } while (Clock::timeMs() - startTime < limit); + while (!getInstance().done) { + startTime = Clock::timeMs(); + IGNORE_RETURN(Os::update()); + if (getInstance().keyServer->update()) { + getInstance().pushKeyToAllServers(); + } + NetworkHandler::dispatch(); + do { + Os::sleep(1); + NetworkHandler::update(); + } while (Clock::timeMs() - startTime < limit); - DatabaseConnection::getInstance().update(); - PurgeManager::update(static_cast(limit) / 1000.0f); - if (getInstance().m_clusterStatusChanged) - { - getInstance().sendClusterStatusToAll(); - getInstance().m_clusterStatusChanged = false; - } + DatabaseConnection::getInstance().update(); + PurgeManager::update(static_cast(limit) / 1000.0f); + if (getInstance().m_clusterStatusChanged) { + getInstance().sendClusterStatusToAll(); + getInstance().m_clusterStatusChanged = false; + } - //if (getInstance().m_sessionApiClient) - // getInstance().m_sessionApiClient->Process(); + //if (getInstance().m_sessionApiClient) + // getInstance().m_sessionApiClient->Process(); - totalTime += limit; //TODO: make a better way to do this - if (!ConfigLoginServer::getDevelopmentMode() && (totalTime > 10000)) - { - getInstance().refreshConnections(); - DatabaseConnection::getInstance().requestClusterList(); - totalTime = 0; - } + totalTime += limit; //TODO: make a better way to do this + if (!ConfigLoginServer::getDevelopmentMode() && (totalTime > 10000)) { + getInstance().refreshConnections(); + DatabaseConnection::getInstance().requestClusterList(); + totalTime = 0; + } - NetworkHandler::clearBytesThisFrame(); + NetworkHandler::clearBytesThisFrame(); - if (port) { - mon->set(WORLD_COUNT_CHANNEL, static_cast(getInstance().m_clientMap.size())); - int count = 0; - ClusterListType::const_iterator i; - for (i = getInstance().m_clusterList.begin(); i != getInstance().m_clusterList.end(); ++i) { - if ((*i)->m_connected) - ++count; - } - mon->set(CLUSTER_COUNT_CHANNEL, count); - mon->Update(); - } - } + if (port) { + mon->set(WORLD_COUNT_CHANNEL, static_cast(getInstance().m_clientMap.size())); + int count = 0; + ClusterListType::const_iterator i; + for (i = getInstance().m_clusterList.begin(); i != getInstance().m_clusterList.end(); ++i) { + if ((*i)->m_connected) { + ++count; + } + } + mon->set(CLUSTER_COUNT_CHANNEL, count); + mon->Update(); + } + } - NetworkHandler::update(); + NetworkHandler::update(); - ConsoleManager::remove(); - DatabaseConnection::getInstance().disconnect(); + ConsoleManager::remove(); + DatabaseConnection::getInstance().disconnect(); #ifdef _DEBUG - LoginServerRemoteDebugSetup::remove(); + LoginServerRemoteDebugSetup::remove(); #endif - SetupSharedLog::remove(); - NetworkHandler::remove(); + SetupSharedLog::remove(); + NetworkHandler::remove(); } //----------------------------------------------------------------------- -void LoginServer::sendAvatarList(const StationId& stationId, int stationIdNumberJediSlot, const AvatarList &avatars, TransferCharacterData * const transferData) -{ - std::vector chardata; - chardata.reserve(avatars.size()); +void +LoginServer::sendAvatarList(const StationId &stationId, int stationIdNumberJediSlot, const AvatarList &avatars, TransferCharacterData *const transferData) { + std::vector chardata; + chardata.reserve(avatars.size()); - EnumerateCharacterId::Chardata temp; - for (AvatarList::const_iterator i = avatars.begin(); i != avatars.end(); ++i) - { - temp.m_name = (*i).m_name; - temp.m_objectTemplateId = (*i).m_objectTemplateId; - temp.m_networkId = (*i).m_networkId; - temp.m_clusterId = (*i).m_clusterId; - temp.m_characterType = (*i).m_characterType; + EnumerateCharacterId::Chardata temp; + for (AvatarList::const_iterator i = avatars.begin(); i != avatars.end(); ++i) { + temp.m_name = (*i).m_name; + temp.m_objectTemplateId = (*i).m_objectTemplateId; + temp.m_networkId = (*i).m_networkId; + temp.m_clusterId = (*i).m_clusterId; + temp.m_characterType = (*i).m_characterType; - chardata.push_back(temp); - } + chardata.push_back(temp); + } - EnumerateCharacterId msg(chardata); + EnumerateCharacterId msg(chardata); - if (transferData) - { - // send this to the appropriate CentralServer - if (transferData->getSourceCharacterName().empty()) - { - // CTS API character list request - bool result = CentralServerConnection::sendCharacterListResponse(transferData->getSourceStationId(), avatars, *transferData); - UNREF(result); - DEBUG_REPORT_LOG(!result, ("Could not send avatar list to StationId %lu because connection has been closed.\n", stationId)); - } - else - { - uint32 characterTemplateId = 0; - NetworkId characterId = NetworkId::cms_invalid; - ClusterListEntry const * const cle = findClusterByName(transferData->getSourceGalaxy()); - if (cle) - { - // find associated character ID - for (AvatarList::const_iterator i = avatars.begin(); i != avatars.end(); ++i) - { - REPORT_LOG(true, ("checking %s == %s\n", Unicode::wideToNarrow(i->m_name).c_str(), transferData->getSourceCharacterName().c_str())); - if (Unicode::wideToNarrow(i->m_name) == transferData->getSourceCharacterName() - && i->m_clusterId == cle->m_clusterId) - { - characterTemplateId = static_cast(i->m_objectTemplateId); - characterId = i->m_networkId; - break; - } - } - } + if (transferData) { + // send this to the appropriate CentralServer + if (transferData->getSourceCharacterName().empty()) { + // CTS API character list request + bool result = CentralServerConnection::sendCharacterListResponse(transferData->getSourceStationId(), avatars, *transferData); + UNREF(result); + DEBUG_REPORT_LOG(!result, ("Could not send avatar list to StationId %lu because connection has been closed.\n", stationId)); + } else { + uint32 characterTemplateId = 0; + NetworkId characterId = NetworkId::cms_invalid; + ClusterListEntry const *const cle = findClusterByName(transferData->getSourceGalaxy()); + if (cle) { + // find associated character ID + for (AvatarList::const_iterator i = avatars.begin(); i != avatars.end(); ++i) { + REPORT_LOG(true, ("checking %s == %s\n", Unicode::wideToNarrow(i->m_name).c_str(), transferData->getSourceCharacterName().c_str())); + if (Unicode::wideToNarrow(i->m_name) == transferData->getSourceCharacterName() && + i->m_clusterId == cle->m_clusterId) { + characterTemplateId = static_cast(i->m_objectTemplateId); + characterId = i->m_networkId; + break; + } + } + } - LOG("CustomerService", ("CharacterTransfer: sendAvatarList() for stationId=%u, characterName=%s, sourceGalaxy=%s, determined characterId=%s, determined character template id=%lu", transferData->getSourceStationId(), transferData->getSourceCharacterName().c_str(), transferData->getSourceGalaxy().c_str(), characterId.getValueString().c_str(), characterTemplateId)); + LOG("CustomerService", ("CharacterTransfer: sendAvatarList() for stationId=%u, characterName=%s, sourceGalaxy=%s, determined characterId=%s, determined character template id=%lu", transferData->getSourceStationId(), transferData->getSourceCharacterName().c_str(), transferData->getSourceGalaxy().c_str(), characterId.getValueString().c_str(), characterTemplateId)); - transferData->setCharacterId(characterId); - transferData->setObjectTemplateCrc(characterTemplateId); + transferData->setCharacterId(characterId); + transferData->setObjectTemplateCrc(characterTemplateId); - // part of move request for character transfer system - const GenericValueTypeMessage response("TransferReplyCharacterDataFromLoginServer", *transferData); - CentralServerConnection::sendToCentralServer(transferData->getSourceGalaxy(), response); - } - } - else - { - ClientConnection *conn = getValidatedClient(stationId); - if (conn) - { - LOG("LoginClientConnection", ("sendAvatarList() for stationId (%lu) at IP (%s), sending avatar list to client", stationId, conn->getRemoteAddress().c_str())); + // part of move request for character transfer system + const GenericValueTypeMessage response("TransferReplyCharacterDataFromLoginServer", *transferData); + CentralServerConnection::sendToCentralServer(transferData->getSourceGalaxy(), response); + } + } else { + ClientConnection *conn = getValidatedClient(stationId); + if (conn) { + LOG("LoginClientConnection", ("sendAvatarList() for stationId (%lu) at IP (%s), sending avatar list to client", stationId, conn->getRemoteAddress().c_str())); - // this message ***MUST*** be sent first, as the client expects to - // receive this information before receiving the avatar list information - GenericValueTypeMessage const msgStationIdHasJediSlot("StationIdHasJediSlot", stationIdNumberJediSlot); - conn->send(msgStationIdHasJediSlot, true); + // this message ***MUST*** be sent first, as the client expects to + // receive this information before receiving the avatar list information + GenericValueTypeMessage const msgStationIdHasJediSlot("StationIdHasJediSlot", stationIdNumberJediSlot); + conn->send(msgStationIdHasJediSlot, true); - conn->send(msg, true); - } - else - { - DEBUG_REPORT_LOG(true, ("Could not send avatar list to StationId %lu.\n", stationId)); - LOG("LoginClientConnection", ("sendAvatarList() for stationId (%lu), cannot find connection to client for sending avatar list", stationId)); - } - } + conn->send(msg, true); + } else { + DEBUG_REPORT_LOG(true, ("Could not send avatar list to StationId %lu.\n", stationId)); + LOG("LoginClientConnection", ("sendAvatarList() for stationId (%lu), cannot find connection to client for sending avatar list", stationId)); + } + } } // ---------------------------------------------------------------------- -void LoginServer::performAccountTransfer(const AvatarList &avatars, TransferAccountData * transferAccountData) -{ - // grab the station ids - StationId sourceStationId = transferAccountData->getSourceStationId(); - StationId destinationStationId = transferAccountData->getDestinationStationId(); +void LoginServer::performAccountTransfer(const AvatarList &avatars, TransferAccountData *transferAccountData) { + // grab the station ids + StationId sourceStationId = transferAccountData->getSourceStationId(); + StationId destinationStationId = transferAccountData->getDestinationStationId(); - // we need to get the avatars' cluster and name for use in the chat transfer process - // also send a message to modify the game server databases for each of the clusterIds in transferAccountData - // avatar data is clusterName, avatarName - std::vector avatarData; - for (AvatarList::const_iterator i = avatars.begin(); i != avatars.end(); ++i) - { - ClusterListEntry * cluster = findClusterById(i->m_clusterId); + // we need to get the avatars' cluster and name for use in the chat transfer process + // also send a message to modify the game server databases for each of the clusterIds in transferAccountData + // avatar data is clusterName, avatarName + std::vector avatarData; + for (AvatarList::const_iterator i = avatars.begin(); i != avatars.end(); ++i) { + ClusterListEntry *cluster = findClusterById(i->m_clusterId); - if (cluster) - { - std::string clusterName = cluster->m_clusterName; - std::string avatarName = Unicode::wideToNarrow(i->m_name); + if (cluster) { + std::string clusterName = cluster->m_clusterName; + std::string avatarName = Unicode::wideToNarrow(i->m_name); - avatarData.push_back(AvatarData(clusterName, avatarName)); + avatarData.push_back(AvatarData(clusterName, avatarName)); - LOG("CustomerService", ("CharacterTransfer: Sending request to update game db (via cluster: %s) for account transfer from %lu to %lu (avatar: %s)", clusterName.c_str(), sourceStationId, destinationStationId, avatarName.c_str())); - const GenericValueTypeMessage message("TransferAccountRequestCentralDatabase", *transferAccountData); - sendToCluster(i->m_clusterId, message); - } - else - { - LOG("CustomerService", ("CharacterTransfer: Could not connect to cluster id %lu to update game db for account transfer from %lu to %lu (avatar: %s)", i->m_clusterId, sourceStationId, destinationStationId, Unicode::wideToNarrow(i->m_name).c_str())); - const GenericValueTypeMessage response("TransferAccountToAccountFailedToUpdateGameDatabase", *transferAccountData); - CentralServerConnection::sendToCentralServer(transferAccountData->getStartGalaxy(), response); - return; - } - } + LOG("CustomerService", ("CharacterTransfer: Sending request to update game db (via cluster: %s) for account transfer from %lu to %lu (avatar: %s)", clusterName.c_str(), sourceStationId, destinationStationId, avatarName.c_str())); + const GenericValueTypeMessage message("TransferAccountRequestCentralDatabase", *transferAccountData); + sendToCluster(i->m_clusterId, message); + } else { + LOG("CustomerService", ("CharacterTransfer: Could not connect to cluster id %lu to update game db for account transfer from %lu to %lu (avatar: %s)", i->m_clusterId, sourceStationId, destinationStationId, Unicode::wideToNarrow(i->m_name).c_str())); + const GenericValueTypeMessage response("TransferAccountToAccountFailedToUpdateGameDatabase", *transferAccountData); + CentralServerConnection::sendToCentralServer(transferAccountData->getStartGalaxy(), response); + return; + } + } - transferAccountData->setSourceAvatarData(avatarData); + transferAccountData->setSourceAvatarData(avatarData); - // we also need to modify the station id for all characters for the loginServer - this will contact the centralServer when it is complete to finish the transfer process - DatabaseConnection::getInstance().changeStationId(sourceStationId, destinationStationId, transferAccountData); + // we also need to modify the station id for all characters for the loginServer - this will contact the centralServer when it is complete to finish the transfer process + DatabaseConnection::getInstance().changeStationId(sourceStationId, destinationStationId, transferAccountData); } // ---------------------------------------------------------------------- -void LoginServer::onValidateClient(StationId suid, const std::string & username, ClientConnection *conn, bool isSecure, const char* sessionKey, uint32 gameBits, uint32 subscriptionBits) -{ - UNREF(username); - UNREF(gameBits); - UNREF(subscriptionBits); - NOT_NULL(conn); - WARNING_STRICT_FATAL(getValidatedClient(suid), ("Validating an already valid client in onValidateClient(). StationId: %d UserName: %s", suid, username.c_str())); +void +LoginServer::onValidateClient(StationId suid, const std::string &username, ClientConnection *conn, bool isSecure, const char *sessionKey, uint32 gameBits, uint32 subscriptionBits) { + UNREF(username); + UNREF(gameBits); + UNREF(subscriptionBits); + NOT_NULL(conn); + WARNING_STRICT_FATAL(getValidatedClient(suid), ("Validating an already valid client in onValidateClient(). StationId: %d UserName: %s", suid, username.c_str())); - int adminLevel = 0; - const bool isAdminAccount = AdminAccountManager::isAdminAccount(Unicode::toLower(username), adminLevel); + int adminLevel = 0; + const bool isAdminAccount = AdminAccountManager::isAdminAccount(Unicode::toLower(username), adminLevel); - if (conn->getRequestedAdminSuid() != 0) - { - //verify internal, secure, is on the god list - bool loginOK = false; - if (!isSecure) - LOG("CustomerService", ("AdminLogin: User %s (account %li) attempted to log into account %li, but was not using a SecureID token", username.c_str(), suid, conn->getRequestedAdminSuid())); - else - { - if (!AdminAccountManager::isInternalIp(conn->getRemoteAddress())) - LOG("CustomerService", ("AdminLogin: User %s (account %li) attempted to log into account %li, but was not logging in from an internal IP", username.c_str(), suid, conn->getRequestedAdminSuid())); - else - { - if (!isAdminAccount || adminLevel < 10) - LOG("CustomerService", ("AdminLogin: User %s (account %li) attempted to log into account %li, but did not have sufficient permissions", username.c_str(), suid, conn->getRequestedAdminSuid())); - else - { - suid = conn->getRequestedAdminSuid(); - loginOK = true; - } - } - } + if (conn->getRequestedAdminSuid() != 0) { + //verify internal, secure, is on the god list + bool loginOK = false; + if (!isSecure) { + LOG("CustomerService", ("AdminLogin: User %s (account %li) attempted to log into account %li, but was not using a SecureID token", username.c_str(), suid, conn->getRequestedAdminSuid())); + } else { + if (!AdminAccountManager::isInternalIp(conn->getRemoteAddress())) { + LOG("CustomerService", ("AdminLogin: User %s (account %li) attempted to log into account %li, but was not logging in from an internal IP", username.c_str(), suid, conn->getRequestedAdminSuid())); + } else { + if (!isAdminAccount || adminLevel < 10) { + LOG("CustomerService", ("AdminLogin: User %s (account %li) attempted to log into account %li, but did not have sufficient permissions", username.c_str(), suid, conn->getRequestedAdminSuid())); + } else { + suid = conn->getRequestedAdminSuid(); + loginOK = true; + } + } + } - if (!loginOK) - { - conn->disconnect(); - return; - } - } + if (!loginOK) { + conn->disconnect(); + return; + } + } - // encrypt the clients credentials with the key, return - // the cipher text to the client for use as a connection - // token with the central server + // encrypt the clients credentials with the key, return + // the cipher text to the client for use as a connection + // token with the central server - //Also the sizeof(int) is likewise magic from the session api - size_t len = sizeof(uint32) + sizeof(bool) + MAX_ACCOUNT_NAME_LENGTH + 1; - unsigned char * keyBuffer = new unsigned char[len]; - unsigned char * keyBufferPointer = keyBuffer; + //Also the sizeof(int) is likewise magic from the session api + size_t len = sizeof(uint32) + sizeof(bool) + MAX_ACCOUNT_NAME_LENGTH + 1; + unsigned char *keyBuffer = new unsigned char[len]; + unsigned char *keyBufferPointer = keyBuffer; - IGNORE_RETURN(memset(keyBuffer, 0, len)); + IGNORE_RETURN(memset(keyBuffer, 0, len)); - if (ConfigLoginServer::getDoConsumption() || ConfigLoginServer::getDoSessionLogin()) - { - // pass the sessionkey - len = apiSessionIdWidth + sizeof(StationId); - memcpy(keyBufferPointer, sessionKey, apiSessionIdWidth); - keyBufferPointer += apiSessionIdWidth; + if (ConfigLoginServer::getDoConsumption() || ConfigLoginServer::getDoSessionLogin()) { + // pass the sessionkey + len = apiSessionIdWidth + sizeof(StationId); + memcpy(keyBufferPointer, sessionKey, apiSessionIdWidth); + keyBufferPointer += apiSessionIdWidth; - // if LoginServer did session login, send the session key back to the client; - // the client normally gets the session key from the LaunchPad, but in this mode - // where the LoginServer does the session login, it will get it from the LoginServer - if (ConfigLoginServer::getDoSessionLogin()) - { - std::string const strSessionKey(sessionKey, apiSessionIdWidth); - GenericValueTypeMessage const msg("SetSessionKey", strSessionKey); - conn->send(msg, true); - } - } - else - { - // If we aren't validating sessions, pack username, security status, and username to connectionserver - memcpy(keyBufferPointer, &suid, sizeof(uint32)); //lint !e64 !e119 !e534 (lint isn't resolving memcpy properly) - keyBufferPointer += sizeof(uint32); - memcpy(keyBufferPointer, &isSecure, sizeof(bool)); //lint !e64 !e119 !e534 - keyBufferPointer += sizeof(bool); - memcpy(keyBufferPointer, username.c_str(), MAX_ACCOUNT_NAME_LENGTH); //lint !e64 !e119 !e534 - } + // if LoginServer did session login, send the session key back to the client; + // the client normally gets the session key from the LaunchPad, but in this mode + // where the LoginServer does the session login, it will get it from the LoginServer + if (ConfigLoginServer::getDoSessionLogin()) { + std::string const strSessionKey(sessionKey, apiSessionIdWidth); + GenericValueTypeMessage const msg("SetSessionKey", strSessionKey); + conn->send(msg, true); + } + } else { + // If we aren't validating sessions, pack username, security status, and username to connectionserver + memcpy(keyBufferPointer, &suid, sizeof(uint32)); //lint !e64 !e119 !e534 (lint isn't resolving memcpy properly) + keyBufferPointer += sizeof(uint32); + memcpy(keyBufferPointer, &isSecure, sizeof(bool)); //lint !e64 !e119 !e534 + keyBufferPointer += sizeof(bool); + memcpy(keyBufferPointer, username.c_str(), MAX_ACCOUNT_NAME_LENGTH); //lint !e64 !e119 !e534 + } - KeyShare::Token token = LoginServer::getInstance().makeToken(keyBuffer, len); - Archive::ByteStream a; - token.pack(a); + KeyShare::Token token = LoginServer::getInstance().makeToken(keyBuffer, len); + Archive::ByteStream a; + token.pack(a); - const LoginClientToken k(a.getBuffer(), static_cast(a.getSize()), static_cast(suid), username); - conn->send(k, true); - delete[] keyBuffer; + const LoginClientToken k(a.getBuffer(), static_cast(a.getSize()), static_cast(suid), username); + conn->send(k, true); + delete[] keyBuffer; - // send cluster enum - bool clientInternal = AdminAccountManager::isInternalIp(conn->getRemoteAddress()); + // send cluster enum + bool clientInternal = AdminAccountManager::isInternalIp(conn->getRemoteAddress()); - std::vector data; + std::vector data; - for (ClusterListType::const_iterator j = m_clusterList.begin(); j != m_clusterList.end(); ++j) - { - ClusterListEntry *cle = *j; - if (cle && cle->m_clusterId != 0 && cle->m_clusterName.size() != 0 && (clientInternal || !cle->m_secret)) - { - LoginEnumCluster::ClusterData item; - item.m_clusterId = cle->m_clusterId; - item.m_clusterName = cle->m_clusterName; - item.m_timeZone = cle->m_timeZone; - data.push_back(item); - } - } + for (ClusterListType::const_iterator j = m_clusterList.begin(); j != m_clusterList.end(); ++j) { + ClusterListEntry *cle = *j; + if (cle && cle->m_clusterId != 0 && cle->m_clusterName.size() != 0 && (clientInternal || !cle->m_secret)) { + LoginEnumCluster::ClusterData item; + item.m_clusterId = cle->m_clusterId; + item.m_clusterName = cle->m_clusterName; + item.m_timeZone = cle->m_timeZone; + data.push_back(item); + } + } - LoginEnumCluster e(data, ConfigLoginServer::getMaxCharactersPerAccount()); + LoginEnumCluster e(data, ConfigLoginServer::getMaxCharactersPerAccount()); - conn->send(e, true); + conn->send(e, true); - //Send off list of cluster that has character - //creation disabled, even if the list is empty - //***MUST*** be done after sending LoginEnumCluster - GenericValueTypeMessage > const msgCharacterCreationDisabledClusterList("CharacterCreationDisabled", ConfigLoginServer::getCharacterCreationDisabledClusterList()); - conn->send(msgCharacterCreationDisabledClusterList, true); + //Send off list of cluster that has character + //creation disabled, even if the list is empty + //***MUST*** be done after sending LoginEnumCluster + GenericValueTypeMessage > const msgCharacterCreationDisabledClusterList("CharacterCreationDisabled", ConfigLoginServer::getCharacterCreationDisabledClusterList()); + conn->send(msgCharacterCreationDisabledClusterList, true); - //Send off request for the avatar list from the database. - DatabaseConnection::getInstance().requestAvatarListForAccount(suid, 0); - LOG("LoginClientConnection", ("onValidateClient() for stationId (%lu) at IP (%s), id (%s), requesting avatar list for account", suid, conn->getRemoteAddress().c_str(), username.c_str())); + //Send off request for the avatar list from the database. + DatabaseConnection::getInstance().requestAvatarListForAccount(suid, 0); + LOG("LoginClientConnection", ("onValidateClient() for stationId (%lu) at IP (%s), id (%s), requesting avatar list for account", suid, conn->getRemoteAddress().c_str(), username.c_str())); - //Set up the connection as being validated with this suid. - conn->setIsValidated(true); - conn->setStationId(suid); - conn->setIsSecure(isSecure); - conn->setAdminLevel(isAdminAccount ? adminLevel : -1); - IGNORE_RETURN(m_validatedClientMap.insert(std::pair(suid, conn))); + //Set up the connection as being validated with this suid. + conn->setIsValidated(true); + conn->setStationId(suid); + conn->setIsSecure(isSecure); + conn->setAdminLevel(isAdminAccount ? adminLevel : -1); + IGNORE_RETURN(m_validatedClientMap.insert(std::pair(suid, conn))); - //Must be done after setting various information in the connection object above - sendClusterStatus(*conn); + //Must be done after setting various information in the connection object above + sendClusterStatus(*conn); } // ---------------------------------------------------------------------- -LoginServer::ClusterListEntry *LoginServer::findClusterByName(const std::string &clusterName) -{ - ClusterListType::iterator i; - for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - NOT_NULL(*i); // not legal to push nullptr pointers on the vector - if ((*i)->m_clusterName == clusterName) - return *i; - } - return nullptr; +LoginServer::ClusterListEntry *LoginServer::findClusterByName(const std::string &clusterName) { + ClusterListType::iterator i; + for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + NOT_NULL(*i); // not legal to push nullptr pointers on the vector + if ((*i)->m_clusterName == clusterName) { + return *i; + } + } + return nullptr; } // ---------------------------------------------------------------------- -uint32 LoginServer::getClusterIDByName(const std::string &sName) -{ - ClusterListEntry const * const p_cluster = findClusterByName(sName); - return p_cluster ? p_cluster->m_clusterId : 0; +uint32 LoginServer::getClusterIDByName(const std::string &sName) { + ClusterListEntry const *const p_cluster = findClusterByName(sName); + return p_cluster ? p_cluster->m_clusterId : 0; } // ---------------------------------------------------------------------- -const std::string & LoginServer::getClusterNameById(uint32 clusterId) -{ - static std::string const empty; +const std::string &LoginServer::getClusterNameById(uint32 clusterId) { + static std::string const empty; - ClusterListEntry const * const cle = findClusterById(clusterId); - if (cle) - return cle->m_clusterName; + ClusterListEntry const *const cle = findClusterById(clusterId); + if (cle) { + return cle->m_clusterName; + } - return empty; + return empty; } // ---------------------------------------------------------------------- -LoginServer::ClusterListEntry *LoginServer::addCluster(const std::string &clusterName) -{ - DEBUG_FATAL(!ConfigLoginServer::getDevelopmentMode(), ("Programmer bug: addCluster(std::string&) can only be used in development mode.\n")); +LoginServer::ClusterListEntry *LoginServer::addCluster(const std::string &clusterName) { + DEBUG_FATAL(!ConfigLoginServer::getDevelopmentMode(), ("Programmer bug: addCluster(std::string&) can only be used in development mode.\n")); - ClusterListEntry *e = new ClusterListEntry; - e->m_clusterName = clusterName; - m_clusterList.push_back(e); - return e; + ClusterListEntry *e = new ClusterListEntry; + e->m_clusterName = clusterName; + m_clusterList.push_back(e); + return e; } // ---------------------------------------------------------------------- -void LoginServer::sendExtendedClusterInfo(ClientConnection &client) const -{ - std::vector data; +void LoginServer::sendExtendedClusterInfo(ClientConnection &client) const { + std::vector data; - for (ClusterListType::const_iterator j = m_clusterList.begin(); j != m_clusterList.end(); ++j) - { - ClusterListEntry *cle = *j; + for (ClusterListType::const_iterator j = m_clusterList.begin(); j != m_clusterList.end(); ++j) { + ClusterListEntry *cle = *j; - if (cle) - { - LoginClusterStatusEx::ClusterData item; - item.m_clusterId = cle->m_clusterId; - item.m_branch = cle->m_branch; - item.m_version = cle->m_changelist; - item.m_networkVersion = cle->m_networkVersion; - data.push_back(item); - } - } + if (cle) { + LoginClusterStatusEx::ClusterData item; + item.m_clusterId = cle->m_clusterId; + item.m_branch = cle->m_branch; + item.m_version = cle->m_changelist; + item.m_networkVersion = cle->m_networkVersion; + data.push_back(item); + } + } - client.send(LoginClusterStatusEx(data), true); + client.send(LoginClusterStatusEx(data), true); } // ---------------------------------------------------------------------- @@ -1571,116 +1412,110 @@ void LoginServer::sendExtendedClusterInfo(ClientConnection &client) const * @todo We'd like to resend this to all clients whenever the status * of any servers changes */ -void LoginServer::sendClusterStatus(ClientConnection &conn) const -{ - const bool clientIsPrivate = AdminAccountManager::isInternalIp(conn.getRemoteAddress()); - const unsigned int subscriptionBits = conn.getSubscriptionBits(); - const bool isFreeTrialAccount = (((subscriptionBits & ClientSubscriptionFeature::FreeTrial) != 0) - && ((subscriptionBits & ClientSubscriptionFeature::Base) == 0)); +void LoginServer::sendClusterStatus(ClientConnection &conn) const { + const bool clientIsPrivate = AdminAccountManager::isInternalIp(conn.getRemoteAddress()); + const unsigned int subscriptionBits = conn.getSubscriptionBits(); + const bool isFreeTrialAccount = (((subscriptionBits & ClientSubscriptionFeature::FreeTrial) != 0) && + ((subscriptionBits & ClientSubscriptionFeature::Base) == 0)); - std::vector data; - std::vector dataEx; + std::vector data; + std::vector dataEx; - for (ClusterListType::const_iterator j = m_clusterList.begin(); j != m_clusterList.end(); ++j) - { - ClusterListEntry *cle = *j; - // Cluster is OK for login if - // 1) We're connected to Central - // 2) We know the cluster Id - // 3) We have at least one Connection Server - // 4) Client is internal or the cluster is not secret - // 5) Cluster has told us its ready for players - if (cle && cle->m_clusterId != 0 && cle->m_connected && !cle->m_connectionServers.empty() && (clientIsPrivate || !cle->m_secret)) - { - DEBUG_FATAL(!cle->m_centralServerConnection, ("Programmer bug: m_connected was true but m_centralServerConnection was nullptr\n")); - LoginClusterStatus::ClusterData item; - item.m_clusterId = cle->m_clusterId; - item.m_timeZone = cle->m_timeZone; + for (ClusterListType::const_iterator j = m_clusterList.begin(); j != m_clusterList.end(); ++j) { + ClusterListEntry *cle = *j; + // Cluster is OK for login if + // 1) We're connected to Central + // 2) We know the cluster Id + // 3) We have at least one Connection Server + // 4) Client is internal or the cluster is not secret + // 5) Cluster has told us its ready for players + if (cle && cle->m_clusterId != 0 && cle->m_connected && !cle->m_connectionServers.empty() && + (clientIsPrivate || !cle->m_secret)) { + DEBUG_FATAL(!cle->m_centralServerConnection, ("Programmer bug: m_connected was true but m_centralServerConnection was nullptr\n")); + LoginClusterStatus::ClusterData item; + item.m_clusterId = cle->m_clusterId; + item.m_timeZone = cle->m_timeZone; - // size_t connectionServerChoice = Random::random(cle->m_connectionServers.size() - 1); //lint !e713 !e732 // loss of precision (arg no 1) - ConnectionServerEntry &connServer = cle->m_connectionServers[0]; + // size_t connectionServerChoice = Random::random(cle->m_connectionServers.size() - 1); //lint !e713 !e732 // loss of precision (arg no 1) + ConnectionServerEntry &connServer = cle->m_connectionServers[0]; - item.m_connectionServerAddress = connServer.clientServiceAddress; - if (clientIsPrivate) - { - item.m_connectionServerPort = connServer.clientServicePortPrivate; - } - else - { - item.m_connectionServerPort = connServer.clientServicePortPublic; - } - if (item.m_connectionServerPort) - { - item.m_connectionServerPingPort = connServer.pingPort; + item.m_connectionServerAddress = connServer.clientServiceAddress; + if (clientIsPrivate) { + item.m_connectionServerPort = connServer.clientServicePortPrivate; + } else { + item.m_connectionServerPort = connServer.clientServicePortPublic; + } + if (item.m_connectionServerPort) { + item.m_connectionServerPingPort = connServer.pingPort; - // for security/confidential information issue, only report - // population count to secured internal connections with - // admin privilege >= 10 - if (clientIsPrivate && conn.getIsSecure() && (conn.getAdminLevel() >= 10)) - item.m_populationOnline = cle->m_numPlayers; - else - item.m_populationOnline = -1; + // for security/confidential information issue, only report + // population count to secured internal connections with + // admin privilege >= 10 + if (clientIsPrivate && conn.getIsSecure() && (conn.getAdminLevel() >= 10)) { + item.m_populationOnline = cle->m_numPlayers; + } else { + item.m_populationOnline = -1; + } - const int percentFull = cle->m_numPlayers * 100 / cle->m_onlinePlayerLimit; - if (percentFull >= 100) - item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_full; - else if (percentFull >= ConfigLoginServer::getPopulationExtremelyHeavyThresholdPercent()) - item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_extremely_heavy; - else if (percentFull >= ConfigLoginServer::getPopulationVeryHeavyThresholdPercent()) - item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_very_heavy; - else if (percentFull >= ConfigLoginServer::getPopulationHeavyThresholdPercent()) - item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_heavy; - else if (percentFull >= ConfigLoginServer::getPopulationMediumThresholdPercent()) - item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_medium; - else if (percentFull >= ConfigLoginServer::getPopulationLightThresholdPercent()) - item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_light; - else - item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_very_light; + const int percentFull = cle->m_numPlayers * 100 / cle->m_onlinePlayerLimit; + if (percentFull >= 100) { + item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_full; + } else if (percentFull >= ConfigLoginServer::getPopulationExtremelyHeavyThresholdPercent()) { + item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_extremely_heavy; + } else if (percentFull >= ConfigLoginServer::getPopulationVeryHeavyThresholdPercent()) { + item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_very_heavy; + } else if (percentFull >= ConfigLoginServer::getPopulationHeavyThresholdPercent()) { + item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_heavy; + } else if (percentFull >= ConfigLoginServer::getPopulationMediumThresholdPercent()) { + item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_medium; + } else if (percentFull >= ConfigLoginServer::getPopulationLightThresholdPercent()) { + item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_light; + } else { + item.m_populationOnlineStatus = LoginClusterStatus::ClusterData::PS_very_light; + } - item.m_maxCharactersPerAccount = cle->m_maxCharactersPerAccount; - if (cle->m_readyForPlayers) - { - item.m_status = LoginClusterStatus::ClusterData::S_up; - if (cle->m_numTutorialPlayers >= cle->m_onlineTutorialLimit) - item.m_status = LoginClusterStatus::ClusterData::S_restricted; - if (isFreeTrialAccount && !cle->m_freeTrialCanCreateChar) - { - item.m_status = LoginClusterStatus::ClusterData::S_restricted; - } - if ((cle->m_numPlayers >= cle->m_onlinePlayerLimit) - || (isFreeTrialAccount && (cle->m_numFreeTrialPlayers >= cle->m_onlineFreeTrialLimit))) - { - item.m_status = LoginClusterStatus::ClusterData::S_full; - } - } - else - item.m_status = LoginClusterStatus::ClusterData::S_loading; - if (cle->m_locked && !clientIsPrivate) - item.m_status = LoginClusterStatus::ClusterData::S_locked; // locked takes precedence over up or loading + item.m_maxCharactersPerAccount = cle->m_maxCharactersPerAccount; + if (cle->m_readyForPlayers) { + item.m_status = LoginClusterStatus::ClusterData::S_up; + if (cle->m_numTutorialPlayers >= cle->m_onlineTutorialLimit) { + item.m_status = LoginClusterStatus::ClusterData::S_restricted; + } + if (isFreeTrialAccount && !cle->m_freeTrialCanCreateChar) { + item.m_status = LoginClusterStatus::ClusterData::S_restricted; + } + if ((cle->m_numPlayers >= cle->m_onlinePlayerLimit) || + (isFreeTrialAccount && (cle->m_numFreeTrialPlayers >= cle->m_onlineFreeTrialLimit))) { + item.m_status = LoginClusterStatus::ClusterData::S_full; + } + } else { + item.m_status = LoginClusterStatus::ClusterData::S_loading; + } + if (cle->m_locked && !clientIsPrivate) { + item.m_status = LoginClusterStatus::ClusterData::S_locked; + } // locked takes precedence over up or loading - item.m_dontRecommend = (cle->m_notRecommendedDatabase || cle->m_notRecommendedCentral); - item.m_onlinePlayerLimit = cle->m_onlinePlayerLimit; - item.m_onlineFreeTrialLimit = cle->m_onlineFreeTrialLimit; + item.m_dontRecommend = (cle->m_notRecommendedDatabase || cle->m_notRecommendedCentral); + item.m_onlinePlayerLimit = cle->m_onlinePlayerLimit; + item.m_onlineFreeTrialLimit = cle->m_onlineFreeTrialLimit; - data.push_back(item); - } + data.push_back(item); + } - ++connServer.numClients; - std::sort(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), ConnectionServerEntryLessThan()); - } + ++connServer.numClients; + std::sort(cle->m_connectionServers.begin(), cle->m_connectionServers.end(), ConnectionServerEntryLessThan()); + } - if (cle) - { - LoginClusterStatusEx::ClusterData itemEx; - itemEx.m_clusterId = cle->m_clusterId; - itemEx.m_branch = cle->m_branch; - itemEx.m_version = cle->m_changelist; - dataEx.push_back(itemEx); - } - } + if (cle) { + LoginClusterStatusEx::ClusterData itemEx; + itemEx.m_clusterId = cle->m_clusterId; + itemEx.m_branch = cle->m_branch; + itemEx.m_version = cle->m_changelist; + dataEx.push_back(itemEx); + } + } - LoginClusterStatus msg(data); - conn.send(msg, true); + LoginClusterStatus msg(data); + conn.send(msg, true); } // ---------------------------------------------------------------------- @@ -1688,43 +1523,25 @@ void LoginServer::sendClusterStatus(ClientConnection &conn) const /** * Send the list of active clusters to all connected clients. */ -void LoginServer::sendClusterStatusToAll() const -{ - for (std::map::const_iterator i = m_validatedClientMap.begin(); i != m_validatedClientMap.end(); ++i) - { - if (i->second) - sendClusterStatus(*(i->second)); - } +void LoginServer::sendClusterStatusToAll() const { + for (std::map::const_iterator i = m_validatedClientMap.begin(); + i != m_validatedClientMap.end(); ++i) { + if (i->second) { + sendClusterStatus(*(i->second)); + } + } } // ---------------------------------------------------------------------- -LoginServer::ClusterListEntry::ClusterListEntry() : - m_clusterId(0), - m_clusterName(), - m_centralServerConnection(0), - m_connectionServers(), - m_numPlayers(0), - m_numFreeTrialPlayers(0), - m_numTutorialPlayers(0), - m_maxCharacters(ConfigLoginServer::getMaxCharactersPerCluster()), - m_maxCharactersPerAccount(0), - m_onlinePlayerLimit(0), - m_onlineFreeTrialLimit(0), - m_onlineTutorialLimit(0), - m_freeTrialCanCreateChar(false), - m_timeZone(0), - m_connected(false), - m_address(""), - m_port(0), - m_allowReconnect(true), - m_secret(false), - m_readyForPlayers(false), - m_locked(false), - m_notRecommendedDatabase(false), - m_notRecommendedCentral(false), - m_changelist(0) -{ +LoginServer::ClusterListEntry::ClusterListEntry() + : m_clusterId(0), m_clusterName(), m_centralServerConnection(0), m_connectionServers(), m_numPlayers(0), + m_numFreeTrialPlayers(0), m_numTutorialPlayers(0), + m_maxCharacters(ConfigLoginServer::getMaxCharactersPerCluster()), m_maxCharactersPerAccount(0), + m_onlinePlayerLimit(0), m_onlineFreeTrialLimit(0), m_onlineTutorialLimit(0), m_freeTrialCanCreateChar(false), + m_timeZone(0), m_connected(false), m_address(""), m_port(0), m_allowReconnect(true), m_secret(false), + m_readyForPlayers(false), m_locked(false), m_notRecommendedDatabase(false), m_notRecommendedCentral(false), + m_changelist(0) { } // ---------------------------------------------------------------------- @@ -1734,78 +1551,68 @@ LoginServer::ClusterListEntry::ClusterListEntry() : * has changed, disconnect and reconnect. * If we don't know about the cluster already, add it to the list. */ -void LoginServer::updateClusterData(uint32 clusterId, const std::string &clusterName, const std::string &address, const uint16 port, bool secret, bool locked, bool notRecommended, int maxCharactersPerAccount, int onlinePlayerLimit, int onlineFreeTrialLimit, bool freeTrialCanCreateChar, int onlineTutorialLimit) -{ - ClusterListEntry *cle = findClusterById(clusterId); +void +LoginServer::updateClusterData(uint32 clusterId, const std::string &clusterName, const std::string &address, const uint16 port, bool secret, bool locked, bool notRecommended, int maxCharactersPerAccount, int onlinePlayerLimit, int onlineFreeTrialLimit, bool freeTrialCanCreateChar, int onlineTutorialLimit) { + ClusterListEntry *cle = findClusterById(clusterId); - if (ConfigLoginServer::getDevelopmentMode()) - { - if (!cle) - cle = findClusterByName(clusterName); - } - else - { - if (cle) - { - // refreshing data on a cluster we already know about - if ((cle->m_clusterName != clusterName) || (cle->m_address != address) || (cle->m_port != port)) - { - DEBUG_REPORT_LOG(true, ("Disconnecting from cluster %lu because its data has changed in the database.\n", clusterId)); - disconnectCluster(*cle, true, true); - } - } - } + if (ConfigLoginServer::getDevelopmentMode()) { + if (!cle) { + cle = findClusterByName(clusterName); + } + } else { + if (cle) { + // refreshing data on a cluster we already know about + if ((cle->m_clusterName != clusterName) || (cle->m_address != address) || (cle->m_port != port)) { + DEBUG_REPORT_LOG(true, ("Disconnecting from cluster %lu because its data has changed in the database.\n", clusterId)); + disconnectCluster(*cle, true, true); + } + } + } - if (!cle) - { - DEBUG_REPORT_LOG(true, ("Cluster %lu: %s\n", clusterId, clusterName.c_str())); + if (!cle) { + DEBUG_REPORT_LOG(true, ("Cluster %lu: %s\n", clusterId, clusterName.c_str())); - cle = new ClusterListEntry; - m_clusterList.push_back(cle); - } + cle = new ClusterListEntry; + m_clusterList.push_back(cle); + } - if ((cle->m_secret != secret) - || (cle->m_locked != locked) - || (cle->m_onlinePlayerLimit != onlinePlayerLimit) - || (cle->m_onlineFreeTrialLimit != onlineFreeTrialLimit) - || (cle->m_freeTrialCanCreateChar != freeTrialCanCreateChar) - || (cle->m_onlineTutorialLimit != onlineTutorialLimit)) - { - // The cluster may now be locked/unlocked to some players, so let them know - m_clusterStatusChanged = true; - } + if ((cle->m_secret != secret) || (cle->m_locked != locked) || (cle->m_onlinePlayerLimit != onlinePlayerLimit) || + (cle->m_onlineFreeTrialLimit != onlineFreeTrialLimit) || + (cle->m_freeTrialCanCreateChar != freeTrialCanCreateChar) || + (cle->m_onlineTutorialLimit != onlineTutorialLimit)) { + // The cluster may now be locked/unlocked to some players, so let them know + m_clusterStatusChanged = true; + } - // tell the cluster if its locked or secret state changes - if (((cle->m_locked != locked) || (cle->m_secret != secret)) && cle->m_connected && cle->m_centralServerConnection) - { - GenericValueTypeMessage > const msgState("UpdateClusterLockedAndSecretState", std::make_pair(locked, secret)); - cle->m_centralServerConnection->send(msgState, true); - } + // tell the cluster if its locked or secret state changes + if (((cle->m_locked != locked) || (cle->m_secret != secret)) && cle->m_connected && + cle->m_centralServerConnection) { + GenericValueTypeMessage > const msgState("UpdateClusterLockedAndSecretState", std::make_pair(locked, secret)); + cle->m_centralServerConnection->send(msgState, true); + } - bool const clusterIdSet = ((cle->m_clusterId == 0) && (clusterId > 0)); - cle->m_clusterId = clusterId; - cle->m_clusterName = clusterName; - cle->m_address = address; - cle->m_port = port; - cle->m_secret = secret; - cle->m_locked = locked; - cle->m_notRecommendedDatabase = notRecommended; - cle->m_maxCharactersPerAccount = maxCharactersPerAccount; - cle->m_onlinePlayerLimit = onlinePlayerLimit; - cle->m_onlineFreeTrialLimit = onlineFreeTrialLimit; - cle->m_freeTrialCanCreateChar = freeTrialCanCreateChar; - cle->m_onlineTutorialLimit = onlineTutorialLimit; - if (cle->m_centralServerConnection) - { - cle->m_centralServerConnection->setClusterId(clusterId); + bool const clusterIdSet = ((cle->m_clusterId == 0) && (clusterId > 0)); + cle->m_clusterId = clusterId; + cle->m_clusterName = clusterName; + cle->m_address = address; + cle->m_port = port; + cle->m_secret = secret; + cle->m_locked = locked; + cle->m_notRecommendedDatabase = notRecommended; + cle->m_maxCharactersPerAccount = maxCharactersPerAccount; + cle->m_onlinePlayerLimit = onlinePlayerLimit; + cle->m_onlineFreeTrialLimit = onlineFreeTrialLimit; + cle->m_freeTrialCanCreateChar = freeTrialCanCreateChar; + cle->m_onlineTutorialLimit = onlineTutorialLimit; + if (cle->m_centralServerConnection) { + cle->m_centralServerConnection->setClusterId(clusterId); - // tell the cluster its cluster id - if (clusterIdSet && ConfigLoginServer::getDevelopmentMode()) - { - GenericValueTypeMessage const msgClusterId("ClusterId", cle->m_clusterId); - cle->m_centralServerConnection->send(msgClusterId, true); - } - } + // tell the cluster its cluster id + if (clusterIdSet && ConfigLoginServer::getDevelopmentMode()) { + GenericValueTypeMessage const msgClusterId("ClusterId", cle->m_clusterId); + cle->m_centralServerConnection->send(msgClusterId, true); + } + } } // ---------------------------------------------------------------------- @@ -1818,40 +1625,38 @@ void LoginServer::updateClusterData(uint32 clusterId, const std::string &cluster * @param reconnect If true, will attempt to reestablish connection to the cluster * (does not apply in development mode) */ -void LoginServer::disconnectCluster(ClusterListEntry &cle, bool const forceDisconnect, bool const reconnect) -{ - if (cle.m_centralServerConnection && forceDisconnect) - cle.m_centralServerConnection->disconnect(); +void LoginServer::disconnectCluster(ClusterListEntry &cle, bool const forceDisconnect, bool const reconnect) { + if (cle.m_centralServerConnection && forceDisconnect) { + cle.m_centralServerConnection->disconnect(); + } - cle.m_centralServerConnection = 0; //TODO: revisit after connection deletion issues are fixed - cle.m_allowReconnect = reconnect; - cle.m_connectionServers.clear(); + cle.m_centralServerConnection = 0; //TODO: revisit after connection deletion issues are fixed + cle.m_allowReconnect = reconnect; + cle.m_connectionServers.clear(); - bool statusChange = false; + bool statusChange = false; - if (cle.m_connected || cle.m_readyForPlayers) - statusChange = true; + if (cle.m_connected || cle.m_readyForPlayers) { + statusChange = true; + } - cle.m_connected = false; - cle.m_readyForPlayers = false; + cle.m_connected = false; + cle.m_readyForPlayers = false; - m_clusterStatusChanged = statusChange; + m_clusterStatusChanged = statusChange; - // for "carousel" cluster, where multiple clusters point to the same address, - // when disconnecting a "carousel" cluster, need to flag the other "carousel" - // clusters to allow reconnect so that another "carousel" cluster can be - // started, and the LoginServer will connect to it - if (!ConfigLoginServer::getDevelopmentMode() && reconnect) - { - for (ClusterListType::iterator i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - NOT_NULL(*i); - if (!(*i)->m_centralServerConnection && !(*i)->m_allowReconnect && ((*i)->m_address == cle.m_address)) - { - (*i)->m_allowReconnect = true; - } - } - } + // for "carousel" cluster, where multiple clusters point to the same address, + // when disconnecting a "carousel" cluster, need to flag the other "carousel" + // clusters to allow reconnect so that another "carousel" cluster can be + // started, and the LoginServer will connect to it + if (!ConfigLoginServer::getDevelopmentMode() && reconnect) { + for (ClusterListType::iterator i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + NOT_NULL(*i); + if (!(*i)->m_centralServerConnection && !(*i)->m_allowReconnect && ((*i)->m_address == cle.m_address)) { + (*i)->m_allowReconnect = true; + } + } + } } // ---------------------------------------------------------------------- @@ -1859,11 +1664,10 @@ void LoginServer::disconnectCluster(ClusterListEntry &cle, bool const forceDisco /** * Called after we've added a new cluster to the database. */ -void LoginServer::onClusterRegistered(uint32 clusterId, const std::string &clusterName) -{ - DEBUG_FATAL(!ConfigLoginServer::getDevelopmentMode(), ("Programmer bug: should not be registering new clusters automatically unless running in development mode.\n")); - static std::string noAddress(""); - updateClusterData(clusterId, clusterName, noAddress, 0, false, false, false, 8, 100, 100, true, 350); +void LoginServer::onClusterRegistered(uint32 clusterId, const std::string &clusterName) { + DEBUG_FATAL(!ConfigLoginServer::getDevelopmentMode(), ("Programmer bug: should not be registering new clusters automatically unless running in development mode.\n")); + static std::string noAddress(""); + updateClusterData(clusterId, clusterName, noAddress, 0, false, false, false, 8, 100, 100, true, 350); } // ---------------------------------------------------------------------- @@ -1872,17 +1676,16 @@ void LoginServer::onClusterRegistered(uint32 clusterId, const std::string &clust * Find a cluster by ID. */ -LoginServer::ClusterListEntry * LoginServer::findClusterById(uint32 clusterId) -{ - ClusterListType::const_iterator i; - for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - NOT_NULL(*i); // not legal to push nullptr pointers on the vector - if ((*i)->m_clusterId == clusterId) - return *i; - } +LoginServer::ClusterListEntry *LoginServer::findClusterById(uint32 clusterId) { + ClusterListType::const_iterator i; + for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + NOT_NULL(*i); // not legal to push nullptr pointers on the vector + if ((*i)->m_clusterId == clusterId) { + return *i; + } + } - return nullptr; + return nullptr; } // ---------------------------------------------------------------------- @@ -1891,120 +1694,113 @@ LoginServer::ClusterListEntry * LoginServer::findClusterById(uint32 clusterId) * Find a cluster list entry using the connection to Central */ -LoginServer::ClusterListEntry * LoginServer::findClusterByConnection(const CentralServerConnection *connection) -{ - ClusterListType::const_iterator i; - for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - NOT_NULL(*i); // not legal to push nullptr pointers on the vector - if ((*i)->m_centralServerConnection == connection) - return *i; - } +LoginServer::ClusterListEntry *LoginServer::findClusterByConnection(const CentralServerConnection *connection) { + ClusterListType::const_iterator i; + for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + NOT_NULL(*i); // not legal to push nullptr pointers on the vector + if ((*i)->m_centralServerConnection == connection) { + return *i; + } + } - return nullptr; + return nullptr; } // ---------------------------------------------------------------------- -void LoginServer::refreshConnections() -{ - if (ConfigLoginServer::getDevelopmentMode()) - return; // in development mode, we don't establish any connections - ClusterListType::iterator i; - for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - NOT_NULL(*i); - if (!(*i)->m_centralServerConnection && (*i)->m_allowReconnect) - { - (*i)->m_centralServerConnection = new CentralServerConnection( - (*i)->m_address, - (*i)->m_port, - (*i)->m_clusterName, - (*i)->m_clusterId); - } - } +void LoginServer::refreshConnections() { + if (ConfigLoginServer::getDevelopmentMode()) { + return; + } // in development mode, we don't establish any connections + ClusterListType::iterator i; + for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + NOT_NULL(*i); + if (!(*i)->m_centralServerConnection && (*i)->m_allowReconnect) { + (*i)->m_centralServerConnection = new CentralServerConnection((*i)->m_address, (*i)->m_port, (*i)->m_clusterName, (*i)->m_clusterId); + } + } } // ---------------------------------------------------------------------- -void LoginServer::sendToCluster(uint32 clusterId, const GameNetworkMessage &message) -{ - ClusterListEntry *cle = findClusterById(clusterId); - if (cle && cle->m_connected && cle->m_centralServerConnection) - cle->m_centralServerConnection->send(message, true); - else - DEBUG_REPORT_LOG(true, ("Could not send message to cluster %lu because it was not connected.\n", clusterId)); +void LoginServer::sendToCluster(uint32 clusterId, const GameNetworkMessage &message) { + ClusterListEntry *cle = findClusterById(clusterId); + if (cle && cle->m_connected && cle->m_centralServerConnection) { + cle->m_centralServerConnection->send(message, true); + } else { + DEBUG_REPORT_LOG(true, ("Could not send message to cluster %lu because it was not connected.\n", clusterId)); + } } //----------------------------------------------------------------------- -void LoginServer::setDone(const bool isDone) -{ - done = isDone; +void LoginServer::setDone(const bool isDone) { + done = isDone; } // ---------------------------------------------------------------------- -void LoginServer::sendToAllClusters(GameNetworkMessage const & message, Connection const * excludeCentralConnection /*= nullptr*/, uint32 excludeClusterId /*= 0*/, char const * excludeClusterName /*= nullptr*/) -{ - ClusterListType::const_iterator i; - for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - if (NON_NULL(*i)->m_connected && (*i)->m_centralServerConnection && ((*i)->m_centralServerConnection != excludeCentralConnection) && ((*i)->m_clusterId != excludeClusterId) && ((excludeClusterName == nullptr) || _stricmp(excludeClusterName, (*i)->m_centralServerConnection->getClusterName().c_str()))) - (*i)->m_centralServerConnection->send(message, true); - } +void +LoginServer::sendToAllClusters(GameNetworkMessage const &message, Connection const *excludeCentralConnection /*= nullptr*/, uint32 excludeClusterId /*= 0*/, char const *excludeClusterName /*= nullptr*/) { + ClusterListType::const_iterator i; + for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + if (NON_NULL(*i)->m_connected && (*i)->m_centralServerConnection && + ((*i)->m_centralServerConnection != excludeCentralConnection) && ((*i)->m_clusterId != excludeClusterId) && + ((excludeClusterName == nullptr) || + _stricmp(excludeClusterName, (*i)->m_centralServerConnection->getClusterName().c_str()))) { + (*i)->m_centralServerConnection->send(message, true); + } + } } // ---------------------------------------------------------------------- -bool LoginServer::areAllClustersUp() const -{ - if (m_clusterList.empty()) - return false; +bool LoginServer::areAllClustersUp() const { + if (m_clusterList.empty()) { + return false; + } - ClusterListType::const_iterator i; - for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - if (!(NON_NULL(*i)->m_readyForPlayers)) - return false; - } - return true; + ClusterListType::const_iterator i; + for (i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + if (!(NON_NULL(*i)->m_readyForPlayers)) { + return false; + } + } + return true; } // ---------------------------------------------------------------------- -void LoginServer::getAllClusterNamesAndIDs(std::map< std::string, uint32 > &results) const -{ - results.clear(); - for (ClusterListType::const_iterator i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - { - if (!*i) - continue; - results[(*i)->m_clusterName] = (*i)->m_clusterId; - } +void LoginServer::getAllClusterNamesAndIDs(std::map &results) const { + results.clear(); + for (ClusterListType::const_iterator i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + if (!*i) { + continue; + } + results[(*i)->m_clusterName] = (*i)->m_clusterId; + } } // ---------------------------------------------------------------------- -void LoginServer::getClusterIds(std::vector result) -{ - result.reserve(m_clusterList.size()); - for (ClusterListType::const_iterator i = m_clusterList.begin(); i != m_clusterList.end(); ++i) - result.push_back(NON_NULL(*i)->m_clusterId); +void LoginServer::getClusterIds(std::vector result) { + result.reserve(m_clusterList.size()); + for (ClusterListType::const_iterator i = m_clusterList.begin(); i != m_clusterList.end(); ++i) { + result.push_back(NON_NULL(*i)->m_clusterId); + } } // ---------------------------------------------------------------------- -void LoginServer::setClusterInfoByName(const std::string &name, const std::string &branch, int changelist, const std::string &networkVersion) -{ - ClusterListEntry *entry = findClusterByName(name); +void +LoginServer::setClusterInfoByName(const std::string &name, const std::string &branch, int changelist, const std::string &networkVersion) { + ClusterListEntry *entry = findClusterByName(name); - if (entry) - { - entry->m_branch = branch; - entry->m_changelist = changelist; - entry->m_networkVersion = networkVersion; - } + if (entry) { + entry->m_branch = branch; + entry->m_changelist = changelist; + entry->m_networkVersion = networkVersion; + } } // ======================================================================