From f1f4db17beab040acffb133abded9a4d3723e0de Mon Sep 17 00:00:00 2001 From: DarthArgus Date: Fri, 30 Sep 2016 20:23:57 -0500 Subject: [PATCH] this should be the last of them --- .../src/shared/core/MessageToQueue.cpp | 98 +-- .../src/shared/core/ServerUIManager.cpp | 6 +- .../src/shared/network/CentralConnection.cpp | 192 +++--- .../network/ConnectionServerConnection.cpp | 641 +++++++++--------- 4 files changed, 498 insertions(+), 439 deletions(-) diff --git a/engine/server/library/serverGame/src/shared/core/MessageToQueue.cpp b/engine/server/library/serverGame/src/shared/core/MessageToQueue.cpp index 847b6ff6..aa3c0f2c 100755 --- a/engine/server/library/serverGame/src/shared/core/MessageToQueue.cpp +++ b/engine/server/library/serverGame/src/shared/core/MessageToQueue.cpp @@ -23,6 +23,8 @@ #include "sharedNetworkMessages/GenericValueTypeMessage.h" #include "sharedObject/NetworkIdManager.h" +#include "sharedFoundation/CrcConstexpr.hpp" + // ====================================================================== std::string MessageToQueue::ms_nullString; @@ -234,53 +236,63 @@ void MessageToQueue::receiveMessage(MessageDispatch::Emitter const &, MessageDis static Archive::ReadIterator ri; ri = static_cast(message).getByteStream().begin(); //lint !e1774 // could use dynamic_cast - if (message.isType("MessageToMessage")) - { - ri = static_cast(message).getByteStream().begin(); - MessageToMessage const msg(ri); + const uint32 messageType = message.getType(); + + switch(messageType) { + case constcrc("MessageToMessage") : + { + ri = static_cast(message).getByteStream().begin(); + MessageToMessage const msg(ri); - // const_cast avoids having to make another copy of the data. Since we expect to receive lots of these mesages, - // avoiding making extra copies matters. In this particular case, we know it is safe since the message is about - // to go out of scope anyway. - handleMessageFromNetwork(const_cast(msg.getData()), msg.getSourceServerPid()); - } - else if (message.isType("WhoHasMessage")) - { - // Attempt to find the object, tell the source server if we have it or not - GenericValueTypeMessage > const whoHasMessage(ri); - uint32 sourceServer = whoHasMessage.getValue().first; - NetworkId const & networkId = whoHasMessage.getValue().second; - - ServerMessageForwarding::begin(sourceServer); - ServerObject const * const object = safe_cast(NetworkIdManager::getObjectById(networkId)); - if (object) - { - GenericValueTypeMessage > > reply( - "ObjectOnServerMessage", - std::make_pair(GameServer::getInstance().getProcessId(), - std::make_pair(networkId, - object->isAuthoritative()))); - ServerMessageForwarding::send(reply); + // const_cast avoids having to make another copy of the data. Since we expect to receive lots of these mesages, + // avoiding making extra copies matters. In this particular case, we know it is safe since the message is about + // to go out of scope anyway. + handleMessageFromNetwork(const_cast(msg.getData()), msg.getSourceServerPid()); + + break; } - else + case constcrc("WhoHasMessage") : { - GenericValueTypeMessage > reply( - "ObjectNotOnServerMessage", - std::make_pair(GameServer::getInstance().getProcessId(), - networkId)); - ServerMessageForwarding::send(reply); + // Attempt to find the object, tell the source server if we have it or not + GenericValueTypeMessage > const whoHasMessage(ri); + uint32 sourceServer = whoHasMessage.getValue().first; + NetworkId const & networkId = whoHasMessage.getValue().second; + + ServerMessageForwarding::begin(sourceServer); + ServerObject const * const object = safe_cast(NetworkIdManager::getObjectById(networkId)); + if (object) + { + GenericValueTypeMessage > > reply( + "ObjectOnServerMessage", + std::make_pair(GameServer::getInstance().getProcessId(), + std::make_pair(networkId, + object->isAuthoritative()))); + ServerMessageForwarding::send(reply); + } + else + { + GenericValueTypeMessage > reply( + "ObjectNotOnServerMessage", + std::make_pair(GameServer::getInstance().getProcessId(), + networkId)); + ServerMessageForwarding::send(reply); + } + ServerMessageForwarding::end(); + + break; + } + case constcrc("ObjectNotOnServerMessage") : + { + GenericValueTypeMessage > const msg(ri); + handleObjectNotOnServer(msg.getValue().first, msg.getValue().second); + break; + } + case constcrc("ObjectOnServerMessage") : + { + GenericValueTypeMessage > > const msg(ri); + handleObjectOnServer(msg.getValue().first, msg.getValue().second.first, msg.getValue().second.second); + break; } - ServerMessageForwarding::end(); - } - else if (message.isType("ObjectNotOnServerMessage")) - { - GenericValueTypeMessage > const msg(ri); - handleObjectNotOnServer(msg.getValue().first, msg.getValue().second); - } - else if (message.isType("ObjectOnServerMessage")) - { - GenericValueTypeMessage > > const msg(ri); - handleObjectOnServer(msg.getValue().first, msg.getValue().second.first, msg.getValue().second.second); } } diff --git a/engine/server/library/serverGame/src/shared/core/ServerUIManager.cpp b/engine/server/library/serverGame/src/shared/core/ServerUIManager.cpp index 14a3123a..b71bbcc5 100755 --- a/engine/server/library/serverGame/src/shared/core/ServerUIManager.cpp +++ b/engine/server/library/serverGame/src/shared/core/ServerUIManager.cpp @@ -26,6 +26,9 @@ #include "sharedNetworkMessages/SuiCreatePageMessage.h" #include "sharedNetworkMessages/SuiEventNotification.h" #include "sharedNetworkMessages/SuiUpdatePageMessage.h" + +#include "sharedFoundation/CrcConstexpr.hpp" + #include #include #include @@ -268,6 +271,7 @@ bool ServerUIManager::removePage(int pageId) void ServerUIManager::receiveMessage(const MessageDispatch::MessageBase& message) { Archive::ReadIterator ri = NON_NULL(dynamic_cast(&message))->getByteStream().begin(); + if (message.isType(SuiEventNotification::MessageType)) { SuiEventNotification const suiEventNotification(ri); @@ -397,7 +401,7 @@ void ServerUIManager::receiveMessage(const MessageDispatch::MessageBase& message if ((eventType == SuiEventType::SET_onClosedOk) || (eventType == SuiEventType::SET_onClosedCancel)) IGNORE_RETURN(removePage(pageId)); } - else if(message.isType("PageChangeAuthority")) + else if(message.getType() == constexpr("PageChangeAuthority")) { //DEBUG_WARNING(true, ("ServerUIManager: received PageChangeAuthority message")); const GenericValueTypeMessage > pageChangeAuthority(ri); diff --git a/engine/server/library/serverGame/src/shared/network/CentralConnection.cpp b/engine/server/library/serverGame/src/shared/network/CentralConnection.cpp index 0bdc9431..464924b7 100755 --- a/engine/server/library/serverGame/src/shared/network/CentralConnection.cpp +++ b/engine/server/library/serverGame/src/shared/network/CentralConnection.cpp @@ -33,6 +33,8 @@ #include "sharedObject/ObjectTemplateList.h" #include "UnicodeUtils.h" +#include "sharedFoundation/CrcConstexpr.hpp" + //----------------------------------------------------------------------- CentralServerConnection::CentralServerConnection(const std::string & a, const unsigned short p) : @@ -76,110 +78,122 @@ void CentralServerConnection::onReceive(const Archive::ByteStream & message) Archive::ReadIterator ri = message.begin(); GameNetworkMessage msg(ri); ri = message.begin(); + + const uint32 messageType = msg.getType(); - if(msg.isType("ConGenericMessage")) - { - // dispatch to CentralCommandParser - ConGenericMessage con(ri); - Unicode::String wideResult; - m_centralCommandParser->parse(NetworkId(static_cast(con.getMsgId())), Unicode::narrowToWide(con.getMsg()), wideResult); - - ConGenericMessage response(Unicode::wideToNarrow(wideResult), con.getMsgId()); - send(response, true); - } - else if(msg.isType("CharacterTransferStatusMessage")) - { - CharacterTransferStatusMessage c(ri); - CreatureObject * character = safe_cast(NetworkIdManager::getObjectById(c.getToCharacterId())); - if(character) + switch(messageType) { + case constcrc("ConGenericMessage") : { - if(character->getClient()) + // dispatch to CentralCommandParser + ConGenericMessage con(ri); + Unicode::String wideResult; + m_centralCommandParser->parse(NetworkId(static_cast(con.getMsgId())), Unicode::narrowToWide(con.getMsg()), wideResult); + + ConGenericMessage response(Unicode::wideToNarrow(wideResult), con.getMsgId()); + send(response, true); + break; + } + case constcrc("CharacterTransferStatusMessage") : + { + CharacterTransferStatusMessage c(ri); + CreatureObject * character = safe_cast(NetworkIdManager::getObjectById(c.getToCharacterId())); + if(character) { - character->receiveCharacterTransferStatusMessage(c.getStatusMessage()); + if(character->getClient()) + { + character->receiveCharacterTransferStatusMessage(c.getStatusMessage()); + } } + break; } - } - else if(msg.isType("TransferRequestNameValidation")) - { - const GenericValueTypeMessage requestNameValidation(ri); - LOG("CustomerService", ("CharacterTransfer: Received TransferRequestNameValidation from CentralServer : %s", requestNameValidation.getValue().toString().c_str())); - - std::string name = requestNameValidation.getValue().getDestinationCharacterName(); - if(name.empty()) + case constcrc("TransferRequestNameValidation") : { - name = requestNameValidation.getValue().getSourceCharacterName(); - } + const GenericValueTypeMessage requestNameValidation(ri); + LOG("CustomerService", ("CharacterTransfer: Received TransferRequestNameValidation from CentralServer : %s", requestNameValidation.getValue().toString().c_str())); - // call the same name validation code that gets called for normal character creation - std::string templateName = requestNameValidation.getValue().getObjectTemplateName(); - if (templateName.empty()) - { - uint32 const templateCrc = requestNameValidation.getValue().getObjectTemplateCrc(); - if (templateCrc != 0) + std::string name = requestNameValidation.getValue().getDestinationCharacterName(); + if(name.empty()) { - templateName = ObjectTemplateList::lookUp(templateCrc).getString(); + name = requestNameValidation.getValue().getSourceCharacterName(); } + + // call the same name validation code that gets called for normal character creation + std::string templateName = requestNameValidation.getValue().getObjectTemplateName(); + if (templateName.empty()) + { + uint32 const templateCrc = requestNameValidation.getValue().getObjectTemplateCrc(); + if (templateCrc != 0) + { + templateName = ObjectTemplateList::lookUp(templateCrc).getString(); + } + } + + VerifyAndLockNameRequest const verifyRequest(requestNameValidation.getValue().getDestinationStationId(), NetworkId::cms_invalid, templateName, Unicode::narrowToWide(name), 0xFFFFFFFF); + StringId const verifyResult = GameServer::getInstance().handleVerifyAndLockNameRequest(verifyRequest, false, false); + + TransferCharacterData replyData(requestNameValidation.getValue()); + replyData.setIsValidName(verifyResult == NameErrors::nameApproved); + GenericValueTypeMessage > reply("TransferReplyNameValidation", std::make_pair(std::string("@") + verifyResult.getCanonicalRepresentation(), replyData)); + send(reply, true); + break; } - - VerifyAndLockNameRequest const verifyRequest(requestNameValidation.getValue().getDestinationStationId(), NetworkId::cms_invalid, templateName, Unicode::narrowToWide(name), 0xFFFFFFFF); - StringId const verifyResult = GameServer::getInstance().handleVerifyAndLockNameRequest(verifyRequest, false, false); - - TransferCharacterData replyData(requestNameValidation.getValue()); - replyData.setIsValidName(verifyResult == NameErrors::nameApproved); - GenericValueTypeMessage > reply("TransferReplyNameValidation", std::make_pair(std::string("@") + verifyResult.getCanonicalRepresentation(), replyData)); - send(reply, true); - } - else if(msg.isType("TransferReplyCharacterList")) - { - const TransferReplyCharacterList reply(ri); - const AvatarList & oldAl = reply.getAvatarList(); - - // remove any characters from the list that would qualify for free CTS; characters that - // qualify for free CTS should/must use the in-game free CTS to transfer the character; - AvatarList newAl; - std::string const & clusterName = GameServer::getInstance().getClusterName(); - for (AvatarList::const_iterator iter = oldAl.begin(); iter != oldAl.end(); ++iter) + case constcrc("TransferReplyCharacterList") : { - if (!FreeCtsDataTable::getFreeCtsInfoForCharacter(static_cast(NameManager::getInstance().getPlayerCreateTime(iter->m_networkId)), clusterName, false)) - newAl.push_back(*iter); + const TransferReplyCharacterList reply(ri); + const AvatarList & oldAl = reply.getAvatarList(); + + // remove any characters from the list that would qualify for free CTS; characters that + // qualify for free CTS should/must use the in-game free CTS to transfer the character; + AvatarList newAl; + std::string const & clusterName = GameServer::getInstance().getClusterName(); + for (AvatarList::const_iterator iter = oldAl.begin(); iter != oldAl.end(); ++iter) + { + if (!FreeCtsDataTable::getFreeCtsInfoForCharacter(static_cast(NameManager::getInstance().getPlayerCreateTime(iter->m_networkId)), clusterName, false)) + newAl.push_back(*iter); + else + LOG("CustomerService", ("CharacterTransfer: removing (%s, %s, %s) from paid CTS character list for station id %u because the character qualifies for free CTS", clusterName.c_str(), Unicode::wideToNarrow(iter->m_name).c_str(), iter->m_networkId.getValueString().c_str(), reply.getStationId())); + } + + // send updated character list back to CentralServer + const TransferReplyCharacterList updatedReply(reply.getTrack(), reply.getStationId(), newAl); + send(updatedReply, true); + break; + } + case constcrc("CtsCompletedForcharacter") : + { + const GenericValueTypeMessage > msg(ri); + MessageToQueue::getInstance().sendMessageToJava(msg.getValue().second, "ctsCompletedForCharacter", std::vector(), 0, false); + break; + } + case constcrc("GameServerCSRequest" ) : + { + GameServerCSRequestMessage request( ri ); + GameServer::getInstance().handleCSRequest( request ); + break; + } + case constcrc( "CSFindAuthObject" ) : + { + // see if we have the object. + GenericValueTypeMessage< std::pair > msg( ri ); + ServerObject * object = safe_cast( NetworkIdManager::getObjectById( msg.getValue().first ) ); + // return an appropriate response. + if( object && object->isAuthoritative() ) + { + GenericValueTypeMessage< std::pair< unsigned int, bool > > rmsg( "CSFindAuthObjectReply", std::make_pair( msg.getValue().second, true ) ); + GameServer::getInstance().sendToCentralServer( rmsg ); + } else - LOG("CustomerService", ("CharacterTransfer: removing (%s, %s, %s) from paid CTS character list for station id %u because the character qualifies for free CTS", clusterName.c_str(), Unicode::wideToNarrow(iter->m_name).c_str(), iter->m_networkId.getValueString().c_str(), reply.getStationId())); + { + GenericValueTypeMessage< std::pair< unsigned int, bool > > rmsg( "CSFindAuthObjectReply", std::make_pair( msg.getValue().second, false ) ); + GameServer::getInstance().sendToCentralServer( rmsg ); + } + break; } - - // send updated character list back to CentralServer - const TransferReplyCharacterList updatedReply(reply.getTrack(), reply.getStationId(), newAl); - send(updatedReply, true); - } - else if(msg.isType("CtsCompletedForcharacter")) - { - const GenericValueTypeMessage > msg(ri); - MessageToQueue::getInstance().sendMessageToJava(msg.getValue().second, "ctsCompletedForCharacter", std::vector(), 0, false); - } - else if( msg.isType( "GameServerCSRequest" ) ) - { - GameServerCSRequestMessage request( ri ); - GameServer::getInstance().handleCSRequest( request ); - } - else if( msg.isType( "CSFindAuthObject" ) ) - { - // see if we have the object. - GenericValueTypeMessage< std::pair > msg( ri ); - ServerObject * object = safe_cast( NetworkIdManager::getObjectById( msg.getValue().first ) ); - // return an appropriate response. - if( object && object->isAuthoritative() ) + default : { - GenericValueTypeMessage< std::pair< unsigned int, bool > > rmsg( "CSFindAuthObjectReply", std::make_pair( msg.getValue().second, true ) ); - GameServer::getInstance().sendToCentralServer( rmsg ); + ServerConnection::onReceive(message); + break; } - else - { - GenericValueTypeMessage< std::pair< unsigned int, bool > > rmsg( "CSFindAuthObjectReply", std::make_pair( msg.getValue().second, false ) ); - GameServer::getInstance().sendToCentralServer( rmsg ); - } - } - else - { - ServerConnection::onReceive(message); } } diff --git a/engine/server/library/serverGame/src/shared/network/ConnectionServerConnection.cpp b/engine/server/library/serverGame/src/shared/network/ConnectionServerConnection.cpp index f47cfe43..05a6129e 100755 --- a/engine/server/library/serverGame/src/shared/network/ConnectionServerConnection.cpp +++ b/engine/server/library/serverGame/src/shared/network/ConnectionServerConnection.cpp @@ -41,6 +41,8 @@ #include "sharedObject/VolumeContainer.h" #include "sharedSkillSystem/SkillObject.h" +#include "sharedFoundation/CrcConstexpr.hpp" + // ====================================================================== namespace ConnectionServerConnectionNamespace @@ -111,370 +113,397 @@ void ConnectionServerConnection::onReceive (const Archive::ByteStream & message) Archive::ReadIterator ri = message.begin(); GameNetworkMessage m(ri); ri = message.begin(); - if(m.isType("GameClientMessage")) - { - GameClientMessage c(ri); - const std::vector & idList = c.getDistributionList(); - std::vector::const_iterator i; - for(i = idList.begin(); i != idList.end(); ++i) + + const uint32 messageType = m.getType(); + + switch(messageType) { + if(m.isType("GameClientMessage")) { - GameServer::getInstance().deliverMessageToClientObject((*i), c.getByteStream()); - } - } - else if (m.isType("SetSyncStamp")) - { - Archive::ReadIterator readIterator = message.begin(); - GenericValueTypeMessage > syncStampMessage(readIterator); - setSyncStamps(syncStampMessage.getValue().first, syncStampMessage.getValue().second); - } - else if (m.isType("ChatOnChangeFriendStatus")) - { - ChatOnChangeFriendStatus chat(ri); - - CommunityManager::handleMessage(chat); - } - else if (m.isType("ChatOnGetFriendsList")) - { - ChatOnGetFriendsList chat(ri); - - CommunityManager::handleMessage(chat); - } - else if (m.isType("ChatOnChangeIgnoreStatus")) - { - ChatOnChangeIgnoreStatus chat(ri); - - CommunityManager::handleMessage(chat); - } - else if (m.isType("ChatOnGetIgnoreList")) - { - ChatOnGetIgnoreList chat(ri); - - CommunityManager::handleMessage(chat); - } - else if (m.isType("ChatStatisticsCS")) - { - GenericValueTypeMessage, std::pair > > chatStatistics(ri); - ServerObject * const so = ServerWorld::findObjectByNetworkId(chatStatistics.getValue().first.first); - if (so) - { - CreatureObject * const character = so->asCreatureObject(); - if (character) + GameClientMessage c(ri); + const std::vector & idList = c.getDistributionList(); + std::vector::const_iterator i; + for(i = idList.begin(); i != idList.end(); ++i) { - PlayerObject * const player = PlayerCreatureController::getPlayerObject(character); - if (player) + GameServer::getInstance().deliverMessageToClientObject((*i), c.getByteStream()); + } + break; + } + case constcrc("SetSyncStamp") : + { + Archive::ReadIterator readIterator = message.begin(); + GenericValueTypeMessage > syncStampMessage(readIterator); + setSyncStamps(syncStampMessage.getValue().first, syncStampMessage.getValue().second); + break; + } + case constcrc("ChatOnChangeFriendStatus") : + { + ChatOnChangeFriendStatus chat(ri); + + CommunityManager::handleMessage(chat); + break; + } + case constcrc("ChatOnGetFriendsList") : + { + ChatOnGetFriendsList chat(ri); + + CommunityManager::handleMessage(chat); + break; + } + case constcrc("ChatOnChangeIgnoreStatus") : + { + ChatOnChangeIgnoreStatus chat(ri); + + CommunityManager::handleMessage(chat); + break; + } + case constcrc("ChatOnGetIgnoreList") : + { + ChatOnGetIgnoreList chat(ri); + + CommunityManager::handleMessage(chat); + break; + } + case constcrc("ChatStatisticsCS") : + { + GenericValueTypeMessage, std::pair > > chatStatistics(ri); + ServerObject * const so = ServerWorld::findObjectByNetworkId(chatStatistics.getValue().first.first); + if (so) + { + CreatureObject * const character = so->asCreatureObject(); + if (character) { - player->handleChatStatisticsFromChatServer(chatStatistics.getValue().first.first, chatStatistics.getValue().first.second, chatStatistics.getValue().second.first, chatStatistics.getValue().second.second); + PlayerObject * const player = PlayerCreatureController::getPlayerObject(character); + if (player) + { + player->handleChatStatisticsFromChatServer(chatStatistics.getValue().first.first, chatStatistics.getValue().first.second, chatStatistics.getValue().second.first, chatStatistics.getValue().second.second); + } } } + break; } - } - else if (m.isType("RequestLoadPackedHouses")) - { - GenericValueTypeMessage characterId(ri); - LOG("CustomerService", ("CharacterTransfer: ConnectionServerConnection received RequestLoadPackedHouses for %s", characterId.getValue().getValueString().c_str())); - - CreatureObject * character = dynamic_cast(NetworkIdManager::getObjectById(characterId.getValue())); - if(character) + case constcrc("RequestLoadPackedHouses") : { - int numHouses = 0; - numHouses = character->loadPackedHouses(); - if (numHouses > 0) - { - character->setLoadCTSPackedHouses(true); - // add the objvar. - character->setObjVarItem("cts.packed_house_count", numHouses); - LOG("CustomerService", ("CharacterTransfer: starting %d packed house load for CTS character %s", numHouses, PlayerObject::getAccountDescription(character).c_str())); - } - else - { - // houses are loaded, go ahead and send the reply message - GenericValueTypeMessage loadedMsg("PackedHousesLoaded", characterId.getValue()); - send(loadedMsg, true); - LOG("CustomerService", ("CharacterTransfer: CTS character %s does not have any packed houses, so telling the connection server", PlayerObject::getAccountDescription(character).c_str())); - } - } - else - LOG("CustomerService", ("CharacterTransfer: character object was nullptr so unable to check if bank is loaded")); + GenericValueTypeMessage characterId(ri); + LOG("CustomerService", ("CharacterTransfer: ConnectionServerConnection received RequestLoadPackedHouses for %s", characterId.getValue().getValueString().c_str())); - } - - else if (m.isType("RequestLoadCTSBank")) - { - GenericValueTypeMessage characterId(ri); - LOG("CustomerService", ("CharacterTransfer: ConnectionServerConnection received RequestLoadCTSBank for %s", characterId.getValue().getValueString().c_str())); - - CreatureObject * character = dynamic_cast(NetworkIdManager::getObjectById(characterId.getValue())); - if(character) - { - ServerObject *bankContainer = character->getBankContainer(); - if (bankContainer) + CreatureObject * character = dynamic_cast(NetworkIdManager::getObjectById(characterId.getValue())); + if(character) { - if (!bankContainer->areContentsLoaded()) + int numHouses = 0; + numHouses = character->loadPackedHouses(); + if (numHouses > 0) { - LOG("CustomerService", ("CharacterTransfer: setting LoadCTSBank flag and request bank to be loaded for %s", PlayerObject::getAccountDescription(character).c_str())); - character->setLoadCTSBank(true); - bankContainer->loadAllContentsFromDB(); + character->setLoadCTSPackedHouses(true); + // add the objvar. + character->setObjVarItem("cts.packed_house_count", numHouses); + LOG("CustomerService", ("CharacterTransfer: starting %d packed house load for CTS character %s", numHouses, PlayerObject::getAccountDescription(character).c_str())); } else { - LOG("CustomerService", ("CharacterTransfer: bank contents already loaded for %s, sending ReplyBankCTSLoaded back to client", PlayerObject::getAccountDescription(character).c_str())); - //Bank contents are already loaded - GenericValueTypeMessage reply("ReplyBankCTSLoaded", characterId.getValue()); - send(reply, true); + // houses are loaded, go ahead and send the reply message + GenericValueTypeMessage loadedMsg("PackedHousesLoaded", characterId.getValue()); + send(loadedMsg, true); + LOG("CustomerService", ("CharacterTransfer: CTS character %s does not have any packed houses, so telling the connection server", PlayerObject::getAccountDescription(character).c_str())); } } else - LOG("CustomerService", ("CharacterTransfer: bank container object was nullptr for getBankContainer call")); - } - else - LOG("CustomerService", ("CharacterTransfer: character object was nullptr so unable to check if bank is loaded")); - } - else if (m.isType("RequestTransferData")) - { - GenericValueTypeMessage requestTransferData(ri); - const TransferCharacterData & transferCharacterData = requestTransferData.getValue(); - - CreatureObject * const character = dynamic_cast(NetworkIdManager::getObjectById(requestTransferData.getValue().getCharacterId())); - PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(character); - time_t characterCreateTime = -1; - FreeCtsDataTable::FreeCtsInfo const * freeCtsInfo = nullptr; - bool freeCtsBypassTimeRestriction = false; - if (character && playerObject) - { - characterCreateTime = static_cast(NameManager::getInstance().getPlayerCreateTime(character->getNetworkId())); + LOG("CustomerService", ("CharacterTransfer: character object was nullptr so unable to check if bank is loaded")); - freeCtsInfo = FreeCtsDataTable::wouldCharacterTransferBeFree(characterCreateTime, static_cast(transferCharacterData.getSourceStationId()), transferCharacterData.getSourceGalaxy(), static_cast(transferCharacterData.getDestinationStationId()), transferCharacterData.getDestinationGalaxy(), false); + break; - // see if we can/should bypass the free CTS time restriction - if (!freeCtsInfo && ConfigServerGame::getAllowIgnoreFreeCtsTimeRestriction() && (transferCharacterData.getTransferRequestSource() == TransferRequestMoveValidation::TRS_ingame_freects_command_transfer)) - { - // if we got this far and the CTS request came from TRS_ingame_freects_command_transfer, then it - // should be allowed as a free CTS, so do another check bypassing the free CTS time restriction - // check to find any matching free CTS rule, even if the time restriction on the rule has expired - freeCtsInfo = FreeCtsDataTable::wouldCharacterTransferBeFree(characterCreateTime, static_cast(transferCharacterData.getSourceStationId()), transferCharacterData.getSourceGalaxy(), static_cast(transferCharacterData.getDestinationStationId()), transferCharacterData.getDestinationGalaxy(), true); - if (freeCtsInfo) - { - freeCtsBypassTimeRestriction = true; - } - } } - LOG("CustomerService", ("CharacterTransfer: Received RequestTransferData for character [character create time (%s) free transfer (%s)] %s", ((characterCreateTime > 0) ? CalendarTime::convertEpochToTimeStringLocal(characterCreateTime).c_str() : "NA"), (freeCtsInfo ? (freeCtsBypassTimeRestriction ? "yes - bypass" : "yes") : "no "), transferCharacterData.toString().c_str())); - - bool succeeded = false; - if(ServerWorld::getSceneId() != NewbieTutorial::getSceneId()) + case constcrc("RequestLoadCTSBank") : { + GenericValueTypeMessage characterId(ri); + LOG("CustomerService", ("CharacterTransfer: ConnectionServerConnection received RequestLoadCTSBank for %s", characterId.getValue().getValueString().c_str())); + + CreatureObject * character = dynamic_cast(NetworkIdManager::getObjectById(characterId.getValue())); if(character) { - // get hair - std::string hairObjectTemplateName; - std::string hairObjectAppearanceData; - SlottedContainer * const container = ContainerInterface::getSlottedContainer(*character); - if(container) + ServerObject *bankContainer = character->getBankContainer(); + if (bankContainer) { - SlotId hairSlot = SlotIdManager::findSlotId(ConstCharCrcString("hair")); - if(hairSlot != SlotId::invalid) + if (!bankContainer->areContentsLoaded()) { - Container::ContainerErrorCode containerErrorCode = Container::CEC_Success; - Container::ContainedItem hairItem = container->getObjectInSlot(hairSlot, containerErrorCode); - const TangibleObject * hairObject = dynamic_cast(hairItem.getObject()); - if(hairObject) - { - hairObjectTemplateName = hairObject->getObjectTemplateName(); - hairObjectAppearanceData = hairObject->getAppearanceData(); - } - } - } - std::string professionName; - const CreatureObject::SkillList & skills = character->getSkillList(); - if (!skills.empty()) - { - for (CreatureObject::SkillList::const_iterator i = skills.begin(); i != skills.end(); ++i) - { - const SkillObject * profession = (*i)->findProfessionForSkill(); - if (profession != nullptr) - professionName = profession->getSkillName(); - } - } - if (professionName.empty()) - { - // just get the 1st profession available - PlayerCreationManager::StringVector professions; - PlayerCreationManager::getProfessionVector (professions, ""); - if (! professions.empty()) - { - professionName = professions[0]; - } - } - - if (playerObject) - { - // set objvar on the creature indicating that transfer will be free, - // so that script can include the information in the packed dictionary - // so that the information can be transferred to the destination galaxy - // indicating that it's a free transfer - character->removeObjVarItem("freeCtsTransactionRuleName"); - - if (freeCtsInfo) - IGNORE_RETURN(character->setObjVarItem("freeCtsTransactionRuleName", (freeCtsInfo->ruleName.empty() ? "freeCts" : freeCtsInfo->ruleName))); - - std::vector dictionaryData = character->uploadCharacterData(transferCharacterData.getWithItems(), transferCharacterData.getAllowOverride()); - - character->removeObjVarItem("freeCtsTransactionRuleName"); - - if(! dictionaryData.empty()) - { - // send the response to the Connection server - TransferCharacterData replyData(transferCharacterData); - replyData.setCustomizationData(character->getAppearanceData()); - replyData.setScriptDictionaryData(dictionaryData); - replyData.setObjectTemplateName(character->getObjectTemplateName()); - replyData.setObjectTemplateCrc(character->getTemplateCrc()); - replyData.setScaleFactor(character->getScaleFactor()); - replyData.setHairTemplateName(hairObjectTemplateName); - replyData.setHairAppearanceData(hairObjectAppearanceData); - replyData.setProfession(professionName); - replyData.setSkillTemplate(playerObject->getSkillTemplate()); - replyData.setWorkingSkill(playerObject->getWorkingSkill()); - - GenericValueTypeMessage reply("ReplyTransferData", replyData); - send(reply, true); - succeeded = true; + LOG("CustomerService", ("CharacterTransfer: setting LoadCTSBank flag and request bank to be loaded for %s", PlayerObject::getAccountDescription(character).c_str())); + character->setLoadCTSBank(true); + bankContainer->loadAllContentsFromDB(); } else { - LOG("CustomerService", ("CharacterTransfer: Transfer failed: Could not retrieve dictionary for character object (%s) for transfer request. %s", requestTransferData.getValue().getCharacterId().getValueString().c_str(), requestTransferData.getValue().toString().c_str())); + LOG("CustomerService", ("CharacterTransfer: bank contents already loaded for %s, sending ReplyBankCTSLoaded back to client", PlayerObject::getAccountDescription(character).c_str())); + //Bank contents are already loaded + GenericValueTypeMessage reply("ReplyBankCTSLoaded", characterId.getValue()); + send(reply, true); + } + } + else + LOG("CustomerService", ("CharacterTransfer: bank container object was nullptr for getBankContainer call")); + } + else + LOG("CustomerService", ("CharacterTransfer: character object was nullptr so unable to check if bank is loaded")); + + break; + } + case constcrc("RequestTransferData") : + { + GenericValueTypeMessage requestTransferData(ri); + const TransferCharacterData & transferCharacterData = requestTransferData.getValue(); + + CreatureObject * const character = dynamic_cast(NetworkIdManager::getObjectById(requestTransferData.getValue().getCharacterId())); + PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(character); + time_t characterCreateTime = -1; + FreeCtsDataTable::FreeCtsInfo const * freeCtsInfo = nullptr; + bool freeCtsBypassTimeRestriction = false; + if (character && playerObject) + { + characterCreateTime = static_cast(NameManager::getInstance().getPlayerCreateTime(character->getNetworkId())); + + freeCtsInfo = FreeCtsDataTable::wouldCharacterTransferBeFree(characterCreateTime, static_cast(transferCharacterData.getSourceStationId()), transferCharacterData.getSourceGalaxy(), static_cast(transferCharacterData.getDestinationStationId()), transferCharacterData.getDestinationGalaxy(), false); + + // see if we can/should bypass the free CTS time restriction + if (!freeCtsInfo && ConfigServerGame::getAllowIgnoreFreeCtsTimeRestriction() && (transferCharacterData.getTransferRequestSource() == TransferRequestMoveValidation::TRS_ingame_freects_command_transfer)) + { + // if we got this far and the CTS request came from TRS_ingame_freects_command_transfer, then it + // should be allowed as a free CTS, so do another check bypassing the free CTS time restriction + // check to find any matching free CTS rule, even if the time restriction on the rule has expired + freeCtsInfo = FreeCtsDataTable::wouldCharacterTransferBeFree(characterCreateTime, static_cast(transferCharacterData.getSourceStationId()), transferCharacterData.getSourceGalaxy(), static_cast(transferCharacterData.getDestinationStationId()), transferCharacterData.getDestinationGalaxy(), true); + if (freeCtsInfo) + { + freeCtsBypassTimeRestriction = true; + } + } + } + + LOG("CustomerService", ("CharacterTransfer: Received RequestTransferData for character [character create time (%s) free transfer (%s)] %s", ((characterCreateTime > 0) ? CalendarTime::convertEpochToTimeStringLocal(characterCreateTime).c_str() : "NA"), (freeCtsInfo ? (freeCtsBypassTimeRestriction ? "yes - bypass" : "yes") : "no "), transferCharacterData.toString().c_str())); + + bool succeeded = false; + if(ServerWorld::getSceneId() != NewbieTutorial::getSceneId()) + { + if(character) + { + // get hair + std::string hairObjectTemplateName; + std::string hairObjectAppearanceData; + SlottedContainer * const container = ContainerInterface::getSlottedContainer(*character); + if(container) + { + SlotId hairSlot = SlotIdManager::findSlotId(ConstCharCrcString("hair")); + if(hairSlot != SlotId::invalid) + { + Container::ContainerErrorCode containerErrorCode = Container::CEC_Success; + Container::ContainedItem hairItem = container->getObjectInSlot(hairSlot, containerErrorCode); + const TangibleObject * hairObject = dynamic_cast(hairItem.getObject()); + if(hairObject) + { + hairObjectTemplateName = hairObject->getObjectTemplateName(); + hairObjectAppearanceData = hairObject->getAppearanceData(); + } + } + } + std::string professionName; + const CreatureObject::SkillList & skills = character->getSkillList(); + if (!skills.empty()) + { + for (CreatureObject::SkillList::const_iterator i = skills.begin(); i != skills.end(); ++i) + { + const SkillObject * profession = (*i)->findProfessionForSkill(); + if (profession != nullptr) + professionName = profession->getSkillName(); + } + } + if (professionName.empty()) + { + // just get the 1st profession available + PlayerCreationManager::StringVector professions; + PlayerCreationManager::getProfessionVector (professions, ""); + if (! professions.empty()) + { + professionName = professions[0]; + } + } + + if (playerObject) + { + // set objvar on the creature indicating that transfer will be free, + // so that script can include the information in the packed dictionary + // so that the information can be transferred to the destination galaxy + // indicating that it's a free transfer + character->removeObjVarItem("freeCtsTransactionRuleName"); + + if (freeCtsInfo) + IGNORE_RETURN(character->setObjVarItem("freeCtsTransactionRuleName", (freeCtsInfo->ruleName.empty() ? "freeCts" : freeCtsInfo->ruleName))); + + std::vector dictionaryData = character->uploadCharacterData(transferCharacterData.getWithItems(), transferCharacterData.getAllowOverride()); + + character->removeObjVarItem("freeCtsTransactionRuleName"); + + if(! dictionaryData.empty()) + { + // send the response to the Connection server + TransferCharacterData replyData(transferCharacterData); + replyData.setCustomizationData(character->getAppearanceData()); + replyData.setScriptDictionaryData(dictionaryData); + replyData.setObjectTemplateName(character->getObjectTemplateName()); + replyData.setObjectTemplateCrc(character->getTemplateCrc()); + replyData.setScaleFactor(character->getScaleFactor()); + replyData.setHairTemplateName(hairObjectTemplateName); + replyData.setHairAppearanceData(hairObjectAppearanceData); + replyData.setProfession(professionName); + replyData.setSkillTemplate(playerObject->getSkillTemplate()); + replyData.setWorkingSkill(playerObject->getWorkingSkill()); + + GenericValueTypeMessage reply("ReplyTransferData", replyData); + send(reply, true); + succeeded = true; + } + else + { + LOG("CustomerService", ("CharacterTransfer: Transfer failed: Could not retrieve dictionary for character object (%s) for transfer request. %s", requestTransferData.getValue().getCharacterId().getValueString().c_str(), requestTransferData.getValue().toString().c_str())); + } + } + else + { + LOG("CustomerService", ("CharacterTransfer: Transfer failed: Could not load player object (%s) for transfer request. %s", requestTransferData.getValue().getCharacterId().getValueString().c_str(), requestTransferData.getValue().toString().c_str())); } } else { - LOG("CustomerService", ("CharacterTransfer: Transfer failed: Could not load player object (%s) for transfer request. %s", requestTransferData.getValue().getCharacterId().getValueString().c_str(), requestTransferData.getValue().toString().c_str())); + LOG("CustomerService", ("CharacterTransfer: Transfer failed: Could not load character object (%s) for transfer request. %s", requestTransferData.getValue().getCharacterId().getValueString().c_str(), requestTransferData.getValue().toString().c_str())); } } else { - LOG("CustomerService", ("CharacterTransfer: Transfer failed: Could not load character object (%s) for transfer request. %s", requestTransferData.getValue().getCharacterId().getValueString().c_str(), requestTransferData.getValue().toString().c_str())); + LOG("CustomerService", ("CharacterTransfer: Transfer failed: transfers from the Tutorial are not allowed. %s", transferCharacterData.toString().c_str())); } - } - else - { - LOG("CustomerService", ("CharacterTransfer: Transfer failed: transfers from the Tutorial are not allowed. %s", transferCharacterData.toString().c_str())); - } - if(! succeeded) - { - GenericValueTypeMessage reply("ReplyTransferDataFail", requestTransferData.getValue()); - send(reply, true); - } - } - else if (m.isType("ApplyTransferData")) - { - GenericValueTypeMessage applyTransferData(ri); - LOG("CustomerService", ("CharacterTransfer: Received ApplyTransferData for character %s", applyTransferData.getValue().toString().c_str())); - const TransferCharacterData & transferCharacterData = applyTransferData.getValue(); - - CreatureObject * character = dynamic_cast(NetworkIdManager::getObjectById(transferCharacterData.getDestinationCharacterId())); - if(character) - { - if(character->receiveCharacterTransferMessage(transferCharacterData.getScriptDictionaryData())) + if(! succeeded) { - // force CTS failure if the source character has this objvar (which has now been - // transferred to the target character); this is for testing CTS failure handing - if (character->getObjVars().hasItem("testing_only_force_cts_failure_testing_only")) + GenericValueTypeMessage reply("ReplyTransferDataFail", requestTransferData.getValue()); + send(reply, true); + } + + break; + } + case constcrc("ApplyTransferData") : + { + GenericValueTypeMessage applyTransferData(ri); + LOG("CustomerService", ("CharacterTransfer: Received ApplyTransferData for character %s", applyTransferData.getValue().toString().c_str())); + const TransferCharacterData & transferCharacterData = applyTransferData.getValue(); + + CreatureObject * character = dynamic_cast(NetworkIdManager::getObjectById(transferCharacterData.getDestinationCharacterId())); + if(character) + { + if(character->receiveCharacterTransferMessage(transferCharacterData.getScriptDictionaryData())) { - GenericValueTypeMessage applyTransferDataFail("ApplyTransferDataFail", transferCharacterData); - send(applyTransferDataFail, true); - LOG("CustomerService", ("CharacterTransfer: *** ERROR: Character has testing_only_force_cts_failure_testing_only objvar, sending ApplyTransferDataFail to central %s", applyTransferData.getValue().toString().c_str())); + // force CTS failure if the source character has this objvar (which has now been + // transferred to the target character); this is for testing CTS failure handing + if (character->getObjVars().hasItem("testing_only_force_cts_failure_testing_only")) + { + GenericValueTypeMessage applyTransferDataFail("ApplyTransferDataFail", transferCharacterData); + send(applyTransferDataFail, true); + LOG("CustomerService", ("CharacterTransfer: *** ERROR: Character has testing_only_force_cts_failure_testing_only objvar, sending ApplyTransferDataFail to central %s", applyTransferData.getValue().toString().c_str())); + } + else + { + GenericValueTypeMessage applyTransferDataSuccess("ApplyTransferDataSuccess", transferCharacterData); + send(applyTransferDataSuccess, true); + LOG("CustomerService", ("CharacterTransfer: Sending ApplyTransferDataSuccess for character %s", applyTransferData.getValue().toString().c_str())); + } } else { - GenericValueTypeMessage applyTransferDataSuccess("ApplyTransferDataSuccess", transferCharacterData); - send(applyTransferDataSuccess, true); - LOG("CustomerService", ("CharacterTransfer: Sending ApplyTransferDataSuccess for character %s", applyTransferData.getValue().toString().c_str())); + GenericValueTypeMessage applyTransferDataFail("ApplyTransferDataFail", transferCharacterData); + send(applyTransferDataFail, true); + LOG("CustomerService", ("CharacterTransfer: *** ERROR: Sending ApplyTransferDataFail for character %s", applyTransferData.getValue().toString().c_str())); } } else { GenericValueTypeMessage applyTransferDataFail("ApplyTransferDataFail", transferCharacterData); send(applyTransferDataFail, true); - LOG("CustomerService", ("CharacterTransfer: *** ERROR: Sending ApplyTransferDataFail for character %s", applyTransferData.getValue().toString().c_str())); + LOG("CustomerService", ("CharacterTransfer: *** ERROR: Could not find object for character, sending ApplyTransferDataFail to central %s", applyTransferData.getValue().toString().c_str())); } + + break; } - else + case constcrc("ChatEnterRoomValidationRequest") : { - GenericValueTypeMessage applyTransferDataFail("ApplyTransferDataFail", transferCharacterData); - send(applyTransferDataFail, true); - LOG("CustomerService", ("CharacterTransfer: *** ERROR: Could not find object for character, sending ApplyTransferDataFail to central %s", applyTransferData.getValue().toString().c_str())); + Archive::ReadIterator readIterator = message.begin(); + GenericValueTypeMessage, unsigned int> > const cervreq(readIterator); + + unsigned int result = CHATRESULT_SUCCESS; + + ServerObject const * const o = ServerWorld::findObjectByNetworkId(cervreq.getValue().first.first); + CreatureObject const * const co = (o ? o->asCreatureObject() : nullptr); + if (co) + { + result = Chat::isAllowedToEnterRoom(*co, cervreq.getValue().first.second); + } + else + { + result = SWG_CHAT_ERR_INVALID_OBJECT; + } + + GenericValueTypeMessage, unsigned int> > const cervresp( + "ChatEnterRoomValidationResponse", + std::make_pair( + std::make_pair(cervreq.getValue().first.first, result), + cervreq.getValue().second)); + + send(cervresp, true); + + break; } - } - else if (m.isType("ChatEnterRoomValidationRequest")) - { - Archive::ReadIterator readIterator = message.begin(); - GenericValueTypeMessage, unsigned int> > const cervreq(readIterator); - - unsigned int result = CHATRESULT_SUCCESS; - - ServerObject const * const o = ServerWorld::findObjectByNetworkId(cervreq.getValue().first.first); - CreatureObject const * const co = (o ? o->asCreatureObject() : nullptr); - if (co) + case constcrc("ChatQueryRoomValidationRequest") : { - result = Chat::isAllowedToEnterRoom(*co, cervreq.getValue().first.second); + Archive::ReadIterator readIterator = message.begin(); + GenericValueTypeMessage, unsigned int> > const cqrvreq(readIterator); + + bool success = false; + + ServerObject const * const o = ServerWorld::findObjectByNetworkId(cqrvreq.getValue().first.first); + CreatureObject const * const co = (o ? o->asCreatureObject() : nullptr); + if (co) + { + success = (CHATRESULT_SUCCESS == Chat::isAllowedToEnterRoom(*co, cqrvreq.getValue().first.second)); + } + + GenericValueTypeMessage, unsigned int> > const cqrvresp( + "ChatQueryRoomValidationResponse", + std::make_pair( + std::make_pair(cqrvreq.getValue().first.first, success), + cqrvreq.getValue().second)); + + send(cqrvresp, true); + + break; } - else + case constcrc("PlayerDroppedFromGameServerCrash") : { - result = SWG_CHAT_ERR_INVALID_OBJECT; + Archive::ReadIterator readIterator = message.begin(); + GenericValueTypeMessage > const m(readIterator); + + std::map const & connectedCharacterLfgData = ServerUniverse::getConnectedCharacterLfgData(); + std::map const & connectedCharacterBiographyData = ServerUniverse::getConnectedCharacterBiographyData(); + + std::set::const_iterator const end = m.getValue().end(); + for (std::set::const_iterator iter = m.getValue().begin(); iter != end; ++iter) + { + if (connectedCharacterLfgData.count(*iter) > 0) + ServerUniverse::removeConnectedCharacterData(*iter); + + if (connectedCharacterBiographyData.count(*iter) > 0) + ServerUniverse::removeConnectedCharacterBiographyData(*iter); + } + + break; } - - GenericValueTypeMessage, unsigned int> > const cervresp( - "ChatEnterRoomValidationResponse", - std::make_pair( - std::make_pair(cervreq.getValue().first.first, result), - cervreq.getValue().second)); - - send(cervresp, true); - } - else if (m.isType("ChatQueryRoomValidationRequest")) - { - Archive::ReadIterator readIterator = message.begin(); - GenericValueTypeMessage, unsigned int> > const cqrvreq(readIterator); - - bool success = false; - - ServerObject const * const o = ServerWorld::findObjectByNetworkId(cqrvreq.getValue().first.first); - CreatureObject const * const co = (o ? o->asCreatureObject() : nullptr); - if (co) + default : { - success = (CHATRESULT_SUCCESS == Chat::isAllowedToEnterRoom(*co, cqrvreq.getValue().first.second)); + ServerConnection::emitMessage(m); + break; } - - GenericValueTypeMessage, unsigned int> > const cqrvresp( - "ChatQueryRoomValidationResponse", - std::make_pair( - std::make_pair(cqrvreq.getValue().first.first, success), - cqrvreq.getValue().second)); - - send(cqrvresp, true); - } - else if (m.isType("PlayerDroppedFromGameServerCrash")) - { - Archive::ReadIterator readIterator = message.begin(); - GenericValueTypeMessage > const m(readIterator); - - std::map const & connectedCharacterLfgData = ServerUniverse::getConnectedCharacterLfgData(); - std::map const & connectedCharacterBiographyData = ServerUniverse::getConnectedCharacterBiographyData(); - - std::set::const_iterator const end = m.getValue().end(); - for (std::set::const_iterator iter = m.getValue().begin(); iter != end; ++iter) - { - if (connectedCharacterLfgData.count(*iter) > 0) - ServerUniverse::removeConnectedCharacterData(*iter); - - if (connectedCharacterBiographyData.count(*iter) > 0) - ServerUniverse::removeConnectedCharacterBiographyData(*iter); - } - } - else - { - ServerConnection::emitMessage(m); } }