Added CustomerServiceServer project

This commit is contained in:
Anonymous
2014-01-21 09:18:28 -07:00
parent eba7ff525c
commit 232bcc82dc
23 changed files with 2846 additions and 2 deletions
+1
View File
@@ -42,6 +42,7 @@ elseif(UNIX)
endif()
include_directories(${STLPORT_INCLUDE_DIR})
link_directories(${STLPORT_LIBDIR})
add_subdirectory(external)
add_subdirectory(engine)
+1 -2
View File
@@ -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)
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 2.8)
project(CustomerServiceServer)
add_subdirectory(src)
@@ -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}
)
@@ -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 <hash_map>
// ======================================================================
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<uint32>(time(NULL)));
Os::setProgramName("CustomerServiceServer");
ConfigCustomerServiceServer::install();
NetworkHandler::install();
CustomerServiceServer::getInstance().run();
NetworkHandler::remove();
SetupSharedFoundation::remove();
return 0;
}
@@ -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<int>(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<std::pair<std::string, unsigned short> > 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<std::pair<std::string, unsigned short> > 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<const EnumerateServers &> emitter;
EnumerateServers e(ri);
emitter.emitMessage(e);
}
}
//-----------------------------------------------------------------------
@@ -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
@@ -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<int>(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"));
}
}
//-----------------------------------------------------------------------
@@ -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
@@ -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<unsigned int>(s_requestTimeoutSeconds);
}
//-----------------------------------------------------------------------
const char * ConfigCustomerServiceServer::getCustomerServiceServerAddress()
{
return s_csServerAddress;
}
//-----------------------------------------------------------------------
unsigned short ConfigCustomerServiceServer::getCustomerServiceServerPort()
{
return static_cast<unsigned short>(s_csServerPort);
}
//-----------------------------------------------------------------------
const char * ConfigCustomerServiceServer::getCentralServerAddress()
{
return s_centralServerAddress;
}
//-----------------------------------------------------------------------
unsigned short ConfigCustomerServiceServer::getCentralServerPort()
{
return static_cast<unsigned short>(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<unsigned short>(s_gameServicePort);
}
//-----------------------------------------------------------------------
unsigned short ConfigCustomerServiceServer::getChatServicePort()
{
return static_cast<unsigned short>(s_chatServicePort);
}
//-----------------------------------------------------------------------
const char* ConfigCustomerServiceServer::getGameServiceBindInterface()
{
return s_gameServiceBindInterface;
}
//-----------------------------------------------------------------------
const char* ConfigCustomerServiceServer::getChatServiceBindInterface()
{
return s_chatServiceBindInterface;
}
//-----------------------------------------------------------------------
bool ConfigCustomerServiceServer::getWriteTicketToBugLog()
{
return s_writeTicketToBugLog;
}
//-----------------------------------------------------------------------
@@ -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
@@ -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<int>(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<NetworkId>::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<NetworkId> v;
v.clear();
v.push_back(clientId);
GameClientMessage msg(v, true, message);
ServerConnection::send(msg, true);
}
//-----------------------------------------------------------------------
@@ -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
@@ -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 <map>
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<const char *>(childPtr->name);
Unicode::String categoryName;
int categoryId = 0;
char * val = reinterpret_cast<char *>(xmlGetProp(childPtr, (const unsigned char *)"name"));
if (val)
{
categoryName = Unicode::utf8ToWide(val);
}
val = reinterpret_cast<char *>(xmlGetProp(childPtr, (const unsigned char *)"id"));
if (val)
{
categoryId = atoi(val);
}
// Check for bug type
val = reinterpret_cast<char *>(xmlGetProp(childPtr, (const unsigned char *)"isBugType"));
bool const isBugType = (val != NULL) && (strcmp(val, "true") == 0);
// Check for service type
val = reinterpret_cast<char *>(xmlGetProp(childPtr, (const unsigned char *)"isServiceType"));
bool const isServiceType = (val != NULL) && (strcmp(val, "true") == 0);
// Check if valid
val = reinterpret_cast<char *>(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<const NetworkId *>(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<const NetworkId *>(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<const NetworkId *>(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<CustomerServiceTicket> 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<const NetworkId *>(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<int>(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<CustomerServiceComment> 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<const NetworkId *>(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<CustomerServiceSearchResult> 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<const NetworkId *>(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<const NetworkId *>(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<bool>(NewActivityFlag), HasTickets);
const NetworkId *tmpNetworkId = reinterpret_cast<const NetworkId *>(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<int>(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<const NetworkId *>(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<const NetworkId *>(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<const NetworkId *>(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<const void *>(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()));
}
}
///////////////////////////////////////////////////////////////////////////////
@@ -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 <vector>
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<NetworkId, ClientInfo, NetworkId::Hash>::fwd ClientConnectionMap;
typedef stdmap<unsigned int, NetworkId>::fwd SuidToNetworkIdMap;
typedef stdvector<CustomerServiceCategory>::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
@@ -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 <map>
#include <set>
#include <stdio.h>
///////////////////////////////////////////////////////////////////////////////
//
// 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<GameServerConnection>(), setup);
// Create the ChatServer connection
setup.port = ConfigCustomerServiceServer::getChatServicePort();
setup.bindInterface = ConfigCustomerServiceServer::getChatServiceBindInterface();
m_chatServerService = new Service(ConnectionAllocator<ChatServerConnection>(), 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<const void *>(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<const void *>(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<const void *>(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<const void *>(tmpNetworkId1), ticketId, 0,
100, CSASSIST_OFFSET_START);
NetworkId *tmpNetworkId2 = new NetworkId(requester);
m_csInterface.requestMarkTicketRead(reinterpret_cast<const void *>(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<const void *>(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<const void *>(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<const void *>(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<const void *>(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<const void *>(tmpNetworkId), &ticket, hiddenDetails.data(), suid);
}
}
//-----------------------------------------------------------------------
void CustomerServiceServer::handleChatServerChatLog(ChatOnRequestLog const &chatOnRequestLog)
{
LOG("CSServer", ("handleChatServerChatLog() sequenceId(%d) entries(%d)", chatOnRequestLog.getSequence(), static_cast<int>(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<int>(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<ChatLogEntry> &chatLogs)
{
std::vector<ChatLogEntry>::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;
}
//-----------------------------------------------------------------------
@@ -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<ConnectionServerConnection *>::fwd ConnectionServerSet;
typedef std::multimap<unsigned long, Unicode::String> 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<ChatLogEntry> m_chatServerChatLog;
bool m_chatServerChatLogReceived;
std::vector<ChatLogEntry> m_gameServerChatLog;
bool m_gameServerChatLogReceived;
};
typedef stdmap<unsigned int, PendingTicket>::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<ChatLogEntry> &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
@@ -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();
}
//-----------------------------------------------------------------------
@@ -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
@@ -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(){}
@@ -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 <hash_map>
#include <string>
//-----------------------------------------------------------------------
#endif // _INCLUDED_FirstCustomerServiceServer_H
@@ -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<GameServerConnection *> 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<int>(getRemotePort())));
s_connections.insert(this);
}
//-----------------------------------------------------------------------
GameServerConnection::~GameServerConnection()
{
std::set<GameServerConnection *>::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<GameServerConnection *>::const_iterator iterConnections = s_connections.begin();
for (; iterConnections != s_connections.end(); ++iterConnections)
{
GameServerConnection *connection = (*iterConnections);
connection->send(message, true);
}
}
//-----------------------------------------------------------------------
@@ -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