From 232bcc82dc6e07d19836131638f4efae3d56bba1 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Tue, 21 Jan 2014 09:18:28 -0700 Subject: [PATCH] Added CustomerServiceServer project --- CMakeLists.txt | 1 + engine/server/application/CMakeLists.txt | 3 +- .../CustomerServiceServer/CMakeLists.txt | 6 + .../CustomerServiceServer/src/CMakeLists.txt | 89 ++ .../CustomerServiceServer/src/linux/main.cpp | 42 + .../src/shared/CentralServerConnection.cpp | 111 +++ .../src/shared/CentralServerConnection.h | 30 + .../src/shared/ChatServerConnection.cpp | 77 ++ .../src/shared/ChatServerConnection.h | 36 + .../shared/ConfigCustomerServiceServer.cpp | 167 ++++ .../src/shared/ConfigCustomerServiceServer.h | 40 + .../src/shared/ConnectionServerConnection.cpp | 156 ++++ .../src/shared/ConnectionServerConnection.h | 33 + .../src/shared/CustomerServiceInterface.cpp | 866 ++++++++++++++++++ .../src/shared/CustomerServiceInterface.h | 102 +++ .../src/shared/CustomerServiceServer.cpp | 769 ++++++++++++++++ .../src/shared/CustomerServiceServer.h | 111 +++ .../CustomerServiceServerMetricsData.cpp | 28 + .../shared/CustomerServiceServerMetricsData.h | 31 + .../src/shared/FirstCustomerServiceServer.cpp | 11 + .../src/shared/FirstCustomerServiceServer.h | 20 + .../src/shared/GameServerConnection.cpp | 83 ++ .../src/shared/GameServerConnection.h | 36 + 23 files changed, 2846 insertions(+), 2 deletions(-) create mode 100644 engine/server/application/CustomerServiceServer/CMakeLists.txt create mode 100644 engine/server/application/CustomerServiceServer/src/CMakeLists.txt create mode 100644 engine/server/application/CustomerServiceServer/src/linux/main.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/CentralServerConnection.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/CentralServerConnection.h create mode 100644 engine/server/application/CustomerServiceServer/src/shared/ChatServerConnection.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/ChatServerConnection.h create mode 100644 engine/server/application/CustomerServiceServer/src/shared/ConfigCustomerServiceServer.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/ConfigCustomerServiceServer.h create mode 100644 engine/server/application/CustomerServiceServer/src/shared/ConnectionServerConnection.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/ConnectionServerConnection.h create mode 100644 engine/server/application/CustomerServiceServer/src/shared/CustomerServiceInterface.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/CustomerServiceInterface.h create mode 100644 engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServer.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServer.h create mode 100644 engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServerMetricsData.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServerMetricsData.h create mode 100644 engine/server/application/CustomerServiceServer/src/shared/FirstCustomerServiceServer.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/FirstCustomerServiceServer.h create mode 100644 engine/server/application/CustomerServiceServer/src/shared/GameServerConnection.cpp create mode 100644 engine/server/application/CustomerServiceServer/src/shared/GameServerConnection.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c10add10..c614eb63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ elseif(UNIX) endif() include_directories(${STLPORT_INCLUDE_DIR}) +link_directories(${STLPORT_LIBDIR}) add_subdirectory(external) add_subdirectory(engine) diff --git a/engine/server/application/CMakeLists.txt b/engine/server/application/CMakeLists.txt index 8d97f791..a4188daf 100644 --- a/engine/server/application/CMakeLists.txt +++ b/engine/server/application/CMakeLists.txt @@ -1,10 +1,9 @@ -link_directories(${STLPORT_LIBDIR}) - add_subdirectory(CentralServer) add_subdirectory(ChatServer) add_subdirectory(CommoditiesServer) add_subdirectory(ConnectionServer) +add_subdirectory(CustomerServiceServer) add_subdirectory(LogServer) add_subdirectory(LoginPing) add_subdirectory(LoginServer) diff --git a/engine/server/application/CustomerServiceServer/CMakeLists.txt b/engine/server/application/CustomerServiceServer/CMakeLists.txt new file mode 100644 index 00000000..df43a5ff --- /dev/null +++ b/engine/server/application/CustomerServiceServer/CMakeLists.txt @@ -0,0 +1,6 @@ + +cmake_minimum_required(VERSION 2.8) + +project(CustomerServiceServer) + +add_subdirectory(src) diff --git a/engine/server/application/CustomerServiceServer/src/CMakeLists.txt b/engine/server/application/CustomerServiceServer/src/CMakeLists.txt new file mode 100644 index 00000000..94ad317d --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/CMakeLists.txt @@ -0,0 +1,89 @@ + +set(SHARED_SOURCES + shared/CentralServerConnection.cpp + shared/CentralServerConnection.h + shared/ChatServerConnection.cpp + shared/ChatServerConnection.h + shared/ConfigCustomerServiceServer.cpp + shared/ChatServerConnection.cpp + shared/ChatServerConnection.h + shared/ConfigCustomerServiceServer.h + shared/ConnectionServerConnection.cpp + shared/ConnectionServerConnection.h + shared/CustomerServiceInterface.cpp + shared/CustomerServiceInterface.h + shared/CustomerServiceServer.cpp + shared/CustomerServiceServer.h + shared/CustomerServiceServerMetricsData.cpp + shared/CustomerServiceServerMetricsData.h + shared/FirstCustomerServiceServer.cpp + shared/FirstCustomerServiceServer.h + shared/GameServerConnection.cpp + shared/GameServerConnection.h +) + +if(WIN32) + set(PLATFORM_SOURCES "") +else() + set(PLATFORM_SOURCES + linux/main.cpp + ) +endif() + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/shared + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCompression/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetwork/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedThread/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverMetrics/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/soePlatform/CSAssist/projects/CSAssist/CSAssistgameapi + ${LIBXML2_INCLUDE_DIR} +) + +add_executable(CustomerServiceServer + ${SHARED_SOURCES} + ${PLATFORM_SOURCES} +) + +target_link_libraries(CustomerServiceServer + sharedCompression + sharedDebug + sharedFile + sharedFoundation + sharedLog + sharedMath + sharedMemoryManager + sharedMessageDispatch + sharedNetwork + sharedNetworkMessages + sharedRandom + sharedSynchronization + sharedThread + sharedXml + serverMetrics + serverNetworkMessages + serverUtility + archive + unicode + unicodeArchive + CSAssist + ${STLPORT_LIBRARIES} + ${CMAKE_DL_LIBS} +) diff --git a/engine/server/application/CustomerServiceServer/src/linux/main.cpp b/engine/server/application/CustomerServiceServer/src/linux/main.cpp new file mode 100644 index 00000000..3c071fd6 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/linux/main.cpp @@ -0,0 +1,42 @@ +#include "sharedFoundation/FirstSharedFoundation.h" + +#include "ConfigCustomerServiceServer.h" +#include "CustomerServiceServer.h" + +#include "sharedCompression/SetupSharedCompression.h" +#include "sharedDebug/SetupSharedDebug.h" +#include "sharedFile/SetupSharedFile.h" +#include "sharedFoundation/Os.h" +#include "sharedFoundation/SetupSharedFoundation.h" +#include "sharedNetwork/NetworkHandler.h" +#include "sharedNetworkMessages/SetupSharedNetworkMessages.h" +#include "sharedRandom/SetupSharedRandom.h" +#include "sharedThread/SetupSharedThread.h" +#include + +// ====================================================================== + +int main(int argc, char *argv[]) +{ + SetupSharedThread::install(); + SetupSharedDebug::install(1024); + + SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game); + setupFoundationData.lpCmdLine = ConvertCommandLine(argc, argv); + SetupSharedFoundation::install(setupFoundationData); + + SetupSharedCompression::install(); + + SetupSharedFile::install(false); + SetupSharedNetworkMessages::install(); + + SetupSharedRandom::install(static_cast(time(NULL))); + Os::setProgramName("CustomerServiceServer"); + ConfigCustomerServiceServer::install(); + NetworkHandler::install(); + CustomerServiceServer::getInstance().run(); + NetworkHandler::remove(); + SetupSharedFoundation::remove(); + + return 0; +} diff --git a/engine/server/application/CustomerServiceServer/src/shared/CentralServerConnection.cpp b/engine/server/application/CustomerServiceServer/src/shared/CentralServerConnection.cpp new file mode 100644 index 00000000..68a2ded3 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/CentralServerConnection.cpp @@ -0,0 +1,111 @@ +// CentralServerConnection.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. + +//----------------------------------------------------------------------- + +#include "FirstCustomerServiceServer.h" +#include "CentralServerConnection.h" + +#include "CustomerServiceServer.h" +#include "Archive/ByteStream.h" +#include "serverNetworkMessages/EnumerateServers.h" +#include "sharedLog/Log.h" +#include "sharedMessageDispatch/Transceiver.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedNetwork/Service.h" +#include "sharedNetwork/NetworkSetupData.h" + +//----------------------------------------------------------------------- + +CentralServerConnection::CentralServerConnection(const std::string & a, const unsigned short p) : +ServerConnection(a, p, NetworkSetupData()) +{ + LOG("CentralServerConnection", ("Connection created...listening on (%s:%d)", a.c_str(), static_cast(p))); +} + +//----------------------------------------------------------------------- + +CentralServerConnection::~CentralServerConnection() +{ +} + +//----------------------------------------------------------------------- + +void CentralServerConnection::onConnectionClosed() +{ + LOG("CentralServerConnection", ("onConnectionClosed()")); + + CustomerServiceServer::getInstance().setDone(true); +} + +//----------------------------------------------------------------------- + +void CentralServerConnection::onConnectionOpened() +{ + LOG("CentralServerConnection", ("onConnectionOpened()")); + + { + // Send to central that the address for the chat server to use when communicating with the customer service server + + Service *chatServerService = CustomerServiceServer::getInstance().getChatServerService(); + + if (chatServerService != NULL) + { + const std::string address(chatServerService->getBindAddress()); + const int port = chatServerService->getBindPort(); + + //DEBUG_REPORT_LOG(true, ("CustServ: sending chat server service address(%s:%d)\n", address.c_str(), port)); + + const GenericValueTypeMessage > message("CustomerServiceServerChatServerServiceAddress", std::make_pair(address, port)); + + send(message, true); + } + else + { + LOG("CentralServerConnection", ("onConnectionOpened() ERROR: ChatServerService is NULL")); + } + } + + { + // Send to central that the address for the game server to use when communicating with the customer service server + + Service *gameServerService = CustomerServiceServer::getInstance().getGameServerService(); + + if (gameServerService != NULL) + { + const std::string address(gameServerService->getBindAddress()); + const int port = gameServerService->getBindPort(); + + //DEBUG_REPORT_LOG(true, ("CustServ: sending game server service address(%s:%d)\n", address.c_str(), port)); + + const GenericValueTypeMessage > message("CustomerServiceServerGameServerServiceAddress", std::make_pair(address, port)); + + send(message, true); + } + else + { + LOG("CentralServerConnection", ("onConnectionOpened() ERROR: GameServerService is NULL")); + } + } +} + +//----------------------------------------------------------------------- + +void CentralServerConnection::onReceive(const Archive::ByteStream & message) +{ + Archive::ReadIterator ri = message.begin(); + GameNetworkMessage m(ri); + + ri = message.begin(); + + if(m.isType("EnumerateServers")) + { + static MessageDispatch::Transceiver emitter; + + EnumerateServers e(ri); + emitter.emitMessage(e); + } +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/application/CustomerServiceServer/src/shared/CentralServerConnection.h b/engine/server/application/CustomerServiceServer/src/shared/CentralServerConnection.h new file mode 100644 index 00000000..86db9b51 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/CentralServerConnection.h @@ -0,0 +1,30 @@ +// CentralServerConnection.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +#ifndef INCLUDED_CentralServerConnection_H +#define INCLUDED_CentralServerConnection_H + +//----------------------------------------------------------------------- + +#include "serverUtility/ServerConnection.h" + +//----------------------------------------------------------------------- + +class CentralServerConnection : public ServerConnection +{ +public: + CentralServerConnection(const std::string & remoteAddress, const unsigned short remotePort); + ~CentralServerConnection(); + + void onConnectionClosed (); + void onConnectionOpened (); + void onReceive (const Archive::ByteStream & bs); +private: + CentralServerConnection & operator = (const CentralServerConnection & rhs); + CentralServerConnection(const CentralServerConnection & source); +};//lint !e1712 default constructor not defined for class + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_CentralServerConnection_H diff --git a/engine/server/application/CustomerServiceServer/src/shared/ChatServerConnection.cpp b/engine/server/application/CustomerServiceServer/src/shared/ChatServerConnection.cpp new file mode 100644 index 00000000..239a4630 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/ChatServerConnection.cpp @@ -0,0 +1,77 @@ +// ChatServerConnection.cpp +// Copyright 2004, Sony Online Entertainment Inc., all rights reserved. + +//----------------------------------------------------------------------- +#include "FirstCustomerServiceServer.h" +#include "ChatServerConnection.h" + +#include "CustomerServiceServer.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/GameNetworkMessage.h" + +//----------------------------------------------------------------------- +namespace ChatServerConnectionNamespace +{ + ChatServerConnection *s_connection = 0; +}; + +using namespace ChatServerConnectionNamespace; + +//----------------------------------------------------------------------- +ChatServerConnection::ChatServerConnection(UdpConnectionMT * u, TcpClient * t) + : ServerConnection(u, t) +{ + LOG("ChatServerConnection", ("Connection created...listening on (%s:%d)", getRemoteAddress().c_str(), static_cast(getRemotePort()))); + + s_connection = this; +} + +//----------------------------------------------------------------------- +ChatServerConnection::~ChatServerConnection() +{ + s_connection = 0; +} + +//----------------------------------------------------------------------- +void ChatServerConnection::onConnectionClosed() +{ + LOG("ChatServerConnection", ("onConnectionClosed()")); +} + +//----------------------------------------------------------------------- +void ChatServerConnection::onConnectionOpened() +{ + LOG("ChatServerConnection", ("onConnectionOpened()")); +} + +//----------------------------------------------------------------------- +void ChatServerConnection::onReceive(const Archive::ByteStream & message) +{ + Archive::ReadIterator ri = message.begin(); + GameNetworkMessage gameNetworkMessage(ri); + + ri = message.begin(); + + if (gameNetworkMessage.isType("ChatOnRequestLog")) + { + ChatOnRequestLog chatOnRequestLog(ri); + CustomerServiceServer::getInstance().handleChatServerChatLog(chatOnRequestLog); + } +} + +//----------------------------------------------------------------------- +void ChatServerConnection::sendTo(GameNetworkMessage const &message) +{ + LOG("ChatServerConnection", ("sendTo() message(%s)", message.getCmdName().c_str())); + + if (s_connection != NULL) + { + s_connection->send(message, true); + } + else + { + LOG("ChatServerConnection", ("sendTo() Unable to send, NULL ChatServerConnection")); + } +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/CustomerServiceServer/src/shared/ChatServerConnection.h b/engine/server/application/CustomerServiceServer/src/shared/ChatServerConnection.h new file mode 100644 index 00000000..12cc64c8 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/ChatServerConnection.h @@ -0,0 +1,36 @@ +// ChatServerConnection.h +// Copyright 2004, Sony Online Entertainment Inc., all rights reserved. + +#ifndef INCLUDED_ChatServerConnection_H +#define INCLUDED_ChatServerConnection_H + +//----------------------------------------------------------------------- + +#include "serverUtility/ServerConnection.h" + +//----------------------------------------------------------------------- + +class GameNetworkMessage; + +class ChatServerConnection : public ServerConnection +{ +public: + + ChatServerConnection(UdpConnectionMT * u, TcpClient * t); + ~ChatServerConnection(); + + void onConnectionClosed(); + void onConnectionOpened(); + void onReceive(const Archive::ByteStream & bs); + + static void sendTo(GameNetworkMessage const &message); + +private: + + ChatServerConnection & operator = (const ChatServerConnection & rhs); + ChatServerConnection(const ChatServerConnection & source); +}; //lint !e1712 default constructor not defined for class + +//----------------------------------------------------------------------- + +#endif // INCLUDED_ChatServerConnection_H diff --git a/engine/server/application/CustomerServiceServer/src/shared/ConfigCustomerServiceServer.cpp b/engine/server/application/CustomerServiceServer/src/shared/ConfigCustomerServiceServer.cpp new file mode 100644 index 00000000..7a693032 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/ConfigCustomerServiceServer.cpp @@ -0,0 +1,167 @@ +// ConfigCustomerServiceServer.cpp +// copyright 2000 Verant Interactive + +//----------------------------------------------------------------------- + +#include "FirstCustomerServiceServer.h" +#include "sharedFoundation/ConfigFile.h" +#include "sharedNetwork/SetupSharedNetwork.h" +#include "ConfigCustomerServiceServer.h" + +//----------------------------------------------------------------------- + +namespace ConfigCustomerServiceServerNamespace +{ + const char * s_clusterName = NULL; + const char * s_centralServerAddress = NULL; + int s_centralServerPort = 0; + const char * s_gameCode = NULL; + const char * s_csServerAddress = NULL; + int s_csServerPort = 0; + int s_maxPacketsPerSecond = 50; + int s_requestTimeoutSeconds = 300; + int s_maxAllowedNumberOfTickets = 1; + int s_gameServicePort = 0; + int s_chatServicePort = 0; + const char* s_chatServiceBindInterface = NULL; + const char* s_gameServiceBindInterface = NULL; + bool s_writeTicketToBugLog = false; +}; + +using namespace ConfigCustomerServiceServerNamespace; + +//----------------------------------------------------------------------- + +#define KEY_INT(a,b) (s_ ## a = ConfigFile::getKeyInt("CustomerServiceServer", #a, b)) +#define KEY_STRING(a,b) (s_ ## a = ConfigFile::getKeyString("CustomerServiceServer", #a, b)) +#define KEY_BOOL(a,b) (s_ ## a = ConfigFile::getKeyBool("CustomerServiceServer", #a, b)) + +//----------------------------------------------------------------------- + +void ConfigCustomerServiceServer::install() +{ + SetupSharedNetwork::SetupData networkSetupData; + SetupSharedNetwork::getDefaultServerSetupData(networkSetupData); + SetupSharedNetwork::install(networkSetupData); + + KEY_STRING (clusterName, "devcluster"); + KEY_STRING (centralServerAddress, "swo-dev8.station.sony.com"); + KEY_INT (centralServerPort, 61242); + KEY_STRING (gameCode, "SWG"); + KEY_STRING (csServerAddress, "sdlogin1.station.sony.com"); + KEY_INT (csServerPort, 3016); + KEY_INT (maxPacketsPerSecond, 50); + KEY_INT (requestTimeoutSeconds, 300); + KEY_INT (maxAllowedNumberOfTickets, 1); + KEY_INT (gameServicePort, 50010); + KEY_STRING (gameServiceBindInterface, ""); + KEY_INT (chatServicePort, 50011); + KEY_STRING (chatServiceBindInterface, ""); + KEY_BOOL (writeTicketToBugLog, false); +} + +//----------------------------------------------------------------------- + +void ConfigCustomerServiceServer::remove() +{ +} + +//----------------------------------------------------------------------- + +int ConfigCustomerServiceServer::getMaxPacketsPerSecond() +{ + return s_maxPacketsPerSecond; +} + +//----------------------------------------------------------------------- + +unsigned int ConfigCustomerServiceServer::getRequestTimeoutSeconds() +{ + return static_cast(s_requestTimeoutSeconds); +} + +//----------------------------------------------------------------------- + +const char * ConfigCustomerServiceServer::getCustomerServiceServerAddress() +{ + return s_csServerAddress; +} + +//----------------------------------------------------------------------- + +unsigned short ConfigCustomerServiceServer::getCustomerServiceServerPort() +{ + return static_cast(s_csServerPort); +} + +//----------------------------------------------------------------------- + +const char * ConfigCustomerServiceServer::getCentralServerAddress() +{ + return s_centralServerAddress; +} + +//----------------------------------------------------------------------- + +unsigned short ConfigCustomerServiceServer::getCentralServerPort() +{ + return static_cast(s_centralServerPort); +} + +//----------------------------------------------------------------------- + +const char * ConfigCustomerServiceServer::getClusterName() +{ + return s_clusterName; +} + +//----------------------------------------------------------------------- + +const char * ConfigCustomerServiceServer::getGameCode() +{ + return s_gameCode; +} + +//----------------------------------------------------------------------- + +int ConfigCustomerServiceServer::getMaxAllowedNumberOfTickets() +{ + return s_maxAllowedNumberOfTickets; +} + +//----------------------------------------------------------------------- + +unsigned short ConfigCustomerServiceServer::getGameServicePort() +{ + return static_cast(s_gameServicePort); +} + +//----------------------------------------------------------------------- + +unsigned short ConfigCustomerServiceServer::getChatServicePort() +{ + return static_cast(s_chatServicePort); +} + +//----------------------------------------------------------------------- + +const char* ConfigCustomerServiceServer::getGameServiceBindInterface() +{ + return s_gameServiceBindInterface; +} + +//----------------------------------------------------------------------- + +const char* ConfigCustomerServiceServer::getChatServiceBindInterface() +{ + return s_chatServiceBindInterface; +} + +//----------------------------------------------------------------------- + +bool ConfigCustomerServiceServer::getWriteTicketToBugLog() +{ + return s_writeTicketToBugLog; +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/CustomerServiceServer/src/shared/ConfigCustomerServiceServer.h b/engine/server/application/CustomerServiceServer/src/shared/ConfigCustomerServiceServer.h new file mode 100644 index 00000000..4ed8136d --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/ConfigCustomerServiceServer.h @@ -0,0 +1,40 @@ +// ConfigCustomerServiceServer.h +// copyright 2000 Verant Interactive + +#ifndef INCLUDED_ConfigCustomerServiceServer_H +#define INCLUDED_ConfigCustomerServiceServer_H + +//----------------------------------------------------------------------- + +class ConfigCustomerServiceServer +{ +public: + + static void install(); + static void remove(); + + static const char * getCustomerServiceServerAddress(); + static unsigned short getCustomerServiceServerPort(); + static const char * getCentralServerAddress(); + static unsigned short getCentralServerPort(); + static const char * getClusterName(); + static const char * getGameCode(); + static int getMaxPacketsPerSecond(); + static unsigned int getRequestTimeoutSeconds(); + static int getMaxAllowedNumberOfTickets(); + static unsigned short getGameServicePort(); + static unsigned short getChatServicePort(); + static const char* getChatServiceBindInterface(); + static const char* getGameServiceBindInterface(); + static bool getWriteTicketToBugLog(); +private: + + // Disabled + + ConfigCustomerServiceServer(); + ~ConfigCustomerServiceServer(); + ConfigCustomerServiceServer(ConfigCustomerServiceServer const &); + ConfigCustomerServiceServer &operator =(ConfigCustomerServiceServer const &); +}; + +#endif // INCLUDED_ConfigCustomerServiceServer_H diff --git a/engine/server/application/CustomerServiceServer/src/shared/ConnectionServerConnection.cpp b/engine/server/application/CustomerServiceServer/src/shared/ConnectionServerConnection.cpp new file mode 100644 index 00000000..3031dd2a --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/ConnectionServerConnection.cpp @@ -0,0 +1,156 @@ +// ConnectionServerConnection.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. + +//----------------------------------------------------------------------- +#include "FirstCustomerServiceServer.h" + +#include "CustomerServiceServer.h" +#include "ConfigCustomerServiceServer.h" +#include "ConnectionServerConnection.h" +#include "serverNetworkMessages/GameConnectionServerMessages.h" +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedLog/Log.h" +#include "sharedMessageDispatch/Transceiver.h" +#include "sharedNetworkMessages/AppendCommentMessage.h" +#include "sharedNetworkMessages/CancelTicketMessage.h" +#include "sharedNetworkMessages/ConnectPlayerMessage.h" +#include "sharedNetworkMessages/CreateTicketMessage.h" +#include "sharedNetworkMessages/GetArticleMessage.h" +#include "sharedNetworkMessages/GetCommentsMessage.h" +#include "sharedNetworkMessages/GetTicketsMessage.h" +#include "sharedNetworkMessages/NewTicketActivityMessage.h" +#include "sharedNetworkMessages/RequestCategoriesMessage.h" +#include "sharedNetworkMessages/SearchKnowledgeBaseMessage.h" +#include "sharedNetwork/NetworkSetupData.h" +#include "UnicodeUtils.h" + +//----------------------------------------------------------------------- + +ConnectionServerConnection::ConnectionServerConnection(const std::string & a, const unsigned short p) : +ServerConnection(a, p, NetworkSetupData()) +{ + LOG("ConnectionServerConnection", ("Connection created...listening on (%s:%d)", a.c_str(), static_cast(p))); +} + +//----------------------------------------------------------------------- + +ConnectionServerConnection::~ConnectionServerConnection() +{ + CustomerServiceServer::getInstance().connectionServerConnectionDestroyed(this); +} + +//----------------------------------------------------------------------- + +void ConnectionServerConnection::onConnectionClosed() +{ + LOG("ConnectionServerConnection", ("onConnectionClosed()")); +} + +//----------------------------------------------------------------------- + +void ConnectionServerConnection::onConnectionOpened() +{ + LOG("ConnectionServerConnection", ("onConnectionOpened()")); +} + +//----------------------------------------------------------------------- + +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); + Archive::ReadIterator cri = c.getByteStream().begin(); + GameNetworkMessage cm(cri); + + std::vector::const_iterator i; + for (i = c.getDistributionList().begin(); i != c.getDistributionList().end(); ++i) + { + cri = c.getByteStream().begin(); + + NetworkId const &networkId = (*i); + + if (cm.isType("RequestCategoriesMessage")) + { + RequestCategoriesMessage message(cri); + CustomerServiceServer::getInstance().requestCategories(networkId, message.getLanguage()); + } + else if (cm.isType("ConnectPlayerMessage")) + { + ConnectPlayerMessage message(cri); + CustomerServiceServer::getInstance().requestRegisterCharacter(networkId, this, message.getStationId()); + } + else if (cm.isType("DisconnectPlayerMessage")) + { + CustomerServiceServer::getInstance().requestUnRegisterCharacter(networkId); + } + else if (cm.isType("CreateTicketMessage")) + { + CreateTicketMessage message(cri); + + CustomerServiceServer::getInstance().createTicket(networkId, + message.getStationId(), message.getCharacterName(), + message.getCategory(), message.getSubCategory(), + message.getDetails(), message.getHiddenDetails(), + message.getHarassingPlayerName(), + message.getLanguage(), message.isBug() + ); + } + else if (cm.isType("AppendCommentMessage")) + { + AppendCommentMessage message(cri); + CustomerServiceServer::getInstance().appendComment(networkId, message.getStationId(), message.getCharacterName(), message.getTicketId(), message.getComment()); + } + else if (cm.isType("CancelTicketMessage")) + { + CancelTicketMessage message(cri); + CustomerServiceServer::getInstance().cancelTicket(networkId, message.getStationId(), message.getTicketId(), message.getComment()); + } + else if (cm.isType("GetTicketsMessage")) + { + GetTicketsMessage message(cri); + CustomerServiceServer::getInstance().getTickets(networkId, message.getStationId()); + } + else if (cm.isType("GetCommentsMessage")) + { + GetCommentsMessage message(cri); + CustomerServiceServer::getInstance().getComments(networkId, + message.getTicketId()); + } + else if (cm.isType("SearchKnowledgeBaseMessage")) + { + SearchKnowledgeBaseMessage message(cri); + CustomerServiceServer::getInstance().searchKnowledgeBase(networkId, message.getSearchString(), message.getLanguage()); + } + else if (cm.isType("GetArticleMessage")) + { + GetArticleMessage message(cri); + CustomerServiceServer::getInstance().getArticle(networkId, message.getId(), message.getLanguage()); + } + else if (cm.isType("NewTicketActivityMessage")) + { + NewTicketActivityMessage message(cri); + + CustomerServiceServer::getInstance().requestNewTicketActivity(networkId, message.getStationId()); + } + } + } +} + +//----------------------------------------------------------------------- + +void ConnectionServerConnection::sendToClient(const NetworkId & clientId, const GameNetworkMessage & message) +{ + static std::vector v; + v.clear(); + v.push_back(clientId); + GameClientMessage msg(v, true, message); + ServerConnection::send(msg, true); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/CustomerServiceServer/src/shared/ConnectionServerConnection.h b/engine/server/application/CustomerServiceServer/src/shared/ConnectionServerConnection.h new file mode 100644 index 00000000..bb0975f7 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/ConnectionServerConnection.h @@ -0,0 +1,33 @@ +// ConnectionServerConnection.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. + +#ifndef _INCLUDED_ConnectionServerConnection_H +#define _INCLUDED_ConnectionServerConnection_H + +//----------------------------------------------------------------------- + +#include "serverUtility/ServerConnection.h" + +//----------------------------------------------------------------------- + +class GameNetworkMessage; + +class ConnectionServerConnection : public ServerConnection +{ +public: + ConnectionServerConnection(const std::string & remoteAddress, const unsigned short remotePort); + ~ConnectionServerConnection(); + + void onConnectionClosed (); + void onConnectionOpened (); + void onReceive (const Archive::ByteStream & bs); + void sendToClient (const NetworkId & clientId, const GameNetworkMessage & message); + +private: + ConnectionServerConnection & operator = (const ConnectionServerConnection & rhs); + ConnectionServerConnection(const ConnectionServerConnection & source); +}; //lint !e1712 default constructor not defined for class + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_ConnectionServerConnection_H diff --git a/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceInterface.cpp b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceInterface.cpp new file mode 100644 index 00000000..e1e93c31 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceInterface.cpp @@ -0,0 +1,866 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// CustomerServiceInterface.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "FirstCustomerServiceServer.h" +#include "CustomerServiceInterface.h" +#include "CustomerServiceServer.h" +#include "UnicodeUtils.h" + +#include "ConfigCustomerServiceServer.h" +#include "ConnectionServerConnection.h" + +#include "sharedFoundation/Clock.h" +#include "sharedFoundation/FormattedString.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/AppendCommentResponseMessage.h" +#include "sharedNetworkMessages/CancelTicketResponseMessage.h" +#include "sharedNetworkMessages/ConnectPlayerResponseMessage.h" +#include "sharedNetworkMessages/CreateTicketResponseMessage.h" +#include "sharedNetworkMessages/GameNetworkMessage.h" +#include "sharedNetworkMessages/GetArticleResponseMessage.h" +#include "sharedNetworkMessages/GetCommentsResponseMessage.h" +#include "sharedNetworkMessages/GetTicketsResponseMessage.h" +#include "sharedNetworkMessages/NewTicketActivityResponseMessage.h" +#include "sharedNetworkMessages/SearchKnowledgeBaseResponseMessage.h" + +#include + +using namespace CSAssist; + +/////////////////////////////////////////////////////////////////////////////// +// +// CustomerServiceInterface::ClientInfo +// +/////////////////////////////////////////////////////////////////////////////// + +CustomerServiceInterface::ClientInfo::ClientInfo() + : m_connection(NULL) + , m_stationUserId(0) + , m_ticketCount(-1) + , m_pendingTicketCount(0) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// +// CustomerServiceInterface +// +/////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------- + +CustomerServiceInterface::CustomerServiceInterface(const char *server, const unsigned port, const unsigned timeout) : +CSAssistGameAPI(server, port, timeout, CSASSIST_APIFLAG_ASSUME_RECONNECT), +m_englishCategoryList(new CategoryList), +m_japaneseCategoryList(new CategoryList), +m_clientConnectionMap(new ClientConnectionMap), +m_suidToNetworkIdMap(new SuidToNetworkIdMap), +m_connectionToBackEndEstablised(false) +{ +} + +//----------------------------------------------------------------------- + +CustomerServiceInterface::~CustomerServiceInterface() +{ + delete m_englishCategoryList; + delete m_japaneseCategoryList; + + delete m_clientConnectionMap; + m_clientConnectionMap = NULL; + + delete m_suidToNetworkIdMap; + m_suidToNetworkIdMap = NULL; +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnConnectCSAssist( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void * /*userData*/ +) +{ + char const * const text = FormattedString<1024>().sprintf("OnConnectCSAssist() track(%i) result(%i) (%s)", track, result, getErrorString(result)); + REPORT_LOG(true, ("CustomerServiceInterface::%s\n", text)); + LOG("CSServer", ("%s", text)); + + if (result == CSASSIST_RESULT_SUCCESS) + { + if (m_connectionToBackEndEstablised) + { + LOG("CSServer", ("OnConnectCSAssist() - Reconnecting to the CS back-end, connection was lost.")); + } + + m_connectionToBackEndEstablised = true; + m_englishCategoryTrack = requestGetIssueHierarchy(NULL, Unicode::narrowToWide("Default").data(), Unicode::narrowToWide("en").data());; + m_japaneseCategoryTrack = requestGetIssueHierarchy(NULL, Unicode::narrowToWide("Default").data(), Unicode::narrowToWide("ja").data());; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnConnectRejectedCSAssist(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void * /*userData*/) +{ + m_connectionToBackEndEstablised = false; + + char const * const text = FormattedString<1024>().sprintf("OnConnectRejectedCSAssist() track(%i) result(%i) (%s)", track, result, getErrorString(result)); + REPORT_LOG(true, ("CustomerServiceInterface::%s\n", text)); + LOG("CSServer", ("%s", text)); +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::parseIssueChild(CategoryList & categoryList, xmlNodePtr childPtr) +{ + static CustomerServiceCategory *currentCategory = NULL; + xmlNodePtr child = childPtr->children; + + //start element + const char *tagName = reinterpret_cast(childPtr->name); + + Unicode::String categoryName; + int categoryId = 0; + char * val = reinterpret_cast(xmlGetProp(childPtr, (const unsigned char *)"name")); + + if (val) + { + categoryName = Unicode::utf8ToWide(val); + } + + val = reinterpret_cast(xmlGetProp(childPtr, (const unsigned char *)"id")); + if (val) + { + categoryId = atoi(val); + } + + // Check for bug type + + val = reinterpret_cast(xmlGetProp(childPtr, (const unsigned char *)"isBugType")); + + bool const isBugType = (val != NULL) && (strcmp(val, "true") == 0); + + // Check for service type + + val = reinterpret_cast(xmlGetProp(childPtr, (const unsigned char *)"isServiceType")); + + bool const isServiceType = (val != NULL) && (strcmp(val, "true") == 0); + + // Check if valid + + val = reinterpret_cast(xmlGetProp(childPtr, (const unsigned char *)"invalid")); + + bool const invalid = (val != NULL) && (strcmp(val, "true") == 0); + + if (!invalid) + { + if (strcmp(tagName, "category") == 0) + { + CustomerServiceCategory * const category = new CustomerServiceCategory(categoryName, categoryId, isBugType, isServiceType); + currentCategory = category; + } + else if (strcmp(tagName, "subCategory") == 0) + { + CustomerServiceCategory const category(categoryName, categoryId, isBugType, isServiceType); + + if (currentCategory) + { + currentCategory->addSubCategory(category); + } + } + } + else + { + // Skip these categories + + if (strcmp(tagName, "category") == 0) + { + LOG("CSServer", ("parseIssueChild() Skipping invalid category(%s) id(%d)", categoryName.c_str(), categoryId)); + } + else if (strcmp(tagName, "subCategory") == 0) + { + LOG("CSServer", ("parseIssueChild() Skipping invalid sub-category(%s) id(%d)", categoryName.c_str(), categoryId)); + } + } + + while (child != NULL) + { + if (child->name != NULL) + { + parseIssueChild(categoryList, child); + } + child = child->next; + } + + if ( !invalid + && (strcmp(tagName, "category") == 0)) + { + categoryList.push_back(*currentCategory); + + if (currentCategory) + { + delete currentCategory; + currentCategory = NULL; + } + } + + //end element +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::parseIssueHierarchy(CategoryList & categoryList, Unicode::String const & xmlData) +{ + xmlDocPtr xmlInfo = NULL; + Unicode::UTF8String xmlDataUtf8(Unicode::wideToUTF8(xmlData)); + + if ((xmlInfo = xmlParseMemory(xmlDataUtf8.c_str(), xmlDataUtf8.length())) != NULL) + { + xmlNodePtr xmlCurrent = xmlDocGetRootElement(xmlInfo); + if (xmlCurrent != NULL) + { + parseIssueChild(categoryList, xmlCurrent); + } + xmlFreeDoc(xmlInfo); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnGetIssueHierarchy( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void * /*userData*/, + const CSAssistGameAPIXML hierarchyBody, + const unsigned modifyData +) +{ + LOG("CSServer", ("OnGetIssueHierarchy() track(%i) modifyData(%u) result(%i:%s)", track, modifyData, result, getErrorString(result))); + + if (result != 0) + { + LOG("CSServer", ("ERROR: failure code returned...the hierarchy will not be parsed.")); + return; + } + + if (hierarchyBody != NULL) + { + if (track == m_englishCategoryTrack) + { + m_englishCategoryList->clear(); + parseIssueHierarchy(*m_englishCategoryList, hierarchyBody); + } + else if (track == m_japaneseCategoryTrack) + { + m_japaneseCategoryList->clear(); + parseIssueHierarchy(*m_japaneseCategoryList, hierarchyBody); + } + else + { + LOG("CSServer", ("ERROR: Unknown track specified(%u)...the hierarchy will not be parsed.", track)); + } + } + else + { + LOG("CSServer", ("ERROR: NULL hierarchy returned from platform...why did this happen?", track, modifyData, result, getErrorString(result))); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnCreateTicket( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void *userData, + const CSAssistGameAPITicketID ticket +) +{ + CreateTicketResponseMessage message(result, ticket); + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnCreateTicket() track(%i) result(%i) (%s) networkId(%s) ticketId(%i)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA", ticket)); + + if (tmpNetworkId != NULL) + { + if (result == CSASSIST_RESULT_SUCCESS) + { + incrementTicketCount(*tmpNetworkId); + } + + decrementPendingTicketCount(*tmpNetworkId); + + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnAppendTicketComment( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void *userData, + const CSAssistGameAPITicketID ticket +) +{ + AppendCommentResponseMessage message(result, ticket); + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnAppendTicketComment() track(%i) result(%i) (%s) networkId(%s) ticketId(%i)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA", ticket)); + + if (tmpNetworkId != NULL) + { + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnCancelTicket( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void *userData, + const CSAssistGameAPITicketID ticket +) +{ + CancelTicketResponseMessage message(result, ticket); + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnCancelTicket() track(%i) result(%i) (%s) networkId(%s) ticketId(%i)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA", ticket)); + + if (tmpNetworkId != NULL) + { + if (result == CSASSIST_RESULT_SUCCESS) + { + decrementTicketCount(*tmpNetworkId); + } + + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnGetTicketByCharacter( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void *userData, + const unsigned numberReturned, + const unsigned totalNumber, + const CSAssistGameAPITicket *ticketBody +) +{ + std::vector tickets; + for (unsigned int i = 0; i < numberReturned; i++) + { + tickets.push_back(CustomerServiceTicket(ticketBody[i].category[0], + ticketBody[i].category[1], + std::string(Unicode::wideToNarrow(ticketBody[i].character).c_str()), + Unicode::String(ticketBody[i].details), + Unicode::wideToNarrow(ticketBody[i].language), + ticketBody[i].ticketID, + ticketBody[i].modifiedDate, + ticketBody[i].isRead, + (ticketBody[i].status == TICKET_STATUS_PENDING_CLOSED) || (ticketBody[i].status == TICKET_STATUS_CLOSED))); + } + GetTicketsResponseMessage message(result, totalNumber, tickets); + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnGetTicketByCharacter() track(%i) result(%i) (%s) networkId(%s) totalNumber(%i) numberReturned(%i)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA", totalNumber, numberReturned)); + + if (tmpNetworkId != NULL) + { + // Save the number of tickets this player has + + ClientConnectionMap::iterator iterClientMap = m_clientConnectionMap->find(*tmpNetworkId); + + if (iterClientMap != m_clientConnectionMap->end()) + { + iterClientMap->second.m_ticketCount = static_cast(totalNumber); + } + + // Send the tickets to the client + + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnGetTicketComments( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void *userData, + const CSAssistGameAPITicketComment *comments, + const unsigned int numberRead +) +{ + std::vector commentsVector; + for (unsigned int i = 0; i < numberRead; i++) + { + commentsVector.push_back(CustomerServiceComment(comments[i].ticketID, + comments[i].commentID, + comments[i].type == CSASSIST_COMMENT_FROM_CSR, + Unicode::String(comments[i].comment), + Unicode::wideToNarrow(comments[i].name))); + } + GetCommentsResponseMessage message(result, commentsVector); + + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnGetTicketComments() track(%i) result(%i) (%s) networkId(%s) numberRead(%i)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA", numberRead)); + + if (tmpNetworkId != NULL) + { + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnSearchKB( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void *userData, + const CSAssistGameAPISearchResult *searchResults, + const unsigned numberRead +) +{ + std::vector searchResultsVector; + for (unsigned int i = 0; i < numberRead; i++) + { + searchResultsVector.push_back(CustomerServiceSearchResult( + Unicode::String(searchResults[i].title), + Unicode::wideToNarrow(searchResults[i].idstring), + searchResults[i].matchPercent)); + } + SearchKnowledgeBaseResponseMessage message(result, searchResultsVector); + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnSearchKB() track(%i) result(%i) (%s) networkId(%s) numberRead(%i)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA", numberRead)); + + if (tmpNetworkId != NULL) + { + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnGetKBArticle( + const CSAssistGameAPITrack track, + const CSAssistGameAPIResult result, + const void *userData, + const CSAssistGameAPIXML articleBody, + const CSAssistUnicodeChar* +) +{ + LOG("CSServer", ("OnGetKBArticle() track(%i) result(%i) (%s)", track, result, getErrorString(result))); + + if(articleBody) + { + GetArticleResponseMessage message(result, Unicode::String(articleBody)); + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + if (tmpNetworkId != NULL) + { + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnIssueHierarchyChanged( + const CSAssistUnicodeChar *version, + const CSAssistUnicodeChar *language +) +{ + LOG("CSServer", ("OnIssueHierarchyChanged()")); + + requestGetIssueHierarchy(NULL, version, language); +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnNewTicketActivity(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const unsigned NewActivityFlag, const unsigned HasTickets) +{ + NewTicketActivityResponseMessage message(static_cast(NewActivityFlag), HasTickets); + + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnNewTicketActivity() track(%i) result(%i) (%s) networkId(%s) activity(%s) ticket count(%i)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA", NewActivityFlag ? "yes" : "no", HasTickets)); + + if (tmpNetworkId != NULL) + { + // Save the number of tickets this player has + + ClientConnectionMap::iterator iterClientMap = m_clientConnectionMap->find(*tmpNetworkId); + + if (iterClientMap != m_clientConnectionMap->end()) + { + iterClientMap->second.m_ticketCount = static_cast(HasTickets); + } + + // Send the new ticket activity to the client + + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnMarkTicketRead(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData) +{ + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnMarkTicketRead() track(%i) result(%i) (%s) networkId(%s)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA")); + + if (tmpNetworkId != NULL) + { + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnTicketChange(const CSAssistGameAPITicketID ticketId, const CSAssistGameAPIUID uid, const CSAssistUnicodeChar *character) +{ + UNREF(character); + + NetworkId networkId; + + if (getNetworkId(uid, networkId)) + { + LOG("CSServer", ("OnTicketChange() ticketId(%i) stationId(%i) networkId(%s)", ticketId, uid, networkId.getValueString().c_str())); + + CustomerServiceServer::getInstance().getTickets(networkId, uid); + } + else + { + LOG("CSServer", ("OnTicketChange() Unable to locate player: ticketId(%i) stationId(%i) networkId: NA", ticketId, uid)); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnRegisterCharacter(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData) +{ + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnRegisterCharacter() track(%i) result(%i) (%s) networkId(%s)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA")); + + if (tmpNetworkId != NULL) + { + ConnectPlayerResponseMessage message(result); + + sendToClient(*tmpNetworkId, message); + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::OnUnRegisterCharacter(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData) +{ + const NetworkId *tmpNetworkId = reinterpret_cast(userData); + + LOG("CSServer", ("OnUnRegisterCharacter() track(%i) result(%i) (%s) networkId(%s)", track, result, getErrorString(result), (tmpNetworkId != NULL) ? tmpNetworkId->getValueString().c_str() : "NA")); + + if (tmpNetworkId != NULL) + { + // If the player was successfully unregistered, remove the local cached reference + + if (result == CSASSIST_RESULT_SUCCESS) + { + removePlayer(*tmpNetworkId); + } + + delete tmpNetworkId; + tmpNetworkId = NULL; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::addPlayer(NetworkId const &networkId, ConnectionServerConnection *connection, const unsigned int suid) +{ + LOG("CSServer", ("addPlayer() networkId(%s) suid(%i)", networkId.getValueString().c_str(), suid)); + + ClientConnectionMap::iterator iterClientConnectionMap = m_clientConnectionMap->find(networkId); + + if (iterClientConnectionMap == m_clientConnectionMap->end()) + { + ClientInfo clientInfo; + clientInfo.m_connection = connection; + clientInfo.m_stationUserId = suid; + + IGNORE_RETURN(m_clientConnectionMap->insert(std::make_pair(networkId, clientInfo))); + IGNORE_RETURN(m_suidToNetworkIdMap->insert(std::make_pair(suid, networkId))); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::removePlayer(NetworkId const &networkId) +{ + ClientConnectionMap::iterator cf = m_clientConnectionMap->find(networkId); + + if (cf != m_clientConnectionMap->end()) + { + LOG("CSServer", ("removePlayer() networkId(%s)", networkId.getValueString().c_str())); + + // Remove the suid id map item + + unsigned int const suid = cf->second.m_stationUserId; + + SuidToNetworkIdMap::iterator iterStationUserIdToNetworkIdMap = m_suidToNetworkIdMap->find(suid); + + if (iterStationUserIdToNetworkIdMap != m_suidToNetworkIdMap->end()) + { + m_suidToNetworkIdMap->erase(iterStationUserIdToNetworkIdMap); + } + + m_clientConnectionMap->erase(cf); + } + else + { + LOG("CSServer", ("removePlayer() Unable to locate player: networkId(%s)", networkId.getValueString().c_str())); + } +} + +//----------------------------------------------------------------------- + +bool CustomerServiceInterface::getNetworkId(unsigned int suid, NetworkId &networkId) +{ + bool result = false; + SuidToNetworkIdMap::const_iterator iterStationUserIdToNetworkIdMap = m_suidToNetworkIdMap->find(suid); + + if (iterStationUserIdToNetworkIdMap != m_suidToNetworkIdMap->end()) + { + result = true; + networkId = iterStationUserIdToNetworkIdMap->second; + } + + return result; +} + +//----------------------------------------------------------------------- + +bool CustomerServiceInterface::getSuid(NetworkId const &networkId, unsigned int &suid) +{ + bool result = false; + ClientConnectionMap::const_iterator cf = m_clientConnectionMap->find(networkId); + + if (cf != m_clientConnectionMap->end()) + { + result = true; + suid = cf->second.m_stationUserId; + } + + return result; +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::sendToClient(const NetworkId &player, const GameNetworkMessage &message) +{ + ClientConnectionMap::iterator cf = m_clientConnectionMap->find(player); + + if (cf != m_clientConnectionMap->end()) + { + ConnectionServerConnection *connection = cf->second.m_connection; + + if (connection) + { + LOG("CSServer", ("sendToClient() networkId(%s) cmdName(%s)", player.getValueString().c_str(), message.getCmdName().c_str())); + + connection->sendToClient(player, message); + } + else + { + LOG("CSServer", ("sendToClient() Connection is NULL: networkId(%s) cmdName(%s)", player.getValueString().c_str(), message.getCmdName().c_str())); + } + } + else + { + LOG("CSServer", ("sendToClient() Unable to locate player: networkId(%s) cmdName(%s)", player.getValueString().c_str(), message.getCmdName().c_str())); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::connectionServerConnectionDestroyed(ConnectionServerConnection * conn) +{ + ClientConnectionMap::iterator i; + + for(i = m_clientConnectionMap->begin(); i != m_clientConnectionMap->end(); ++i) + { + if(i->second.m_connection == conn) + { + requestUnRegisterCharacter((*i).first); + } + } +} + +//----------------------------------------------------------------------- + +CustomerServiceInterface::CategoryList const & CustomerServiceInterface::getEnglishCategoryList() const +{ + return *m_englishCategoryList; +} + +//----------------------------------------------------------------------- + +CustomerServiceInterface::CategoryList const & CustomerServiceInterface::getJapaneseCategoryList() const +{ + return *m_japaneseCategoryList; +} + +//----------------------------------------------------------------------- + +int CustomerServiceInterface::getTicketCount(NetworkId const &networkId) const +{ + int result = -1; + + // Get the sum of the current tickets and pending tickets + + ClientConnectionMap::iterator iterClientMap = m_clientConnectionMap->find(networkId); + + if (iterClientMap != m_clientConnectionMap->end()) + { + result = (iterClientMap->second.m_ticketCount + iterClientMap->second.m_pendingTicketCount); + } + else + { + LOG("CSServer", ("getTicketCount() Unable to locate player: networkId(%s)", networkId.getValueString().c_str())); + } + + return result; +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::requestUnRegisterCharacter(const NetworkId &requester) +{ + unsigned int suid = 0; + + if (getSuid(requester, suid)) + { + LOG("CSServer", ("requestUnRegisterCharacter() networkId(%s) suid(%i)", requester.getValueString().c_str(), suid)); + + NetworkId *tmpNetworkId = new NetworkId(requester); + CSAssistGameAPI::requestUnRegisterCharacter(reinterpret_cast(tmpNetworkId), suid, NULL); + } + else + { + LOG("CSServer", ("requestUnRegisterCharacter() Unable to locate player for unregister: networkId(%s) suid: NA", requester.getValueString().c_str())); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::incrementPendingTicketCount(NetworkId const &networkId) +{ + ClientConnectionMap::iterator iterClientMap = m_clientConnectionMap->find(networkId); + + if (iterClientMap != m_clientConnectionMap->end()) + { + ++(iterClientMap->second.m_pendingTicketCount); + + LOG("CSServer", ("incrementPendingTicketCount() Increasing (by one) the pending ticket count of networkId(%s) to tickets(%d) pending(%d).", networkId.getValueString().c_str(), iterClientMap->second.m_ticketCount, iterClientMap->second.m_pendingTicketCount)); + } + else + { + LOG("CSServer", ("incrementPendingTicketCount() Unable to locate player: networkId(%s)", networkId.getValueString().c_str())); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::decrementPendingTicketCount(NetworkId const &networkId) +{ + // Decrement the player's ticket count + + ClientConnectionMap::iterator iterClientMap = m_clientConnectionMap->find(networkId); + + if (iterClientMap != m_clientConnectionMap->end()) + { + --(iterClientMap->second.m_pendingTicketCount); + + LOG("CSServer", ("decrementPendingTicketCount() Decreasing (by one) the pending ticket count of networkId(%s) to tickets(%d) pending(%d).", networkId.getValueString().c_str(), iterClientMap->second.m_ticketCount, iterClientMap->second.m_pendingTicketCount)); + } + else + { + LOG("CSServer", ("decrementPendingTicketCount() Unable to locate player: networkId(%s)", networkId.getValueString().c_str())); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::incrementTicketCount(NetworkId const &networkId) +{ + ClientConnectionMap::iterator iterClientMap = m_clientConnectionMap->find(networkId); + + if (iterClientMap != m_clientConnectionMap->end()) + { + ++(iterClientMap->second.m_ticketCount); + + LOG("CSServer", ("incrementTicketCount() Increasing (by one) the ticket count of networkId(%s) to tickets(%d) pending(%d).", networkId.getValueString().c_str(), iterClientMap->second.m_ticketCount, iterClientMap->second.m_pendingTicketCount)); + } + else + { + LOG("CSServer", ("incrementTicketCount() Unable to locate player: networkId(%s)", networkId.getValueString().c_str())); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceInterface::decrementTicketCount(NetworkId const &networkId) +{ + // Decrement the player's ticket count + + ClientConnectionMap::iterator iterClientMap = m_clientConnectionMap->find(networkId); + + if (iterClientMap != m_clientConnectionMap->end()) + { + --(iterClientMap->second.m_ticketCount); + + LOG("CSServer", ("decrementTicketCount() Decreasing (by one) the ticket count of networkId(%s) to tickets(%d) pending(%d).", networkId.getValueString().c_str(), iterClientMap->second.m_ticketCount, iterClientMap->second.m_pendingTicketCount)); + } + else + { + LOG("CSServer", ("decrementTicketCount() Unable to locate player: networkId(%s)", networkId.getValueString().c_str())); + } +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceInterface.h b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceInterface.h new file mode 100644 index 00000000..36acb978 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceInterface.h @@ -0,0 +1,102 @@ +// CustomerServiceInterface.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. + +#ifndef _INCLUDED_CustomerServiceInterface_H +#define _INCLUDED_CustomerServiceInterface_H + +#include "CSAssistgameapi.h" +#include "CSAssistgameobjects.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedNetworkMessages/CustomerServiceCategory.h" +#include + +extern "C" { +#include "libxml/parser.h" +} + +using namespace CSAssist; + +class ConnectionServerConnection; +class GameNetworkMessage; + +//-------------------------------------------------------- + +class CustomerServiceInterface : public CSAssistGameAPI +{ +private: + + class ClientInfo + { + public: + + ClientInfo(); + + ConnectionServerConnection *m_connection; + unsigned int m_stationUserId; + int m_ticketCount; + int m_pendingTicketCount; + }; + + typedef stdhash_map::fwd ClientConnectionMap; + typedef stdmap::fwd SuidToNetworkIdMap; + typedef stdvector::fwd CategoryList; + + CategoryList * const m_englishCategoryList; + CSAssistGameAPITrack m_englishCategoryTrack; + + CategoryList * const m_japaneseCategoryList; + CSAssistGameAPITrack m_japaneseCategoryTrack; + + ClientConnectionMap * m_clientConnectionMap; + SuidToNetworkIdMap * m_suidToNetworkIdMap; + bool m_connectionToBackEndEstablised; + +protected: + + void parseIssueChild(CategoryList & categoryList, xmlNodePtr childPtr); + void parseIssueHierarchy(CategoryList & categoryList, Unicode::String const & xmlData); + +public: + CustomerServiceInterface(const char *server, const unsigned port, const unsigned timeout); + virtual ~CustomerServiceInterface(); + + void addPlayer(NetworkId const &networkId, ConnectionServerConnection *connection, const unsigned int suid); + void removePlayer(NetworkId const &networkId); + void checkQueuedLogins(); + void sendToClient(const NetworkId &player, const GameNetworkMessage &message); + bool getNetworkId(unsigned int suid, NetworkId &networkId); + bool getSuid(NetworkId const &networkId, unsigned int &suid); + int getTicketCount(NetworkId const &networkId) const; + void connectionServerConnectionDestroyed(ConnectionServerConnection *); + void requestUnRegisterCharacter(const NetworkId &requester); + void incrementPendingTicketCount(NetworkId const &networkId); + void decrementPendingTicketCount(NetworkId const &networkId); + void incrementTicketCount(NetworkId const &networkId); + void decrementTicketCount(NetworkId const &networkId); + + CategoryList const & getEnglishCategoryList() const; + CategoryList const & getJapaneseCategoryList() const; + + virtual void OnConnectCSAssist(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData); + virtual void OnConnectRejectedCSAssist(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData); + virtual void OnAppendTicketComment(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const CSAssistGameAPITicketID ticket); + virtual void OnCancelTicket(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const CSAssistGameAPITicketID ticket); + virtual void OnCreateTicket(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const CSAssistGameAPITicketID ticket); + virtual void OnGetIssueHierarchy(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const CSAssistGameAPIXML hierarchyBody, const unsigned modifyData); + virtual void OnSearchKB(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const CSAssistGameAPISearchResult *searchResults, const unsigned numberRead); + virtual void OnGetKBArticle(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const CSAssistGameAPIXML articleBody, const CSAssistUnicodeChar *articleTitle); + virtual void OnGetTicketByCharacter(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const unsigned numberReturned, const unsigned totalNumber, const CSAssistGameAPITicket *ticketBody); + virtual void OnGetTicketComments(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const CSAssistGameAPITicketComment *comments, const unsigned int numberRead); + virtual void OnIssueHierarchyChanged(const CSAssistUnicodeChar *version, const CSAssistUnicodeChar *language); + virtual void OnNewTicketActivity(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData, const unsigned NewActivityFlag, const unsigned HasTickets); + virtual void OnMarkTicketRead(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData); + virtual void OnTicketChange(const CSAssistGameAPITicketID ticketId, const CSAssistGameAPIUID uid, const CSAssistUnicodeChar *character); + virtual void OnRegisterCharacter(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData); + virtual void OnUnRegisterCharacter(const CSAssistGameAPITrack track, const CSAssistGameAPIResult result, const void *userData); + +private: + + CustomerServiceInterface & operator =(CustomerServiceInterface const &); +}; + +#endif //_INCLUDED_CustomerServiceInterface_H diff --git a/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServer.cpp b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServer.cpp new file mode 100644 index 00000000..7beaacc5 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServer.cpp @@ -0,0 +1,769 @@ +// CustomerServiceServer.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. + +//----------------------------------------------------------------------- + +#include "FirstCustomerServiceServer.h" +#include "CustomerServiceServer.h" +#include "CustomerServiceServerMetricsData.h" + +#include "CentralServerConnection.h" +#include "ChatServerConnection.h" +#include "ConfigCustomerServiceServer.h" +#include "ConnectionServerConnection.h" +#include "GameServerConnection.h" +#include "UnicodeUtils.h" + +#include "serverUtility/ChatLogManager.h" +#include "sharedFoundation/Clock.h" +#include "sharedFoundation/FormattedString.h" +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedFoundation/Os.h" +#include "sharedLog/Log.h" +#include "sharedLog/SetupSharedLog.h" +#include "sharedMessageDispatch/Transceiver.h" +#include "sharedNetwork/NetworkSetupData.h" +#include "sharedNetwork/Service.h" +#include "sharedNetworkMessages/ChatRequestLog.h" +#include "sharedNetworkMessages/ConnectPlayerResponseMessage.h" +#include "sharedNetworkMessages/CreateTicketResponseMessage.h" +#include "serverMetrics/MetricsManager.h" +#include "serverNetworkMessages/EnumerateServers.h" +#include "sharedNetworkMessages/RequestCategoriesResponseMessage.h" + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// +// CustomerServiceServerNamespace +// +/////////////////////////////////////////////////////////////////////////////// + +namespace CustomerServiceServerNamespace +{ + const unsigned int s_chatLogRequestTimeout = 45; + CustomerServiceServerMetricsData * s_customerServiceServerMetricsData = 0; +} + +using namespace CustomerServiceServerNamespace; + +CustomerServiceServer *CustomerServiceServer::m_instance = NULL; + +/////////////////////////////////////////////////////////////////////////////// +// +// CustomerServiceServer::PendingTicket +// +/////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------- + +CustomerServiceServer::PendingTicket::PendingTicket() + : m_networkId() + , m_time(0) + , m_ticket() + , m_hiddenDetails() + , m_harassingPlayerName() + , m_suid(0) + , m_chatServerChatLog() + , m_chatServerChatLogReceived(false) + , m_gameServerChatLog() + , m_gameServerChatLogReceived(false) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// +// CustomerServiceServer +// +/////////////////////////////////////////////////////////////////////////////// + +//----------------------------------------------------------------------- + +CustomerServiceServer::CustomerServiceServer() : +m_callback(new MessageDispatch::Callback), +m_centralServerConnection(NULL), +m_connectionServerSet(new ConnectionServerSet), +m_done(false), +m_csInterface(ConfigCustomerServiceServer::getCustomerServiceServerAddress(), ConfigCustomerServiceServer::getCustomerServiceServerPort(), ConfigCustomerServiceServer::getRequestTimeoutSeconds()), +m_gameServerService(NULL), +m_chatServerService(NULL), +m_nextSequenceId(0), +m_pendingTicketList(new PendingTicketList) +{ + SetupSharedLog::install("SwgCustServServer"); + + s_customerServiceServerMetricsData = new CustomerServiceServerMetricsData; + MetricsManager::install(s_customerServiceServerMetricsData, false, "CustomerServiceServer" , "", 0); + m_centralServerConnection = new CentralServerConnection( + ConfigCustomerServiceServer::getCentralServerAddress(), + ConfigCustomerServiceServer::getCentralServerPort()); + + m_callback->connect(*this, &CustomerServiceServer::onEnumerateServers); + + char text[512]; + snprintf(text, sizeof(text), "CustomerServiceServer() - ServerName(%s) ServerPort(%i) GameCode(%s)", ConfigCustomerServiceServer::getCustomerServiceServerAddress(), ConfigCustomerServiceServer::getCustomerServiceServerPort(), ConfigCustomerServiceServer::getGameCode()); + REPORT_LOG(true, ("%s\n", text)); + LOG("CSServer", ("%s", text)); + + LOG("CSServer", ("CustomerServiceServer() - MaxPacketsPerSecond(%d)", ConfigCustomerServiceServer::getMaxPacketsPerSecond())); + LOG("CSServer", ("CustomerServiceServer() - RequestTimeoutSeconds(%d)", ConfigCustomerServiceServer::getRequestTimeoutSeconds())); + LOG("CSServer", ("CustomerServiceServer() - MaxAllowedNumberOfTickets(%d)", ConfigCustomerServiceServer::getMaxAllowedNumberOfTickets())); + + m_csInterface.setMaxPacketsPerSecond(ConfigCustomerServiceServer::getMaxPacketsPerSecond()); + + m_csInterface.connectCSAssist(NULL, + Unicode::narrowToWide(ConfigCustomerServiceServer::getGameCode()).data(), + Unicode::narrowToWide(ConfigCustomerServiceServer::getClusterName()).data()); + + // Create the GameServer connection + + NetworkSetupData setup; + setup.port = ConfigCustomerServiceServer::getGameServicePort(); + setup.maxConnections = 100; + setup.bindInterface = ConfigCustomerServiceServer::getGameServiceBindInterface(); + m_gameServerService = new Service(ConnectionAllocator(), setup); + + // Create the ChatServer connection + + setup.port = ConfigCustomerServiceServer::getChatServicePort(); + setup.bindInterface = ConfigCustomerServiceServer::getChatServiceBindInterface(); + m_chatServerService = new Service(ConnectionAllocator(), setup); +} + +//----------------------------------------------------------------------- + +CustomerServiceServer::~CustomerServiceServer() +{ + ConnectionServerSet::const_iterator i = m_connectionServerSet->begin(); + while (i != m_connectionServerSet->end()) + { + ConnectionServerConnection *c = (*i); + delete c; + ++i; + } + + if(m_centralServerConnection) + m_centralServerConnection->disconnect(); + + delete m_callback; + m_callback = NULL; + + delete m_connectionServerSet; + m_connectionServerSet = NULL; + + delete m_gameServerService; + m_gameServerService = NULL; + + delete m_chatServerService; + m_chatServerService = NULL; + + delete m_pendingTicketList; + m_pendingTicketList = NULL; + + MetricsManager::remove(); + delete s_customerServiceServerMetricsData; + +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::onEnumerateServers(const EnumerateServers &e) +{ + if (e.getAdd()) + { + switch(e.getServerType()) + { + case EnumerateServers::CONNECTION_SERVER: + { + ConnectionServerConnection *c = new ConnectionServerConnection( + e.getAddress(), e.getPort()); + IGNORE_RETURN(m_connectionServerSet->insert(c)); + break; + } + + default: + break; + } + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::reconnectToCentralServer() +{ + if (m_centralServerConnection) + { + m_centralServerConnection->disconnect(); + } + m_centralServerConnection = new CentralServerConnection( + ConfigCustomerServiceServer::getCentralServerAddress(), + ConfigCustomerServiceServer::getCentralServerPort()); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::run() +{ + Clock::setFrameRateLimit(100.0f); + while(!isDone()) + { + update(); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::update() +{ + m_csInterface.Update(); + NetworkHandler::update(); + NetworkHandler::dispatch(); + + MetricsManager::update(Clock::frameTime() * 1000); + processPendingTickets(); + + if (!Os::update()) + m_done = true; + Os::sleep(1); +} + +//----------------------------------------------------------------------- + +CustomerServiceServer &CustomerServiceServer::getInstance() +{ + if (m_instance == NULL) + { + m_instance = new CustomerServiceServer; + } + return *m_instance; +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::requestCategories(NetworkId const & requester, std::string const & language) +{ + LOG("CSServer", ("requestCategories() networkId(%s) langauge(%s)", requester.getValueString().c_str(), language.c_str())); + + if (language == "ja") + { + RequestCategoriesResponseMessage const message(CSASSIST_RESULT_SUCCESS, m_csInterface.getJapaneseCategoryList()); + m_csInterface.sendToClient(requester, message); + } + else + { + if (language != "en") + { + LOG("CSServer", ("ERROR: Unknown language(%s) specified...sending English categories to the client.", language.c_str())); + } + + RequestCategoriesResponseMessage const message(CSASSIST_RESULT_SUCCESS, m_csInterface.getEnglishCategoryList()); + m_csInterface.sendToClient(requester, message); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::createTicket( + const NetworkId &requester, + unsigned int suid, + const std::string &characterName, + unsigned int category, + unsigned int subCategory, + const Unicode::String &details, + const Unicode::String &hiddenDetails, + const Unicode::String &harassingCharacterName, + const std::string &language, + bool isBug +) +{ + int const ticketCount = m_csInterface.getTicketCount(requester); + bool ticketAllowed = false; + + if (isBug) + { + ticketAllowed = true; + + if (ConfigCustomerServiceServer::getWriteTicketToBugLog()) + { + FormattedString<8192> fs; + + char const * const logMessage = fs.sprintf( + "Bugs:" + "char_id=%s, " + "character_name=%s, " + "category=%d, " + "subcategory=%d, " + "language=%s\n" + "%s", + requester.getValueString().c_str(), + characterName.c_str(), + category, + subCategory, + language.c_str(), + Unicode::wideToNarrow(details).c_str() + ); + + LOG("CustomerService", ("%s", logMessage)); + } + } + else if (ticketCount < 0) + { + LOG("CSServer", ("createTicket() - Ticket Creation Blocked for networkId(%s) suid(%i) because we have not received how many tickets this player has already.", requester.getValueString().c_str(), suid)); + + CreateTicketResponseMessage const message(CSASSIST_RESULT_NOCREATE_TICKET, 0); + m_csInterface.sendToClient(requester, message); + } + else if (ticketCount < ConfigCustomerServiceServer::getMaxAllowedNumberOfTickets()) + { + ticketAllowed = true; + } + else + { + LOG("CSServer", ("createTicket() - Ticket Creation Blocked for networkId(%s) suid(%i) ticket count(%d) max tickets allowed(%d)", requester.getValueString().c_str(), suid, ticketCount, ConfigCustomerServiceServer::getMaxAllowedNumberOfTickets())); + + CreateTicketResponseMessage const message(CSASSIST_RESULT_NOCREATE_TICKET, 0); + m_csInterface.sendToClient(requester, message); + } + + if (ticketAllowed) + { + LOG("CSServer", ("createTicket() - networkId(%s) suid(%i) category(%i) subCategory(%i) isBug(%s)", requester.getValueString().c_str(), suid, category, subCategory, isBug ? "yes" : "no")); + + CSAssistGameAPITicket ticket; + + ticket.setUID(suid); + ticket.setGame(Unicode::narrowToWide(ConfigCustomerServiceServer::getGameCode()).data()); + ticket.setServer(Unicode::narrowToWide(ConfigCustomerServiceServer::getClusterName()).data()); + ticket.setCharacter(Unicode::narrowToWide(characterName).data()); + ticket.setDetails(details.c_str()); + ticket.setLanguage(Unicode::narrowToWide(language).data()); + ticket.setCategory(0, category); + ticket.setCategory(1, subCategory); + + if (isBug) + { + ticket.setBug(); + } + + bool const logChat = !harassingCharacterName.empty(); + + createTicket(requester, ticket, hiddenDetails, harassingCharacterName, suid, logChat); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::appendComment( + const NetworkId &requester, + unsigned int suid, + const std::string &characterName, + unsigned int ticketId, + const Unicode::String &comment +) +{ + LOG("CSServer", ("appendComment() - networkId(%s) suid(%i) characterName(%s) ticketId(%i)", requester.getValueString().c_str(), suid, characterName.c_str(), ticketId)); + + NetworkId *tmpNetworkId = new NetworkId(requester); + m_csInterface.requestAppendTicketComment( + reinterpret_cast(tmpNetworkId), ticketId, suid, + Unicode::narrowToWide(characterName.c_str()).data(), + comment.data()); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::cancelTicket( + const NetworkId &requester, + unsigned int suid, + unsigned int ticketId, + const Unicode::String &comment +) +{ + NetworkId *tmpNetworkId = new NetworkId(requester); + + LOG("CSServer", ("cancelTicket() - networkId(%s) suid(%i) ticketId(%i)", requester.getValueString().c_str(), suid, ticketId)); + + m_csInterface.requestCancelTicket( + reinterpret_cast(tmpNetworkId), ticketId, suid, + comment.data()); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::getTickets( + const NetworkId &requester, + unsigned int suid +) +{ + LOG("CSServer", ("getTickets() - networkId(%s) suid(%i)", requester.getValueString().c_str(), suid)); + + bool const markAsRead = false; + unsigned int const start = 0; + unsigned int const count = 2000; + + NetworkId *tmpNetworkId = new NetworkId(requester); + m_csInterface.requestGetTicketByCharacter( + reinterpret_cast(tmpNetworkId), suid, NULL, + start, count, markAsRead); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::getComments( + const NetworkId &requester, + unsigned int ticketId +) +{ + LOG("CSServer", ("getComments() - networkId(%s) ticketId(%i)", requester.getValueString().c_str(), ticketId)); + + NetworkId *tmpNetworkId1 = new NetworkId(requester); + m_csInterface.requestGetTicketComments( + reinterpret_cast(tmpNetworkId1), ticketId, 0, + 100, CSASSIST_OFFSET_START); + + NetworkId *tmpNetworkId2 = new NetworkId(requester); + m_csInterface.requestMarkTicketRead(reinterpret_cast(tmpNetworkId2), ticketId); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::searchKnowledgeBase( + const NetworkId &requester, + const Unicode::String &searchString, + const std::string &language +) +{ + LOG("CSServer", ("searchKnowledgeBase() - networkId(%s)", requester.getValueString().c_str())); + + NetworkId *tmpNetworkId = new NetworkId(requester); +// printf("Searching Knowledge base with %s, %s\n", +// Unicode::wideToNarrow(searchString).c_str(), +// language.c_str()); + + m_csInterface.requestSearchKB( + reinterpret_cast(tmpNetworkId), + searchString.data(), + Unicode::narrowToWide(language).data(), + 0); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::getArticle( + const NetworkId &requester, + const std::string &id, + const std::string &language +) +{ + LOG("CSServer", ("getArticle() - networkId(%s) id(%s) language(%s)", requester.getValueString().c_str(), id.c_str(), language.c_str())); + + NetworkId *tmpNetworkId = new NetworkId(requester); + m_csInterface.requestGetKBArticle( + reinterpret_cast(tmpNetworkId), + Unicode::narrowToWide(id).data(), + Unicode::narrowToWide(language).data(), + 0); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::requestNewTicketActivity(const NetworkId &requester, unsigned int suid) +{ + LOG("CSServer", ("requestNewTicketActivity() - networkId(%s) suid(%i)", requester.getValueString().c_str(), suid)); + + NetworkId *tmpNetworkId = new NetworkId(requester); + + m_csInterface.requestNewTicketActivity(reinterpret_cast(tmpNetworkId), suid, NULL); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::requestRegisterCharacter(const NetworkId &requester, ConnectionServerConnection *connection, const unsigned int suid) +{ + LOG("CSServer", ("requestRegisterCharacter() - networkId(%s) suid(%i)", requester.getValueString().c_str(), suid)); + + m_csInterface.addPlayer(requester, connection, suid); + + // If the suid is not valid, don't send the request to the backend + + if (suid == 0) + { + LOG("CSServer", ("CustomerServiceInterface::requestRegisterCharacter() - FAILING due to invalid suid(%i) networkId(%s)", suid, requester.getValueString().c_str())); + } + else + { + LOG("CSServer", ("CustomerServiceInterface::requestRegisterCharacter() - networkId(%s) suid(%i)", requester.getValueString().c_str(), suid)); + + NetworkId *tmpNetworkId = new NetworkId(requester); + m_csInterface.requestRegisterCharacter(reinterpret_cast(tmpNetworkId), suid, NULL, 0); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::requestUnRegisterCharacter(const NetworkId &requester) +{ + m_csInterface.requestUnRegisterCharacter(requester); +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::connectionServerConnectionDestroyed(ConnectionServerConnection *connectionServerConnection) +{ + m_csInterface.connectionServerConnectionDestroyed(connectionServerConnection); +} + +//----------------------------------------------------------------------- + +Service *CustomerServiceServer::getGameServerService() const +{ + return m_gameServerService; +} + +//----------------------------------------------------------------------- + +Service *CustomerServiceServer::getChatServerService() const +{ + return m_chatServerService; +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::createTicket(NetworkId const &networkId, const CSAssistGameAPITicket &ticket, Unicode::String const &hiddenDetails, Unicode::String const &harassingPlayerName, const unsigned int suid, const bool logChat) +{ + m_csInterface.incrementPendingTicketCount(networkId); + + if (logChat) + { + // Request the chat logs + + Unicode::String player; + player.append(ticket.game); + player.append(Unicode::narrowToWide(".")); + player.append(ticket.server); + player.append(Unicode::narrowToWide(".")); + player.append(ticket.character); + + { + ChatRequestLog const chatRequestLogMessage(m_nextSequenceId, player); + ChatServerConnection::sendTo(chatRequestLogMessage); + } + { + ChatRequestLog const chatRequestLogMessage(m_nextSequenceId, Unicode::narrowToWide(networkId.getValueString())); + GameServerConnection::broadcast(chatRequestLogMessage); + } + + // Store the ticket information locally + + PendingTicket pendingTicket; + + pendingTicket.m_networkId = networkId; + pendingTicket.m_time = Os::getRealSystemTime(); + pendingTicket.m_ticket = ticket; + pendingTicket.m_hiddenDetails = hiddenDetails; + pendingTicket.m_harassingPlayerName = harassingPlayerName; + pendingTicket.m_suid = suid; + + m_pendingTicketList->insert(std::make_pair(m_nextSequenceId, pendingTicket)); + + ++m_nextSequenceId; + } + else + { + // Go ahead and create the ticket + + LOG("CSServer", ("createTicket() name(%s) networkId(%s)", Unicode::wideToNarrow(ticket.character).c_str(), networkId.getValueString().c_str())); + + NetworkId *tmpNetworkId = new NetworkId(networkId); + m_csInterface.requestCreateTicket(reinterpret_cast(tmpNetworkId), &ticket, hiddenDetails.data(), suid); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::handleChatServerChatLog(ChatOnRequestLog const &chatOnRequestLog) +{ + LOG("CSServer", ("handleChatServerChatLog() sequenceId(%d) entries(%d)", chatOnRequestLog.getSequence(), static_cast(chatOnRequestLog.getLogEntries().size()))); + + PendingTicketList::iterator iterPendingTicketList = m_pendingTicketList->find(chatOnRequestLog.getSequence()); + + if (iterPendingTicketList != m_pendingTicketList->end()) + { + LOG("CSServer", ("handleChatServerChatLog() ticket found!")); + PendingTicket &pendingTicket = iterPendingTicketList->second; + + pendingTicket.m_chatServerChatLog = chatOnRequestLog.getLogEntries(); + pendingTicket.m_chatServerChatLogReceived = true; + } + else + { + LOG("CSServer", ("handleChatServerChatLog() ERROR: Unable to find owner for ChatServer chat log.")); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::handleGameServerChatLog(ChatOnRequestLog const &chatOnRequestLog) +{ + LOG("CSServer", ("handleGameServerChatLog() sequenceId(%d) entries(%d)", chatOnRequestLog.getSequence(), static_cast(chatOnRequestLog.getLogEntries().size()))); + PendingTicketList::iterator iterPendingTicketList = m_pendingTicketList->find(chatOnRequestLog.getSequence()); + + if (iterPendingTicketList != m_pendingTicketList->end()) + { + LOG("CSServer", ("handleGameServerChatLog() ticket found!")); + PendingTicket &pendingTicket = iterPendingTicketList->second; + + pendingTicket.m_gameServerChatLog = chatOnRequestLog.getLogEntries(); + pendingTicket.m_gameServerChatLogReceived = true; + } + else + { + LOG("CSServer", ("handleGameServerChatLog() ERROR: Unable to find owner for GameServer chat log.")); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::processPendingTickets() +{ + // See if any pending tickets are ready to be sent + + PendingTicketList::iterator iterPendingTicketList = m_pendingTicketList->begin(); + + for (; iterPendingTicketList != m_pendingTicketList->end(); ++iterPendingTicketList) + { + PendingTicket &pendingTicket = iterPendingTicketList->second; + + SortedChatLog sortedChatLog; + + if ((Os::getRealSystemTime() - pendingTicket.m_time) > s_chatLogRequestTimeout) + { + // If it has taken over the specified seconds to get the ticket + // chat logs, just send the ticket and mention that we were + // unable to receive the chat logs + + if (!pendingTicket.m_chatServerChatLog.empty()) + { + addChatLogs(sortedChatLog, pendingTicket.m_chatServerChatLog); + LOG("CSServer", ("processPendingTickets() ChatServer chat log received")); + } + + if (!pendingTicket.m_gameServerChatLog.empty()) + { + addChatLogs(sortedChatLog, pendingTicket.m_gameServerChatLog); + LOG("CSServer", ("processPendingTickets() GameServer chat log received")); + } + + Unicode::String report; + createReport(pendingTicket, sortedChatLog, report); + + Unicode::String hiddenDetails(pendingTicket.m_hiddenDetails); + hiddenDetails.append(Unicode::narrowToWide("\n")); + hiddenDetails.append(report); + + LOG("CSServer", ("processPendingTickets() TIMEOUT - Partial chat logs received")); + m_csInterface.decrementPendingTicketCount(pendingTicket.m_networkId); + + bool const logChat = false; + createTicket(pendingTicket.m_networkId, pendingTicket.m_ticket, hiddenDetails, Unicode::emptyString, pendingTicket.m_suid, logChat); + + // Bail, we will catch another ticket next frame + + m_pendingTicketList->erase(iterPendingTicketList); + break; + } + else if ( pendingTicket.m_chatServerChatLogReceived + && pendingTicket.m_gameServerChatLogReceived) + { + // If the ticket has populated its 2 chat log fields, if so, send it out! + + addChatLogs(sortedChatLog, pendingTicket.m_chatServerChatLog); + addChatLogs(sortedChatLog, pendingTicket.m_gameServerChatLog); + + Unicode::String report; + createReport(pendingTicket, sortedChatLog, report); + + Unicode::String hiddenDetails(pendingTicket.m_hiddenDetails); + hiddenDetails.append(Unicode::narrowToWide("\n\n")); + hiddenDetails.append(report); + + LOG("CSServer", ("processPendingTickets() All chat logs received")); + m_csInterface.decrementPendingTicketCount(pendingTicket.m_networkId); + + bool const logChat = false; + createTicket(pendingTicket.m_networkId, pendingTicket.m_ticket, hiddenDetails, Unicode::emptyString, pendingTicket.m_suid, logChat); + + // Bail, we will catch another ticket next frame + + m_pendingTicketList->erase(iterPendingTicketList); + break; + } + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::addChatLogs(SortedChatLog &sortedChatLog, std::vector &chatLogs) +{ + std::vector::const_iterator iterLogEntries = chatLogs.begin(); + Unicode::String chatMessage; + + for (; iterLogEntries != chatLogs.end(); ++iterLogEntries) + { + ChatLogEntry const &chatLogEntry = (*iterLogEntries); + + ChatLogManager::buildLogEntry(chatMessage, chatLogEntry.m_from, chatLogEntry.m_to, chatLogEntry.m_message, chatLogEntry.m_channel, chatLogEntry.m_time); + + sortedChatLog.insert(std::make_pair(chatLogEntry.m_time, chatMessage)); + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::createReport(PendingTicket const & pendingTicket, SortedChatLog const & sortedChatLog, Unicode::String & report) +{ + // Put the final report together + + Unicode::String header; + std::string const reportingPlayer(Unicode::wideToNarrow(pendingTicket.m_ticket.character)); + std::string const harassingPlayer(Unicode::wideToNarrow(pendingTicket.m_harassingPlayerName)); + + ChatLogManager::getReportHeader(header, reportingPlayer, pendingTicket.m_networkId, std::string(), 0, harassingPlayer, NetworkId::cms_invalid, std::string(), 0); + + report.clear(); + report.append(header); + + if (!pendingTicket.m_chatServerChatLogReceived) + { + report.append(Unicode::narrowToWide("Unable to retrieve the ChatServer chat logs.\n")); + } + + if (!pendingTicket.m_gameServerChatLogReceived) + { + report.append(Unicode::narrowToWide("Unable to retrieve the GameServer spatial chat logs.\n")); + } + + FormattedString<8192> fs; + SortedChatLog::const_iterator iterSortedChatLog = sortedChatLog.begin(); + int count = 0; + + for (; iterSortedChatLog != sortedChatLog.end(); ++iterSortedChatLog) + { + char const * const text = fs.sprintf("[%3d]", ++count); + + report += Unicode::narrowToWide(text); + report += iterSortedChatLog->second; + } +} + +//----------------------------------------------------------------------- + +void CustomerServiceServer::setDone(bool done) +{ + m_done = done; +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServer.h b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServer.h new file mode 100644 index 00000000..a63dd50e --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServer.h @@ -0,0 +1,111 @@ +// CustomerServiceServer.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. + +#ifndef _INCLUDED_CustomerServiceServer_H +#define _INCLUDED_CustomerServiceServer_H + +#include "CustomerServiceInterface.h" + +#include "sharedFoundation/NetworkId.h" +#include "sharedNetworkMessages/ChatOnRequestLog.h" + +//-------------------------------------------------------- +namespace MessageDispatch +{ + class Callback; +} + +class CentralServerConnection; +class ConnectionServerConnection; +class EnumerateServers; +class Service; + +//-------------------------------------------------------- + +class CustomerServiceServer +{ +private: + + //Methods + + void onEnumerateServers(const EnumerateServers &servers); + void update(); + void processPendingTickets(); + + //typedefs + + typedef stdset::fwd ConnectionServerSet; + typedef std::multimap SortedChatLog; + + //Member variables + + MessageDispatch::Callback * m_callback; + CentralServerConnection * m_centralServerConnection; + ConnectionServerSet * m_connectionServerSet; + bool m_done; + CustomerServiceInterface m_csInterface; + static CustomerServiceServer *m_instance; + Service * m_gameServerService; + Service * m_chatServerService; + unsigned int m_nextSequenceId; + + struct PendingTicket + { + PendingTicket(); + + NetworkId m_networkId; + unsigned long m_time; + CSAssistGameAPITicket m_ticket; + Unicode::String m_hiddenDetails; + Unicode::String m_harassingPlayerName; + unsigned int m_suid; + std::vector m_chatServerChatLog; + bool m_chatServerChatLogReceived; + std::vector m_gameServerChatLog; + bool m_gameServerChatLogReceived; + }; + + typedef stdmap::fwd PendingTicketList; + PendingTicketList *m_pendingTicketList; + + void createTicket(NetworkId const &networkId, const CSAssistGameAPITicket &ticket, Unicode::String const &hiddenDetails, Unicode::String const &harassingPlayerName, const unsigned int suid, const bool logChat); + void addChatLogs(SortedChatLog &sortedChatLog, std::vector &chatLogs); + void createReport(PendingTicket const &pendingTicket, SortedChatLog const &sortedChatLog, Unicode::String & report); + +public: + CustomerServiceServer(); + ~CustomerServiceServer(); + + static CustomerServiceServer & getInstance(); + + Service *getGameServerService() const; + Service *getChatServerService() const; + + void run(); + bool isDone() {return m_done;} + void reconnectToCentralServer(); + void handleChatServerChatLog(ChatOnRequestLog const &chatOnRequestLog); + void handleGameServerChatLog(ChatOnRequestLog const &chatOnRequestLog); + + void requestRegisterCharacter(const NetworkId &requester, ConnectionServerConnection *connection, const unsigned int suid); + void requestUnRegisterCharacter(const NetworkId &requester); + void appendComment(const NetworkId &requester, unsigned int suid, const std::string &characterName, unsigned int ticketId, const Unicode::String &comment); + void cancelTicket(const NetworkId &requester, unsigned int suid, unsigned int ticketId, const Unicode::String &comment); + void createTicket(const NetworkId &requester, unsigned int suid, const std::string &characterName, unsigned int category, unsigned int subCategory, const Unicode::String &details, const Unicode::String &hiddenDetails, Unicode::String const &harassingPlayerName, const std::string &language, bool isBug); + void getArticle(const NetworkId &requester, const std::string &id, const std::string &language); + void getComments(const NetworkId &requester, unsigned int ticketId); + void getTickets(const NetworkId &requester, unsigned int suid); + void requestCategories(NetworkId const & requester, std::string const & language); + void searchKnowledgeBase(const NetworkId &requester, const Unicode::String &searchString, const std::string &language); + void connectionServerConnectionDestroyed(ConnectionServerConnection *connectionServerConnection); + void requestNewTicketActivity(const NetworkId &requester, unsigned int suid); + void setDone(bool done); + +private: + + // Disabled + + CustomerServiceServer & operator =(CustomerServiceServer const &); +}; + +#endif //_INCLUDED_CustomerServiceServer_H diff --git a/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServerMetricsData.cpp b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServerMetricsData.cpp new file mode 100644 index 00000000..b91e4f47 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServerMetricsData.cpp @@ -0,0 +1,28 @@ +//CustomerServiceServerMetricsData.cpp +//Copyright 2002 Sony Online Entertainment + +#include "FirstCustomerServiceServer.h" +#include "CustomerServiceServerMetricsData.h" + +//----------------------------------------------------------------------- + +CustomerServiceServerMetricsData::CustomerServiceServerMetricsData() : +MetricsData() +{ + MetricsPair p; +} + +//----------------------------------------------------------------------- + +CustomerServiceServerMetricsData::~CustomerServiceServerMetricsData() +{ +} + +//----------------------------------------------------------------------- + +void CustomerServiceServerMetricsData::updateData() +{ + MetricsData::updateData(); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServerMetricsData.h b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServerMetricsData.h new file mode 100644 index 00000000..9ecda22e --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/CustomerServiceServerMetricsData.h @@ -0,0 +1,31 @@ +//CustomerServiceServerMetricsData.h +//Copyright 2002 Sony Online Entertainment + + +#ifndef _CustomerServiceServerMetricsData_H +#define _CustomerServiceServerMetricsData_H + +//----------------------------------------------------------------------- + +#include "serverMetrics/MetricsData.h" + +//----------------------------------------------------------------------- + +class CustomerServiceServerMetricsData : public MetricsData +{ +public: + CustomerServiceServerMetricsData(); + ~CustomerServiceServerMetricsData(); + + virtual void updateData(); + +private: + + // Disabled. + CustomerServiceServerMetricsData(const CustomerServiceServerMetricsData&); + CustomerServiceServerMetricsData &operator =(const CustomerServiceServerMetricsData&); +}; + + +//----------------------------------------------------------------------- +#endif diff --git a/engine/server/application/CustomerServiceServer/src/shared/FirstCustomerServiceServer.cpp b/engine/server/application/CustomerServiceServer/src/shared/FirstCustomerServiceServer.cpp new file mode 100644 index 00000000..05d248ca --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/FirstCustomerServiceServer.cpp @@ -0,0 +1,11 @@ +// FirstCustomerServiceServer.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. + +//----------------------------------------------------------------------- + +#include "FirstCustomerServiceServer.h" + +//----------------------------------------------------------------------- + +// satisfy strangeness with MS if there are no other files included in the PCH +void FirstCustomerServiceServerFoo(){} diff --git a/engine/server/application/CustomerServiceServer/src/shared/FirstCustomerServiceServer.h b/engine/server/application/CustomerServiceServer/src/shared/FirstCustomerServiceServer.h new file mode 100644 index 00000000..24edd4d1 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/FirstCustomerServiceServer.h @@ -0,0 +1,20 @@ +// FirstCustomerServiceServer.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. + +#ifndef _INCLUDED_FirstCustomerServiceServer_H +#define _INCLUDED_FirstCustomerServiceServer_H + +//----------------------------------------------------------------------- + +#pragma warning ( disable : 4702 ) + +#include "Archive/ByteStream.h" +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedNetwork/Connection.h" +#include +#include + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_FirstCustomerServiceServer_H diff --git a/engine/server/application/CustomerServiceServer/src/shared/GameServerConnection.cpp b/engine/server/application/CustomerServiceServer/src/shared/GameServerConnection.cpp new file mode 100644 index 00000000..edf37e3b --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/GameServerConnection.cpp @@ -0,0 +1,83 @@ +// GameServerConnection.cpp +// Copyright 2004, Sony Online Entertainment Inc., all rights reserved. + +//----------------------------------------------------------------------- +#include "FirstCustomerServiceServer.h" +#include "GameServerConnection.h" + +#include "CustomerServiceServer.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/ChatOnRequestLog.h" +#include "sharedNetworkMessages/GameNetworkMessage.h" + +//----------------------------------------------------------------------- +namespace GameServerConnectionNamespace +{ + std::set s_connections; +}; + +using namespace GameServerConnectionNamespace; + +//----------------------------------------------------------------------- +GameServerConnection::GameServerConnection(UdpConnectionMT * u, TcpClient * t) + : ServerConnection(u, t) +{ + LOG("GameServerConnection", ("Connection created...listening on (%s:%d)", getRemoteAddress().c_str(), static_cast(getRemotePort()))); + + s_connections.insert(this); +} + +//----------------------------------------------------------------------- +GameServerConnection::~GameServerConnection() +{ + std::set::iterator iterConnections = s_connections.find(this); + + if (iterConnections != s_connections.end()) + { + s_connections.erase(iterConnections); + } +} + +//----------------------------------------------------------------------- +void GameServerConnection::onConnectionClosed() +{ + LOG("GameServerConnection", ("onConnectionClosed()")); +} + +//----------------------------------------------------------------------- +void GameServerConnection::onConnectionOpened() +{ + LOG("GameServerConnection", ("onConnectionOpened()")); +} + +//----------------------------------------------------------------------- +void GameServerConnection::onReceive(const Archive::ByteStream & message) +{ + Archive::ReadIterator ri = message.begin(); + GameNetworkMessage gameNetworkMessage(ri); + ri = message.begin(); + + if (gameNetworkMessage.isType("ChatOnRequestLog")) + { + LOG("GameServerConnection", ("onReceive(ChatRequestLog)")); + ChatOnRequestLog chatOnRequestLog(ri); + CustomerServiceServer::getInstance().handleGameServerChatLog(chatOnRequestLog); + } +} + +//----------------------------------------------------------------------- +void GameServerConnection::broadcast(GameNetworkMessage const &message) +{ + LOG("GameServerConnection", ("broadcast() message(%s)", message.getCmdName().c_str())); + + std::set::const_iterator iterConnections = s_connections.begin(); + + for (; iterConnections != s_connections.end(); ++iterConnections) + { + GameServerConnection *connection = (*iterConnections); + + connection->send(message, true); + } +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/CustomerServiceServer/src/shared/GameServerConnection.h b/engine/server/application/CustomerServiceServer/src/shared/GameServerConnection.h new file mode 100644 index 00000000..c635c2f4 --- /dev/null +++ b/engine/server/application/CustomerServiceServer/src/shared/GameServerConnection.h @@ -0,0 +1,36 @@ +// GameServerConnection.h +// Copyright 2004, Sony Online Entertainment Inc., all rights reserved. + +#ifndef INCLUDED_GameServerConnection_H +#define INCLUDED_GameServerConnection_H + +//----------------------------------------------------------------------- + +#include "serverUtility/ServerConnection.h" + +//----------------------------------------------------------------------- + +class GameNetworkMessage; + +class GameServerConnection : public ServerConnection +{ +public: + + GameServerConnection(UdpConnectionMT * u, TcpClient * t); + ~GameServerConnection(); + + void onConnectionClosed(); + void onConnectionOpened(); + void onReceive(const Archive::ByteStream & bs); + + static void broadcast(GameNetworkMessage const &message); + +private: + + GameServerConnection & operator = (const GameServerConnection & rhs); + GameServerConnection(const GameServerConnection & source); +}; //lint !e1712 default constructor not defined for class + +//----------------------------------------------------------------------- + +#endif // INCLUDED_GameServerConnection_H