diff --git a/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserServer.cpp b/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserServer.cpp index 6fe053e7..0e2e490f 100755 --- a/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserServer.cpp +++ b/engine/server/library/serverGame/src/shared/console/ConsoleCommandParserServer.cpp @@ -73,6 +73,8 @@ #include "sharedUtility/DataTableManager.h" #include "serverUtility/FreeCtsDataTable.h" +#include "sharedFoundation/CrcConstexpr.hpp" + #include // ====================================================================== diff --git a/engine/server/library/serverGame/src/shared/core/GameServer.cpp b/engine/server/library/serverGame/src/shared/core/GameServer.cpp index 3e14c6a7..f92159bd 100755 --- a/engine/server/library/serverGame/src/shared/core/GameServer.cpp +++ b/engine/server/library/serverGame/src/shared/core/GameServer.cpp @@ -897,1175 +897,1215 @@ void GameServer::receiveMessage(const MessageDispatch::Emitter & source, const M ServerConnection * const serverConnection = const_cast(dynamic_cast(&source)); - if(message.isType("CentralConnectionOpened")) - { - MESSAGE_PROFILER_BLOCK("CentralConnectionOpened"); - if (!m_centralServerConnection) - m_centralServerConnection = const_cast(static_cast(&source)); - } - else if (message.isType("CustomerServiceServerGameServerServiceAddress")) - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const address(ri); + const uint32 messageType = message.getType(); - DEBUG_REPORT_LOG(true, ("GameServer: Creating customer service server connection @ (%s:%d)\n", address.getValue().first.c_str(), address.getValue().second)); - - if (m_customerServiceServerConnection != nullptr) - { - m_customerServiceServerConnection->disconnect(); + select (messageType) + { + case constcrc("CentralConnectionOpened") : { + MESSAGE_PROFILER_BLOCK("CentralConnectionOpened"); + if (!m_centralServerConnection) + m_centralServerConnection = const_cast(static_cast(&source)); + break; } + case constcrc("CustomerServiceServerGameServerServiceAddress"): { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const address(ri); - m_customerServiceServerConnection = new CustomerServiceServerConnection(address.getValue().first, address.getValue().second); - } - else if(message.isType("BaselinesMessage")) - { - MESSAGE_PROFILER_BLOCK("BaselinesMessage"); - ri = static_cast(message).getByteStream().begin(); - BaselinesMessage const m(ri); - ServerObject *so = ServerWorld::findUninitializedObjectByNetworkId(m.getTarget()); - if (so) - { - so->applyBaselines(m); + DEBUG_REPORT_LOG(true, ("GameServer: Creating customer service server connection @ (%s:%d)\n", address + .getValue().first.c_str(), address.getValue().second)); + + if (m_customerServiceServerConnection != nullptr) { + m_customerServiceServerConnection->disconnect(); + } + + m_customerServiceServerConnection = new CustomerServiceServerConnection(address.getValue().first, address + .getValue().second); + break; } - else - { - // find any object - so = safe_cast(NetworkIdManager::getObjectById(m.getTarget())); - if (so) - { - DEBUG_WARNING(true, ("Applied baselines on object %s which is already initialized.", m.getTarget().getValueString().c_str())); + case constcrc("BaselinesMessage") : { + MESSAGE_PROFILER_BLOCK("BaselinesMessage"); + ri = static_cast(message).getByteStream().begin(); + BaselinesMessage const m(ri); + ServerObject *so = ServerWorld::findUninitializedObjectByNetworkId(m.getTarget()); + if (so) { so->applyBaselines(m); } - else - { - DEBUG_WARNING(true, ("Got baselines on object %s which could not be found.", m.getTarget().getValueString().c_str())); - } - } - } - else if(message.isType("BatchBaselinesMessage")) - { - MESSAGE_PROFILER_BLOCK("BaselinesMessage"); - ri = static_cast(message).getByteStream().begin(); - BatchBaselinesMessage const m(ri); - - std::vector const & baselines = m.getData(); - - ServerObject * lastObject = nullptr; - - for (std::vector::const_iterator i=baselines.begin(); i!=baselines.end(); ++i) - { - // There's a good chance the baselines for an object will come together, so remember the previous object - // and don't look it up again if the network id hasn't changed. - if (!lastObject || lastObject->getNetworkId() != i->m_networkId) - { - lastObject = ServerWorld::findUninitializedObjectByNetworkId(i->m_networkId); - - if (!lastObject) - { - lastObject = safe_cast(NetworkIdManager::getObjectById(i->m_networkId)); - if (lastObject) - { - WARNING(true, ("Applied baselines on object %s which is already initialized.", i->m_networkId.getValueString().c_str())); - - } - else - { - WARNING(true, ("Got baselines on object %s which could not be found.", i->m_networkId.getValueString().c_str())); - } + else { + // find any object + so = safe_cast(NetworkIdManager::getObjectById(m.getTarget())); + if (so) { + DEBUG_WARNING(true, ("Applied baselines on object %s which is already initialized.", m.getTarget() + .getValueString() + .c_str())); + so->applyBaselines(m); + } + else { + DEBUG_WARNING(true, ("Got baselines on object %s which could not be found.", m.getTarget() + .getValueString() + .c_str())); } } - if (lastObject) - { - lastObject->applyBaselines(i->m_packageId, i->m_package); + break; + } + case constcrc("BatchBaselinesMessage") : { + MESSAGE_PROFILER_BLOCK("BaselinesMessage"); + ri = static_cast(message).getByteStream().begin(); + BatchBaselinesMessage const m(ri); + + std::vector const &baselines = m.getData(); + + ServerObject *lastObject = nullptr; + + for (std::vector::const_iterator i = baselines.begin(); + i != baselines.end(); ++i) { + // There's a good chance the baselines for an object will come together, so remember the previous object + // and don't look it up again if the network id hasn't changed. + if (!lastObject || lastObject->getNetworkId() != i->m_networkId) { + lastObject = ServerWorld::findUninitializedObjectByNetworkId(i->m_networkId); + + if (!lastObject) { + lastObject = safe_cast(NetworkIdManager::getObjectById(i->m_networkId)); + if (lastObject) { + WARNING(true, ("Applied baselines on object %s which is already initialized.", i + ->m_networkId.getValueString().c_str())); + + } + else { + WARNING(true, ("Got baselines on object %s which could not be found.", i->m_networkId + .getValueString() + .c_str())); + } + } + } + if (lastObject) { + lastObject->applyBaselines(i->m_packageId, i->m_package); + } } + break; + } + case constcrc("DeltasMessage") : { + MESSAGE_PROFILER_BLOCK("DeltasMessage"); + ri = static_cast(message).getByteStream().begin(); + DeltasMessage const m(ri); + ServerObject *const so = safe_cast(NetworkIdManager::getObjectById(m.getTarget())); + if (so) + so->applyDeltas(m); + else + DEBUG_WARNING(true, ("Got DeltasMessage on object %s, which could not be found.", m.getTarget() + .getValueString() + .c_str())); + break; } - } - else if(message.isType("DeltasMessage")) - { - MESSAGE_PROFILER_BLOCK("DeltasMessage"); - ri = static_cast(message).getByteStream().begin(); - DeltasMessage const m(ri); - ServerObject * const so = safe_cast(NetworkIdManager::getObjectById(m.getTarget())); - if (so) - so->applyDeltas(m); - else - DEBUG_WARNING(true, ("Got DeltasMessage on object %s, which could not be found.", m.getTarget().getValueString().c_str())); - } - else if(message.isType("ChunkCompleteMessage")) - { - MESSAGE_PROFILER_BLOCK("ChunkCompleteMessage"); - ri = static_cast(message).getByteStream().begin(); - ChunkCompleteMessage const m(ri); - GameServer::getInstance().sendToPlanetServer(m); + case constcrc("ChunkCompleteMessage") : { + MESSAGE_PROFILER_BLOCK("ChunkCompleteMessage"); + ri = static_cast(message).getByteStream().begin(); + ChunkCompleteMessage const m(ri); + GameServer::getInstance().sendToPlanetServer(m); - std::vector > const & chunks = m.getChunks(); - for (std::vector >::const_iterator i=chunks.begin(); i!=chunks.end(); ++i) + std::vector > const &chunks = m.getChunks(); + for (std::vector < std::pair < int, int > > ::const_iterator i = chunks.begin(); i != chunks.end(); + ++i) ServerBuildoutManager::onChunkComplete(i->first, i->second); - } - - else if(message.isType("CentralConnectionClosed")) - { - MESSAGE_PROFILER_BLOCK("CentralConnectionClosed"); - // @ todo : shutdown gracefully - DEBUG_REPORT_LOG(true, ("The connection to the central server has been closed\n")); - setDone("CentralConnectionClosed : %s", serverConnection->getDisconnectReason().c_str()); - m_centralServerConnection = 0; - } - else if(message.isType("TaskConnectionOpened")) - { - MESSAGE_PROFILER_BLOCK("TaskConnectionOpened"); - DEBUG_REPORT_LOG(true, ("The connection with the task manager has been established\n")); - } - else if(message.isType("TaskConnectionClosed")) - { - MESSAGE_PROFILER_BLOCK("TaskConnectionClosed"); - DEBUG_REPORT_LOG(true, ("The connection to the task manager has closed\n")); - m_taskManagerConnection = 0; - } - else if (message.isType("AddGameServer")) - { - MESSAGE_PROFILER_BLOCK("AddGameServer"); - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const addGameServerMessage(ri); - - uint32 const pid = addGameServerMessage.getValue(); - - DEBUG_REPORT_LOG(true, ("Received AddGameServer for server %lu.\n", pid)); - - FATAL(std::find(m_gameServerPids.begin(), m_gameServerPids.end(), pid) != m_gameServerPids.end(), ("Got AddGameServer for server %lu which we thought was already running?", pid)); - - m_gameServerPids.push_back(pid); - std::sort(m_gameServerPids.begin(), m_gameServerPids.end()); - } - else if (message.isType("ExcommunicateGameServerMessage")) - { - MESSAGE_PROFILER_BLOCK("ExcommunicateGameServerMessage"); - ri = static_cast(message).getByteStream().begin(); - ExcommunicateGameServerMessage msg(ri); - - uint32 const pid = msg.getServerId(); - - DEBUG_REPORT_LOG(true, ("Received ExcommunicateGameServer for server %lu.\n", pid)); - LOG("GameGameConnect", ("Server %lu was told that server %lu has gone away by Central", getProcessId(), pid)); - - FATAL(pid == getProcessId(), ("Crashing because Central told us to (probably indicates we weren't responding to pings)")); - - std::vector::iterator i = std::find(m_gameServerPids.begin(), m_gameServerPids.end(), pid); - if (i != m_gameServerPids.end()) - { - m_gameServerPids.erase(i); - - MessageToQueue::getInstance().onGameServerDisconnect(pid); - ServerUniverse::getInstance().onServerConnectionClosed(pid); - AuthTransferTracker::handleGameServerDisconnect(pid); - } - } - else if(message.isType("CommoditiesServerConnectionClosed")) - { - DEBUG_REPORT_LOG(true, ("CommoditiesServer connection closed\n")); - CommoditiesMarket::closeCommoditiesServerConnection(); - } - else if (message.isType("ConnectionServerAddress")) - { - MESSAGE_PROFILER_BLOCK("ConnectionServerAddress"); - // Central is telling us about a new connection server. - ri = static_cast(message).getByteStream().begin(); - ConnectionServerAddress const msg(ri); - ConnectionServerConnection * const newConn = new ConnectionServerConnection(msg.getGameServiceAddress(), msg.getGameServicePort()); - m_connectionServerVector->push_back(newConn); - } - else if (message.isType("ConnectionServerConnectionClosed") || message.isType("ConnectionServerConnectionDestroyed")) - { - MESSAGE_PROFILER_BLOCK("ConnectionServerConnectionClosed"); - ConnectionServerConnection const * const c = dynamic_cast(&source); - ConnectionServerVector::iterator i = std::find(m_connectionServerVector->begin(), m_connectionServerVector->end(), c); - if (i != m_connectionServerVector->end()) - { - m_connectionServerVector->erase(i); - } - } - else if(message.isType("NewClient")) - { - MESSAGE_PROFILER_BLOCK("NewClient"); - static std::string const loginTrace("TRACE_LOGIN"); - ri = static_cast(message).getByteStream().begin(); - NewClient const msg(ri); - LOG(loginTrace, ("NewClient(%s)", msg.getNetworkId().getValueString().c_str())); - - //@todo make sure this holds up with non players (like vehicles) - //because right not, we construct a new client object for EACH object - //even ones that could be controlled by the same client. - //Also is it possible to receive this message for an object we already control? - - if (m_clients->find(msg.getNetworkId()) != m_clients->end()) - { - // inconsistant state, drop the client - LOG(loginTrace, ("NewClient(%s) : Error! Getting a NewClient message for a client that already exists", msg.getNetworkId().getValueString().c_str())); - - KickPlayer const kickMessage(msg.getNetworkId(), "Duplicate Client"); - sendToConnectionServers(kickMessage); - dropClient(msg.getNetworkId()); - return; + break; } - // don't allow login if the character is in the middle of CTS or has been successfully CTS(ed) - ServerObject * const obj = ServerWorld::findObjectByNetworkId(msg.getNetworkId()); - if (obj) - { - bool kickRequested = false; + case constcrc("CentralConnectionClosed") : { + MESSAGE_PROFILER_BLOCK("CentralConnectionClosed"); + // @ todo : shutdown gracefully + DEBUG_REPORT_LOG(true, ("The connection to the central server has been closed\n")); + setDone("CentralConnectionClosed : %s", serverConnection->getDisconnectReason().c_str()); + m_centralServerConnection = 0; + break; + } + case constcrc("TaskConnectionOpened") : { + MESSAGE_PROFILER_BLOCK("TaskConnectionOpened"); + DEBUG_REPORT_LOG(true, ("The connection with the task manager has been established\n")); + break; + } + case constcrc("TaskConnectionClosed") : { + MESSAGE_PROFILER_BLOCK("TaskConnectionClosed"); + DEBUG_REPORT_LOG(true, ("The connection to the task manager has closed\n")); + m_taskManagerConnection = 0; + break; + } + case constcrc("AddGameServer") : { + MESSAGE_PROFILER_BLOCK("AddGameServer"); + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const addGameServerMessage(ri); - DynamicVariableList const & objVars = obj->getObjVars(); - int timeOut; - if (objVars.getItem("disableLoginCtsInProgress", timeOut)) - { - if (timeOut > static_cast(ServerClock::getInstance().getGameTimeSeconds())) - { - MessageToQueue::getInstance().sendMessageToC(obj->getNetworkId(), "C++kickPlayerCtsCompletedOrInProgress", "", 0, false); + uint32 const pid = addGameServerMessage.getValue(); + + DEBUG_REPORT_LOG(true, ("Received AddGameServer for server %lu.\n", pid)); + + FATAL(std::find(m_gameServerPids.begin(), m_gameServerPids.end(), pid) != m_gameServerPids + .end(), ("Got AddGameServer for server %lu which we thought was already running?", pid)); + + m_gameServerPids.push_back(pid); + std::sort(m_gameServerPids.begin(), m_gameServerPids.end()); + break; + } + case constcrc("ExcommunicateGameServerMessage") : { + MESSAGE_PROFILER_BLOCK("ExcommunicateGameServerMessage"); + ri = static_cast(message).getByteStream().begin(); + ExcommunicateGameServerMessage msg(ri); + + uint32 const pid = msg.getServerId(); + + DEBUG_REPORT_LOG(true, ("Received ExcommunicateGameServer for server %lu.\n", pid)); + LOG("GameGameConnect", ("Server %lu was told that server %lu has gone away by Central", getProcessId(), pid)); + + FATAL(pid == + getProcessId(), ("Crashing because Central told us to (probably indicates we weren't responding to pings)")); + + std::vector::iterator i = std::find(m_gameServerPids.begin(), m_gameServerPids.end(), pid); + if (i != m_gameServerPids.end()) { + m_gameServerPids.erase(i); + + MessageToQueue::getInstance().onGameServerDisconnect(pid); + ServerUniverse::getInstance().onServerConnectionClosed(pid); + AuthTransferTracker::handleGameServerDisconnect(pid); + } + break; + } + case constcrc("CommoditiesServerConnectionClosed") : { + DEBUG_REPORT_LOG(true, ("CommoditiesServer connection closed\n")); + CommoditiesMarket::closeCommoditiesServerConnection(); + break; + } + case constcrc("ConnectionServerAddress") : { + MESSAGE_PROFILER_BLOCK("ConnectionServerAddress"); + // Central is telling us about a new connection server. + ri = static_cast(message).getByteStream().begin(); + ConnectionServerAddress const msg(ri); + ConnectionServerConnection *const newConn = new ConnectionServerConnection(msg.getGameServiceAddress(), msg + .getGameServicePort()); + m_connectionServerVector->push_back(newConn); + break; + } + case constcrc("ConnectionServerConnectionClosed"): + case constcrc("ConnectionServerConnectionDestroyed") : { + MESSAGE_PROFILER_BLOCK("ConnectionServerConnectionClosed"); + ConnectionServerConnection const *const c = dynamic_cast(&source); + ConnectionServerVector::iterator i = std::find(m_connectionServerVector->begin(), m_connectionServerVector + ->end(), c); + if (i != m_connectionServerVector->end()) { + m_connectionServerVector->erase(i); + } + break; + } + case constcrc("NewClient") : { + MESSAGE_PROFILER_BLOCK("NewClient"); + static std::string const loginTrace("TRACE_LOGIN"); + ri = static_cast(message).getByteStream().begin(); + NewClient const msg(ri); + LOG(loginTrace, ("NewClient(%s)", msg.getNetworkId().getValueString().c_str())); + + //@todo make sure this holds up with non players (like vehicles) + //because right not, we construct a new client object for EACH object + //even ones that could be controlled by the same client. + //Also is it possible to receive this message for an object we already control? + + if (m_clients->find(msg.getNetworkId()) != m_clients->end()) { + // inconsistant state, drop the client + LOG(loginTrace, ("NewClient(%s) : Error! Getting a NewClient message for a client that already exists", msg + .getNetworkId().getValueString().c_str())); + + KickPlayer const kickMessage(msg.getNetworkId(), "Duplicate Client"); + sendToConnectionServers(kickMessage); + dropClient(msg.getNetworkId()); + return; + } + + // don't allow login if the character is in the middle of CTS or has been successfully CTS(ed) + ServerObject *const obj = ServerWorld::findObjectByNetworkId(msg.getNetworkId()); + if (obj) { + bool kickRequested = false; + + DynamicVariableList const &objVars = obj->getObjVars(); + int timeOut; + if (objVars.getItem("disableLoginCtsInProgress", timeOut)) { + if (timeOut > static_cast(ServerClock::getInstance().getGameTimeSeconds())) { + MessageToQueue::getInstance().sendMessageToC(obj + ->getNetworkId(), "C++kickPlayerCtsCompletedOrInProgress", "", 0, false); + kickRequested = true; + } + else { + obj->removeObjVarItem("disableLoginCtsInProgress"); + } + } + + int transferredTime; + if (!kickRequested && objVars.getItem("disableLoginCtsCompleted", transferredTime) && + !msg.getUsingAdminLogin()) { + MessageToQueue::getInstance() + .sendMessageToC(obj->getNetworkId(), "C++kickPlayerCtsCompletedOrInProgress", "", 0, false); kickRequested = true; } - else - { - obj->removeObjVarItem("disableLoginCtsInProgress"); - } } - int transferredTime; - if (!kickRequested && objVars.getItem("disableLoginCtsCompleted", transferredTime) && !msg.getUsingAdminLogin()) - { - MessageToQueue::getInstance().sendMessageToC(obj->getNetworkId(), "C++kickPlayerCtsCompletedOrInProgress", "", 0, false); - kickRequested = true; + LOG(loginTrace, ("NewClient(%s) : A new client is being created from connection server", msg.getNetworkId() + .getValueString() + .c_str())); + std::set const observedObjectSet(msg.getObservedObjects().begin(), msg.getObservedObjects() + .end()); + Client *const c = new Client( + const_cast(static_cast(source)), + msg.getNetworkId(), + msg.getAccountName(), + msg.getIpAddress(), + msg.getIsSecure(), + msg.getIsSkipLoadScreen(), + msg.getStationId(), + observedObjectSet, + msg.getGameFeatures(), + msg.getSubscriptionFeatures(), + Client::AccountFeatureIdList(), + msg.getEntitlementTotalTime(), + msg.getEntitlementEntitledTime(), + msg.getEntitlementTotalTimeSinceLastLogin(), + msg.getEntitlementEntitledTimeSinceLastLogin(), + msg.getBuddyPoints(), + msg.getConsumedRewardEvents(), + msg.getClaimedRewardItems(), + msg.getUsingAdminLogin(), + CombatDataTable::CSFT_All, + 128, + 90, + false, + false, + msg.getSendToStarport()); + + ClientMap::iterator f = m_clients->find(msg.getNetworkId()); + + if (f != m_clients->end()) + m_clients->erase(msg.getNetworkId()); + + m_clients->insert(std::make_pair(msg.getNetworkId(), c)); + + if (!msg.getUsingAdminLogin()) { + AccountFeatureIdRequest const req(NetworkId::cms_invalid, GameServer::getInstance().getProcessId(), msg + .getNetworkId(), static_cast(msg + .getStationId()), PlatformGameCode::SWG, AccountFeatureIdRequest::RR_Reload); + c->sendToConnectionServer(req); } + break; } + case constcrc("AuthTransferClientMessage") : { + MESSAGE_PROFILER_BLOCK("AuthTransferClientMessage"); + static const std::string loginTrace("TRACE_LOGIN"); + ri = static_cast(message).getByteStream().begin(); + AuthTransferClientMessage const msg(ri); + LOG(loginTrace, ("AuthTransferClientMessage(%s)", msg.getNetworkId().getValueString().c_str())); - LOG(loginTrace, ("NewClient(%s) : A new client is being created from connection server", msg.getNetworkId().getValueString().c_str())); - std::set const observedObjectSet(msg.getObservedObjects().begin(), msg.getObservedObjects().end()); - Client * const c = new Client( - const_cast(static_cast(source)), - msg.getNetworkId(), - msg.getAccountName(), - msg.getIpAddress(), - msg.getIsSecure(), - msg.getIsSkipLoadScreen(), - msg.getStationId(), - observedObjectSet, - msg.getGameFeatures(), - msg.getSubscriptionFeatures(), - Client::AccountFeatureIdList(), - msg.getEntitlementTotalTime(), - msg.getEntitlementEntitledTime(), - msg.getEntitlementTotalTimeSinceLastLogin(), - msg.getEntitlementEntitledTimeSinceLastLogin(), - msg.getBuddyPoints(), - msg.getConsumedRewardEvents(), - msg.getClaimedRewardItems(), - msg.getUsingAdminLogin(), - CombatDataTable::CSFT_All, - 128, - 90, - false, - false, - msg.getSendToStarport() ); + //@todo make sure this holds up with non players (like vehicles) + //because right not, we construct a new client object for EACH object + //even ones that could be controlled by the same client. + //Also is it possible to receive this message for an object we already control? - ClientMap::iterator f = m_clients->find(msg.getNetworkId()); - - if(f != m_clients->end()) - m_clients->erase(msg.getNetworkId()); - - m_clients->insert(std::make_pair(msg.getNetworkId(), c)); - - if (!msg.getUsingAdminLogin()) - { - AccountFeatureIdRequest const req(NetworkId::cms_invalid, GameServer::getInstance().getProcessId(), msg.getNetworkId(), static_cast(msg.getStationId()), PlatformGameCode::SWG, AccountFeatureIdRequest::RR_Reload); - c->sendToConnectionServer(req); - } - } - else if(message.isType("AuthTransferClientMessage")) - { - MESSAGE_PROFILER_BLOCK("AuthTransferClientMessage"); - static const std::string loginTrace("TRACE_LOGIN"); - ri = static_cast(message).getByteStream().begin(); - AuthTransferClientMessage const msg(ri); - LOG(loginTrace, ("AuthTransferClientMessage(%s)", msg.getNetworkId().getValueString().c_str())); - - //@todo make sure this holds up with non players (like vehicles) - //because right not, we construct a new client object for EACH object - //even ones that could be controlled by the same client. - //Also is it possible to receive this message for an object we already control? - - if (m_clients->find(msg.getNetworkId()) != m_clients->end()) - { - // inconsistant state, drop the client - LOG(loginTrace, ("AuthTransferClientMessage(%s) : Error! Getting a AuthTransferClientMessage message for a client that already exists", msg.getNetworkId().getValueString().c_str())); - KickPlayer const kickMessage(msg.getNetworkId(), "Duplicate Client"); - sendToConnectionServers(kickMessage); - dropClient(msg.getNetworkId()); - return; - } - - // locate the connection server for the client - ConnectionServerConnection * const connectionServer = getConnectionServerConnection(msg.getConnectionServerIp(), msg.getConnectionServerPort()); - - if (!connectionServer) - { - // inconsistant state, drop the client - LOG(loginTrace, ("AuthTransferClientMessage(%s) : Error! Getting a AuthTransferClientMessage message for a client but could not locate connection server (%s:%hu)", msg.getNetworkId().getValueString().c_str(), msg.getConnectionServerIp().c_str(), msg.getConnectionServerPort())); - KickPlayer const kickMessage(msg.getNetworkId(), "Invalid Connection Server"); - sendToConnectionServers(kickMessage); - dropClient(msg.getNetworkId()); - return; - } - - LOG(loginTrace, ("AuthTransferClientMessage(%s) : A new client is being created from game server %lu", msg.getNetworkId().getValueString().c_str(), msg.getSourceServerPid())); - - std::set observedObjectSet(msg.getObservedObjects().begin(), msg.getObservedObjects().end()); - Client * c = new Client(*connectionServer, msg.getNetworkId(), msg.getAccount(), msg.getIpAddress(), msg.getSecure(), msg.getSkipLoadScreen(), msg.getStationId(), observedObjectSet, msg.getGameFeatures(), msg.getSubscriptionFeatures(), msg.getAccountFeatureIds(), msg.getEntitlementTotalTime(), msg.getEntitlementEntitledTime(), msg.getEntitlementTotalTimeSinceLastLogin(), msg.getEntitlementEntitledTimeSinceLastLogin(), msg.getBuddyPoints(), msg.getConsumedRewardEvents(), msg.getClaimedRewardItems(), msg.getUsingAdminLogin(), static_cast(msg.getCombatSpamFilter()), msg.getCombatSpamRangeSquaredFilter(), msg.getFurnitureRotationDegree(), msg.getHasUnoccupiedJediSlot(), msg.getIsJediSlotCharacter()); - ClientMap::iterator f = m_clients->find(msg.getNetworkId()); - - if(f != m_clients->end()) - m_clients->erase(msg.getNetworkId()); - - m_clients->insert(std::make_pair(msg.getNetworkId(), c)); - } - - //--- - // application messages - else if(message.isType("CentralGameServerSetProcessId")) - { - MESSAGE_PROFILER_BLOCK("CentralGameServerSetProcessId"); - ri = static_cast(message).getByteStream().begin(); - CentralGameServerSetProcessId const m(ri); - - m_processId = m.getProcessId(); - LOG("GameServer", ("I am process %d", m_processId)); - LOG("GameGameConnect", ("Received CentralGameServerSetProcessId message for pid %d", m_processId)); - DEBUG_FATAL(m.getClockSubtractInterval()==0,("Got 0 for the clock subtract interval (probably indicates we connected to Central too early).\n")); - ServerClock::getInstance().setSubtractInterval(m.getClockSubtractInterval()); - m_clusterName = m.getClusterName(); - - ScriptParams s; - s.addParam(m_clusterName.c_str()); - GameScriptObject::runOneScript("base_class", "setGalaxyName", "s", s); - Chat::createSystemRooms(m_clusterName, ServerWorld::getSceneId()); - - if (!m_centralServerConnection) - { - m_centralServerConnection = const_cast(static_cast(&source)); - DEBUG_FATAL(true, ("m_centralServerConnection should have already been set when receiving CentralConnectionOpened.")); - } - - CentralGameServerConnect const connectMessage( - ConfigServerGame::getSceneID(), - "", - 0, - "", - 0); - - m_centralServerConnection->send(connectMessage, true); - - loadRetroactiveCtsHistory(); - loadRetroactivePlayerCityCreationTime(); - } - else if (message.isType("SetAuthoritativeMessage")) - { - MESSAGE_PROFILER_BLOCK("SetAuthoritativeMessage"); - ri = static_cast(message).getByteStream().begin(); - SetAuthoritativeMessage const t(ri); - - ServerObject * const object = ServerWorld::findObjectByNetworkId(t.getId()); - if (object) - { - bool allowed = true; - - // if the PlanetServer is asking us to transfer authority for an object that - // is contained, reject it, because contained object must have the same authority - // as its container; this can happen in a race condition where authority transfer - // is requested, and while the request is happening, the object moves into a container - if ((&source == m_planetServerConnection) && !t.getSceneChange() && object->isAuthoritative()) - { - Object const * const topmostContainer = ContainerInterface::getTopmostContainer(*object); - - if (topmostContainer != object) - { - WARNING(true, ("Denying authority transfer for (%s) from game server (%lu) to game server (%lu) because it is contained by (%s)", object->getDebugInformation().c_str(), GameServer::getInstance().getProcessId(), t.getProcess(), (topmostContainer ? topmostContainer->getDebugInformation().c_str() : "nullptr"))); - - allowed = false; - - GenericValueTypeMessage > const denyMessage( - "DenySetAuthoritativeMessage", - std::make_pair(t.getId(), GameServer::getInstance().getProcessId())); - - sendToPlanetServer(denyMessage); - - object->updatePositionOnPlanetServer(true); - } + if (m_clients->find(msg.getNetworkId()) != m_clients->end()) { + // inconsistant state, drop the client + LOG(loginTrace, ("AuthTransferClientMessage(%s) : Error! Getting a AuthTransferClientMessage message for a client that already exists", msg + .getNetworkId().getValueString().c_str())); + KickPlayer const kickMessage(msg.getNetworkId(), "Duplicate Client"); + sendToConnectionServers(kickMessage); + dropClient(msg.getNetworkId()); + return; } - if (allowed) - { - if (t.getGoalIsValid()) - object->transferAuthority(t.getProcess(), !t.getSceneChange(), t.getHandlingCrash(), t.getGoalCell(), t.getGoalTransform(), false); - else - object->transferAuthority(t.getProcess(), !t.getSceneChange(), t.getHandlingCrash(), false); + // locate the connection server for the client + ConnectionServerConnection *const connectionServer = getConnectionServerConnection(msg + .getConnectionServerIp(), msg.getConnectionServerPort()); + + if (!connectionServer) { + // inconsistant state, drop the client + LOG(loginTrace, ("AuthTransferClientMessage(%s) : Error! Getting a AuthTransferClientMessage message for a client but could not locate connection server (%s:%hu)", msg + .getNetworkId().getValueString().c_str(), msg.getConnectionServerIp().c_str(), msg + .getConnectionServerPort())); + KickPlayer const kickMessage(msg.getNetworkId(), "Invalid Connection Server"); + sendToConnectionServers(kickMessage); + dropClient(msg.getNetworkId()); + return; } + + LOG(loginTrace, ("AuthTransferClientMessage(%s) : A new client is being created from game server %lu", msg + .getNetworkId().getValueString().c_str(), msg.getSourceServerPid())); + + std::set observedObjectSet(msg.getObservedObjects().begin(), msg.getObservedObjects().end()); + Client *c = new Client(*connectionServer, msg.getNetworkId(), msg.getAccount(), msg.getIpAddress(), msg + .getSecure(), msg.getSkipLoadScreen(), msg.getStationId(), observedObjectSet, msg + .getGameFeatures(), msg.getSubscriptionFeatures(), msg.getAccountFeatureIds(), msg + .getEntitlementTotalTime(), msg.getEntitlementEntitledTime(), msg + .getEntitlementTotalTimeSinceLastLogin(), msg.getEntitlementEntitledTimeSinceLastLogin(), msg + .getBuddyPoints(), msg.getConsumedRewardEvents(), msg.getClaimedRewardItems(), msg + .getUsingAdminLogin(), static_cast(msg + .getCombatSpamFilter()), msg.getCombatSpamRangeSquaredFilter(), msg + .getFurnitureRotationDegree(), msg.getHasUnoccupiedJediSlot(), msg.getIsJediSlotCharacter()); + ClientMap::iterator f = m_clients->find(msg.getNetworkId()); + + if (f != m_clients->end()) + m_clients->erase(msg.getNetworkId()); + + m_clients->insert(std::make_pair(msg.getNetworkId(), c)); + break; } - } - else if(message.isType("LoadObjectMessage")) - { - MESSAGE_PROFILER_BLOCK("LoadObjectMessage"); - ri = static_cast(message).getByteStream().begin(); - LoadObjectMessage const t(ri); + //--- + // application messages + case constcrc("CentralGameServerSetProcessId") : { + MESSAGE_PROFILER_BLOCK("CentralGameServerSetProcessId"); + ri = static_cast(message).getByteStream().begin(); + CentralGameServerSetProcessId const m(ri); - ServerObject * const target = ServerWorld::findObjectByNetworkId(t.getId()); - if (target) - createRemoteProxy(t.getProcess(), target); - else - WARNING(true, ("Told to create object %s on %d we know nothing about (received LoadObjectMessage for an object not on this server, PlanetServer is probably confused)", t.getId().getValueString().c_str(), t.getProcess())); - } - else if(message.isType("UnloadObjectMessage")) - { - MESSAGE_PROFILER_BLOCK("UnloadObjectMessage"); - ri = static_cast(message).getByteStream().begin(); - UnloadObjectMessage const t(ri); + m_processId = m.getProcessId(); + LOG("GameServer", ("I am process %d", m_processId)); + LOG("GameGameConnect", ("Received CentralGameServerSetProcessId message for pid %d", m_processId)); + DEBUG_FATAL(m.getClockSubtractInterval() == + 0, ("Got 0 for the clock subtract interval (probably indicates we connected to Central too early).\n")); + ServerClock::getInstance().setSubtractInterval(m.getClockSubtractInterval()); + m_clusterName = m.getClusterName(); - DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("Got unload object message for %s\n", t.getId().getValueString().c_str())); + ScriptParams s; + s.addParam(m_clusterName.c_str()); + GameScriptObject::runOneScript("base_class", "setGalaxyName", "s", s); + Chat::createSystemRooms(m_clusterName, ServerWorld::getSceneId()); - ServerObject * const object = ServerWorld::findObjectByNetworkId(t.getId()); - if (object) - object->unload(); - DEBUG_WARNING(! object, ("Handling unload object message but the object does not exist\n")); - } - else if(message.isType("UnloadProxyMessage")) - { - MESSAGE_PROFILER_BLOCK("UnloadProxyMessage"); - ri = static_cast(message).getByteStream().begin(); - UnloadProxyMessage const unloadProxyMessage(ri); - - DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("Received UnloadProxyMessage for object %s server %lu\n", unloadProxyMessage.getObjectId().getValueString().c_str(), unloadProxyMessage.getProxyGameServerId())); - - ServerObject * const object = ServerWorld::findObjectByNetworkId(unloadProxyMessage.getObjectId()); - if(object) - { - if(object->isAuthoritative()) - { - if (unloadProxyMessage.getProxyGameServerId() != getProcessId()) - object->removeServerFromProxyList(unloadProxyMessage.getProxyGameServerId()); - else - DEBUG_WARNING(true,("Can't unproxy object %s from this server because this server is authoritative.", unloadProxyMessage.getObjectId().getValueString().c_str())); + if (!m_centralServerConnection) { + m_centralServerConnection = const_cast(static_cast(&source)); + DEBUG_FATAL(true, ("m_centralServerConnection should have already been set when receiving CentralConnectionOpened.")); } - else - { - DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(),("Forwarding UnloadProxyMessage for %s to authoritative server\n", unloadProxyMessage.getObjectId().getValueString().c_str())); - ServerMessageForwarding::begin(object->getAuthServerProcessId()); + CentralGameServerConnect const connectMessage( + ConfigServerGame::getSceneID(), + "", + 0, + "", + 0); - ServerMessageForwarding::send(unloadProxyMessage); + m_centralServerConnection->send(connectMessage, true); - ServerMessageForwarding::end(); - } + loadRetroactiveCtsHistory(); + loadRetroactivePlayerCityCreationTime(); + break; } - else - DEBUG_WARNING(true, ("Received UnloadProxyMessage for object %s server %lu, but the object could not be found", unloadProxyMessage.getObjectId().getValueString().c_str(), unloadProxyMessage.getProxyGameServerId())); - } - else if(message.isType("ProfilerOperationMessage")) - { - MESSAGE_PROFILER_BLOCK("ProfilerOperationMessage"); - ri = static_cast(message).getByteStream().begin(); - ProfilerOperationMessage const m(ri); - uint32 const processId = m.getProcessId(); - if (processId == 0 || processId == getProcessId()) - Profiler::handleOperation(m.getOperation().c_str()); - } - else if(message.isType("CentralCreateCharacter")) - { - MESSAGE_PROFILER_BLOCK("CentralCreateCharacter"); - ri = static_cast(message).getByteStream().begin(); - handleCreateCharacter(new CentralCreateCharacter(ri)); - } - else if (message.isType("VerifyNameResponse")) - { - MESSAGE_PROFILER_BLOCK("VerifyNameResponse"); - ri = static_cast(message).getByteStream().begin(); - VerifyNameResponse vrn(ri); - - if (isCreatePending(vrn.getStationId())) - { - handleCharacterCreateNameVerification(vrn); - } - else - { - handleVerifyAndLockNameVerification(vrn); - } - } - else if (message.isType("RandomNameRequest")) - { - MESSAGE_PROFILER_BLOCK("RandomNameRequest"); - ri = static_cast(message).getByteStream().begin(); - RandomNameRequest const crnr(ri); - handleNameRequest(crnr); - } - else if (message.isType("VerifyAndLockNameRequest")) - { - MESSAGE_PROFILER_BLOCK("VerifyAndLockNameRequest"); - ri = static_cast(message).getByteStream().begin(); - VerifyAndLockNameRequest const valnr(ri); - handleVerifyAndLockNameRequest(valnr, true, true); - } - else if(message.isType("ObjControllerMessage")) - { - MESSAGE_PROFILER_BLOCK("ObjControllerMessage"); + case constcrc("SetAuthoritativeMessage") : { + MESSAGE_PROFILER_BLOCK("SetAuthoritativeMessage"); + ri = static_cast(message).getByteStream().begin(); + SetAuthoritativeMessage const t(ri); - ri = static_cast(message).getByteStream().begin(); - ObjControllerMessage c(ri); + ServerObject *const object = ServerWorld::findObjectByNetworkId(t.getId()); + if (object) { + bool allowed = true; - // Could be in baselines so it may be initialized or it may not. Since we don't know we have to use NetworkIdManager to get it. - // The object could also have been destroyed due to an auth transfer, so if it has been and not all servers have confirmed it, - // we need to forward the message. + // if the PlanetServer is asking us to transfer authority for an object that + // is contained, reject it, because contained object must have the same authority + // as its container; this can happen in a race condition where authority transfer + // is requested, and while the request is happening, the object moves into a container + if ((&source == m_planetServerConnection) && !t.getSceneChange() && object->isAuthoritative()) { + Object const *const topmostContainer = ContainerInterface::getTopmostContainer(*object); - bool appended = false; + if (topmostContainer != object) { + WARNING(true, ("Denying authority transfer for (%s) from game server (%lu) to game server (%lu) because it is contained by (%s)", object + ->getDebugInformation().c_str(), GameServer::getInstance().getProcessId(), t + .getProcess(), (topmostContainer ? topmostContainer->getDebugInformation().c_str() + : "nullptr"))); - ServerObject * const target = safe_cast(NetworkIdManager::getObjectById(c.getNetworkId())); - if (target != nullptr) - { - // valid target, get its controller - ServerController * const controller = safe_cast(target->getController()); - if (controller != nullptr) - { - uint32 flags = c.getFlags(); - if(flags & GameControllerMessageFlags::DEST_AUTH_SERVER) - { - if(ConfigServerGame::getEnableDebugControllerMessageSpam()) - { - WARNING(! target->isAuthoritative(), ("Received a controller message (%d) destined for the authoritative object (%s:%s) on this server, but the object is NOT authoritative on this server", c.getMessage(), target->getObjectTemplateName(), target->getNetworkId().getValueString().c_str() )); + allowed = false; + + GenericValueTypeMessage > const denyMessage( + "DenySetAuthoritativeMessage", + std::make_pair(t.getId(), GameServer::getInstance().getProcessId())); + + sendToPlanetServer(denyMessage); + + object->updatePositionOnPlanetServer(true); } } - flags |= GameControllerMessageFlags::SOURCE_REMOTE_SERVER; - controller->appendMessage(c.getMessage(), c.getValue(), c.getData(), flags); - appended = true; - } - } - else - { - uint32 const destServer = AuthTransferTracker::getAuthTransferDest(c.getNetworkId()); - if (destServer) - { - if(ConfigServerGame::getEnableDebugControllerMessageSpam()) - { - WARNING(true, ("ObjControllerMessage %d for object %s arrived, but the object has transferred authority to server %d", c.getMessage(), c.getNetworkId().getValueString().c_str(), destServer)); + + if (allowed) { + if (t.getGoalIsValid()) + object->transferAuthority(t.getProcess(), !t.getSceneChange(), t.getHandlingCrash(), t + .getGoalCell(), t.getGoalTransform(), false); + else + object->transferAuthority(t.getProcess(), !t.getSceneChange(), t.getHandlingCrash(), false); } + } + break; + } + case constcrc("LoadObjectMessage") : { + MESSAGE_PROFILER_BLOCK("LoadObjectMessage"); - ServerMessageForwarding::begin(destServer); + ri = static_cast(message).getByteStream().begin(); + LoadObjectMessage const t(ri); - ServerMessageForwarding::send(c); + ServerObject *const target = ServerWorld::findObjectByNetworkId(t.getId()); + if (target) + createRemoteProxy(t.getProcess(), target); + else + WARNING(true, ("Told to create object %s on %d we know nothing about (received LoadObjectMessage for an object not on this server, PlanetServer is probably confused)", t + .getId().getValueString().c_str(), t.getProcess())); + break; + } + case constcrc("UnloadObjectMessage") : { + MESSAGE_PROFILER_BLOCK("UnloadObjectMessage"); + ri = static_cast(message).getByteStream().begin(); + UnloadObjectMessage const t(ri); - ServerMessageForwarding::end(); + DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("Got unload object message for %s\n", t.getId() + .getValueString() + .c_str())); + + ServerObject *const object = ServerWorld::findObjectByNetworkId(t.getId()); + if (object) + object->unload(); + DEBUG_WARNING(!object, ("Handling unload object message but the object does not exist\n")); + break; + } + case constcrc("UnloadProxyMessage") : { + MESSAGE_PROFILER_BLOCK("UnloadProxyMessage"); + ri = static_cast(message).getByteStream().begin(); + UnloadProxyMessage const unloadProxyMessage(ri); + + DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("Received UnloadProxyMessage for object %s server %lu\n", unloadProxyMessage + .getObjectId().getValueString().c_str(), unloadProxyMessage.getProxyGameServerId())); + + ServerObject *const object = ServerWorld::findObjectByNetworkId(unloadProxyMessage.getObjectId()); + if (object) { + if (object->isAuthoritative()) { + if (unloadProxyMessage.getProxyGameServerId() != getProcessId()) + object->removeServerFromProxyList(unloadProxyMessage.getProxyGameServerId()); + else + DEBUG_WARNING(true, ("Can't unproxy object %s from this server because this server is authoritative.", unloadProxyMessage + .getObjectId().getValueString().c_str())); + } + else { + DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("Forwarding UnloadProxyMessage for %s to authoritative server\n", unloadProxyMessage + .getObjectId().getValueString().c_str())); + + ServerMessageForwarding::begin(object->getAuthServerProcessId()); + + ServerMessageForwarding::send(unloadProxyMessage); + + ServerMessageForwarding::end(); + } } else - DEBUG_WARNING(true, ("Got ObjControllerMessage for object %s, which could not be found.", c.getNetworkId().getValueString().c_str())); + DEBUG_WARNING(true, ("Received UnloadProxyMessage for object %s server %lu, but the object could not be found", unloadProxyMessage + .getObjectId().getValueString().c_str(), unloadProxyMessage.getProxyGameServerId())); + break; } - - if (!appended) - delete c.getData(); - } - else if(message.isType("EndBaselinesMessage")) - { - MESSAGE_PROFILER_BLOCK("EndBaselinesMessage"); - ri = static_cast(message).getByteStream().begin(); - EndBaselinesMessage const t(ri); - ServerObject * const object = ServerWorld::findUninitializedObjectByNetworkId(t.getId()); - if (object != nullptr) - { - DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("Received EndBaselinesMessage for %s\n", t.getId().getValueString().c_str())); - ServerController * const controller = dynamic_cast(object->getController()); - NOT_NULL(controller); - - bool const fromDbServer = serverConnection && serverConnection == m_databaseProcessConnection; - object->serverObjectEndBaselines(fromDbServer); + case constcrc("ProfilerOperationMessage") : { + MESSAGE_PROFILER_BLOCK("ProfilerOperationMessage"); + ri = static_cast(message).getByteStream().begin(); + ProfilerOperationMessage const m(ri); + uint32 const processId = m.getProcessId(); + if (processId == 0 || processId == getProcessId()) + Profiler::handleOperation(m.getOperation().c_str()); + break; } - else - { - ServerObject * const badObject = ServerWorld::findObjectByNetworkId(t.getId()); - WARNING(!badObject, ("Got EndBaeslinesMessage on object (%s) that doesn't exist!", t.getId().getValueString().c_str())); - WARNING(badObject, ("Got EndBaselinesMessage on object (%s : %s) which has already been created and placed in the world!", badObject->getTemplateName(), badObject->getNetworkId().getValueString().c_str())); + case constcrc("CentralCreateCharacter") : { + MESSAGE_PROFILER_BLOCK("CentralCreateCharacter"); + ri = static_cast(message).getByteStream().begin(); + handleCreateCharacter(new CentralCreateCharacter(ri)); + break; } - } - else if(message.isType("TaskShutdownGameServer")) - { - MESSAGE_PROFILER_BLOCK("TaskShutdownGameServer"); - setDone("TaskShutdownGameServer"); - } - else if (message.isType("CreateObjectByCrcMessage")) - { - s_totalObjectCreateMessagesReceived ++; + case constcrc("VerifyNameResponse") : { + MESSAGE_PROFILER_BLOCK("VerifyNameResponse"); + ri = static_cast(message).getByteStream().begin(); + VerifyNameResponse vrn(ri); - MESSAGE_PROFILER_BLOCK("CreateObjectByCrcMessage"); - ri = static_cast(message).getByteStream().begin(); + if (isCreatePending(vrn.getStationId())) { + handleCharacterCreateNameVerification(vrn); + } + else { + handleVerifyAndLockNameVerification(vrn); + } + break; + } + case constcrc("RandomNameRequest") : { + MESSAGE_PROFILER_BLOCK("RandomNameRequest"); + ri = static_cast(message).getByteStream().begin(); + RandomNameRequest const crnr(ri); + handleNameRequest(crnr); + break; + } + case constcrc("VerifyAndLockNameRequest") : { + MESSAGE_PROFILER_BLOCK("VerifyAndLockNameRequest"); + ri = static_cast(message).getByteStream().begin(); + VerifyAndLockNameRequest const valnr(ri); + handleVerifyAndLockNameRequest(valnr, true, true); + break; + } + case constcrc("ObjControllerMessage") : { + MESSAGE_PROFILER_BLOCK("ObjControllerMessage"); - NetworkId networkId; - uint32 templateCrc; - bool createAuthoritative; + ri = static_cast(message).getByteStream().begin(); + ObjControllerMessage c(ri); - CreateObjectByCrcMessage const t(ri); + // Could be in baselines so it may be initialized or it may not. Since we don't know we have to use NetworkIdManager to get it. + // The object could also have been destroyed due to an auth transfer, so if it has been and not all servers have confirmed it, + // we need to forward the message. + + bool appended = false; + + ServerObject *const target = safe_cast(NetworkIdManager::getObjectById(c.getNetworkId())); + if (target != nullptr) { + // valid target, get its controller + ServerController *const controller = safe_cast(target->getController()); + if (controller != nullptr) { + uint32 flags = c.getFlags(); + if (flags & GameControllerMessageFlags::DEST_AUTH_SERVER) { + if (ConfigServerGame::getEnableDebugControllerMessageSpam()) { + WARNING(!target + ->isAuthoritative(), ("Received a controller message (%d) destined for the authoritative object (%s:%s) on this server, but the object is NOT authoritative on this server", c + .getMessage(), target->getObjectTemplateName(), target->getNetworkId() + .getValueString().c_str())); + } + } + flags |= GameControllerMessageFlags::SOURCE_REMOTE_SERVER; + controller->appendMessage(c.getMessage(), c.getValue(), c.getData(), flags); + appended = true; + } + } + else { + uint32 const destServer = AuthTransferTracker::getAuthTransferDest(c.getNetworkId()); + if (destServer) { + if (ConfigServerGame::getEnableDebugControllerMessageSpam()) { + WARNING(true, ("ObjControllerMessage %d for object %s arrived, but the object has transferred authority to server %d", c + .getMessage(), c.getNetworkId().getValueString().c_str(), destServer)); + } + + ServerMessageForwarding::begin(destServer); + + ServerMessageForwarding::send(c); + + ServerMessageForwarding::end(); + } + else + DEBUG_WARNING(true, ("Got ObjControllerMessage for object %s, which could not be found.", c + .getNetworkId().getValueString().c_str())); + } + + if (!appended) + delete c.getData(); + + break; + } + case constcrc("EndBaselinesMessage") : { + MESSAGE_PROFILER_BLOCK("EndBaselinesMessage"); + ri = static_cast(message).getByteStream().begin(); + EndBaselinesMessage const t(ri); + ServerObject *const object = ServerWorld::findUninitializedObjectByNetworkId(t.getId()); + if (object != nullptr) { + DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("Received EndBaselinesMessage for %s\n", t + .getId().getValueString().c_str())); + ServerController *const controller = dynamic_cast(object->getController()); + NOT_NULL(controller); + + bool const fromDbServer = serverConnection && serverConnection == m_databaseProcessConnection; + object->serverObjectEndBaselines(fromDbServer); + } + else { + ServerObject *const badObject = ServerWorld::findObjectByNetworkId(t.getId()); + WARNING(!badObject, ("Got EndBaeslinesMessage on object (%s) that doesn't exist!", t.getId() + .getValueString() + .c_str())); + WARNING(badObject, ("Got EndBaselinesMessage on object (%s : %s) which has already been created and placed in the world!", badObject + ->getTemplateName(), badObject->getNetworkId().getValueString().c_str())); + } + + break; + } + case constcrc("TaskShutdownGameServer") : { + MESSAGE_PROFILER_BLOCK("TaskShutdownGameServer"); + setDone("TaskShutdownGameServer"); + break; + } + case constcrc("CreateObjectByCrcMessage") : { + s_totalObjectCreateMessagesReceived++; + + MESSAGE_PROFILER_BLOCK("CreateObjectByCrcMessage"); + ri = static_cast(message).getByteStream().begin(); + + NetworkId networkId; + uint32 templateCrc; + bool createAuthoritative; + + CreateObjectByCrcMessage const t(ri); networkId = t.getId(); templateCrc = t.getCrc(); createAuthoritative = t.getCreateAuthoritative(); - NOT_NULL(serverConnection); - DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("CreateObjectMessageByName %s:%s\n", ObjectTemplateList::lookUp(templateCrc).getString(), networkId.getValueString().c_str())); + NOT_NULL(serverConnection); + DEBUG_REPORT_LOG(ConfigServerGame::getLogObjectLoading(), ("CreateObjectMessageByName %s:%s\n", ObjectTemplateList::lookUp(templateCrc) + .getString(), networkId.getValueString().c_str())); - Object * const object = NetworkIdManager::getObjectById(networkId); - bool okToCreate = true; - if (object) - { - DEBUG_REPORT_LOG(true, ("WARNING: GOT create message for object %s that already exists!\n", networkId.getValueString().c_str())); - if (object->getKill()) - { - delete object; - okToCreate = true; + Object *const object = NetworkIdManager::getObjectById(networkId); + bool okToCreate = true; + if (object) { + DEBUG_REPORT_LOG(true, ("WARNING: GOT create message for object %s that already exists!\n", networkId + .getValueString().c_str())); + if (object->getKill()) { + delete object; + okToCreate = true; + } + else { + WARNING_STRICT_FATAL(true, ("Hey, Got create message for object %s That isn't being deleted!", networkId + .getValueString().c_str())); + okToCreate = false; + } + } + + if (okToCreate) { + //-- Since space is single-server, we will never have proxied space objects and we can ignore the hyperspace variable in the CreateObjectBy*Message message. + ServerWorld::createProxyObject(templateCrc, networkId, createAuthoritative); + } + + break; + } + case constcrc("CreateSyncUiMessage") : { + MESSAGE_PROFILER_BLOCK("CreateSyncUiMessage"); + ri = static_cast(message).getByteStream().begin(); + CreateSyncUiMessage const msg(ri); + ServerObject *const so = safe_cast(NetworkIdManager::getObjectById(msg.getId())); + if (so) + so->addSynchronizedUi(msg.getClients()); + + break; + } + case constcrc("SynchronizeScriptVarsMessage") : { + MESSAGE_PROFILER_BLOCK("SynchronizeScriptVarsMessage"); + ri = static_cast(message).getByteStream().begin(); + SynchronizeScriptVarsMessage const msg(ri); + ServerObject *so = ServerWorld::findUninitializedObjectByNetworkId(msg.getNetworkId()); + if (so) { + GameScriptObject const *const script = so->getScriptObject(); + if (script) + script->unpackScriptVars(msg.getData()); + } + else { + so = safe_cast(NetworkIdManager::getObjectById(msg.getNetworkId())); + DEBUG_WARNING(so, ("Got SynchronizeScriptVarsMessage for initialized object")); + } + + break; + } + case constcrc("SynchronizeScriptVarDeltasMessage") : { + MESSAGE_PROFILER_BLOCK("SynchronizeScriptVarDeltasMessage"); + ri = static_cast(message).getByteStream().begin(); + SynchronizeScriptVarDeltasMessage const msg(ri); + ServerObject *const so = safe_cast(NetworkIdManager::getObjectById(msg.getNetworkId())); + if (so) { + GameScriptObject const *const script = so->getScriptObject(); + if (script) + script->unpackDeltaScriptVars(msg.getData()); } else - { - WARNING_STRICT_FATAL(true, ("Hey, Got create message for object %s That isn't being deleted!", networkId.getValueString().c_str())); - okToCreate = false; + DEBUG_WARNING(true, ("Got SynchronizeScriptVarDeltasMessage on object %s, which could not be found.", msg + .getNetworkId().getValueString().c_str())); + + break; + } + case constcrc("UpdateObjectPositionMessage") : { + MESSAGE_PROFILER_BLOCK("UpdateObjectPositionMessage"); + ri = static_cast(message).getByteStream().begin(); + UpdateObjectPositionMessage const msg(ri); + ServerObject *const so = ServerWorld::findUninitializedObjectByNetworkId(msg.getNetworkId()); + if (so) + so->applyObjectPositionUpdate(msg); + + break; + } + case constcrc("UpdateContainmentMessage") : { + MESSAGE_PROFILER_BLOCK("UpdateContainmentMessage"); + ri = static_cast(message).getByteStream().begin(); + UpdateContainmentMessage const msg(ri); + ServerObject *const so = safe_cast(NetworkIdManager::getObjectById(msg.getNetworkId())); + if (so) { + // Handle the containment update. + so->updateContainment(msg.getContainerId(), msg.getSlotArrangement()); } + + break; } + case constcrc("DropClient") : { + MESSAGE_PROFILER_BLOCK("DropClient"); + ri = static_cast(message).getByteStream().begin(); + DropClient const msg(ri); + dropClient(msg.getNetworkId(), msg.getImmediate()); - if (okToCreate) - { - //-- Since space is single-server, we will never have proxied space objects and we can ignore the hyperspace variable in the CreateObjectBy*Message message. - ServerWorld::createProxyObject(templateCrc, networkId, createAuthoritative); + break; } - } - else if(message.isType("CreateSyncUiMessage")) - { - MESSAGE_PROFILER_BLOCK("CreateSyncUiMessage"); - ri = static_cast(message).getByteStream().begin(); - CreateSyncUiMessage const msg(ri); - ServerObject * const so = safe_cast(NetworkIdManager::getObjectById(msg.getId())); - if (so) - so->addSynchronizedUi(msg.getClients()); - } - else if(message.isType("SynchronizeScriptVarsMessage")) - { - MESSAGE_PROFILER_BLOCK("SynchronizeScriptVarsMessage"); - ri = static_cast(message).getByteStream().begin(); - SynchronizeScriptVarsMessage const msg(ri); - ServerObject *so = ServerWorld::findUninitializedObjectByNetworkId(msg.getNetworkId()); - if (so) - { - GameScriptObject const * const script = so->getScriptObject(); - if (script) - script->unpackScriptVars(msg.getData()); + case constcrc("SetPlanetServerMessage") : { + MESSAGE_PROFILER_BLOCK("SetPlanetServerMessage"); + DEBUG_REPORT_LOG(true, ("Received SetPlanetServerMessage\n")); + ri = static_cast(message).getByteStream().begin(); + SetPlanetServerMessage const m(ri); + m_planetServerConnection = new PlanetServerConnection(m.getAddress(), m.getPort()); + break; } - else - { - so = safe_cast(NetworkIdManager::getObjectById(msg.getNetworkId())); - DEBUG_WARNING(so, ("Got SynchronizeScriptVarsMessage for initialized object")); + case constcrc("PlanetConnectionOpened") : { + MESSAGE_PROFILER_BLOCK("PlanetConnectionOpened"); + m_planetServerConnection = const_cast(static_cast(&source)); + DEBUG_REPORT_LOG(true, ("Connection with the Planet server has been established\n")); + onPlanetServerConnectionEstablished(); + break; } - } - else if (message.isType("SynchronizeScriptVarDeltasMessage")) - { - MESSAGE_PROFILER_BLOCK("SynchronizeScriptVarDeltasMessage"); - ri = static_cast(message).getByteStream().begin(); - SynchronizeScriptVarDeltasMessage const msg(ri); - ServerObject * const so = safe_cast(NetworkIdManager::getObjectById(msg.getNetworkId())); - if (so) - { - GameScriptObject const * const script = so->getScriptObject(); - if (script) - script->unpackDeltaScriptVars(msg.getData()); + case constcrc("PlanetConnectionClosed") : { + MESSAGE_PROFILER_BLOCK("PlanetConnectionClosed"); + if (m_planetServerConnection) { + m_planetServerConnection->setDisconnectReason("received PlanetConnectionClosed"); + m_planetServerConnection->disconnect(); + } + m_planetServerConnection = 0; + setDone("PlanetConnectionClosed : %s", serverConnection->getDisconnectReason().c_str()); + break; } - else - DEBUG_WARNING(true,("Got SynchronizeScriptVarDeltasMessage on object %s, which could not be found.", msg.getNetworkId().getValueString().c_str())); - } - else if(message.isType("UpdateObjectPositionMessage")) - { - MESSAGE_PROFILER_BLOCK("UpdateObjectPositionMessage"); - ri = static_cast(message).getByteStream().begin(); - UpdateObjectPositionMessage const msg(ri); - ServerObject * const so = ServerWorld::findUninitializedObjectByNetworkId(msg.getNetworkId()); - if (so) - so->applyObjectPositionUpdate(msg); - } - else if(message.isType("UpdateContainmentMessage")) - { - MESSAGE_PROFILER_BLOCK("UpdateContainmentMessage"); - ri = static_cast(message).getByteStream().begin(); - UpdateContainmentMessage const msg(ri); - ServerObject * const so = safe_cast(NetworkIdManager::getObjectById(msg.getNetworkId())); - if (so) - { - // Handle the containment update. - so->updateContainment(msg.getContainerId(), msg.getSlotArrangement()); + case constcrc("GameServerSetupMessage") : { + MESSAGE_PROFILER_BLOCK("GameServerSetupMessage"); + LOG("GameGameConnect", ("Game Server %d Received GameServerSetupMessage.", m_processId)); + + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::vector < uint32 > , std::pair < uint32, std::pair < std::string, + uint16 > > > > + const m(ri); + + m_gameServerPids = m.getValue().first; + std::sort(m_gameServerPids.begin(), m_gameServerPids.end()); + + ServerMessageForwarding::beginBroadcast(); + + GenericValueTypeMessage const addGameServerMessage("AddGameServer", getProcessId()); + ServerMessageForwarding::send(addGameServerMessage); + + ServerMessageForwarding::end(); + + uint32 const databaseProcessId = m.getValue().second.first; + std::string const &databaseProcessAddress = m.getValue().second.second.first; + uint16 const databaseProcessPort = m.getValue().second.second.second; + + connectToDatabaseProcess(databaseProcessAddress, databaseProcessPort, databaseProcessId); + + m_connectionTimeout = Clock::timeMs() + ConfigServerGame::getConnectToAllGameServersTimeout() * 1000; + + break; } - } - else if(message.isType("DropClient")) - { - MESSAGE_PROFILER_BLOCK("DropClient"); - ri = static_cast(message).getByteStream().begin(); - DropClient const msg(ri); - dropClient(msg.getNetworkId(), msg.getImmediate()); - } - else if(message.isType("SetPlanetServerMessage")) - { - MESSAGE_PROFILER_BLOCK("SetPlanetServerMessage"); - DEBUG_REPORT_LOG(true,("Received SetPlanetServerMessage\n")); - ri = static_cast(message).getByteStream().begin(); - SetPlanetServerMessage const m(ri); - m_planetServerConnection = new PlanetServerConnection(m.getAddress(),m.getPort()); - } - else if (message.isType("PlanetConnectionOpened")) - { - MESSAGE_PROFILER_BLOCK("PlanetConnectionOpened"); - m_planetServerConnection = const_cast(static_cast(&source)); - DEBUG_REPORT_LOG(true, ("Connection with the Planet server has been established\n")); - onPlanetServerConnectionEstablished(); - } - else if (message.isType("PlanetConnectionClosed")) - { - MESSAGE_PROFILER_BLOCK("PlanetConnectionClosed"); - if (m_planetServerConnection) - { - m_planetServerConnection->setDisconnectReason("received PlanetConnectionClosed"); - m_planetServerConnection->disconnect(); + case constcrc("LoadUniverseMessage") : { + MESSAGE_PROFILER_BLOCK("LoadUniverseMessage"); + ri = static_cast(message).getByteStream().begin(); + LoadUniverseMessage const msg(ri); + + DEBUG_REPORT_LOG(true, ("Got LoadUniverseMessage\n")); + ServerUniverse::getInstance().requestCreateProxiesOnServer(msg.getProcess()); + break; } - m_planetServerConnection = 0; - setDone("PlanetConnectionClosed : %s", serverConnection->getDisconnectReason().c_str()); - } - else if (message.isType("GameServerSetupMessage")) - { - MESSAGE_PROFILER_BLOCK("GameServerSetupMessage"); - LOG("GameGameConnect", ("Game Server %d Received GameServerSetupMessage.", m_processId)); + case constcrc("SetUniverseAuthoritativeMessage") : { + MESSAGE_PROFILER_BLOCK("SetUniverseAuthoritativeMessage"); + ri = static_cast(message).getByteStream().begin(); + SetUniverseAuthoritativeMessage const m(ri); + ServerUniverse::getInstance().setUniverseProcess(m.getProcess()); + break; + } + case constcrc("AddResourceTypeMessage") : { + ri = static_cast(message).getByteStream().begin(); + AddResourceTypeMessage const msg(ri); + ServerUniverse::getInstance().handleAddResourceTypeMessage(msg); + break; + } + case constcrc("AddImportedResourceType") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, std::pair > > > const m(ri); + if (!ServerUniverse::getInstance().getImportedResourceTypeById(msg.getValue().first)) + IGNORE_RETURN(ResourceTypeObject::addImportedResourceType(msg.getValue().second)); - m_gameServerPids = m.getValue().first; - std::sort(m_gameServerPids.begin(), m_gameServerPids.end()); + break; + } + case constcrc("UniverseCompleteMessage") : { + MESSAGE_PROFILER_BLOCK("UniverseCompleteMessage"); + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); - ServerMessageForwarding::beginBroadcast(); + ServerUniverse::getInstance().universeComplete(msg.getValue()); + GameServerUniverseLoadedMessage const reply(getProcessId(), msg.getValue()); + GameServer::getInstance().sendToCentralServer(reply); + GameServer::getInstance().sendToPlanetServer(reply); + gs_gameServerReady = true; - GenericValueTypeMessage const addGameServerMessage("AddGameServer", getProcessId()); - ServerMessageForwarding::send(addGameServerMessage); + break; + } + case constcrc("GameServerUniverseLoadedMessage") : { + MESSAGE_PROFILER_BLOCK("GameServerUniverseLoadedMessage"); + ri = static_cast(message).getByteStream().begin(); + GameServerUniverseLoadedMessage const msg(ri); - ServerMessageForwarding::end(); + ServerUniverse::getInstance().universeLoadedAck(msg.getProcessId()); - uint32 const databaseProcessId = m.getValue().second.first; - std::string const &databaseProcessAddress = m.getValue().second.second.first; - uint16 const databaseProcessPort = m.getValue().second.second.second; + break; + } + case constcrc("PreloadRequestCompleteMessage") : { + MESSAGE_PROFILER_BLOCK("PreloadRequestCompleteMessage"); + LOG("Preload", ("Game Server %d received preloadRequestCompleteMessage from database", getInstance() + .m_processId)); + ri = static_cast(message).getByteStream().begin(); + PreloadRequestCompleteMessage const msg(ri); - connectToDatabaseProcess(databaseProcessAddress, databaseProcessPort, databaseProcessId); + DEBUG_REPORT_LOG(true, ("Got PreloadRequestCompleteMessage. We are server %lu in the preload list\n", msg + .getPreloadAreaId())); - m_connectionTimeout = Clock::timeMs() + ConfigServerGame::getConnectToAllGameServersTimeout() * 1000; - } - else if (message.isType("LoadUniverseMessage")) - { - MESSAGE_PROFILER_BLOCK("LoadUniverseMessage"); - ri = static_cast(message).getByteStream().begin(); - LoadUniverseMessage const msg(ri); + m_preloadAreaId = msg.getPreloadAreaId(); + MetricsManager::install(m_metricsData, true, "GameServer", ServerWorld::getSceneId(), msg + .getPreloadAreaId()); + s_metricsManagerInstalled = true; + GameServer::getInstance().sendToPlanetServer(msg); - DEBUG_REPORT_LOG(true,("Got LoadUniverseMessage\n")); - ServerUniverse::getInstance().requestCreateProxiesOnServer(msg.getProcess()); - } - else if (message.isType("SetUniverseAuthoritativeMessage")) - { - MESSAGE_PROFILER_BLOCK("SetUniverseAuthoritativeMessage"); - ri = static_cast(message).getByteStream().begin(); - SetUniverseAuthoritativeMessage const m(ri); - ServerUniverse::getInstance().setUniverseProcess(m.getProcess()); - } - else if (message.isType("AddResourceTypeMessage")) - { - ri = static_cast(message).getByteStream().begin(); - AddResourceTypeMessage const msg(ri); - ServerUniverse::getInstance().handleAddResourceTypeMessage(msg); - } - else if (message.isType("AddImportedResourceType")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - - if (!ServerUniverse::getInstance().getImportedResourceTypeById(msg.getValue().first)) - IGNORE_RETURN(ResourceTypeObject::addImportedResourceType(msg.getValue().second)); - } - else if (message.isType("UniverseCompleteMessage")) - { - MESSAGE_PROFILER_BLOCK("UniverseCompleteMessage"); - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - - ServerUniverse::getInstance().universeComplete(msg.getValue()); - GameServerUniverseLoadedMessage const reply(getProcessId(), msg.getValue()); - GameServer::getInstance().sendToCentralServer(reply); - GameServer::getInstance().sendToPlanetServer(reply); - gs_gameServerReady = true; - } - else if (message.isType("GameServerUniverseLoadedMessage")) - { - MESSAGE_PROFILER_BLOCK("GameServerUniverseLoadedMessage"); - ri = static_cast(message).getByteStream().begin(); - GameServerUniverseLoadedMessage const msg(ri); - - ServerUniverse::getInstance().universeLoadedAck(msg.getProcessId()); - } - else if (message.isType("PreloadRequestCompleteMessage")) - { - MESSAGE_PROFILER_BLOCK("PreloadRequestCompleteMessage"); - LOG("Preload", ("Game Server %d received preloadRequestCompleteMessage from database", getInstance().m_processId)); - ri = static_cast(message).getByteStream().begin(); - PreloadRequestCompleteMessage const msg(ri); - - DEBUG_REPORT_LOG(true,("Got PreloadRequestCompleteMessage. We are server %lu in the preload list\n",msg.getPreloadAreaId())); - - m_preloadAreaId = msg.getPreloadAreaId(); - MetricsManager::install(m_metricsData, true, "GameServer", ServerWorld::getSceneId(), msg.getPreloadAreaId()); - s_metricsManagerInstalled = true; - GameServer::getInstance().sendToPlanetServer(msg); - - // Our assigned preload number should be the same as the preload number we were started with; - // The cluster will still work but the restartgameserver.pl script may end up restarting the wrong - // game server because of the mismatch; it's worth putting out a log to look into what went wrong + // Our assigned preload number should be the same as the preload number we were started with; + // The cluster will still work but the restartgameserver.pl script may end up restarting the wrong + // game server because of the mismatch; it's worth putting out a log to look into what went wrong #ifndef _DEBUG - if (static_cast(msg.getPreloadAreaId()) != ConfigServerGame::getPreloadNumber()) - LOG("Preload", ("Game Server %d got assigned preload number %lu but was launched with preload number %d", getInstance().m_processId, msg.getPreloadAreaId(), ConfigServerGame::getPreloadNumber())); + if (static_cast(msg.getPreloadAreaId()) != ConfigServerGame::getPreloadNumber()) + LOG("Preload", ("Game Server %d got assigned preload number %lu but was launched with preload number %d", getInstance() + .m_processId, msg.getPreloadAreaId(), ConfigServerGame::getPreloadNumber())); #endif - // Notify ServerWorld that preloading is complete, so it can trigger scripts as appropriate - ServerWorld::onPreloadComplete(); - } - else if (message.isType("SceneTransferMessage")) - { - MESSAGE_PROFILER_BLOCK("SceneTransferMessage"); - ri = static_cast(message).getByteStream().begin(); - SceneTransferMessage const msg(ri); + // Notify ServerWorld that preloading is complete, so it can trigger scripts as appropriate + ServerWorld::onPreloadComplete(); - ServerObject * obj = ServerWorld::findObjectByNetworkId(msg.getNetworkId()); - if (obj) - obj->removeObjVarItem(OBJVAR_HAS_OUTSTANDING_REQUEST_SCENE_TRANSFER); - - if (obj && obj->isAuthoritative() && isGameServerConnected(msg.getDestinationGameServer()) && (!obj->isPlayerControlled() || obj->getClient())) - { - if (obj->getSceneId() == msg.getSceneName()) - { - WARNING_STRICT_FATAL(true, ("Same scene planetwarps are no longer supported!")); - if (obj->getClient()) - dropClient(obj->getNetworkId()); - obj->unload(); - } - else - { - // Mounts: if it is a rider that is trying to planet warp, change the planet warp object - // to be the mount. - CreatureObject *const objAsCreature = obj->asCreatureObject(); - if (objAsCreature) - { - if (objAsCreature->getState(States::RidingMount)) - { - // The obj instance is a mounted rider. Replace obj with the mount. - CreatureObject *const mountObject = objAsCreature->getMountedCreature(); - if (mountObject) - { - // Set the proper position for the rider to that for the - // scene transfer. Failure to take this step causes the - // ServerObject::setClient() call on the destination server - // to have the wrong position for the player, thus setting - // up location-based containment improperly, screwing up - // the client's view of the world. - obj->setPosition_p(msg.getPosition_w()); - - // Replace obj with mount. - obj = mountObject; - } - else - { - LOG("mounts-bug", ("GS::SceneTransferMessage: server id=[%d],rider id=[%s] has RidingMount state but getMountedCreature() returns nullptr.", static_cast(getProcessId()), obj->getNetworkId().getValueString().c_str())); - objAsCreature->emergencyDismountForRider(); - } - } - else - { - ShipObject * const ship = getAttachedShip(objAsCreature); - if (ship) - { - // Set the proper position for the rider to that for the - // scene transfer. Failure to take this step causes the - // ServerObject::setClient() call on the destination server - // to have the wrong position for the player, thus setting - // up location-based containment improperly, screwing up - // the client's view of the world. - obj->setPosition_w(msg.getPosition_w()); - - obj = ship; - } - } - } - - // Proceed with scene transfer on the transfer focus object. - bool doSceneChange = false; - - if (ContainerInterface::getTopmostContainer(*obj) == obj) - doSceneChange = true; - else - { - Transform tr(obj->getTransform_o2w()); - if (tr.isNaN()) - { - WARNING(true, ("Scene change for %s with nan in transform (i=%g,%g,%g j=%g,%g,%g k=%g,%g,%g, p=%g,%g,%g)", - obj->getDebugInformation().c_str(), - tr.getLocalFrameI_p().x, tr.getLocalFrameI_p().y, tr.getLocalFrameI_p().z, - tr.getLocalFrameJ_p().x, tr.getLocalFrameJ_p().y, tr.getLocalFrameJ_p().z, - tr.getLocalFrameK_p().x, tr.getLocalFrameK_p().y, tr.getLocalFrameK_p().z, - tr.getPosition_p().x, tr.getPosition_p().y, tr.getPosition_p().z)); - tr.resetRotate_l2p(); - } - Container::ContainerErrorCode err = Container::CEC_Success; - doSceneChange = ContainerInterface::transferItemToWorld(*obj, tr, 0, err); - } - - if (doSceneChange) - { - obj->setSceneIdOnThisAndContents(msg.getSceneName()); - - //-- As soon as we change the scene id on the object, tell central about the - // scene change. This fixes a bug that can occur if the authority transfer - // never completes where Central is left thinking we're still on this gameserver's - // scene (the source scene) but the object's data says we're on the destination - // due to the scene set above. - GenericValueTypeMessage > > const setSceneMsg("SetSceneForPlayer", std::make_pair(msg.getNetworkId(), std::make_pair(msg.getSceneName(), false))); - GameServer::getInstance().sendToCentralServer(setSceneMsg); - - if (!msg.getSceneName().empty()) - { - std::map const & connectedCharacterLfgData = ServerUniverse::getConnectedCharacterLfgData(); - std::map::const_iterator iterFind = connectedCharacterLfgData.find(msg.getNetworkId()); - if ((iterFind != connectedCharacterLfgData.end()) && (iterFind->second.locationPlanet != msg.getSceneName())) - ServerUniverse::setConnectedCharacterPlanetData(msg.getNetworkId(), msg.getSceneName()); - } - - obj->getContainedByProperty()->setContainedBy(NetworkId::cms_invalid); - obj->setPosition_p(msg.getPosition_w()); - if (msg.getContainerId() != NetworkId::cms_invalid) - obj->setInteriorTeleportDestination(msg.getContainerId(), msg.getContainerName(), msg.getPosition_p()); - if (!msg.getScriptCallback().empty()) - obj->setTeleportScriptCallback(msg.getScriptCallback()); - obj->transferAuthority(msg.getDestinationGameServer(), false, false, false); - obj->clearProxyList(); - } - } + break; } - } - else if (message.isType("ChatServerOnline")) - { - MESSAGE_PROFILER_BLOCK("ChatServerOnline"); - // a chat server advised the central server that it is online and - // is ready for game servers to connect to it. - ri = static_cast(message).getByteStream().begin(); - ChatServerOnline const cso(ri); + case constcrc("SceneTransferMessage") : { + MESSAGE_PROFILER_BLOCK("SceneTransferMessage"); + ri = static_cast(message).getByteStream().begin(); + SceneTransferMessage const msg(ri); - if (m_chatServerConnection) - { - //we shouldn't have one already, but if we do then close it and - //accept the new one. - WARNING(true, ("We got notification of a new chat server coming online while we still had connection to an existing. We're going to disconnect from the old one and connect to the new one. This shouldn't cause any real problems, but we shouldn't have lingering chat connections laying around.")); - m_chatServerConnection->setDisconnectReason("got ChatServerOnline message"); - m_chatServerConnection->disconnect(); + ServerObject *obj = ServerWorld::findObjectByNetworkId(msg.getNetworkId()); + if (obj) + obj->removeObjVarItem(OBJVAR_HAS_OUTSTANDING_REQUEST_SCENE_TRANSFER); + + if (obj && obj->isAuthoritative() && isGameServerConnected(msg.getDestinationGameServer()) && + (!obj->isPlayerControlled() || obj->getClient())) { + if (obj->getSceneId() == msg.getSceneName()) { + WARNING_STRICT_FATAL(true, ("Same scene planetwarps are no longer supported!")); + if (obj->getClient()) + dropClient(obj->getNetworkId()); + obj->unload(); + } + else { + // Mounts: if it is a rider that is trying to planet warp, change the planet warp object + // to be the mount. + CreatureObject *const objAsCreature = obj->asCreatureObject(); + if (objAsCreature) { + if (objAsCreature->getState(States::RidingMount)) { + // The obj instance is a mounted rider. Replace obj with the mount. + CreatureObject *const mountObject = objAsCreature->getMountedCreature(); + if (mountObject) { + // Set the proper position for the rider to that for the + // scene transfer. Failure to take this step causes the + // ServerObject::setClient() call on the destination server + // to have the wrong position for the player, thus setting + // up location-based containment improperly, screwing up + // the client's view of the world. + obj->setPosition_p(msg.getPosition_w()); + + // Replace obj with mount. + obj = mountObject; + } + else { + LOG("mounts-bug", ("GS::SceneTransferMessage: server id=[%d],rider id=[%s] has RidingMount state but getMountedCreature() returns nullptr.", static_cast(getProcessId()), obj + ->getNetworkId().getValueString().c_str())); + objAsCreature->emergencyDismountForRider(); + } + } + else { + ShipObject *const ship = getAttachedShip(objAsCreature); + if (ship) { + // Set the proper position for the rider to that for the + // scene transfer. Failure to take this step causes the + // ServerObject::setClient() call on the destination server + // to have the wrong position for the player, thus setting + // up location-based containment improperly, screwing up + // the client's view of the world. + obj->setPosition_w(msg.getPosition_w()); + + obj = ship; + } + } + } + + // Proceed with scene transfer on the transfer focus object. + bool doSceneChange = false; + + if (ContainerInterface::getTopmostContainer(*obj) == obj) + doSceneChange = true; + else { + Transform tr(obj->getTransform_o2w()); + if (tr.isNaN()) { + WARNING(true, ("Scene change for %s with nan in transform (i=%g,%g,%g j=%g,%g,%g k=%g,%g,%g, p=%g,%g,%g)", + obj->getDebugInformation().c_str(), + tr.getLocalFrameI_p().x, tr.getLocalFrameI_p().y, tr.getLocalFrameI_p().z, + tr.getLocalFrameJ_p().x, tr.getLocalFrameJ_p().y, tr.getLocalFrameJ_p().z, + tr.getLocalFrameK_p().x, tr.getLocalFrameK_p().y, tr.getLocalFrameK_p().z, + tr.getPosition_p().x, tr.getPosition_p().y, tr.getPosition_p().z)); + tr.resetRotate_l2p(); + } + Container::ContainerErrorCode err = Container::CEC_Success; + doSceneChange = ContainerInterface::transferItemToWorld(*obj, tr, 0, err); + } + + if (doSceneChange) { + obj->setSceneIdOnThisAndContents(msg.getSceneName()); + + //-- As soon as we change the scene id on the object, tell central about the + // scene change. This fixes a bug that can occur if the authority transfer + // never completes where Central is left thinking we're still on this gameserver's + // scene (the source scene) but the object's data says we're on the destination + // due to the scene set above. + GenericValueTypeMessage < std::pair < NetworkId, std::pair < std::string, bool > > > + const setSceneMsg( + "SetSceneForPlayer", std::make_pair(msg.getNetworkId(), std::make_pair(msg + .getSceneName(), false))); + GameServer::getInstance().sendToCentralServer(setSceneMsg); + + if (!msg.getSceneName().empty()) { + std::map const &connectedCharacterLfgData = ServerUniverse::getConnectedCharacterLfgData(); + std::map::const_iterator iterFind = connectedCharacterLfgData + .find(msg.getNetworkId()); + if ((iterFind != connectedCharacterLfgData.end()) && + (iterFind->second.locationPlanet != msg.getSceneName())) + ServerUniverse::setConnectedCharacterPlanetData(msg.getNetworkId(), msg.getSceneName()); + } + + obj->getContainedByProperty()->setContainedBy(NetworkId::cms_invalid); + obj->setPosition_p(msg.getPosition_w()); + if (msg.getContainerId() != NetworkId::cms_invalid) + obj->setInteriorTeleportDestination(msg.getContainerId(), msg.getContainerName(), msg + .getPosition_p()); + if (!msg.getScriptCallback().empty()) + obj->setTeleportScriptCallback(msg.getScriptCallback()); + obj->transferAuthority(msg.getDestinationGameServer(), false, false, false); + obj->clearProxyList(); + } + } + } + + break; + } + case constcrc("ChatServerOnline") : { + MESSAGE_PROFILER_BLOCK("ChatServerOnline"); + // a chat server advised the central server that it is online and + // is ready for game servers to connect to it. + ri = static_cast(message).getByteStream().begin(); + ChatServerOnline const cso(ri); + + if (m_chatServerConnection) { + //we shouldn't have one already, but if we do then close it and + //accept the new one. + WARNING(true, ("We got notification of a new chat server coming online while we still had connection to an existing. We're going to disconnect from the old one and connect to the new one. This shouldn't cause any real problems, but we shouldn't have lingering chat connections laying around.")); + m_chatServerConnection->setDisconnectReason("got ChatServerOnline message"); + m_chatServerConnection->disconnect(); + m_chatServerConnection = 0; + Chat::setChatServer(m_chatServerConnection); + } + + if (!m_chatServerConnection) { + REPORT_LOG(true, ("New chat server connection active\n")); + m_chatServerConnection = new ChatServerConnection(cso.getAddress(), cso.getPort()); + Chat::setChatServer(m_chatServerConnection); + if (!m_clusterName.empty()) { + Chat::createSystemRooms(m_clusterName, ServerWorld::getSceneId()); + } + } + + break; + } + case constcrc("ChatServerConnectionClosed") : { + MESSAGE_PROFILER_BLOCK("ChatServerConnectionClosed"); + REPORT_LOG(true, ("GameServer: Chat Server connection closed\n")); + if (m_chatServerConnection) { + m_chatServerConnection->setDisconnectReason("got ChatServerConnectionClosed message"); + m_chatServerConnection->disconnect(); + + // if there is an interruption of service on the network + // between the GameServer and ChatServer, but the ChatServer + // is still running, the game server might never reconnect. Advise + // Central that the GameServer has lost a connection with the chat + // server + GameNetworkMessage const chatClosed("ChatClosedConnectionWithGameServer"); + sendToCentralServer(chatClosed); + } m_chatServerConnection = 0; - Chat::setChatServer(m_chatServerConnection); - } - if(! m_chatServerConnection) - { - REPORT_LOG(true, ("New chat server connection active\n")); - m_chatServerConnection = new ChatServerConnection(cso.getAddress(), cso.getPort()); - Chat::setChatServer(m_chatServerConnection); - if(! m_clusterName.empty()) - { - Chat::createSystemRooms(m_clusterName, ServerWorld::getSceneId()); + break; + } + case constcrc("TeleportMessage") : { + MESSAGE_PROFILER_BLOCK("TeleportMessage"); + ri = static_cast(message).getByteStream().begin(); + TeleportMessage const msg(ri); + handleTeleportMessage(msg); + break; + } + case constcrc("TeleportToMessage") : { + MESSAGE_PROFILER_BLOCK("TeleportToMessage"); + ri = static_cast(message).getByteStream().begin(); + TeleportToMessage const msg(ri); + ServerObject *const serverObj = safe_cast(NetworkIdManager::getObjectById(msg + .getTargetId())); + if (serverObj && serverObj->isAuthoritative()) { + + // send teleport message + Object const *const firstParent = ContainerInterface::getFirstParentInWorld(*serverObj); + if (firstParent) { + ServerMessageForwarding::begin(msg.getProcessId()); + + TeleportMessage const teleportMessage( + msg.getActorId(), + serverObj->getSceneId(), + firstParent->getPosition_w(), + firstParent->getAttachedTo() ? firstParent->getAttachedTo()->getNetworkId() + : NetworkId::cms_invalid, + firstParent->getPosition_p()); + ServerMessageForwarding::send(teleportMessage); + + ServerMessageForwarding::end(); + } } + break; } - } - else if(message.isType("ChatServerConnectionClosed")) - { - MESSAGE_PROFILER_BLOCK("ChatServerConnectionClosed"); - REPORT_LOG(true, ("GameServer: Chat Server connection closed\n")); - if (m_chatServerConnection) - { - m_chatServerConnection->setDisconnectReason("got ChatServerConnectionClosed message"); - m_chatServerConnection->disconnect(); - - // if there is an interruption of service on the network - // between the GameServer and ChatServer, but the ChatServer - // is still running, the game server might never reconnect. Advise - // Central that the GameServer has lost a connection with the chat - // server - GameNetworkMessage const chatClosed("ChatClosedConnectionWithGameServer"); - sendToCentralServer(chatClosed); + case constcrc("RetrievedItemLoadMessage") : { + MESSAGE_PROFILER_BLOCK("RetrievedItemLoadMessage"); + ri = static_cast(message).getByteStream().begin(); + RetrievedItemLoadMessage const msg(ri); + handleRetrievedItemLoadMessage(msg); + break; } - m_chatServerConnection = 0; - } - else if(message.isType("TeleportMessage")) - { - MESSAGE_PROFILER_BLOCK("TeleportMessage"); - ri = static_cast(message).getByteStream().begin(); - TeleportMessage const msg(ri); - handleTeleportMessage(msg); - } - else if (message.isType("TeleportToMessage")) - { - MESSAGE_PROFILER_BLOCK("TeleportToMessage"); - ri = static_cast(message).getByteStream().begin(); - TeleportToMessage const msg(ri); - ServerObject * const serverObj = safe_cast(NetworkIdManager::getObjectById(msg.getTargetId())); - if (serverObj && serverObj->isAuthoritative()) - { + case constcrc("BiographyMessage") : { + MESSAGE_PROFILER_BLOCK("BiographyMessage"); + ri = static_cast(message).getByteStream().begin(); + BiographyMessage const msg(ri); + BiographyManager::onBiographyRetrieved(msg.getOwner(), msg.getBio()); + break; + } + case constcrc("LoadContainedObjectMessage") : { + MESSAGE_PROFILER_BLOCK("LoadContainedObjectMessage"); + ri = static_cast(message).getByteStream().begin(); + LoadContainedObjectMessage const m(ri); + ServerObject *const obj = safe_cast(NetworkIdManager::getObjectById(m.getContainerId())); + if (obj) { + WARNING(!obj + ->isAuthoritative(), ("Got LoadContainedObjectMessage, but the container is not authoritative. Container is %s, Object id %s", + obj->getDebugInformation().c_str(), m.getObjectId().getValueString().c_str())); - // send teleport message - Object const * const firstParent = ContainerInterface::getFirstParentInWorld(*serverObj); - if (firstParent) - { - ServerMessageForwarding::begin(msg.getProcessId()); - - TeleportMessage const teleportMessage( - msg.getActorId(), - serverObj->getSceneId(), - firstParent->getPosition_w(), - firstParent->getAttachedTo() ? firstParent->getAttachedTo()->getNetworkId() : NetworkId::cms_invalid, - firstParent->getPosition_p()); - ServerMessageForwarding::send(teleportMessage); - - ServerMessageForwarding::end(); + obj->onContainedObjectLoaded(m.getObjectId()); } + else { + WARNING(true, ("Got LoadContainedObjectMessage, but could not find the container. Container id %s, Object id %s", + m.getContainerId().getValueString().c_str(), m.getObjectId().getValueString().c_str())); + } + break; } - } - else if(message.isType("RetrievedItemLoadMessage")) - { - MESSAGE_PROFILER_BLOCK("RetrievedItemLoadMessage"); - ri = static_cast(message).getByteStream().begin(); - RetrievedItemLoadMessage const msg(ri); - handleRetrievedItemLoadMessage(msg); - } - else if(message.isType("BiographyMessage")) - { - MESSAGE_PROFILER_BLOCK("BiographyMessage"); - ri = static_cast(message).getByteStream().begin(); - BiographyMessage const msg(ri); - BiographyManager::onBiographyRetrieved(msg.getOwner(),msg.getBio()); - } - else if(message.isType("LoadContainedObjectMessage")) - { - MESSAGE_PROFILER_BLOCK("LoadContainedObjectMessage"); - ri = static_cast(message).getByteStream().begin(); - LoadContainedObjectMessage const m(ri); - ServerObject * const obj = safe_cast(NetworkIdManager::getObjectById(m.getContainerId())); - if (obj) - { - WARNING(!obj->isAuthoritative(), ("Got LoadContainedObjectMessage, but the container is not authoritative. Container is %s, Object id %s", - obj->getDebugInformation().c_str(), m.getObjectId().getValueString().c_str())); + case constcrc("LoadContentsMessage") : { + MESSAGE_PROFILER_BLOCK("LoadContentsMessage"); + ri = static_cast(message).getByteStream().begin(); + LoadContentsMessage const m(ri); + ServerObject *const obj = safe_cast(NetworkIdManager::getObjectById(m.getContainerId())); + if (obj) { + WARNING(!obj + ->isAuthoritative(), ("Got LoadContentsMessage, but the container is not authoritative. Container is %s", + obj->getDebugInformation().c_str())); - obj->onContainedObjectLoaded(m.getObjectId()); + obj->onAllContentsLoaded(); + } + else { + WARNING(true, ("Got LoadContentsMessage, but could not find the container. Container id %s", + m.getContainerId().getValueString().c_str())); + } + break; } - else - { - WARNING(true, ("Got LoadContainedObjectMessage, but could not find the container. Container id %s, Object id %s", - m.getContainerId().getValueString().c_str(), m.getObjectId().getValueString().c_str())); + case constcrc("FirstPlanetGameServerIdMessage") : { + MESSAGE_PROFILER_BLOCK("FirstPlanetGameServerIdMessage"); + ri = static_cast(message).getByteStream().begin(); + FirstPlanetGameServerIdMessage const msg(ri); + m_firstGameServerForPlanet = msg.getGameServerId(); + DEBUG_REPORT_LOG(true, ("First game server for %s is %lu\n", ServerWorld::getSceneId() + .c_str(), m_firstGameServerForPlanet)); + break; } - } - else if(message.isType("LoadContentsMessage")) - { - MESSAGE_PROFILER_BLOCK("LoadContentsMessage"); - ri = static_cast(message).getByteStream().begin(); - LoadContentsMessage const m(ri); - ServerObject * const obj = safe_cast(NetworkIdManager::getObjectById(m.getContainerId())); - if (obj) - { - WARNING(!obj->isAuthoritative(),("Got LoadContentsMessage, but the container is not authoritative. Container is %s", - obj->getDebugInformation().c_str())); + case constcrc("CreateDynamicRegionCircleMessage") : { + MESSAGE_PROFILER_BLOCK("CreateDynamicRegionCircleMessage"); + ri = static_cast(message).getByteStream().begin(); + CreateDynamicRegionCircleMessage const msg(ri); + RegionMaster::createNewDynamicRegion(msg.getCenterX(), msg.getCenterZ(), msg.getRadius(), msg.getName(), msg + .getPlanet(), msg.getPvp(), msg.getBuildable(), msg.getMunicipal(), msg.getGeography(), msg + .getMinDifficulty(), msg.getMaxDifficulty(), msg.getSpawnable(), msg.getMission(), msg + .getVisible(), msg.getNotify()); + break; + } + case constcrc("CreateDynamicRegionRectangleMessage") : { + MESSAGE_PROFILER_BLOCK("CreateDynamicRegionRectangleMessage"); + ri = static_cast(message).getByteStream().begin(); + CreateDynamicRegionRectangleMessage const msg(ri); + RegionMaster::createNewDynamicRegion(msg.getMinX(), msg.getMinZ(), msg.getMaxX(), msg.getMaxZ(), msg + .getName(), msg.getPlanet(), msg.getPvp(), msg.getBuildable(), msg.getMunicipal(), msg + .getGeography(), msg.getMinDifficulty(), msg.getMaxDifficulty(), msg.getSpawnable(), msg + .getMission(), msg.getVisible(), msg.getNotify()); + break; + } + case constcrc("CreateGroupMessage") : { + MESSAGE_PROFILER_BLOCK("CreateGroupMessage"); + ri = static_cast(message).getByteStream().begin(); + CreateGroupMessage const msg(ri); + ServerUniverse::getInstance().createGroup(msg.getLeader(), msg.getMembers()); + break; + } + case constcrc("ReloadAdminTableMessage") : { + MESSAGE_PROFILER_BLOCK("ReloadAdminTableMessage"); + ri = static_cast(message).getByteStream().begin(); + ReloadAdminTableMessage const msg(ri); + handleReloadAdminTableMessage(msg); + break; + } + case constcrc("ReloadCommandTableMessage") : { + MESSAGE_PROFILER_BLOCK("ReloadCommandTableMessage"); + ri = static_cast(message).getByteStream().begin(); + ReloadCommandTableMessage const msg(ri); + handleReloadCommandTableMessage(msg); + break; + } + case constcrc("ReloadScriptMessage") : { + MESSAGE_PROFILER_BLOCK("ReloadScriptMessage"); + ri = static_cast(message).getByteStream().begin(); + ReloadScriptMessage const msg(ri); + handleReloadScriptMessage(msg); + break; + } + case constcrc("ReloadTemplateMessage") : { + MESSAGE_PROFILER_BLOCK("ReloadTemplateMessage"); + ri = static_cast(message).getByteStream().begin(); + ReloadTemplateMessage const msg(ri); + handleReloadTemplateMessage(msg); + break; + } + case constcrc("EnableNewJediTrackingMessage") : { + MESSAGE_PROFILER_BLOCK("EnableNewJediTrackingMessage"); + ri = static_cast(message).getByteStream().begin(); + EnableNewJediTrackingMessage const msg(ri); + handleEnableNewJediTrackingMessage(msg); + break; + } + default: { + if (!message.isType(ReloadDatatableMessage::ms_messageName)) { + // GameServer::receiveMessage() is getting too big for the compiler to handle + // so some of the message handling is done in the private helper receiveMessage2() + receiveMessage2(source, message); + } else { + MESSAGE_PROFILER_BLOCK(ReloadDatatableMessage::ms_messageName); + ri = static_cast(message).getByteStream().begin(); + ReloadDatatableMessage const msg(ri); + handleReloadDatatableMessage(msg); + } - obj->onAllContentsLoaded(); + break; } - else - { - WARNING(true,("Got LoadContentsMessage, but could not find the container. Container id %s", - m.getContainerId().getValueString().c_str())); - } - } - else if(message.isType("FirstPlanetGameServerIdMessage")) - { - MESSAGE_PROFILER_BLOCK("FirstPlanetGameServerIdMessage"); - ri = static_cast(message).getByteStream().begin(); - FirstPlanetGameServerIdMessage const msg(ri); - m_firstGameServerForPlanet = msg.getGameServerId(); - DEBUG_REPORT_LOG(true,("First game server for %s is %lu\n",ServerWorld::getSceneId().c_str(),m_firstGameServerForPlanet)); - } - else if(message.isType("CreateDynamicRegionCircleMessage")) - { - MESSAGE_PROFILER_BLOCK("CreateDynamicRegionCircleMessage"); - ri = static_cast(message).getByteStream().begin(); - CreateDynamicRegionCircleMessage const msg(ri); - RegionMaster::createNewDynamicRegion(msg.getCenterX(), msg.getCenterZ(), msg.getRadius(), msg.getName(), msg.getPlanet(), msg.getPvp(), msg.getBuildable(), msg.getMunicipal(), msg.getGeography(), msg.getMinDifficulty(), msg.getMaxDifficulty(), msg.getSpawnable(), msg.getMission(), msg.getVisible(), msg.getNotify()); - } - else if(message.isType("CreateDynamicRegionRectangleMessage")) - { - MESSAGE_PROFILER_BLOCK("CreateDynamicRegionRectangleMessage"); - ri = static_cast(message).getByteStream().begin(); - CreateDynamicRegionRectangleMessage const msg(ri); - RegionMaster::createNewDynamicRegion(msg.getMinX(), msg.getMinZ(), msg.getMaxX(), msg.getMaxZ(), msg.getName(), msg.getPlanet(), msg.getPvp(), msg.getBuildable(), msg.getMunicipal(), msg.getGeography(), msg.getMinDifficulty(), msg.getMaxDifficulty(), msg.getSpawnable(), msg.getMission(), msg.getVisible(), msg.getNotify()); - } - else if(message.isType("CreateGroupMessage")) - { - MESSAGE_PROFILER_BLOCK("CreateGroupMessage"); - ri = static_cast(message).getByteStream().begin(); - CreateGroupMessage const msg(ri); - ServerUniverse::getInstance().createGroup(msg.getLeader(), msg.getMembers()); - } - else if(message.isType("ReloadAdminTableMessage")) - { - MESSAGE_PROFILER_BLOCK("ReloadAdminTableMessage"); - ri = static_cast(message).getByteStream().begin(); - ReloadAdminTableMessage const msg(ri); - handleReloadAdminTableMessage(msg); - } - else if(message.isType("ReloadCommandTableMessage")) - { - MESSAGE_PROFILER_BLOCK("ReloadCommandTableMessage"); - ri = static_cast(message).getByteStream().begin(); - ReloadCommandTableMessage const msg(ri); - handleReloadCommandTableMessage(msg); - } - else if (message.isType(ReloadDatatableMessage::ms_messageName)) - { - MESSAGE_PROFILER_BLOCK(ReloadDatatableMessage::ms_messageName); - ri = static_cast(message).getByteStream().begin(); - ReloadDatatableMessage const msg(ri); - handleReloadDatatableMessage(msg); - } - else if(message.isType("ReloadScriptMessage")) - { - MESSAGE_PROFILER_BLOCK("ReloadScriptMessage"); - ri = static_cast(message).getByteStream().begin(); - ReloadScriptMessage const msg(ri); - handleReloadScriptMessage(msg); - } - else if(message.isType("ReloadTemplateMessage")) - { - MESSAGE_PROFILER_BLOCK("ReloadTemplateMessage"); - ri = static_cast(message).getByteStream().begin(); - ReloadTemplateMessage const msg(ri); - handleReloadTemplateMessage(msg); - } - else if(message.isType("EnableNewJediTrackingMessage")) - { - MESSAGE_PROFILER_BLOCK("EnableNewJediTrackingMessage"); - ri = static_cast(message).getByteStream().begin(); - EnableNewJediTrackingMessage const msg(ri); - handleEnableNewJediTrackingMessage(msg); - } - else - { - // GameServer::receiveMessage() is getting too big for the compiler to handle - // so some of the message handling is done in the private helper receiveMessage2() - receiveMessage2(source, message); } } @@ -2080,1495 +2120,1638 @@ void GameServer::receiveMessage2(const MessageDispatch::Emitter & source, const PROFILER_AUTO_BLOCK_DEFINE("GameServer::receiveMessage2"); - if(message.isType("AuthTransferConfirmMessage")) - { - MESSAGE_PROFILER_BLOCK("AuthTransferConfirmMessage"); - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - AuthTransferTracker::handleConfirmAuthTransfer(msg.getValue().first, msg.getValue().second); - } - else if(message.isType("PersistedPlayerMessage")) - { - MESSAGE_PROFILER_BLOCK("PersistedPlayerMessage"); - ri = static_cast(message).getByteStream().begin(); - PersistedPlayerMessage const msg(ri); - LogoutTracker::onPersisted(msg.getPlayerId()); - sendToPlanetServer(msg); - } - else if(message.isType("RenameCharacterMessageEx")) - { - MESSAGE_PROFILER_BLOCK("RenameCharacterMessageEx"); - ri = static_cast(message).getByteStream().begin(); - RenameCharacterMessageEx msg(ri); - NameManager::getInstance().renamePlayer(msg.getCharacterId(), msg.getNewName(), msg.getNewName()); + const uint32 messageType = message.getType(); - // update the character's name in the citizen and guild listing - if (ServerUniverse::getInstance().isAuthoritative()) - { - std::string const newName(Unicode::wideToNarrow(msg.getNewName())); - GuildInterface::verifyGuildMemberName(msg.getCharacterId(), newName); - CityInterface::verifyCitizenName(msg.getCharacterId(), newName); - CityInterface::verifyPgcChroniclerName(msg.getCharacterId(), newName); + switch(messageType) { + case constcrc("AuthTransferConfirmMessage") : { + MESSAGE_PROFILER_BLOCK("AuthTransferConfirmMessage"); + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + AuthTransferTracker::handleConfirmAuthTransfer(msg.getValue().first, msg.getValue().second); + break; } - } - else if(message.isType("PopulationListMessage")) - { - MESSAGE_PROFILER_BLOCK("PopulationListMessage"); - ri = static_cast(message).getByteStream().begin(); - PopulationListMessage const msg(ri); - ServerUniverse::getInstance().updatePopulationList(msg.getList()); - } - else if (message.isType("CentralPingMessage")) - { - MESSAGE_PROFILER_BLOCK("CentralPingMessage"); - CentralPingMessage const reply; - sendToCentralServer(reply); - } - else if (message.isType("LocateObject")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > > const msg(ri); - - uint32 const responsePid = msg.getValue().first; - NetworkId const &targetId = msg.getValue().second.first; - NetworkId const &responseId = msg.getValue().second.second; - - ServerObject const * const targetObj = safe_cast(NetworkIdManager::getObjectById(targetId)); - if (targetObj) - { - std::vector containers; - for (Object const *o = ContainerInterface::getContainedByObject(*targetObj); o; o = ContainerInterface::getContainedByObject(*o)) - containers.push_back(o->getNetworkId()); - - NetworkId residenceOf; - if (!targetObj->getObjVars().getItem("player_structure.residence.building", residenceOf)) - residenceOf = NetworkId::cms_invalid; - - LocateObjectResponseMessage const msg( - targetId, - responseId, - responsePid, - targetObj->findPosition_w(), - ConfigServerGame::getSceneID(), - targetObj->getObjectTemplateName(), - getProcessId(), - containers, - targetObj->isAuthoritative(), - residenceOf); - - sendToCentralServer(msg); + case constcrc("PersistedPlayerMessage") : { + MESSAGE_PROFILER_BLOCK("PersistedPlayerMessage"); + ri = static_cast(message).getByteStream().begin(); + PersistedPlayerMessage const msg(ri); + LogoutTracker::onPersisted(msg.getPlayerId()); + sendToPlanetServer(msg); + break; } - } - else if (message.isType("LocateObjectByTemplateName")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > > const msg(ri); + case constcrc("RenameCharacterMessageEx") : { + MESSAGE_PROFILER_BLOCK("RenameCharacterMessageEx"); + ri = static_cast(message).getByteStream().begin(); + RenameCharacterMessageEx msg(ri); + NameManager::getInstance().renamePlayer(msg.getCharacterId(), msg.getNewName(), msg.getNewName()); - uint32 const responsePid = msg.getValue().first; - uint32 const templateCrc = msg.getValue().second.first; - NetworkId const & responseId = msg.getValue().second.second; - - NetworkIdManager::NetworkIdObjectHashMap const & allObjects = NetworkIdManager::getAllObjects(); - for (NetworkIdManager::NetworkIdObjectHashMap::const_iterator iter = allObjects.begin(); iter != allObjects.end(); ++iter) - { - if (!iter->second->isAuthoritative()) - { - continue; + // update the character's name in the citizen and guild listing + if (ServerUniverse::getInstance().isAuthoritative()) { + std::string const newName(Unicode::wideToNarrow(msg.getNewName())); + GuildInterface::verifyGuildMemberName(msg.getCharacterId(), newName); + CityInterface::verifyCitizenName(msg.getCharacterId(), newName); + CityInterface::verifyPgcChroniclerName(msg.getCharacterId(), newName); } + break; + } + case constcrc("PopulationListMessage") : { + MESSAGE_PROFILER_BLOCK("PopulationListMessage"); + ri = static_cast(message).getByteStream().begin(); + PopulationListMessage const msg(ri); + ServerUniverse::getInstance().updatePopulationList(msg.getList()); + break; + } + case constcrc("CentralPingMessage") : { + MESSAGE_PROFILER_BLOCK("CentralPingMessage"); + CentralPingMessage const reply; + sendToCentralServer(reply); + break; + } + case constcrc("LocateObject") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < uint32, std::pair < NetworkId, NetworkId > > > + const msg(ri); - ObjectTemplate const * const objectTemplate = iter->second->getObjectTemplate(); - if (objectTemplate && (objectTemplate->getCrcName().getCrc() == templateCrc)) - { - std::vector containers; - for (Object const *o = ContainerInterface::getContainedByObject(*(iter->second)); o; o = ContainerInterface::getContainedByObject(*o)) + uint32 const responsePid = msg.getValue().first; + NetworkId const &targetId = msg.getValue().second.first; + NetworkId const &responseId = msg.getValue().second.second; + + ServerObject const * + const targetObj = safe_cast < ServerObject const * > (NetworkIdManager::getObjectById(targetId)); + if (targetObj) { + std::vector containers; + for (Object const *o = ContainerInterface::getContainedByObject(*targetObj); o; o = ContainerInterface::getContainedByObject(*o)) containers.push_back(o->getNetworkId()); + NetworkId residenceOf; + if (!targetObj->getObjVars().getItem("player_structure.residence.building", residenceOf)) + residenceOf = NetworkId::cms_invalid; + LocateObjectResponseMessage const msg( - iter->second->getNetworkId(), - responseId, - responsePid, - iter->second->findPosition_w(), - ConfigServerGame::getSceneID(), - objectTemplate->getName(), - getProcessId(), - containers, - true, - NetworkId::cms_invalid); + targetId, + responseId, + responsePid, + targetObj->findPosition_w(), + ConfigServerGame::getSceneID(), + targetObj->getObjectTemplateName(), + getProcessId(), + containers, + targetObj->isAuthoritative(), + residenceOf); sendToCentralServer(msg); } + break; } - } - else if (message.isType("LocatePlayerByPartialName")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > > const msg(ri); + case constcrc("LocateObjectByTemplateName") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < uint32, std::pair < uint32, NetworkId > > > + const msg(ri); - uint32 const responsePid = msg.getValue().first; - std::string const & partialName = msg.getValue().second.first; - NetworkId const & responseId = msg.getValue().second.second; + uint32 const responsePid = msg.getValue().first; + uint32 const templateCrc = msg.getValue().second.first; + NetworkId const &responseId = msg.getValue().second.second; - // Try to find player objects with matching names - std::set const &players = PlayerObject::getAllPlayerObjects(); - if (!players.empty()) - { - // Convert the player name to wide character string - Unicode::String const widePartialName = Unicode::toLower(Unicode::utf8ToWide(partialName)); - - // See if a player object has a "matching" first name - std::set::const_iterator i; - for (i = players.begin(); i != players.end(); ++i) - { - PlayerObject const * const playerObject = *i; - CreatureObject const * const creatureObject = playerObject->getCreatureObject(); - - // don't include logged out players waiting to be saved or not initialized - if (!creatureObject || !creatureObject->isInWorld() || !creatureObject->isAuthoritative() || !creatureObject->getClient()) + NetworkIdManager::NetworkIdObjectHashMap const &allObjects = NetworkIdManager::getAllObjects(); + for (NetworkIdManager::NetworkIdObjectHashMap::const_iterator iter = allObjects.begin(); + iter != allObjects.end(); ++iter) { + if (!iter->second->isAuthoritative()) { continue; + } - // Lower case the first name of the player for the comparison - Unicode::String lowerCasePlayerName = Unicode::toLower(creatureObject->getAssignedObjectFirstName()); + ObjectTemplate const *const objectTemplate = iter->second->getObjectTemplate(); + if (objectTemplate && (objectTemplate->getCrcName().getCrc() == templateCrc)) { + std::vector containers; + for (Object const *o = ContainerInterface::getContainedByObject(*(iter + ->second)); o; o = ContainerInterface::getContainedByObject(*o)) + containers.push_back(o->getNetworkId()); - // Try to find the partial name somewhere within the player name - if (partialName == "*" || lowerCasePlayerName.find(widePartialName) != Unicode::String::npos) - { - LocatePlayerResponseMessage const msg( - creatureObject->getNetworkId(), - responseId, - responsePid, - ConfigServerGame::getSceneID(), - creatureObject->findPosition_w(), - getProcessId()); + LocateObjectResponseMessage const msg( + iter->second->getNetworkId(), + responseId, + responsePid, + iter->second->findPosition_w(), + ConfigServerGame::getSceneID(), + objectTemplate->getName(), + getProcessId(), + containers, + true, + NetworkId::cms_invalid); sendToCentralServer(msg); } } + break; } - } - else if (message.isType("LocateWarden")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); + case constcrc("LocatePlayerByPartialName") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < uint32, std::pair < std::string, NetworkId > > > + const msg(ri); - uint32 const responsePid = msg.getValue().first; - NetworkId const & responseId = msg.getValue().second; + uint32 const responsePid = msg.getValue().first; + std::string const &partialName = msg.getValue().second.first; + NetworkId const &responseId = msg.getValue().second.second; - // Try to find warden player objects - std::set const &players = PlayerObject::getAllPlayerObjects(); - if (!players.empty()) - { - std::set::const_iterator i; - for (i = players.begin(); i != players.end(); ++i) - { - PlayerObject const * const playerObject = *i; - CreatureObject const * const creatureObject = playerObject->getCreatureObject(); + // Try to find player objects with matching names + std::set < PlayerObject const * > const &players = PlayerObject::getAllPlayerObjects(); + if (!players.empty()) { + // Convert the player name to wide character string + Unicode::String const widePartialName = Unicode::toLower(Unicode::utf8ToWide(partialName)); - // don't include logged out players waiting to be saved or not initialized - if (!creatureObject || !creatureObject->isInWorld() || !creatureObject->isAuthoritative() || !creatureObject->getClient()) - continue; + // See if a player object has a "matching" first name + std::set < PlayerObject const * > ::const_iterator + i; + for (i = players.begin(); i != players.end(); ++i) { + PlayerObject const *const playerObject = *i; + CreatureObject const *const creatureObject = playerObject->getCreatureObject(); - if (playerObject->isWarden()) - { - LocatePlayerResponseMessage const msg( - creatureObject->getNetworkId(), - responseId, - responsePid, - ConfigServerGame::getSceneID(), - creatureObject->findPosition_w(), - getProcessId()); - - sendToCentralServer(msg); - } - } - } - } - else if (message.isType("LocateCreatureByCreatureName")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > > const msg(ri); - - uint32 const responsePid = msg.getValue().first; - std::string const & creatureName = msg.getValue().second.first; - NetworkId const & responseId = msg.getValue().second.second; - - CreatureObject::AllCreaturesSet const &creatureList = CreatureObject::getAllCreatures(); - for (CreatureObject::AllCreaturesSet::const_iterator i = creatureList.begin(); i != creatureList.end(); ++i) - { - CreatureObject const * const creatureObj = *i; - if (creatureObj->isAuthoritative()) - { - AICreatureController const * const aiCreatureController = AICreatureController::asAiCreatureController(creatureObj->getController()); - if (aiCreatureController == nullptr) - { - continue; - } - - PersistentCrcString const & pcsCreatureName = aiCreatureController->getCreatureName(); - if (pcsCreatureName.isEmpty()) - { - continue; - } - - if (creatureName != pcsCreatureName.getString()) - { - continue; - } - - std::vector containers; - for (Object const *o = ContainerInterface::getContainedByObject(*creatureObj); o; o = ContainerInterface::getContainedByObject(*o)) - containers.push_back(o->getNetworkId()); - - LocateObjectResponseMessage const msg( - creatureObj->getNetworkId(), - responseId, - responsePid, - creatureObj->findPosition_w(), - ConfigServerGame::getSceneID(), - creatureObj->getObjectTemplateName(), - getProcessId(), - containers, - true, - NetworkId::cms_invalid); - - sendToCentralServer(msg); - } - } - } - else if (message.isType("LSBOIReq")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, std::pair, NetworkId> > > const locateStructureByOwnerIdReq(ri); - - handleMessageLocateStructureByOwnerIdReq(*this, locateStructureByOwnerIdReq.getValue().first.first, locateStructureByOwnerIdReq.getValue().first.second, locateStructureByOwnerIdReq.getValue().second.first.first, locateStructureByOwnerIdReq.getValue().second.first.second, locateStructureByOwnerIdReq.getValue().second.second); - } - else if (message.isType("LSBOIRsp")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, std::vector > > const locateStructureByOwnerIdRsp(ri); - - handleMessageLocateStructureByOwnerIdRsp(locateStructureByOwnerIdRsp.getValue().first.second, locateStructureByOwnerIdRsp.getValue().second); - } - else if (message.isType("ReportSystemClockTime")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - -#ifdef WIN32 - std::string hostName = NetworkHandler::getHostName(); -#else - std::string hostName = NetworkHandler::getHumanReadableHostName(); -#endif - - std::string time = FormattedString<1024>().sprintf("(%3d,%5dms) %30s.%-2lu (%3lu) on %35s:%-7d (%lu) ", ObjectTracker::getNumPlayers(), static_cast(Clock::frameTime()*1000), ServerWorld::getSceneId().c_str(), m_preloadAreaId, m_processId, hostName.c_str(), Os::getProcessId(), ServerClock::getInstance().getGameTimeSeconds()); - time += CalendarTime::convertEpochToTimeStringGMT(::time(nullptr)); - - GenericValueTypeMessage > > rsctr( - "ReportSystemClockTimeResponse", std::make_pair(msg.getValue().first, std::make_pair(time, msg.getValue().second))); - - sendToCentralServer(rsctr); - } - else if (message.isType("ReportSystemClockTimeResponse")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > > const msg(ri); - - ConsoleMgr::broadcastString(msg.getValue().second.first, msg.getValue().second.second); - } - else if (message.isType("ReportPlanetaryTime")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - - time_t const timeNow = ::time(nullptr); - std::string time = FormattedString<1024>().sprintf("%30s.%-2lu (%3lu) (%lu) (%ld, ", ServerWorld::getSceneId().c_str(), m_preloadAreaId, m_processId, ServerClock::getInstance().getGameTimeSeconds(), timeNow); - time += CalendarTime::convertEpochToTimeStringGMT(timeNow); - time += ")"; - - const TerrainObject* const terrainObject = TerrainObject::getInstance(); - if (terrainObject) - { - const float environmentCycleTime = terrainObject->getEnvironmentCycleTime(); - if (environmentCycleTime > 0.f) - { - const float day = fmodf(static_cast(ServerClock::getInstance().getGameTimeSeconds()), environmentCycleTime) / environmentCycleTime; - int hour = 6 + static_cast(day * 24.f * 60.f) / 60; - if (hour >= 24) - hour -= 24; - const int minute = static_cast(fmodf(day * 24.f * 60.f, 60.f)); - - time += FormattedString<1024>().sprintf(" (%g, %02d:%02d, %f)", environmentCycleTime, hour, minute, day); - } - else - { - time += FormattedString<1024>().sprintf(" (environmentCycleTime %g is <= 0.f)", environmentCycleTime); - } - } - else - { - time += " (terrainObject is nullptr)"; - } - - GenericValueTypeMessage > > rptr( - "ReportPlanetaryTimeResponse", std::make_pair(msg.getValue().first, std::make_pair(time, msg.getValue().second))); - - sendToCentralServer(rptr); - } - else if (message.isType("ReportPlanetaryTimeResponse")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > > const msg(ri); - - ConsoleMgr::broadcastString(msg.getValue().second.first, msg.getValue().second.second); - } - else if (message.isType("ClusterStartComplete")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - - if (msg.getValue()) - { - // cluster initial start has completed - if (ServerUniverse::getInstance().isAuthoritative()) - { - // add player city travel points - std::map const & allCities = CityInterface::getAllCityInfo(); - for (std::map::const_iterator iter = allCities.begin(); iter != allCities.end(); ++iter) - { - CityInfo const & ci = iter->second; - if (ci.getCityName().empty()) + // don't include logged out players waiting to be saved or not initialized + if (!creatureObject || !creatureObject->isInWorld() || !creatureObject->isAuthoritative() || + !creatureObject->getClient()) continue; - if ((ci.getRadius() >= 400) && (ci.getTravelCost() > 0)) - { - PlanetObject *planet = ServerUniverse::getInstance().getPlanetByName(ci.getPlanet()); - if (planet) - { - planet->addTravelPoint( - ci.getCityName(), - ci.getTravelLoc(), - ci.getTravelCost(), - ci.getTravelInterplanetary(), - TravelPoint::TPT_PC_Shuttleport); + // Lower case the first name of the player for the comparison + Unicode::String lowerCasePlayerName = Unicode::toLower(creatureObject + ->getAssignedObjectFirstName()); + + // Try to find the partial name somewhere within the player name + if (partialName == "*" || lowerCasePlayerName.find(widePartialName) != Unicode::String::npos) { + LocatePlayerResponseMessage const msg( + creatureObject->getNetworkId(), + responseId, + responsePid, + ConfigServerGame::getSceneID(), + creatureObject->findPosition_w(), + getProcessId()); + + sendToCentralServer(msg); + } + } + } + break; + } + case constcrc("LocateWarden") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + + uint32 const responsePid = msg.getValue().first; + NetworkId const &responseId = msg.getValue().second; + + // Try to find warden player objects + std::set < PlayerObject const * > const &players = PlayerObject::getAllPlayerObjects(); + if (!players.empty()) { + std::set < PlayerObject const * > ::const_iterator + i; + for (i = players.begin(); i != players.end(); ++i) { + PlayerObject const *const playerObject = *i; + CreatureObject const *const creatureObject = playerObject->getCreatureObject(); + + // don't include logged out players waiting to be saved or not initialized + if (!creatureObject || !creatureObject->isInWorld() || !creatureObject->isAuthoritative() || + !creatureObject->getClient()) + continue; + + if (playerObject->isWarden()) { + LocatePlayerResponseMessage const msg( + creatureObject->getNetworkId(), + responseId, + responsePid, + ConfigServerGame::getSceneID(), + creatureObject->findPosition_w(), + getProcessId()); + + sendToCentralServer(msg); + } + } + } + break; + } + case constcrc("LocateCreatureByCreatureName") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < uint32, std::pair < std::string, NetworkId > > > + const msg(ri); + + uint32 const responsePid = msg.getValue().first; + std::string const &creatureName = msg.getValue().second.first; + NetworkId const &responseId = msg.getValue().second.second; + + CreatureObject::AllCreaturesSet const &creatureList = CreatureObject::getAllCreatures(); + for (CreatureObject::AllCreaturesSet::const_iterator i = creatureList.begin(); + i != creatureList.end(); ++i) { + CreatureObject const *const creatureObj = *i; + if (creatureObj->isAuthoritative()) { + AICreatureController const *const aiCreatureController = AICreatureController::asAiCreatureController(creatureObj + ->getController()); + if (aiCreatureController == nullptr) { + continue; + } + + PersistentCrcString const &pcsCreatureName = aiCreatureController->getCreatureName(); + if (pcsCreatureName.isEmpty()) { + continue; + } + + if (creatureName != pcsCreatureName.getString()) { + continue; + } + + std::vector containers; + for (Object const *o = ContainerInterface::getContainedByObject(*creatureObj); o; o = ContainerInterface::getContainedByObject(*o)) + containers.push_back(o->getNetworkId()); + + LocateObjectResponseMessage const msg( + creatureObj->getNetworkId(), + responseId, + responsePid, + creatureObj->findPosition_w(), + ConfigServerGame::getSceneID(), + creatureObj->getObjectTemplateName(), + getProcessId(), + containers, + true, + NetworkId::cms_invalid); + + sendToCentralServer(msg); + } + } + break; + } + case constcrc("LSBOIReq") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < uint32, bool >, std::pair < std::pair < NetworkId, + NetworkId >, NetworkId > > > + const locateStructureByOwnerIdReq(ri); + + handleMessageLocateStructureByOwnerIdReq(*this, locateStructureByOwnerIdReq.getValue().first + .first, locateStructureByOwnerIdReq + .getValue().first.second, locateStructureByOwnerIdReq.getValue().second.first + .first, locateStructureByOwnerIdReq.getValue() + .second + .first + .second, locateStructureByOwnerIdReq + .getValue().second.second); + break; + } + case constcrc("LSBOIRsp") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < uint32, NetworkId >, std::vector < std::string > > > + const locateStructureByOwnerIdRsp(ri); + + handleMessageLocateStructureByOwnerIdRsp(locateStructureByOwnerIdRsp.getValue().first + .second, locateStructureByOwnerIdRsp + .getValue().second); + break; + } + case constcrc("ReportSystemClockTime") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + +#ifdef WIN32 + std::string hostName = NetworkHandler::getHostName(); +#else + std::string hostName = NetworkHandler::getHumanReadableHostName(); +#endif + + std::string time = FormattedString<1024>() + .sprintf("(%3d,%5dms) %30s.%-2lu (%3lu) on %35s:%-7d (%lu) ", ObjectTracker::getNumPlayers(), static_cast( + Clock::frameTime() * 1000), ServerWorld::getSceneId() + .c_str(), m_preloadAreaId, m_processId, hostName + .c_str(), Os::getProcessId(), ServerClock::getInstance().getGameTimeSeconds()); + time += CalendarTime::convertEpochToTimeStringGMT(::time(nullptr)); + + GenericValueTypeMessage < std::pair < uint32, std::pair < std::string, NetworkId > > > rsctr( + "ReportSystemClockTimeResponse", std::make_pair(msg.getValue().first, std::make_pair(time, msg + .getValue().second))); + + sendToCentralServer(rsctr); + break; + } + case constcrc("ReportSystemClockTimeResponse") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < uint32, std::pair < std::string, NetworkId > > > + const msg(ri); + + ConsoleMgr::broadcastString(msg.getValue().second.first, msg.getValue().second.second); + break; + } + case constcrc("ReportPlanetaryTime") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + + time_t const timeNow = ::time(nullptr); + std::string time = FormattedString<1024>() + .sprintf("%30s.%-2lu (%3lu) (%lu) (%ld, ", ServerWorld::getSceneId() + .c_str(), m_preloadAreaId, m_processId, ServerClock::getInstance() + .getGameTimeSeconds(), timeNow); + time += CalendarTime::convertEpochToTimeStringGMT(timeNow); + time += ")"; + + const TerrainObject *const terrainObject = TerrainObject::getInstance(); + if (terrainObject) { + const float environmentCycleTime = terrainObject->getEnvironmentCycleTime(); + if (environmentCycleTime > 0.f) { + const float day = fmodf(static_cast(ServerClock::getInstance() + .getGameTimeSeconds()), environmentCycleTime) / environmentCycleTime; + int hour = 6 + static_cast(day * 24.f * 60.f) / 60; + if (hour >= 24) + hour -= 24; + const int minute = static_cast(fmodf(day * 24.f * 60.f, 60.f)); + + time += FormattedString<1024>() + .sprintf(" (%g, %02d:%02d, %f)", environmentCycleTime, hour, minute, day); + } + else { + time += FormattedString<1024>() + .sprintf(" (environmentCycleTime %g is <= 0.f)", environmentCycleTime); + } + } + else { + time += " (terrainObject is nullptr)"; + } + + GenericValueTypeMessage < std::pair < uint32, std::pair < std::string, NetworkId > > > rptr( + "ReportPlanetaryTimeResponse", std::make_pair(msg.getValue().first, std::make_pair(time, msg + .getValue().second))); + + sendToCentralServer(rptr); + break; + } + case constcrc("ReportPlanetaryTimeResponse") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < uint32, std::pair < std::string, NetworkId > > > + const msg(ri); + + ConsoleMgr::broadcastString(msg.getValue().second.first, msg.getValue().second.second); + break; + } + case constcrc("ClusterStartComplete") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + + if (msg.getValue()) { + // cluster initial start has completed + if (ServerUniverse::getInstance().isAuthoritative()) { + // add player city travel points + std::map const &allCities = CityInterface::getAllCityInfo(); + for (std::map::const_iterator iter = allCities.begin(); + iter != allCities.end(); ++iter) { + CityInfo const &ci = iter->second; + if (ci.getCityName().empty()) + continue; + + if ((ci.getRadius() >= 400) && (ci.getTravelCost() > 0)) { + PlanetObject *planet = ServerUniverse::getInstance().getPlanetByName(ci.getPlanet()); + if (planet) { + planet->addTravelPoint( + ci.getCityName(), + ci.getTravelLoc(), + ci.getTravelCost(), + ci.getTravelInterplanetary(), + TravelPoint::TPT_PC_Shuttleport); + } + } + } + + // do some sanity check of GCW score + GuildObject *const go = ServerUniverse::getInstance().getMasterGuildObject(); + CityObject const *const co = ServerUniverse::getInstance().getMasterCityObject(); + if (go && go->isAuthoritative() && co && co->isAuthoritative()) { + // depersist GCW score, if it hasn't already been done + std::map const &gcwImperialScorePercentile = go + ->getGcwImperialScorePercentile(); + if (gcwImperialScorePercentile.empty()) { + // this will also calculate the GCW Region Defender Bonus + go->depersistGcwImperialScorePercentile(); + } + else { + // for sanity's sake, (re)calculate the GCW Region Defender Bonus + for (std::map::const_iterator iter = gcwImperialScorePercentile.begin(); + iter != gcwImperialScorePercentile.end(); ++iter) + go->updateGcwRegionDefenderBonus(iter->first); } } } - // do some sanity check of GCW score - GuildObject * const go = ServerUniverse::getInstance().getMasterGuildObject(); - CityObject const * const co = ServerUniverse::getInstance().getMasterCityObject(); - if (go && go->isAuthoritative() && co && co->isAuthoritative()) - { - // depersist GCW score, if it hasn't already been done - std::map const & gcwImperialScorePercentile = go->getGcwImperialScorePercentile(); - if (gcwImperialScorePercentile.empty()) - { - // this will also calculate the GCW Region Defender Bonus - go->depersistGcwImperialScorePercentile(); + if (ConfigServerGame::getEnableCityCitizenshipFixup() && + ServerUniverse::getInstance().isAuthoritative()) { + std::vector const &allGameServerPids = getAllGameServerPids(); + if (!allGameServerPids.empty()) { + ServerMessageForwarding::beginBroadcast(); + GenericValueTypeMessage clusterStartupResidenceStructureListRequest("CSRSLReq", getProcessId()); + ServerMessageForwarding::send(clusterStartupResidenceStructureListRequest); + ServerMessageForwarding::end(); + + s_clusterStartupResidenceStructureListResponse.clear(); + for (std::vector::const_iterator iter = allGameServerPids.begin(); + iter != allGameServerPids.end(); ++iter) + IGNORE_RETURN(s_clusterStartupResidenceStructureListResponse.insert(*iter)); } - else - { - // for sanity's sake, (re)calculate the GCW Region Defender Bonus - for (std::map::const_iterator iter = gcwImperialScorePercentile.begin(); iter != gcwImperialScorePercentile.end(); ++iter) - go->updateGcwRegionDefenderBonus(iter->first); + else { + s_clusterStartupResidenceStructureListByStructure.clear(); + s_clusterStartupResidenceStructureListResponse.clear(); } } - } - - if (ConfigServerGame::getEnableCityCitizenshipFixup() && ServerUniverse::getInstance().isAuthoritative()) - { - std::vector const & allGameServerPids = getAllGameServerPids(); - if (!allGameServerPids.empty()) - { - ServerMessageForwarding::beginBroadcast(); - GenericValueTypeMessage clusterStartupResidenceStructureListRequest("CSRSLReq", getProcessId()); - ServerMessageForwarding::send(clusterStartupResidenceStructureListRequest); - ServerMessageForwarding::end(); - - s_clusterStartupResidenceStructureListResponse.clear(); - for (std::vector::const_iterator iter = allGameServerPids.begin(); iter != allGameServerPids.end(); ++iter) - IGNORE_RETURN(s_clusterStartupResidenceStructureListResponse.insert(*iter)); - } - else - { + else if (!ConfigServerGame::getEnableCityCitizenshipFixup()) { s_clusterStartupResidenceStructureListByStructure.clear(); s_clusterStartupResidenceStructureListResponse.clear(); } } - else if (!ConfigServerGame::getEnableCityCitizenshipFixup()) - { + else { s_clusterStartupResidenceStructureListByStructure.clear(); s_clusterStartupResidenceStructureListResponse.clear(); } + break; } - else - { - s_clusterStartupResidenceStructureListByStructure.clear(); - s_clusterStartupResidenceStructureListResponse.clear(); - } - } - else if (message.isType("CSRSLReq")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const clusterStartupResidenceStructureListRequest(ri); + case constcrc("CSRSLReq") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const clusterStartupResidenceStructureListRequest(ri); - ServerMessageForwarding::begin(clusterStartupResidenceStructureListRequest.getValue()); + ServerMessageForwarding::begin(clusterStartupResidenceStructureListRequest.getValue()); - std::map > clusterStartupResidenceStructureListByCity; - if (!s_clusterStartupResidenceStructureListByStructure.empty()) - { - for (std::map >::const_iterator iter = s_clusterStartupResidenceStructureListByStructure.begin(); iter != s_clusterStartupResidenceStructureListByStructure.end(); ++iter) - IGNORE_RETURN(clusterStartupResidenceStructureListByCity[iter->second.first].insert(iter->second.second)); - } - - GenericValueTypeMessage > > > clusterStartupResidenceStructureListResponse("CSRSLRsp", std::make_pair(getProcessId(), clusterStartupResidenceStructureListByCity)); - ServerMessageForwarding::send(clusterStartupResidenceStructureListResponse); - ServerMessageForwarding::end(); - - s_clusterStartupResidenceStructureListByStructure.clear(); - s_clusterStartupResidenceStructureListResponse.clear(); - } - else if (message.isType("CSRSLRsp")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > > > const clusterStartupResidenceStructureListResponse(ri); - - if (s_clusterStartupResidenceStructureListResponse.erase(clusterStartupResidenceStructureListResponse.getValue().first) != 0) - { - static std::map > s_clusterStartupResidenceStructureListByCity; - - std::map > const & residenceList = clusterStartupResidenceStructureListResponse.getValue().second; - if (!residenceList.empty()) - { - for (std::map >::const_iterator iter = residenceList.begin(); iter != residenceList.end(); ++iter) - { - if (!iter->second.empty()) - s_clusterStartupResidenceStructureListByCity[iter->first].insert(iter->second.begin(), iter->second.end()); - } + std::map > clusterStartupResidenceStructureListByCity; + if (!s_clusterStartupResidenceStructureListByStructure.empty()) { + for (std::map < NetworkId, std::pair < int, NetworkId > > + ::const_iterator iter = s_clusterStartupResidenceStructureListByStructure + .begin(); iter != s_clusterStartupResidenceStructureListByStructure.end(); + ++iter) + IGNORE_RETURN(clusterStartupResidenceStructureListByCity[iter->second.first] + .insert(iter->second.second)); } - if (s_clusterStartupResidenceStructureListResponse.empty()) - { - // add our own information to the list - if (!s_clusterStartupResidenceStructureListByStructure.empty()) - { - for (std::map >::const_iterator iter = s_clusterStartupResidenceStructureListByStructure.begin(); iter != s_clusterStartupResidenceStructureListByStructure.end(); ++iter) - IGNORE_RETURN(s_clusterStartupResidenceStructureListByCity[iter->second.first].insert(iter->second.second)); + GenericValueTypeMessage < std::pair < uint32, std::map < int, std::set < NetworkId > > > > + clusterStartupResidenceStructureListResponse("CSRSLRsp", std::make_pair(getProcessId(), clusterStartupResidenceStructureListByCity)); + ServerMessageForwarding::send(clusterStartupResidenceStructureListResponse); + ServerMessageForwarding::end(); + + s_clusterStartupResidenceStructureListByStructure.clear(); + s_clusterStartupResidenceStructureListResponse.clear(); + + break; + } + case constcrc("CSRSLRsp") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < uint32, std::map < int, std::set < NetworkId > > > > + const clusterStartupResidenceStructureListResponse(ri); + + if (s_clusterStartupResidenceStructureListResponse + .erase(clusterStartupResidenceStructureListResponse.getValue().first) != 0) { + static std::map > s_clusterStartupResidenceStructureListByCity; + + std::map > const &residenceList = clusterStartupResidenceStructureListResponse + .getValue().second; + if (!residenceList.empty()) { + for (std::map < int, std::set < NetworkId > > ::const_iterator iter = residenceList.begin(); iter != + residenceList + .end(); + ++iter) + { + if (!iter->second.empty()) + s_clusterStartupResidenceStructureListByCity[iter->first] + .insert(iter->second.begin(), iter->second.end()); + } } - // we now have the complete list of every declared structure within - // city limits; besides the mayor, only owners of these structures - // can be in the citizenship list, so fix up the citizenship list - // of all cities right now - - // skip the fixup if it looks like the cluster was started - // without loading the entire planet because it means structures - // were not loaded, so we don't have the information to determine citizenship - if (!s_clusterStartupResidenceStructureListByCity.empty()) - { - // cities that have no declared structures don't have anything in - // the report, so we have to manually add in those cities - std::map > allCityMayors; - std::map const & allCities = CityInterface::getAllCityInfo(); - - for (std::map::const_iterator iterAllCities = allCities.begin(); iterAllCities != allCities.end(); ++iterAllCities) - { - if (s_clusterStartupResidenceStructureListByCity.count(iterAllCities->first) <= 0) - IGNORE_RETURN(s_clusterStartupResidenceStructureListByCity.insert(std::make_pair(iterAllCities->first, std::set()))); - - if (iterAllCities->second.getLeaderId().isValid()) - allCityMayors[iterAllCities->second.getLeaderId()] = std::make_pair(iterAllCities->first, iterAllCities->second.getCityName()); + if (s_clusterStartupResidenceStructureListResponse.empty()) { + // add our own information to the list + if (!s_clusterStartupResidenceStructureListByStructure.empty()) { + for (std::map < NetworkId, std::pair < int, NetworkId > > + ::const_iterator iter = s_clusterStartupResidenceStructureListByStructure + .begin(); iter != s_clusterStartupResidenceStructureListByStructure.end(); + ++iter) + IGNORE_RETURN(s_clusterStartupResidenceStructureListByCity[iter->second.first] + .insert(iter->second.second)); } - // remove citizens (except the mayor) that do not have a declared structure inside the city limits - // if necessary, add as citizen those that have a declared structure inside the city limits - std::string cityName; - std::string citizenName; - int citizenLastLoginTime = 0; - NetworkId currentCityMayor; - CitizenInfo const * currentCityMayorCitizenInfo; - std::string currentCityMayorName; - std::vector citizensToRemove; - std::string citizensToRemoveNames; - std::string citizensToRemoveDeletedNames; - std::string citizensToRemoveInactiveNames; - std::string citizensToAddNames; - bool needToAddMayorAsCitizen; - bool removeCurrentCitizen; - bool removeCurrentCitizenDeleted; - bool removeCurrentCitizenInactive; - bool hasDeclaredResidence; - int const timeNow = static_cast(::time(nullptr)); - bool const citizenInactivePackupActive = (ConfigServerGame::getCityCitizenshipInactivePackupStartTimeEpoch() <= timeNow); - std::map, CitizenInfo> const & allCitizens = CityInterface::getAllCitizensInfo(); - for (std::map >::iterator iterCityId = s_clusterStartupResidenceStructureListByCity.begin(); iterCityId != s_clusterStartupResidenceStructureListByCity.end(); ++iterCityId) - { - CityInfo const & cityInfo = CityInterface::getCityInfo(iterCityId->first); + // we now have the complete list of every declared structure within + // city limits; besides the mayor, only owners of these structures + // can be in the citizenship list, so fix up the citizenship list + // of all cities right now - cityName = cityInfo.getCityName(); - if (cityName.empty()) - continue; + // skip the fixup if it looks like the cluster was started + // without loading the entire planet because it means structures + // were not loaded, so we don't have the information to determine citizenship + if (!s_clusterStartupResidenceStructureListByCity.empty()) { + // cities that have no declared structures don't have anything in + // the report, so we have to manually add in those cities + std::map > allCityMayors; + std::map const &allCities = CityInterface::getAllCityInfo(); - if (!cityInfo.getCityHallId().isValid()) - continue; + for (std::map::const_iterator iterAllCities = allCities.begin(); + iterAllCities != allCities.end(); ++iterAllCities) { + if (s_clusterStartupResidenceStructureListByCity.count(iterAllCities->first) <= 0) + IGNORE_RETURN(s_clusterStartupResidenceStructureListByCity + .insert(std::make_pair(iterAllCities->first, std::set()))); - currentCityMayor = cityInfo.getLeaderId(); - if (currentCityMayor.isValid()) - currentCityMayorCitizenInfo = CityInterface::getCitizenInfo(iterCityId->first, currentCityMayor); - else - currentCityMayorCitizenInfo = nullptr; + if (iterAllCities->second.getLeaderId().isValid()) + allCityMayors[iterAllCities->second.getLeaderId()] = std::make_pair(iterAllCities + ->first, iterAllCities->second.getCityName()); + } - if (currentCityMayorCitizenInfo) - currentCityMayorName = currentCityMayorCitizenInfo->m_citizenName; - else - currentCityMayorName.clear(); - - if (currentCityMayor.isValid() && !currentCityMayorCitizenInfo) - needToAddMayorAsCitizen = true; - else - needToAddMayorAsCitizen = false; - - LOG("CityFixup", ("City %d (%s:%s, %s:%s) has %d declared structures within its city limits.", iterCityId->first, cityName.c_str(), cityInfo.getCityHallId().getValueString().c_str(), currentCityMayorName.c_str(), currentCityMayor.getValueString().c_str(), iterCityId->second.size())); - - // remove any current citizen who has not logged in for 90 days and is not marked - // as a "protected citizen" OR who no longer exists in the DB OR who does not have - // a declared structure in the city EXCEPT the mayor of the city; also remove any - // current citizen who is a mayor of another city, since mayor can only be the - // citizen of the city that they are mayor of - static const Unicode::String mailSubjectRemove = Unicode::narrowToWide("@" + StringId("city/city", "city_fixup_remove_citizens_subject").getCanonicalRepresentation()); - citizensToRemove.clear(); - citizensToRemoveNames.clear(); - citizensToRemoveDeletedNames.clear(); - citizensToRemoveInactiveNames.clear(); - for (std::map, CitizenInfo>::const_iterator iterCurrentCitizen = allCitizens.lower_bound(std::make_pair(iterCityId->first, NetworkId::cms_invalid)); iterCurrentCitizen != allCitizens.end(); ++iterCurrentCitizen) + // remove citizens (except the mayor) that do not have a declared structure inside the city limits + // if necessary, add as citizen those that have a declared structure inside the city limits + std::string cityName; + std::string citizenName; + int citizenLastLoginTime = 0; + NetworkId currentCityMayor; + CitizenInfo const *currentCityMayorCitizenInfo; + std::string currentCityMayorName; + std::vector citizensToRemove; + std::string citizensToRemoveNames; + std::string citizensToRemoveDeletedNames; + std::string citizensToRemoveInactiveNames; + std::string citizensToAddNames; + bool needToAddMayorAsCitizen; + bool removeCurrentCitizen; + bool removeCurrentCitizenDeleted; + bool removeCurrentCitizenInactive; + bool hasDeclaredResidence; + int const timeNow = static_cast(::time(nullptr)); + bool const citizenInactivePackupActive = ( + ConfigServerGame::getCityCitizenshipInactivePackupStartTimeEpoch() <= timeNow); + std::map , CitizenInfo> const &allCitizens = CityInterface::getAllCitizensInfo(); + for (std::map < int, std::set < NetworkId > > + ::iterator iterCityId = s_clusterStartupResidenceStructureListByCity + .begin(); iterCityId != s_clusterStartupResidenceStructureListByCity.end(); + ++iterCityId) { - if (iterCurrentCitizen->first.first != iterCityId->first) - break; + CityInfo const &cityInfo = CityInterface::getCityInfo(iterCityId->first); - // the erase() will tell us whether this current citizen is confirmed to have - // a declared structure in the city; what it also does for us is whoever is left - // in the list after all the erase() is done are people who have a declared - // structure in the city but are not current citizens, and will need to be added - // as citizens - citizenName = iterCurrentCitizen->second.m_citizenName; - removeCurrentCitizen = false; - removeCurrentCitizenDeleted = false; - removeCurrentCitizenInactive = false; - hasDeclaredResidence = (iterCityId->second.erase(iterCurrentCitizen->first.second) >= 1); + cityName = cityInfo.getCityName(); + if (cityName.empty()) + continue; - // mayor never gets removed - if (iterCurrentCitizen->first.second != currentCityMayor) + if (!cityInfo.getCityHallId().isValid()) + continue; + + currentCityMayor = cityInfo.getLeaderId(); + if (currentCityMayor.isValid()) + currentCityMayorCitizenInfo = CityInterface::getCitizenInfo(iterCityId + ->first, currentCityMayor); + else + currentCityMayorCitizenInfo = nullptr; + + if (currentCityMayorCitizenInfo) + currentCityMayorName = currentCityMayorCitizenInfo->m_citizenName; + else + currentCityMayorName.clear(); + + if (currentCityMayor.isValid() && !currentCityMayorCitizenInfo) + needToAddMayorAsCitizen = true; + else + needToAddMayorAsCitizen = false; + + LOG("CityFixup", ("City %d (%s:%s, %s:%s) has %d declared structures within its city limits.", iterCityId + ->first, cityName.c_str(), cityInfo.getCityHallId().getValueString() + .c_str(), currentCityMayorName + .c_str(), currentCityMayor.getValueString().c_str(), iterCityId->second.size())); + + // remove any current citizen who has not logged in for 90 days and is not marked + // as a "protected citizen" OR who no longer exists in the DB OR who does not have + // a declared structure in the city EXCEPT the mayor of the city; also remove any + // current citizen who is a mayor of another city, since mayor can only be the + // citizen of the city that they are mayor of + static const Unicode::String mailSubjectRemove = Unicode::narrowToWide("@" + + StringId("city/city", "city_fixup_remove_citizens_subject") + .getCanonicalRepresentation()); + citizensToRemove.clear(); + citizensToRemoveNames.clear(); + citizensToRemoveDeletedNames.clear(); + citizensToRemoveInactiveNames.clear(); + for (std::map < std::pair < int, NetworkId >, CitizenInfo > + ::const_iterator iterCurrentCitizen = allCitizens + .lower_bound(std::make_pair(iterCityId->first, NetworkId::cms_invalid)); + iterCurrentCitizen != allCitizens.end(); + ++iterCurrentCitizen) { - if (!hasDeclaredResidence) - { - // remove citizen because he doesn't have a declared residence inside the city limits - removeCurrentCitizen = true; - LOG("CustomerService", ("CityFixup: removed %s (%s) (no declared residence) as citizen of city %d (%s).", iterCurrentCitizen->first.second.getValueString().c_str(), citizenName.c_str(), iterCityId->first, cityName.c_str())); - } - else if (allCityMayors.count(iterCurrentCitizen->first.second) >= 1) - { - // remove citizen because he is already the mayor of another city - removeCurrentCitizen = true; - LOG("CustomerService", ("CityFixup: removed %s (%s) (already mayor of %d:%s) as citizen of city %d (%s).", iterCurrentCitizen->first.second.getValueString().c_str(), citizenName.c_str(), allCityMayors[iterCurrentCitizen->first.second].first, allCityMayors[iterCurrentCitizen->first.second].second.c_str(), iterCityId->first, cityName.c_str())); - } - else - { - citizenLastLoginTime = NameManager::getInstance().getPlayerLastLoginTime(iterCurrentCitizen->first.second); - if (citizenLastLoginTime <= 0) - { - // remove citizen because he no longer exists in the DB + if (iterCurrentCitizen->first.first != iterCityId->first) + break; + + // the erase() will tell us whether this current citizen is confirmed to have + // a declared structure in the city; what it also does for us is whoever is left + // in the list after all the erase() is done are people who have a declared + // structure in the city but are not current citizens, and will need to be added + // as citizens + citizenName = iterCurrentCitizen->second.m_citizenName; + removeCurrentCitizen = false; + removeCurrentCitizenDeleted = false; + removeCurrentCitizenInactive = false; + hasDeclaredResidence = (iterCityId->second.erase(iterCurrentCitizen->first.second) >= + 1); + + // mayor never gets removed + if (iterCurrentCitizen->first.second != currentCityMayor) { + if (!hasDeclaredResidence) { + // remove citizen because he doesn't have a declared residence inside the city limits removeCurrentCitizen = true; - removeCurrentCitizenDeleted = true; - LOG("CustomerService", ("CityFixup: removed %s (%s) (deleted) as citizen of city %d (%s).", iterCurrentCitizen->first.second.getValueString().c_str(), citizenName.c_str(), iterCityId->first, cityName.c_str())); + LOG("CustomerService", ("CityFixup: removed %s (%s) (no declared residence) as citizen of city %d (%s).", iterCurrentCitizen + ->first.second.getValueString().c_str(), citizenName.c_str(), iterCityId + ->first, cityName.c_str())); } - else if (citizenInactivePackupActive && ((citizenLastLoginTime + ConfigServerGame::getCityCitizenshipInactivePackupInactiveTimeSeconds()) <= timeNow) && !(iterCurrentCitizen->second.m_citizenPermissions & CitizenPermissions::InactiveProtected)) - { - // remove citizen because he has not logged in for 90 days and is not marked as a "protected citizen" + else if (allCityMayors.count(iterCurrentCitizen->first.second) >= 1) { + // remove citizen because he is already the mayor of another city removeCurrentCitizen = true; - removeCurrentCitizenInactive = true; - LOG("CustomerService", ("CityFixup: removed %s (%s) (inactive %s) as citizen of city %d (%s).", iterCurrentCitizen->first.second.getValueString().c_str(), citizenName.c_str(), CalendarTime::convertSecondsToDHMS(static_cast(timeNow - citizenLastLoginTime)).c_str(), iterCityId->first, cityName.c_str())); + LOG("CustomerService", ("CityFixup: removed %s (%s) (already mayor of %d:%s) as citizen of city %d (%s).", iterCurrentCitizen + ->first.second.getValueString().c_str(), citizenName + .c_str(), allCityMayors[iterCurrentCitizen->first.second] + .first, allCityMayors[iterCurrentCitizen->first.second].second + .c_str(), iterCityId + ->first, cityName.c_str())); + } + else { + citizenLastLoginTime = NameManager::getInstance() + .getPlayerLastLoginTime(iterCurrentCitizen->first.second); + if (citizenLastLoginTime <= 0) { + // remove citizen because he no longer exists in the DB + removeCurrentCitizen = true; + removeCurrentCitizenDeleted = true; + LOG("CustomerService", ("CityFixup: removed %s (%s) (deleted) as citizen of city %d (%s).", iterCurrentCitizen + ->first.second.getValueString().c_str(), citizenName + .c_str(), iterCityId->first, cityName.c_str())); + } + else if (citizenInactivePackupActive && ((citizenLastLoginTime + + ConfigServerGame::getCityCitizenshipInactivePackupInactiveTimeSeconds()) <= + timeNow) && + !(iterCurrentCitizen->second.m_citizenPermissions & + CitizenPermissions::InactiveProtected)) { + // remove citizen because he has not logged in for 90 days and is not marked as a "protected citizen" + removeCurrentCitizen = true; + removeCurrentCitizenInactive = true; + LOG("CustomerService", ("CityFixup: removed %s (%s) (inactive %s) as citizen of city %d (%s).", iterCurrentCitizen + ->first.second.getValueString().c_str(), citizenName + .c_str(), CalendarTime::convertSecondsToDHMS(static_cast( + timeNow - citizenLastLoginTime)).c_str(), iterCityId + ->first, cityName.c_str())); + } + } + } + + if (removeCurrentCitizen) { + // build up list of citizens to remove + citizensToRemove.push_back(iterCurrentCitizen->first.second); + + // build list of citizens that gets removed to send mail to mayor + if (!currentCityMayorName.empty()) { + if (removeCurrentCitizenDeleted) { + if (!citizensToRemoveDeletedNames.empty()) + citizensToRemoveDeletedNames += "\r\n"; + + citizensToRemoveDeletedNames += citizenName; + + // send multiple mail if there are too many names + if (citizensToRemoveDeletedNames.size() > 2000) { + ProsePackage pp; + pp.stringId = StringId("city/city", "city_fixup_remove_deleted_citizens_body"); + pp.target.str = Unicode::narrowToWide(citizensToRemoveDeletedNames); + + Unicode::String oob; + OutOfBandPackager::pack(pp, -1, oob); + + Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); + + citizensToRemoveDeletedNames.clear(); + } + } + else if (removeCurrentCitizenInactive) { + if (!citizensToRemoveInactiveNames.empty()) + citizensToRemoveInactiveNames += "\r\n"; + + citizensToRemoveInactiveNames += citizenName; + citizensToRemoveInactiveNames += " (offline "; + citizensToRemoveInactiveNames += CalendarTime::convertSecondsToDHMS(static_cast( + timeNow - citizenLastLoginTime)); + citizensToRemoveInactiveNames += ")"; + + // send multiple mail if there are too many names + if (citizensToRemoveInactiveNames.size() > 2000) { + ProsePackage pp; + pp.stringId = StringId("city/city", "city_fixup_remove_inactive_citizens_body"); + pp.target.str = Unicode::narrowToWide(citizensToRemoveInactiveNames); + + Unicode::String oob; + OutOfBandPackager::pack(pp, -1, oob); + + Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); + + citizensToRemoveInactiveNames.clear(); + } + } + else { + if (!citizensToRemoveNames.empty()) + citizensToRemoveNames += "\r\n"; + + citizensToRemoveNames += citizenName; + + // send multiple mail if there are too many names + if (citizensToRemoveNames.size() > 2000) { + ProsePackage pp; + pp.stringId = StringId("city/city", "city_fixup_remove_citizens_body"); + pp.target.str = Unicode::narrowToWide(citizensToRemoveNames); + + Unicode::String oob; + OutOfBandPackager::pack(pp, -1, oob); + + Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); + + citizensToRemoveNames.clear(); + } + } } } } - if (removeCurrentCitizen) - { - // build up list of citizens to remove - citizensToRemove.push_back(iterCurrentCitizen->first.second); - - // build list of citizens that gets removed to send mail to mayor - if (!currentCityMayorName.empty()) - { - if (removeCurrentCitizenDeleted) - { - if (!citizensToRemoveDeletedNames.empty()) - citizensToRemoveDeletedNames += "\r\n"; - - citizensToRemoveDeletedNames += citizenName; - - // send multiple mail if there are too many names - if (citizensToRemoveDeletedNames.size() > 2000) - { - ProsePackage pp; - pp.stringId = StringId("city/city", "city_fixup_remove_deleted_citizens_body"); - pp.target.str = Unicode::narrowToWide(citizensToRemoveDeletedNames); - - Unicode::String oob; - OutOfBandPackager::pack(pp, -1, oob); - - Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); - - citizensToRemoveDeletedNames.clear(); - } - } - else if (removeCurrentCitizenInactive) - { - if (!citizensToRemoveInactiveNames.empty()) - citizensToRemoveInactiveNames += "\r\n"; - - citizensToRemoveInactiveNames += citizenName; - citizensToRemoveInactiveNames += " (offline "; - citizensToRemoveInactiveNames += CalendarTime::convertSecondsToDHMS(static_cast(timeNow - citizenLastLoginTime)); - citizensToRemoveInactiveNames += ")"; - - // send multiple mail if there are too many names - if (citizensToRemoveInactiveNames.size() > 2000) - { - ProsePackage pp; - pp.stringId = StringId("city/city", "city_fixup_remove_inactive_citizens_body"); - pp.target.str = Unicode::narrowToWide(citizensToRemoveInactiveNames); - - Unicode::String oob; - OutOfBandPackager::pack(pp, -1, oob); - - Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); - - citizensToRemoveInactiveNames.clear(); - } - } - else - { - if (!citizensToRemoveNames.empty()) - citizensToRemoveNames += "\r\n"; - - citizensToRemoveNames += citizenName; - - // send multiple mail if there are too many names - if (citizensToRemoveNames.size() > 2000) - { - ProsePackage pp; - pp.stringId = StringId("city/city", "city_fixup_remove_citizens_body"); - pp.target.str = Unicode::narrowToWide(citizensToRemoveNames); - - Unicode::String oob; - OutOfBandPackager::pack(pp, -1, oob); - - Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); - - citizensToRemoveNames.clear(); - } - } - } - } - } - - if (!currentCityMayorName.empty()) - { - if (!citizensToRemoveDeletedNames.empty()) - { - ProsePackage pp; - pp.stringId = StringId("city/city", "city_fixup_remove_deleted_citizens_body"); - pp.target.str = Unicode::narrowToWide(citizensToRemoveDeletedNames); - - Unicode::String oob; - OutOfBandPackager::pack(pp, -1, oob); - - Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); - } - - if (!citizensToRemoveInactiveNames.empty()) - { - ProsePackage pp; - pp.stringId = StringId("city/city", "city_fixup_remove_inactive_citizens_body"); - pp.target.str = Unicode::narrowToWide(citizensToRemoveInactiveNames); - - Unicode::String oob; - OutOfBandPackager::pack(pp, -1, oob); - - Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); - } - - if (!citizensToRemoveNames.empty()) - { - ProsePackage pp; - pp.stringId = StringId("city/city", "city_fixup_remove_citizens_body"); - pp.target.str = Unicode::narrowToWide(citizensToRemoveNames); - - Unicode::String oob; - OutOfBandPackager::pack(pp, -1, oob); - - Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); - } - } - - // remove citizens - for (std::vector::const_iterator iterCitizenToRemove = citizensToRemove.begin(); iterCitizenToRemove != citizensToRemove.end(); ++iterCitizenToRemove) - { - CityInterface::removeCitizen(iterCityId->first, *iterCitizenToRemove, false); - } - - // add mayor as a citizen if necessary - if (needToAddMayorAsCitizen) - IGNORE_RETURN(iterCityId->second.insert(currentCityMayor)); - - // add citizens - static const Unicode::String mailSubjectAdd = Unicode::narrowToWide("@" + StringId("city/city", "city_fixup_add_citizens_subject").getCanonicalRepresentation()); - citizensToAddNames.clear(); - for (std::set::const_iterator iterCitizenToAdd = iterCityId->second.begin(); iterCitizenToAdd != iterCityId->second.end(); ++iterCitizenToAdd) - { - // make sure it's a valid player - if (!NameManager::getInstance().isPlayer(*iterCitizenToAdd)) - continue; - - // citizens who have not logged in within the past 90 days should not be - // added as a citizen EXCEPT for the mayor who should always be a citizen - if ((*iterCitizenToAdd != currentCityMayor) && citizenInactivePackupActive) - { - citizenLastLoginTime = NameManager::getInstance().getPlayerLastLoginTime(*iterCitizenToAdd); - if ((citizenLastLoginTime <= 0) || ((citizenLastLoginTime + ConfigServerGame::getCityCitizenshipInactivePackupInactiveTimeSeconds()) <= timeNow)) - continue; - } - - // don't add someone who is already a mayor of another city, unless - // we are adding this city's mayor as a citizen of this city - if ((*iterCitizenToAdd != currentCityMayor) && (allCityMayors.count(*iterCitizenToAdd) >= 1)) - continue; - - // add the new citizen - citizenName = NameManager::getInstance().getPlayerFullName(*iterCitizenToAdd); - if (citizenName.empty()) - continue; - - // build list of citizens that gets added to send mail to mayor - if (!currentCityMayorName.empty()) - { - if (!citizensToAddNames.empty()) - citizensToAddNames += "\r\n"; - - citizensToAddNames += citizenName; - - // send multiple mail if there are too many names - if (citizensToAddNames.size() > 2000) - { + if (!currentCityMayorName.empty()) { + if (!citizensToRemoveDeletedNames.empty()) { ProsePackage pp; - pp.stringId = StringId("city/city", "city_fixup_add_citizens_body"); - pp.target.str = Unicode::narrowToWide(citizensToAddNames); + pp.stringId = StringId("city/city", "city_fixup_remove_deleted_citizens_body"); + pp.target.str = Unicode::narrowToWide(citizensToRemoveDeletedNames); Unicode::String oob; OutOfBandPackager::pack(pp, -1, oob); - Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectAdd, Unicode::emptyString, oob); + Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); + } - citizensToAddNames.clear(); + if (!citizensToRemoveInactiveNames.empty()) { + ProsePackage pp; + pp.stringId = StringId("city/city", "city_fixup_remove_inactive_citizens_body"); + pp.target.str = Unicode::narrowToWide(citizensToRemoveInactiveNames); + + Unicode::String oob; + OutOfBandPackager::pack(pp, -1, oob); + + Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); + } + + if (!citizensToRemoveNames.empty()) { + ProsePackage pp; + pp.stringId = StringId("city/city", "city_fixup_remove_citizens_body"); + pp.target.str = Unicode::narrowToWide(citizensToRemoveNames); + + Unicode::String oob; + OutOfBandPackager::pack(pp, -1, oob); + + Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectRemove, Unicode::emptyString, oob); } } - if (*iterCitizenToAdd == currentCityMayor) - LOG("CustomerService", ("CityFixup: added %s (%s) (is mayor) as citizen of city %d (%s).", iterCitizenToAdd->getValueString().c_str(), citizenName.c_str(), iterCityId->first, cityName.c_str())); - else - LOG("CustomerService", ("CityFixup: added %s (%s) (has declared residence) as citizen of city %d (%s).", iterCitizenToAdd->getValueString().c_str(), citizenName.c_str(), iterCityId->first, cityName.c_str())); + // remove citizens + for (std::vector::const_iterator iterCitizenToRemove = citizensToRemove.begin(); + iterCitizenToRemove != citizensToRemove.end(); ++iterCitizenToRemove) { + CityInterface::removeCitizen(iterCityId->first, *iterCitizenToRemove, false); + } - CityInterface::setCitizenInfo(iterCityId->first, *iterCitizenToAdd, citizenName, NetworkId::cms_invalid, CitizenPermissions::Citizen); - } + // add mayor as a citizen if necessary + if (needToAddMayorAsCitizen) + IGNORE_RETURN(iterCityId->second.insert(currentCityMayor)); - if (!citizensToAddNames.empty() && !currentCityMayorName.empty()) - { - ProsePackage pp; - pp.stringId = StringId("city/city", "city_fixup_add_citizens_body"); - pp.target.str = Unicode::narrowToWide(citizensToAddNames); + // add citizens + static const Unicode::String mailSubjectAdd = Unicode::narrowToWide("@" + + StringId("city/city", "city_fixup_add_citizens_subject") + .getCanonicalRepresentation()); + citizensToAddNames.clear(); + for (std::set::const_iterator iterCitizenToAdd = iterCityId->second.begin(); + iterCitizenToAdd != iterCityId->second.end(); ++iterCitizenToAdd) { + // make sure it's a valid player + if (!NameManager::getInstance().isPlayer(*iterCitizenToAdd)) + continue; - Unicode::String oob; - OutOfBandPackager::pack(pp, -1, oob); + // citizens who have not logged in within the past 90 days should not be + // added as a citizen EXCEPT for the mayor who should always be a citizen + if ((*iterCitizenToAdd != currentCityMayor) && citizenInactivePackupActive) { + citizenLastLoginTime = NameManager::getInstance() + .getPlayerLastLoginTime(*iterCitizenToAdd); + if ((citizenLastLoginTime <= 0) || ((citizenLastLoginTime + + ConfigServerGame::getCityCitizenshipInactivePackupInactiveTimeSeconds()) <= + timeNow)) + continue; + } - Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectAdd, Unicode::emptyString, oob); + // don't add someone who is already a mayor of another city, unless + // we are adding this city's mayor as a citizen of this city + if ((*iterCitizenToAdd != currentCityMayor) && + (allCityMayors.count(*iterCitizenToAdd) >= 1)) + continue; + + // add the new citizen + citizenName = NameManager::getInstance().getPlayerFullName(*iterCitizenToAdd); + if (citizenName.empty()) + continue; + + // build list of citizens that gets added to send mail to mayor + if (!currentCityMayorName.empty()) { + if (!citizensToAddNames.empty()) + citizensToAddNames += "\r\n"; + + citizensToAddNames += citizenName; + + // send multiple mail if there are too many names + if (citizensToAddNames.size() > 2000) { + ProsePackage pp; + pp.stringId = StringId("city/city", "city_fixup_add_citizens_body"); + pp.target.str = Unicode::narrowToWide(citizensToAddNames); + + Unicode::String oob; + OutOfBandPackager::pack(pp, -1, oob); + + Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectAdd, Unicode::emptyString, oob); + + citizensToAddNames.clear(); + } + } + + if (*iterCitizenToAdd == currentCityMayor) + LOG("CustomerService", ("CityFixup: added %s (%s) (is mayor) as citizen of city %d (%s).", iterCitizenToAdd + ->getValueString().c_str(), citizenName.c_str(), iterCityId->first, cityName + .c_str())); + else + LOG("CustomerService", ("CityFixup: added %s (%s) (has declared residence) as citizen of city %d (%s).", iterCitizenToAdd + ->getValueString().c_str(), citizenName.c_str(), iterCityId->first, cityName + .c_str())); + + CityInterface::setCitizenInfo(iterCityId + ->first, *iterCitizenToAdd, citizenName, NetworkId::cms_invalid, CitizenPermissions::Citizen); + } + + if (!citizensToAddNames.empty() && !currentCityMayorName.empty()) { + ProsePackage pp; + pp.stringId = StringId("city/city", "city_fixup_add_citizens_body"); + pp.target.str = Unicode::narrowToWide(citizensToAddNames); + + Unicode::String oob; + OutOfBandPackager::pack(pp, -1, oob); + + Chat::sendPersistentMessage("City Hall", currentCityMayorName, mailSubjectAdd, Unicode::emptyString, oob); + } } } + + s_clusterStartupResidenceStructureListByCity.clear(); + s_clusterStartupResidenceStructureListByStructure.clear(); + s_clusterStartupResidenceStructureListResponse.clear(); + + CityInterface::checkForDualCitizenship(); } - - s_clusterStartupResidenceStructureListByCity.clear(); - s_clusterStartupResidenceStructureListByStructure.clear(); - s_clusterStartupResidenceStructureListResponse.clear(); - - CityInterface::checkForDualCitizenship(); } + break; } - } - else if (message.isType("LocateStructureMessage")) - { - ri = static_cast(message).getByteStream().begin(); - LocateStructureMessage const msg(ri); - GameServer::getInstance().sendToCentralServer(msg); - } - else if (message.isType("LoadStructureMessage")) - { - ri = static_cast(message).getByteStream().begin(); - LoadStructureMessage const msg(ri); - - ServerObject * const house = ServerWorld::findObjectByNetworkId(msg.getStructureId()); - if (house) - { - //result += Unicode::narrowToWide("Error. Object already loaded."); - std::string replyMessage = "Structure " + msg.getStructureId().getValueString() + " already loaded"; - Chat::sendSystemMessage(msg.getWhoRequested(), Unicode::narrowToWide(replyMessage), Unicode::String()); + case constcrc("LocateStructureMessage") : { + ri = static_cast(message).getByteStream().begin(); + LocateStructureMessage const msg(ri); + GameServer::getInstance().sendToCentralServer(msg); + break; } - else - { - LoadContentsMessage const lcm(msg.getStructureId()); - GameServer::getInstance().sendToDatabaseServer(lcm); - std::string const replyMessage = "Structure " + msg.getStructureId().getValueString() + " is being loaded"; - Chat::sendSystemMessage(msg.getWhoRequested(), Unicode::narrowToWide(replyMessage), Unicode::String()); - } - } - else if (message.isType("LocateObjectResponseMessage")) - { - ri = static_cast(message).getByteStream().begin(); - LocateObjectResponseMessage const msg(ri); + case constcrc("LoadStructureMessage") : { + ri = static_cast(message).getByteStream().begin(); + LoadStructureMessage const msg(ri); - ServerObject * const responseObject = safe_cast(NetworkIdManager::getObjectById(msg.getResponseId())); - if (responseObject && responseObject->isAuthoritative()) - { - int const cityId = CityInterface::getCityAtLocation(msg.getScene(), static_cast(msg.getPosition_w().x), static_cast(msg.getPosition_w().z), 0); - std::string const cityName = CityInterface::getCityInfo(cityId).getCityName(); - - NetworkId const residenceOf = msg.getResidenceOf(); - std::string residenceOfName; - if (residenceOf.isValid()) - residenceOfName = NameManager::getInstance().getPlayerFullName(residenceOf); - - ScriptParams params; - params.addParam(msg.getTargetId(), "target"); - params.addParam(msg.getPosition_w(), "location"); - params.addParam(msg.getScene().c_str(), "scene"); - params.addParam(msg.getSharedTemplateName().c_str(), "sharedTemplateName"); - params.addParam(static_cast(msg.getTargetPid()), "pid"); - params.addParam(msg.getContainers(), "containers"); - params.addParam(msg.getIsAuthoritative(), "isAuthoritative"); - params.addParam(cityId, "cityId"); - params.addParam(cityName.c_str(), "cityName"); - params.addParam(residenceOf, "residenceOfId"); - params.addParam(residenceOfName.c_str(), "residenceOfName"); - - ScriptDictionaryPtr dictionary; - responseObject->getScriptObject()->makeScriptDictionary(params, dictionary); - if (dictionary.get() != nullptr) - { - dictionary->serialize(); - MessageToQueue::getInstance().sendMessageToJava(responseObject->getNetworkId(), "foundObject", dictionary->getSerializedData(), 0, false); + ServerObject *const house = ServerWorld::findObjectByNetworkId(msg.getStructureId()); + if (house) { + //result += Unicode::narrowToWide("Error. Object already loaded."); + std::string replyMessage = "Structure " + msg.getStructureId().getValueString() + " already loaded"; + Chat::sendSystemMessage(msg.getWhoRequested(), Unicode::narrowToWide(replyMessage), Unicode::String()); } - } - } - else if (message.isType("LocatePlayerResponseMessage")) - { - ri = static_cast(message).getByteStream().begin(); - LocatePlayerResponseMessage const msg(ri); - - ServerObject * const responseObject = safe_cast(NetworkIdManager::getObjectById(msg.getResponseId())); - if (responseObject && responseObject->isAuthoritative() && responseObject->getClient()) - { - std::string playerInfo = FormattedString<512>().sprintf("%s (%s) is on server %lu. %s (%.2f, %.2f, %.2f)", - msg.getTargetId().getValueString().c_str(), - NameManager::getInstance().getPlayerFullName(msg.getTargetId()).c_str(), - msg.getTargetPid(), msg.getScene().c_str(), - msg.getPosition_w().x, msg.getPosition_w().y, msg.getPosition_w().z); - - ConsoleMgr::broadcastString(playerInfo, responseObject->getClient()); - } - } - else if(message.isType("PlayerSanityCheck")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - PlayerSanityChecker::handlePlayerSanityCheck(msg.getValue().first, msg.getValue().second); - } - else if(message.isType("PlayerSanityCheckSuccess")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - PlayerSanityChecker::handlePlayerSanityCheckSuccess(msg.getValue()); - } - else if(message.isType("PlayerSanityCheckProxy")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - PlayerSanityChecker::handlePlayerSanityCheckProxy(msg.getValue().first, msg.getValue().second); - } - else if(message.isType("PlayerSanityCheckProxyFail")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - PlayerSanityChecker::handlePlayerSanityCheckProxyFail(msg.getValue().first, msg.getValue().second); - } - else if (message.isType("EnablePlayerSanityCheckerMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - PlayerSanityChecker::enable(msg.getValue()); - } - else if(message.isType("StartSaveReplyMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - - ServerObject const * const requestedBy = safe_cast(NetworkIdManager::getObjectById(msg.getValue().first)); - - if (requestedBy) - { - if (msg.getValue().second) - Chat::sendSystemMessage(*requestedBy,Unicode::narrowToWide("Save has been started"),Unicode::String()); - else - Chat::sendSystemMessage(*requestedBy,Unicode::narrowToWide("Save could not be started because one was already in progress"),Unicode::String()); - } - } - else if(message.isType("DatabaseConsoleReplyMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - - Chat::sendSystemMessage(msg.getValue().first,Unicode::narrowToWide(msg.getValue().second),Unicode::String()); - } - else if(message.isType("FindAuthObject")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - ServerObject const * const so = safe_cast(NetworkIdManager::getObjectById(msg.getValue().first)); - bool const found = so && so->isAuthoritative(); - - GenericValueTypeMessage, bool> > const authResponse( - "FindAuthObjectResponse", - std::make_pair(msg.getValue(), found)); - sendToPlanetServer(authResponse); - } - else if(message.isType("CharacterNamesMessage")) - { - ri = static_cast(message).getByteStream().begin(); - CharacterNamesMessage const msg(ri); - NameManager::getInstance().addPlayers(msg.getIds(), msg.getStationIds(), msg.getNames(), msg.getFullNames(), msg.getCreateTimes(), msg.getLoginTimes()); - } - else if (message.isType ("LocationResponse")) - { - Archive::ReadIterator readIterator = static_cast (message).getByteStream ().begin (); - LocationResponse const locationResponse (readIterator); - - //-- get the script object to invole the trigger on - Object * const object = NetworkIdManager::getObjectById (locationResponse.getNetworkId ()); - if (!object) - { - DEBUG_WARNING (true, ("LocationResponse: could not resolve object %s which asked for a location", locationResponse.getNetworkId ().getValueString ().c_str ())); - return; - } - - ServerObject * const scriptObject = object->asServerObject (); - if (!scriptObject) - { - DEBUG_WARNING (true, ("LocationResponse: object id=%s template=%s is not a server object", object->getNetworkId ().getValueString ().c_str (), object->getObjectTemplateName ())); - return; - } - - //-- if the location is valid, create a reservation object - Vector position_w (locationResponse.getX (), 0.f, locationResponse.getZ ()); - ServerObject * serverObject = 0; - if (locationResponse.getValid ()) - { - //-- construct the name - char objectTemplateName [512]; - snprintf (objectTemplateName, 512, "object/tangible/location/location_%i.iff", static_cast (locationResponse.getRadius ())); - - //-- get the height of the terrain - TerrainObject const * const terrainObject = TerrainObject::getConstInstance (); - if (terrainObject) - terrainObject->getHeightForceChunkCreation (position_w, position_w.y); - - //-- create the object - Transform tr; - tr.setPosition_p(position_w); - serverObject = ServerWorld::createNewObject(objectTemplateName, tr, 0, false); - DEBUG_REPORT_LOG (!serverObject, ("LocationResponse: failed to create object %s\n", objectTemplateName)); - if (serverObject) - serverObject->addToWorld (); - } - - //-- inform script of the result - ScriptParams scriptParameters; - scriptParameters.addParam (locationResponse.getLocationId ().c_str()); - scriptParameters.addParam (serverObject ? serverObject->getNetworkId () : NetworkId::cms_invalid); - scriptParameters.addParam (position_w); - scriptParameters.addParam (locationResponse.getRadius ()); - - if (scriptObject->getScriptObject ()->trigAllScripts (Scripting::TRIG_LOCATION_RECEIVED, scriptParameters) != SCRIPT_CONTINUE) - DEBUG_REPORT_LOG (true, ("LocationResponse: TRIG_LOCATION_RECEIVED: did not return SCRIPT_CONTINUE\n")); - } - else if (message.isType("ReleaseCharacterNameByIdMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - - NameManager::getInstance().releasePlayerName(msg.getValue()); - } - else if (message.isType("AddAttribModName")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - AttribModNameManager::getInstance().addAttribModNameFromRemote(msg.getValue().c_str()); - } - else if (message.isType("AddAttribModNamesList")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - DEBUG_REPORT_LOG(true, ("Received attrib mod names list <%s> from remote server\n", msg.getValue().c_str())); - AttribModNameManager::getInstance().addAttribModNamesListFromRemote(msg.getValue().c_str()); - } - else if(ClusterWideDataClient::handleMessage(source, message)) - { - // nothing else to do with the message since it was - // handled by the Cluster wide data client - } - else if (message.isType("AiCreatureStateMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - - NetworkId const & networkId = msg.getValue().m_networkId; - AiMovementMessage const & movement = msg.getValue().m_movement; - - CreatureObject * const creatureObject = CreatureObject::getCreatureObject(networkId); - - if (creatureObject != nullptr) - { - Controller * const controller = creatureObject->getController(); - - if (controller != nullptr) - { - DEBUG_LOG("debug_ai", ("GameServer::receiveMessage() Received AiCreatureStateMessage for networkId(%s) movementType(%s)", networkId.getValueString().c_str(), AiMovementBase::getMovementString(movement.getMovementType()))); - - int const flags = GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_SERVER; - - // Movement - - controller->appendMessage(CM_aiSetMovement, 0, new AiMovementMessage(movement), flags); + else { + LoadContentsMessage const lcm(msg.getStructureId()); + GameServer::getInstance().sendToDatabaseServer(lcm); + std::string const replyMessage = + "Structure " + msg.getStructureId().getValueString() + " is being loaded"; + Chat::sendSystemMessage(msg.getWhoRequested(), Unicode::narrowToWide(replyMessage), Unicode::String()); } - else - { - WARNING(true, ("GameServer::receiveMessage() Received AiCreatureStateMessage for networkId(%s) movementType(%s) but the object does not have a Controller", networkId.getValueString().c_str(), AiMovementBase::getMovementString(movement.getMovementType()))); + break; + } + case constcrc("LocateObjectResponseMessage") : { + ri = static_cast(message).getByteStream().begin(); + LocateObjectResponseMessage const msg(ri); + + ServerObject *const responseObject = safe_cast(NetworkIdManager::getObjectById(msg + .getResponseId())); + if (responseObject && responseObject->isAuthoritative()) { + int const cityId = CityInterface::getCityAtLocation(msg.getScene(), static_cast(msg.getPosition_w() + .x), static_cast(msg + .getPosition_w().z), 0); + std::string const cityName = CityInterface::getCityInfo(cityId).getCityName(); + + NetworkId const residenceOf = msg.getResidenceOf(); + std::string residenceOfName; + if (residenceOf.isValid()) + residenceOfName = NameManager::getInstance().getPlayerFullName(residenceOf); + + ScriptParams params; + params.addParam(msg.getTargetId(), "target"); + params.addParam(msg.getPosition_w(), "location"); + params.addParam(msg.getScene().c_str(), "scene"); + params.addParam(msg.getSharedTemplateName().c_str(), "sharedTemplateName"); + params.addParam(static_cast(msg.getTargetPid()), "pid"); + params.addParam(msg.getContainers(), "containers"); + params.addParam(msg.getIsAuthoritative(), "isAuthoritative"); + params.addParam(cityId, "cityId"); + params.addParam(cityName.c_str(), "cityName"); + params.addParam(residenceOf, "residenceOfId"); + params.addParam(residenceOfName.c_str(), "residenceOfName"); + + ScriptDictionaryPtr dictionary; + responseObject->getScriptObject()->makeScriptDictionary(params, dictionary); + if (dictionary.get() != nullptr) { + dictionary->serialize(); + MessageToQueue::getInstance() + .sendMessageToJava(responseObject->getNetworkId(), "foundObject", dictionary + ->getSerializedData(), 0, false); + } } + break; } - else - { - WARNING(true, ("GameServer::receiveMessage() Received AiCreatureStateMessage for networkId(%s) movementType(%s) but could not resolve to a CreatureObject", networkId.getValueString().c_str(), AiMovementBase::getMovementString(movement.getMovementType()))); - } - } - else if (message.isType("UnloadPersistedCharacter")) - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const upc(ri); + case constcrc("LocatePlayerResponseMessage") : { + ri = static_cast(message).getByteStream().begin(); + LocatePlayerResponseMessage const msg(ri); - ServerObject * const object = ServerWorld::findObjectByNetworkId(upc.getValue()); - if (object) - { - WARNING(true, ("Unloaded character object (%s) which has been persisted but still exists on this game server", object->getDebugInformation().c_str())); - object->unload(); - } - } - else if (message.isType("AboutToLoadCharacterFromDB")) - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const atlcfdb(ri); + ServerObject *const responseObject = safe_cast(NetworkIdManager::getObjectById(msg + .getResponseId())); + if (responseObject && responseObject->isAuthoritative() && responseObject->getClient()) { + std::string playerInfo = FormattedString<512>() + .sprintf("%s (%s) is on server %lu. %s (%.2f, %.2f, %.2f)", + msg.getTargetId().getValueString().c_str(), + NameManager::getInstance().getPlayerFullName(msg.getTargetId()).c_str(), + msg.getTargetPid(), msg.getScene().c_str(), + msg.getPosition_w().x, msg.getPosition_w().y, msg.getPosition_w().z); - ServerObject * const object = ServerWorld::findObjectByNetworkId(atlcfdb.getValue().first); - if (object) - { - WARNING(true, ("Unloaded character object (%s) because the character object is about to be loaded from the DB onto game server (%lu), I am game server (%lu)", object->getDebugInformation().c_str(), atlcfdb.getValue().second, getProcessId())); - object->unload(); - } - } - else if (message.isType("ClearTheaterMessage")) - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const ctm(ri); - - ServerUniverse::getInstance().remoteClearTheater(ctm.getValue()); - } - else if (message.isType("SetTheaterMessage")) - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const stm(ri); - - ServerUniverse::getInstance().remoteSetTheater(stm.getValue().first, stm.getValue().second); - } - else if (message.isType("PageChangeAuthority")) - { - ServerUIManager::receiveMessage(message); - } - else if (message.isType("PlayedTimeAccumMessage")) - { - Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); - PlayedTimeAccumMessage const ptam(ri); - Object * obj = NetworkIdManager::getObjectById(ptam.getNetworkId()); - if (obj != nullptr && obj->asServerObject() != nullptr && obj->asServerObject()->asCreatureObject() != nullptr) - { - CreatureObject * target = obj->asServerObject()->asCreatureObject(); - PlayerObject *targetPlayer = target->asPlayerObject(); - if(targetPlayer) - { - targetPlayer->setPlayedTimeAccumOnly(ptam.getPlayedTimeAccum()); - } - else - { - target->setPseudoPlayedTime(ptam.getPlayedTimeAccum()); + ConsoleMgr::broadcastString(playerInfo, responseObject->getClient()); } + break; } + case constcrc("PlayerSanityCheck") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + PlayerSanityChecker::handlePlayerSanityCheck(msg.getValue().first, msg.getValue().second); + break; + } + case constcrc("PlayerSanityCheckSuccess") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + PlayerSanityChecker::handlePlayerSanityCheckSuccess(msg.getValue()); + break; + } + case constcrc("PlayerSanityCheckProxy") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + PlayerSanityChecker::handlePlayerSanityCheckProxy(msg.getValue().first, msg.getValue().second); + break; + } + case constcrc("PlayerSanityCheckProxyFail") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + PlayerSanityChecker::handlePlayerSanityCheckProxyFail(msg.getValue().first, msg.getValue().second); + break; + } + case constcrc("EnablePlayerSanityCheckerMessage") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + PlayerSanityChecker::enable(msg.getValue()); + break; + } + case constcrc("StartSaveReplyMessage") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); - } - else if (message.isType("ManualDepleteResourceMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - ServerUniverse::getInstance().manualDepleteResource(msg.getValue()); - } - else if (message.isType("ClaimRewardsReplyMessage")) - { - ri = static_cast(message).getByteStream().begin(); - ClaimRewardsReplyMessage msg(ri); - VeteranRewardManager::handleClaimRewardsReply(msg.getStationId(), msg.getPlayer(), msg.getRewardEvent(), msg.getRewardItem(), msg.getAccountFeatureId(), msg.getConsumeAccountFeatureId(), msg.getPreviousAccountFeatureIdCount(), msg.getCurrentAccountFeatureIdCount(), msg.getResult(), true); - } - else if (message.isType("SetOverrideAccountAgeMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage msg(ri); + ServerObject const * + const requestedBy = safe_cast < ServerObject const * > + (NetworkIdManager::getObjectById(msg.getValue().first)); - VeteranRewardManager::setOverrideAccountAge(msg.getValue()); - } - else if (message.isType("GetMoneyFromOfflineObjectMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GetMoneyFromOfflineObjectMessage msg(ri); - - std::string const & callback = msg.getSuccess() ? msg.getSuccessCallback() : msg.getFailCallback(); - MessageToQueue::getInstance().sendMessageToJava(msg.getReplyTo(), callback, msg.getPackedDictionary(), 0, false); - } - else if (message.isType(SlowDownEffectMessage::MessageType)) - { - ri = static_cast(message).getByteStream().begin(); - SlowDownEffectMessage msg(ri); - - // get the attacker - Object * obj = NetworkIdManager::getObjectById(msg.getSource()); - if (obj != nullptr && obj->asServerObject() != nullptr && obj->asServerObject()->asCreatureObject() != nullptr) - { - CreatureObject * attacker = obj->asServerObject()->asCreatureObject(); - - // get the target - obj = NetworkIdManager::getObjectById(msg.getTarget()); - if (obj != nullptr && obj->asServerObject() != nullptr && obj->asServerObject()->asTangibleObject() != nullptr) - { - TangibleObject * defender = obj->asServerObject()->asTangibleObject(); - if (attacker->isAuthoritative()) - attacker->addSlowDownEffect(*defender, msg.getConeLength(), msg.getConeAngle(), msg.getSlopeAngle(), msg.getExpireTime()); + if (requestedBy) { + if (msg.getValue().second) + Chat::sendSystemMessage(*requestedBy, Unicode::narrowToWide("Save has been started"), Unicode::String()); else - attacker->addSlowDownEffectProxy(*defender, msg.getConeLength(), msg.getConeAngle(), msg.getSlopeAngle(), msg.getExpireTime()); + Chat::sendSystemMessage(*requestedBy, Unicode::narrowToWide("Save could not be started because one was already in progress"), Unicode::String()); } + break; } - } - else if (message.isType("StructuresForPurgeMessage")) - { - ri = static_cast(message).getByteStream().begin(); - StructuresForPurgeMessage msg(ri); - PurgeManager::handleStructuresAndVendorsForPurge(msg.getStationId(), msg.getStructures(), msg.getVendors(), msg.getWarnOnly()); - } - else if (message.isType("RequestLoadAckMessage")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage msg(ri); + case constcrc("DatabaseConsoleReplyMessage") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); - GenericValueTypeMessage reply("LoadAckMessage",msg.getValue()); - sendToDatabaseServer(reply); - } - else if (message.isType("FactionalSystemMessage")) - { - ri = static_cast(message).getByteStream().begin(); - FactionalSystemMessage msg(ri); - handleFactionalSystemMessage(msg); - } - else if (message.isType("MessageToPlayersOnPlanet")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage >, std::pair >, std::pair > > const msg(ri); - handleMessageToPlayersOnPlanet(msg.getValue().first.first.first, msg.getValue().first.first.second, msg.getValue().first.second.first, msg.getValue().second.first, msg.getValue().second.second, msg.getValue().first.second.second); - } - else if (message.isType("PopStatReq")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const populationStatisticsRequest(ri); - UNREF(populationStatisticsRequest); + Chat::sendSystemMessage(msg.getValue().first, Unicode::narrowToWide(msg.getValue() + .second), Unicode::String()); + break; + } + case constcrc("FindAuthObject") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + ServerObject const * + const so = safe_cast < ServerObject const * > (NetworkIdManager::getObjectById(msg.getValue().first)); + bool const found = so && so->isAuthoritative(); - const GenericValueTypeMessage > populationStatisticsResponse("PopStatRsp", LfgCharacterData::calculateStatistics(ServerUniverse::getConnectedCharacterLfgData())); - sendToCentralServer(populationStatisticsResponse); - } - else if (message.isType("GcwScoreStatReq")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const gcwScoreStatisticsRequest(ri); - UNREF(gcwScoreStatisticsRequest); + GenericValueTypeMessage < std::pair < std::pair < NetworkId, unsigned + int > , bool > > + const authResponse( + "FindAuthObjectResponse", + std::make_pair(msg.getValue(), found)); + sendToPlanetServer(authResponse); + break; + } + case constcrc("CharacterNamesMessage") : { + ri = static_cast(message).getByteStream().begin(); + CharacterNamesMessage const msg(ri); + NameManager::getInstance() + .addPlayers(msg.getIds(), msg.getStationIds(), msg.getNames(), msg.getFullNames(), msg + .getCreateTimes(), msg.getLoginTimes()); + break; + } + case constcrc("LocationResponse") : { + Archive::ReadIterator readIterator = static_cast (message).getByteStream() + .begin(); + LocationResponse const locationResponse(readIterator); - static const std::map > emptyGcwScore; - PlanetObject const * const tatooine = ServerUniverse::getInstance().getTatooinePlanet(); - - static const std::map emptyGcwScorePercentile; - GuildObject const * const guildObject = ServerUniverse::getInstance().getMasterGuildObject(); - - const GenericValueTypeMessage, std::pair >, std::map > > > > gcwScoreStatisticsResponse("GcwScoreStatRsp", std::make_pair((guildObject ? guildObject->getGcwImperialScorePercentile() : emptyGcwScorePercentile), std::make_pair((tatooine ? tatooine->getGcwImperialScore() : emptyGcwScore), (tatooine ? tatooine->getGcwRebelScore() : emptyGcwScore)))); - sendToCentralServer(gcwScoreStatisticsResponse); - } - else if (message.isType("GcwScoreStatRaw")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage >, std::map > > > > const msg(ri); - if (ConfigServerGame::getReceiveGcwScoreFromOtherGalaxies() && ServerUniverse::getInstance().isAuthoritative() && _stricmp(getClusterName().c_str(), msg.getValue().first.c_str())) - { - GuildObject * const go = ServerUniverse::getInstance().getMasterGuildObject(); - if (go && go->isAuthoritative()) - { - go->setGcwRawScoreFromOtherGalaxy(msg.getValue().first, msg.getValue().second.first, msg.getValue().second.second); + //-- get the script object to invole the trigger on + Object *const object = NetworkIdManager::getObjectById(locationResponse.getNetworkId()); + if (!object) { + DEBUG_WARNING(true, ("LocationResponse: could not resolve object %s which asked for a location", locationResponse + .getNetworkId().getValueString().c_str())); + return; } - } - } - else if (message.isType("GcwScoreStatPct")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, std::map > > > const msg(ri); - if (ConfigServerGame::getReceiveGcwScoreFromOtherGalaxies() && ServerUniverse::getInstance().isAuthoritative() && _stricmp(getClusterName().c_str(), msg.getValue().first.c_str())) - { - GuildObject * const go = ServerUniverse::getInstance().getMasterGuildObject(); - if (go && go->isAuthoritative()) - { - go->setGcwImperialScorePercentileFromOtherGalaxy(msg.getValue().first, msg.getValue().second.first, msg.getValue().second.second); + + ServerObject *const scriptObject = object->asServerObject(); + if (!scriptObject) { + DEBUG_WARNING(true, ("LocationResponse: object id=%s template=%s is not a server object", object + ->getNetworkId().getValueString().c_str(), object->getObjectTemplateName())); + return; } - } - } - else if (message.isType("LLTStatReq")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const lastLoginTimeStatisticsRequest(ri); - UNREF(lastLoginTimeStatisticsRequest); - static std::map > lastLoginTimeStatistics; - if (lastLoginTimeStatistics.empty()) + //-- if the location is valid, create a reservation object + Vector position_w(locationResponse.getX(), 0.f, locationResponse.getZ()); + ServerObject *serverObject = 0; + if (locationResponse.getValid()) { + //-- construct the name + char objectTemplateName[512]; + snprintf(objectTemplateName, 512, "object/tangible/location/location_%i.iff", static_cast (locationResponse + .getRadius())); + + //-- get the height of the terrain + TerrainObject const *const terrainObject = TerrainObject::getConstInstance(); + if (terrainObject) + terrainObject->getHeightForceChunkCreation(position_w, position_w.y); + + //-- create the object + Transform tr; + tr.setPosition_p(position_w); + serverObject = ServerWorld::createNewObject(objectTemplateName, tr, 0, false); + DEBUG_REPORT_LOG(!serverObject, ("LocationResponse: failed to create object %s\n", objectTemplateName)); + if (serverObject) + serverObject->addToWorld(); + } + + //-- inform script of the result + ScriptParams scriptParameters; + scriptParameters.addParam(locationResponse.getLocationId().c_str()); + scriptParameters.addParam(serverObject ? serverObject->getNetworkId() : NetworkId::cms_invalid); + scriptParameters.addParam(position_w); + scriptParameters.addParam(locationResponse.getRadius()); + + if (scriptObject->getScriptObject()->trigAllScripts(Scripting::TRIG_LOCATION_RECEIVED, scriptParameters) != + SCRIPT_CONTINUE) + DEBUG_REPORT_LOG(true, ("LocationResponse: TRIG_LOCATION_RECEIVED: did not return SCRIPT_CONTINUE\n")); + break; + } + case constcrc("ReleaseCharacterNameByIdMessage") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + + NameManager::getInstance().releasePlayerName(msg.getValue()); + break; + } + case constcrc("AddAttribModName") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + AttribModNameManager::getInstance().addAttribModNameFromRemote(msg.getValue().c_str()); + break; + } + case constcrc("AddAttribModNamesList") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + DEBUG_REPORT_LOG(true, ("Received attrib mod names list <%s> from remote server\n", msg.getValue() + .c_str())); + AttribModNameManager::getInstance().addAttribModNamesListFromRemote(msg.getValue().c_str()); + break; + } + case constcrc("AiCreatureStateMessage") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + + NetworkId const &networkId = msg.getValue().m_networkId; + AiMovementMessage const &movement = msg.getValue().m_movement; + + CreatureObject *const creatureObject = CreatureObject::getCreatureObject(networkId); + + if (creatureObject != nullptr) { + Controller *const controller = creatureObject->getController(); + + if (controller != nullptr) { + DEBUG_LOG("debug_ai", ("GameServer::receiveMessage() Received AiCreatureStateMessage for networkId(%s) movementType(%s)", networkId + .getValueString().c_str(), AiMovementBase::getMovementString(movement.getMovementType()))); + + int const flags = GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | + GameControllerMessageFlags::DEST_SERVER; + + // Movement + + controller->appendMessage(CM_aiSetMovement, 0, new AiMovementMessage(movement), flags); + } + else { + WARNING(true, ("GameServer::receiveMessage() Received AiCreatureStateMessage for networkId(%s) movementType(%s) but the object does not have a Controller", networkId + .getValueString().c_str(), AiMovementBase::getMovementString(movement.getMovementType()))); + } + } + else { + WARNING(true, ("GameServer::receiveMessage() Received AiCreatureStateMessage for networkId(%s) movementType(%s) but could not resolve to a CreatureObject", networkId + .getValueString().c_str(), AiMovementBase::getMovementString(movement.getMovementType()))); + } + break; + } + case constcrc("UnloadPersistedCharacter") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const upc(ri); + + ServerObject *const object = ServerWorld::findObjectByNetworkId(upc.getValue()); + if (object) { + WARNING(true, ("Unloaded character object (%s) which has been persisted but still exists on this game server", object + ->getDebugInformation().c_str())); + object->unload(); + } + break; + } + case constcrc("AboutToLoadCharacterFromDB") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const atlcfdb(ri); + + ServerObject *const object = ServerWorld::findObjectByNetworkId(atlcfdb.getValue().first); + if (object) { + WARNING(true, ("Unloaded character object (%s) because the character object is about to be loaded from the DB onto game server (%lu), I am game server (%lu)", object + ->getDebugInformation().c_str(), atlcfdb.getValue().second, getProcessId())); + object->unload(); + } + break; + } + case constcrc("ClearTheaterMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const ctm(ri); + + ServerUniverse::getInstance().remoteClearTheater(ctm.getValue()); + break; + } + case constcrc("SetTheaterMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const stm(ri); + + ServerUniverse::getInstance().remoteSetTheater(stm.getValue().first, stm.getValue().second); + break; + } + case constcrc("PageChangeAuthority") : { + ServerUIManager::receiveMessage(message); + break; + } + case constcrc("PlayedTimeAccumMessage") : { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + PlayedTimeAccumMessage const ptam(ri); + Object *obj = NetworkIdManager::getObjectById(ptam.getNetworkId()); + if (obj != nullptr && obj->asServerObject() != nullptr && + obj->asServerObject()->asCreatureObject() != nullptr) { + CreatureObject *target = obj->asServerObject()->asCreatureObject(); + PlayerObject *targetPlayer = target->asPlayerObject(); + if (targetPlayer) { + targetPlayer->setPlayedTimeAccumOnly(ptam.getPlayedTimeAccum()); + } + else { + target->setPseudoPlayedTime(ptam.getPlayedTimeAccum()); + } + } + + break; + + } + case constcrc("ManualDepleteResourceMessage") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + ServerUniverse::getInstance().manualDepleteResource(msg.getValue()); + break; + } + case constcrc("ClaimRewardsReplyMessage") : { + ri = static_cast(message).getByteStream().begin(); + ClaimRewardsReplyMessage msg(ri); + VeteranRewardManager::handleClaimRewardsReply(msg.getStationId(), msg.getPlayer(), msg.getRewardEvent(), msg + .getRewardItem(), msg.getAccountFeatureId(), msg.getConsumeAccountFeatureId(), msg + .getPreviousAccountFeatureIdCount(), msg.getCurrentAccountFeatureIdCount(), msg.getResult(), true); + break; + } + case constcrc("SetOverrideAccountAgeMessage") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + + VeteranRewardManager::setOverrideAccountAge(msg.getValue()); + break; + } + case constcrc("GetMoneyFromOfflineObjectMessage") : { + ri = static_cast(message).getByteStream().begin(); + GetMoneyFromOfflineObjectMessage msg(ri); + + std::string const &callback = msg.getSuccess() ? msg.getSuccessCallback() : msg.getFailCallback(); + MessageToQueue::getInstance() + .sendMessageToJava(msg.getReplyTo(), callback, msg.getPackedDictionary(), 0, false); + break; + } + case constcrc("StructuresForPurgeMessage") : { + ri = static_cast(message).getByteStream().begin(); + StructuresForPurgeMessage msg(ri); + PurgeManager::handleStructuresAndVendorsForPurge(msg.getStationId(), msg.getStructures(), msg + .getVendors(), msg.getWarnOnly()); + break; + } + case constcrc("RequestLoadAckMessage") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + + GenericValueTypeMessage reply("LoadAckMessage", msg.getValue()); + sendToDatabaseServer(reply); + break; + } + case constcrc("FactionalSystemMessage") : { + ri = static_cast(message).getByteStream().begin(); + FactionalSystemMessage msg(ri); + handleFactionalSystemMessage(msg); + break; + } + case constcrc("MessageToPlayersOnPlanet") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < std::pair < std::string, std::vector < int8 > >, + std::pair < float, bool > >, std::pair < Vector, float > > > + const msg(ri); + handleMessageToPlayersOnPlanet(msg.getValue().first.first.first, msg.getValue().first.first.second, msg + .getValue().first.second.first, msg.getValue().second.first, msg.getValue().second.second, msg + .getValue().first.second.second); + break; + } + case constcrc("PopStatReq") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const populationStatisticsRequest(ri); + UNREF(populationStatisticsRequest); + + const GenericValueTypeMessage > populationStatisticsResponse("PopStatRsp", LfgCharacterData::calculateStatistics(ServerUniverse::getConnectedCharacterLfgData())); + sendToCentralServer(populationStatisticsResponse); + break; + } + case constcrc("GcwScoreStatReq") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const gcwScoreStatisticsRequest(ri); + UNREF(gcwScoreStatisticsRequest); + + static const std::map > emptyGcwScore; + PlanetObject const *const tatooine = ServerUniverse::getInstance().getTatooinePlanet(); + + static const std::map emptyGcwScorePercentile; + GuildObject const *const guildObject = ServerUniverse::getInstance().getMasterGuildObject(); + + const GenericValueTypeMessage , std::pair< + std::map < std::string, std::pair < int64, int64>>, std::map < std::string, std::pair < int64, + int64 > > > > > + gcwScoreStatisticsResponse("GcwScoreStatRsp", std::make_pair((guildObject ? guildObject + ->getGcwImperialScorePercentile() : emptyGcwScorePercentile), std::make_pair((tatooine + ? tatooine + ->getGcwImperialScore() + : emptyGcwScore), (tatooine + ? tatooine + ->getGcwRebelScore() + : emptyGcwScore)))); + sendToCentralServer(gcwScoreStatisticsResponse); + + break; + } + case constcrc("GcwScoreStatRaw") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::string, std::pair < std::map < std::string, std::pair < int64, + int64 > >, std::map < std::string, std::pair < int64, int64 > > > > > + const msg(ri); + if (ConfigServerGame::getReceiveGcwScoreFromOtherGalaxies() && + ServerUniverse::getInstance().isAuthoritative() && + _stricmp(getClusterName().c_str(), msg.getValue().first.c_str())) { + GuildObject *const go = ServerUniverse::getInstance().getMasterGuildObject(); + if (go && go->isAuthoritative()) { + go->setGcwRawScoreFromOtherGalaxy(msg.getValue().first, msg.getValue().second.first, msg.getValue() + .second + .second); + } + } + + break; + } + case constcrc("GcwScoreStatPct") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::string, std::pair < std::map < std::string, int >, std::map < + std::string, + int > > > > + const msg(ri); + if (ConfigServerGame::getReceiveGcwScoreFromOtherGalaxies() && + ServerUniverse::getInstance().isAuthoritative() && + _stricmp(getClusterName().c_str(), msg.getValue().first.c_str())) { + GuildObject *const go = ServerUniverse::getInstance().getMasterGuildObject(); + if (go && go->isAuthoritative()) { + go->setGcwImperialScorePercentileFromOtherGalaxy(msg.getValue().first, msg.getValue().second + .first, msg.getValue() + .second + .second); + } + } + + break; + } + case constcrc("LLTStatReq") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const lastLoginTimeStatisticsRequest(ri); + UNREF(lastLoginTimeStatisticsRequest); + + static std::map > lastLoginTimeStatistics; + if (lastLoginTimeStatistics.empty()) { + lastLoginTimeStatistics[(60 * 60 * 24 * + 1)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day001"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 2)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day002"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 3)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day003"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 4)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day004"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 5)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day005"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 6)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day006"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 7)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day007"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 14)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day014"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 21)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day021"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 30)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day030"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 60)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day060"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 90)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day090"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 180)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day180"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 270)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day270"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 365)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Year1"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 730)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Year2"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * + 1095)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Year3"), 0); + lastLoginTimeStatistics[(60 * 60 * 24 * 9999)] = std::make_pair(std::string("totalCharacters"), 0); + } + + NameManager::getInstance().getPlayerWithLastLoginTimeAfterDistribution(lastLoginTimeStatistics); + + std::map < int, std::pair < std::string, int > > ::iterator + iter = lastLoginTimeStatistics.begin(); + std::map < int, std::pair < std::string, int > > ::iterator + previousIter = lastLoginTimeStatistics.begin(); + for (; iter != lastLoginTimeStatistics.end(); ++iter) { + if (iter != previousIter) + iter->second.second += previousIter->second.second; + + previousIter = iter; + } + + static std::map > createTimeStatistics; + if (createTimeStatistics.empty()) { + createTimeStatistics[(60 * 60 * 24 * + 1)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day001"), 0); + createTimeStatistics[(60 * 60 * 24 * + 2)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day002"), 0); + createTimeStatistics[(60 * 60 * 24 * + 3)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day003"), 0); + createTimeStatistics[(60 * 60 * 24 * + 4)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day004"), 0); + createTimeStatistics[(60 * 60 * 24 * + 5)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day005"), 0); + createTimeStatistics[(60 * 60 * 24 * + 6)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day006"), 0); + createTimeStatistics[(60 * 60 * 24 * + 7)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day007"), 0); + createTimeStatistics[(60 * 60 * 24 * + 14)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day014"), 0); + createTimeStatistics[(60 * 60 * 24 * + 21)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day021"), 0); + createTimeStatistics[(60 * 60 * 24 * + 30)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day030"), 0); + createTimeStatistics[(60 * 60 * 24 * + 60)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day060"), 0); + createTimeStatistics[(60 * 60 * 24 * + 90)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day090"), 0); + createTimeStatistics[(60 * 60 * 24 * + 180)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day180"), 0); + createTimeStatistics[(60 * 60 * 24 * + 270)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day270"), 0); + createTimeStatistics[(60 * 60 * 24 * + 365)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Year1"), 0); + createTimeStatistics[(60 * 60 * 24 * + 730)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Year2"), 0); + createTimeStatistics[(60 * 60 * 24 * + 1095)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Year3"), 0); + createTimeStatistics[(60 * 60 * 24 * 9999)] = std::make_pair(std::string("totalCharacters"), 0); + } + + NameManager::getInstance().getPlayerWithCreateTimeAfterDistribution(createTimeStatistics); + + iter = createTimeStatistics.begin(); + previousIter = createTimeStatistics.begin(); + for (; iter != createTimeStatistics.end(); ++iter) { + if (iter != previousIter) + iter->second.second += previousIter->second.second; + + previousIter = iter; + } + + const GenericValueTypeMessage >, std::map < int, + std::pair < std::string, int > > > > + lastLoginTimeStatisticsResponse("LLTStatRsp", std::make_pair(lastLoginTimeStatistics, createTimeStatistics)); + sendToCentralServer(lastLoginTimeStatisticsResponse); + + break; + } + case constcrc("LfgStatReq") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const characterMatchStatisticsRequest(ri); + UNREF(characterMatchStatisticsRequest); + + unsigned long numberOfCharacterMatchRequests, numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs; + CharacterMatchManager::getMatchStatistics(numberOfCharacterMatchRequests, numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs); + + if (numberOfCharacterMatchRequests || numberOfCharacterMatchResults || + timeSpentOnCharacterMatchRequestsMs) { + CharacterMatchManager::clearMatchStatistics(); + + const GenericValueTypeMessage >> characterMatchStatisticsResponse("LfgStatRsp", std::make_pair(numberOfCharacterMatchRequests, std::make_pair(numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs))); + sendToCentralServer(characterMatchStatisticsResponse); + } + + break; + } + case constcrc("ClusterId") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage const msg(ri); + + if (m_clusterId == 0) { + FATAL(((msg.getValue() < 1) || + (msg.getValue() > 255)), ("Cluster Id (%lu) must be between 1 and 255 inclusive", msg + .getValue())); + + m_clusterId = static_cast(msg.getValue()); + } + break; + } + case constcrc("OccupyUnlockedSlotRsp") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < int, NetworkId >, uint32 > > + const occupyUnlockedSlotRsp(ri); + + char buffer[32]; + snprintf(buffer, sizeof(buffer) - 1, "%d", occupyUnlockedSlotRsp.getValue().first.first); + buffer[sizeof(buffer) - 1] = '\0'; + + MessageToQueue::getInstance().sendMessageToC(occupyUnlockedSlotRsp.getValue().first.second, + "C++OccupyUnlockedSlotRsp", + buffer, + 0, + false); + + break; + } + case constcrc("VacateUnlockedSlotRsp") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < int, NetworkId >, std::pair < uint32, uint32 > > > + const vacateUnlockedSlotRsp(ri); + + char buffer[32]; + snprintf(buffer, sizeof(buffer) - 1, "%d", vacateUnlockedSlotRsp.getValue().first.first); + buffer[sizeof(buffer) - 1] = '\0'; + + MessageToQueue::getInstance().sendMessageToC(vacateUnlockedSlotRsp.getValue().first.second, + "C++VacateUnlockedSlotRsp", + buffer, + 0, + false); + break; + } + case constcrc("SwapUnlockedSlotRsp") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage < std::pair < std::pair < int, NetworkId >, std::pair < uint32, std::pair < + NetworkId, + std::string > > > > + const swapUnlockedSlotRsp(ri); + + Archive::ByteStream bs; + swapUnlockedSlotRsp.pack(bs); + + MessageToQueue::getInstance().sendMessageToC(swapUnlockedSlotRsp.getValue().first.second, + "C++SwapUnlockedSlotRsp", + std::string(reinterpret_cast(bs.getBuffer()), static_cast(bs.getSize())), + 0, + false); + break; + } + case constcrc("AdjustAccountFeatureIdResponse") : { + ri = static_cast(message).getByteStream().begin(); + AdjustAccountFeatureIdResponse const msg(ri); + + handleAdjustAccountFeatureIdResponse(msg); + break; + } + case constcrc("AccountFeatureIdResponse") : { + ri = static_cast(message).getByteStream().begin(); + AccountFeatureIdResponse const msg(ri); + + handleAccountFeatureIdResponse(msg); + break; + } + case constcrc("FeatureIdTransactionResponse") : { + ri = static_cast(message).getByteStream().begin(); + FeatureIdTransactionResponse const msg(ri); + + Archive::ByteStream bs; + msg.pack(bs); + + MessageToQueue::getInstance().sendMessageToC(msg.getPlayer(), + "C++FeatureIdTransactionResponse", + std::string(reinterpret_cast(bs.getBuffer()), static_cast(bs.getSize())), + 0, + false); + break; + } + case constcrc("TransferReplyMoveValidation") : { + ri = static_cast(message).getByteStream().begin(); + TransferReplyMoveValidation const msg(ri); + + Archive::ByteStream bs; + msg.pack(bs); + + MessageToQueue::getInstance().sendMessageToC(msg.getSourceCharacterId(), + "C++TransferReplyMoveValidation", + std::string(reinterpret_cast(bs.getBuffer()), static_cast(bs.getSize())), + 0, + false); + break; + } + case constcrc("TransferReplyNameValidation") : { + ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > const msg(ri); + + Archive::ByteStream bs; + msg.pack(bs); + + MessageToQueue::getInstance().sendMessageToC(msg.getValue().second.getCharacterId(), + "C++TransferReplyNameValidation", + std::string(reinterpret_cast(bs.getBuffer()), static_cast(bs.getSize())), + 0, + false); + break; + } + case constcrc("CreateDynamicSpawnRegionCircleMessage") : { + ri = static_cast(message).getByteStream().begin(); + CreateDynamicSpawnRegionCircleMessage const msg(ri); + + RegionMaster::createNewDynamicRegionWithSpawn(msg.getCenterX(), msg.getCenterY(), msg.getCenterZ(), msg + .getRadius(), msg.getName(), msg.getPlanet(), + msg.getPvp(), msg.getBuildable(), msg.getMunicipal(), msg.getGeography(), msg + .getMinDifficulty(), msg.getMaxDifficulty(), + msg.getSpawnable(), msg.getMission(), msg.getVisible(), msg.getNotify(), msg.getSpawntable(), msg + .getDuration()); + break; + } + default : { - lastLoginTimeStatistics[(60 * 60 * 24 * 1)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day001"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 2)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day002"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 3)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day003"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 4)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day004"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 5)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day005"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 6)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day006"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 7)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day007"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 14)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day014"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 21)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day021"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 30)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day030"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 60)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day060"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 90)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day090"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 180)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day180"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 270)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Day270"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 365)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Year1"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 730)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Year2"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 1095)] = std::make_pair(std::string("totalCharacters.loginWithinPast_Year3"), 0); - lastLoginTimeStatistics[(60 * 60 * 24 * 9999)] = std::make_pair(std::string("totalCharacters"), 0); + if(ClusterWideDataClient::handleMessage(source, message)) { + // nothing else to do with the message since it was + // handled by the Cluster wide data client + } else if (message.isType(SlowDownEffectMessage::MessageType)) { + ri = static_cast(message).getByteStream().begin(); + SlowDownEffectMessage msg(ri); + + // get the attacker + Object * obj = NetworkIdManager::getObjectById(msg.getSource()); + if (obj != nullptr && obj->asServerObject() != nullptr && obj->asServerObject()->asCreatureObject() != nullptr) + { + CreatureObject * attacker = obj->asServerObject()->asCreatureObject(); + + // get the target + obj = NetworkIdManager::getObjectById(msg.getTarget()); + if (obj != nullptr && obj->asServerObject() != nullptr && obj->asServerObject()->asTangibleObject() != nullptr) + { + TangibleObject * defender = obj->asServerObject()->asTangibleObject(); + if (attacker->isAuthoritative()) + attacker->addSlowDownEffect(*defender, msg.getConeLength(), msg.getConeAngle(), msg.getSlopeAngle(), msg.getExpireTime()); + else + attacker->addSlowDownEffectProxy(*defender, msg.getConeLength(), msg.getConeAngle(), msg.getSlopeAngle(), msg.getExpireTime()); + } + } + } + + break; } - - NameManager::getInstance().getPlayerWithLastLoginTimeAfterDistribution(lastLoginTimeStatistics); - - std::map >::iterator iter = lastLoginTimeStatistics.begin(); - std::map >::iterator previousIter = lastLoginTimeStatistics.begin(); - for (; iter != lastLoginTimeStatistics.end(); ++iter) - { - if (iter != previousIter) - iter->second.second += previousIter->second.second; - - previousIter = iter; - } - - static std::map > createTimeStatistics; - if (createTimeStatistics.empty()) - { - createTimeStatistics[(60 * 60 * 24 * 1)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day001"), 0); - createTimeStatistics[(60 * 60 * 24 * 2)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day002"), 0); - createTimeStatistics[(60 * 60 * 24 * 3)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day003"), 0); - createTimeStatistics[(60 * 60 * 24 * 4)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day004"), 0); - createTimeStatistics[(60 * 60 * 24 * 5)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day005"), 0); - createTimeStatistics[(60 * 60 * 24 * 6)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day006"), 0); - createTimeStatistics[(60 * 60 * 24 * 7)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day007"), 0); - createTimeStatistics[(60 * 60 * 24 * 14)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day014"), 0); - createTimeStatistics[(60 * 60 * 24 * 21)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day021"), 0); - createTimeStatistics[(60 * 60 * 24 * 30)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day030"), 0); - createTimeStatistics[(60 * 60 * 24 * 60)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day060"), 0); - createTimeStatistics[(60 * 60 * 24 * 90)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day090"), 0); - createTimeStatistics[(60 * 60 * 24 * 180)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day180"), 0); - createTimeStatistics[(60 * 60 * 24 * 270)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Day270"), 0); - createTimeStatistics[(60 * 60 * 24 * 365)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Year1"), 0); - createTimeStatistics[(60 * 60 * 24 * 730)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Year2"), 0); - createTimeStatistics[(60 * 60 * 24 * 1095)] = std::make_pair(std::string("totalCharacters.createdWithinPast_Year3"), 0); - createTimeStatistics[(60 * 60 * 24 * 9999)] = std::make_pair(std::string("totalCharacters"), 0); - } - - NameManager::getInstance().getPlayerWithCreateTimeAfterDistribution(createTimeStatistics); - - iter = createTimeStatistics.begin(); - previousIter = createTimeStatistics.begin(); - for (; iter != createTimeStatistics.end(); ++iter) - { - if (iter != previousIter) - iter->second.second += previousIter->second.second; - - previousIter = iter; - } - - const GenericValueTypeMessage >, std::map > > > lastLoginTimeStatisticsResponse("LLTStatRsp", std::make_pair(lastLoginTimeStatistics, createTimeStatistics)); - sendToCentralServer(lastLoginTimeStatisticsResponse); - } - else if (message.isType("LfgStatReq")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const characterMatchStatisticsRequest(ri); - UNREF(characterMatchStatisticsRequest); - - unsigned long numberOfCharacterMatchRequests, numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs; - CharacterMatchManager::getMatchStatistics(numberOfCharacterMatchRequests, numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs); - - if (numberOfCharacterMatchRequests || numberOfCharacterMatchResults || timeSpentOnCharacterMatchRequestsMs) - { - CharacterMatchManager::clearMatchStatistics(); - - const GenericValueTypeMessage > > characterMatchStatisticsResponse("LfgStatRsp", std::make_pair(numberOfCharacterMatchRequests, std::make_pair(numberOfCharacterMatchResults, timeSpentOnCharacterMatchRequestsMs))); - sendToCentralServer(characterMatchStatisticsResponse); - } - } - else if (message.isType("ClusterId")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage const msg(ri); - - if (m_clusterId == 0) - { - FATAL(((msg.getValue() < 1) || (msg.getValue() > 255)),("Cluster Id (%lu) must be between 1 and 255 inclusive", msg.getValue())); - - m_clusterId = static_cast(msg.getValue()); - } - } - else if (message.isType("OccupyUnlockedSlotRsp")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, uint32> > const occupyUnlockedSlotRsp(ri); - - char buffer[32]; - snprintf(buffer, sizeof(buffer)-1, "%d", occupyUnlockedSlotRsp.getValue().first.first); - buffer[sizeof(buffer)-1] = '\0'; - - MessageToQueue::getInstance().sendMessageToC(occupyUnlockedSlotRsp.getValue().first.second, - "C++OccupyUnlockedSlotRsp", - buffer, - 0, - false); - } - else if (message.isType("VacateUnlockedSlotRsp")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, std::pair > > const vacateUnlockedSlotRsp(ri); - - char buffer[32]; - snprintf(buffer, sizeof(buffer)-1, "%d", vacateUnlockedSlotRsp.getValue().first.first); - buffer[sizeof(buffer)-1] = '\0'; - - MessageToQueue::getInstance().sendMessageToC(vacateUnlockedSlotRsp.getValue().first.second, - "C++VacateUnlockedSlotRsp", - buffer, - 0, - false); - } - else if (message.isType("SwapUnlockedSlotRsp")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage, std::pair > > > const swapUnlockedSlotRsp(ri); - - Archive::ByteStream bs; - swapUnlockedSlotRsp.pack(bs); - - MessageToQueue::getInstance().sendMessageToC(swapUnlockedSlotRsp.getValue().first.second, - "C++SwapUnlockedSlotRsp", - std::string(reinterpret_cast(bs.getBuffer()), static_cast(bs.getSize())), - 0, - false); - } - else if (message.isType("AdjustAccountFeatureIdResponse")) - { - ri = static_cast(message).getByteStream().begin(); - AdjustAccountFeatureIdResponse const msg(ri); - - handleAdjustAccountFeatureIdResponse(msg); - } - else if (message.isType("AccountFeatureIdResponse")) - { - ri = static_cast(message).getByteStream().begin(); - AccountFeatureIdResponse const msg(ri); - - handleAccountFeatureIdResponse(msg); - } - else if (message.isType("FeatureIdTransactionResponse")) - { - ri = static_cast(message).getByteStream().begin(); - FeatureIdTransactionResponse const msg(ri); - - Archive::ByteStream bs; - msg.pack(bs); - - MessageToQueue::getInstance().sendMessageToC(msg.getPlayer(), - "C++FeatureIdTransactionResponse", - std::string(reinterpret_cast(bs.getBuffer()), static_cast(bs.getSize())), - 0, - false); - } - else if (message.isType("TransferReplyMoveValidation")) - { - ri = static_cast(message).getByteStream().begin(); - TransferReplyMoveValidation const msg(ri); - - Archive::ByteStream bs; - msg.pack(bs); - - MessageToQueue::getInstance().sendMessageToC(msg.getSourceCharacterId(), - "C++TransferReplyMoveValidation", - std::string(reinterpret_cast(bs.getBuffer()), static_cast(bs.getSize())), - 0, - false); - } - else if (message.isType("TransferReplyNameValidation")) - { - ri = static_cast(message).getByteStream().begin(); - GenericValueTypeMessage > const msg(ri); - - Archive::ByteStream bs; - msg.pack(bs); - - MessageToQueue::getInstance().sendMessageToC(msg.getValue().second.getCharacterId(), - "C++TransferReplyNameValidation", - std::string(reinterpret_cast(bs.getBuffer()), static_cast(bs.getSize())), - 0, - false); - } - else if (message.isType("CreateDynamicSpawnRegionCircleMessage")) - { - ri = static_cast(message).getByteStream().begin(); - CreateDynamicSpawnRegionCircleMessage const msg(ri); - - RegionMaster::createNewDynamicRegionWithSpawn(msg.getCenterX(), msg.getCenterY(), msg.getCenterZ(), msg.getRadius(), msg.getName(), msg.getPlanet(), - msg.getPvp(), msg.getBuildable(), msg.getMunicipal(), msg.getGeography(), msg.getMinDifficulty(), msg.getMaxDifficulty(), - msg.getSpawnable(), msg.getMission(), msg.getVisible(), msg.getNotify(), msg.getSpawntable(), msg.getDuration()); } }