Added ConnectionServer project

This commit is contained in:
Anonymous
2014-01-17 01:42:55 -07:00
parent c76ba3f66a
commit 26b88b4533
29 changed files with 7917 additions and 0 deletions
@@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 2.8)
project(ConnectionServer)
add_subdirectory(src)
@@ -0,0 +1,115 @@
set(SHARED_SOURCES
shared/CentralConnection.cpp
shared/CentralConnection.h
shared/ChatServerConnection.cpp
shared/ChatServerConnection.h
shared/ClientConnection.cpp
shared/ClientConnection.h
shared/Client.cpp
shared/Client.h
shared/ConfigConnectionServer.cpp
shared/ConfigConnectionServer.h
shared/ConnectionServer.cpp
shared/ConnectionServer.h
shared/ConnectionServerMetricsData.cpp
shared/ConnectionServerMetricsData.h
shared/CustomerServiceConnection.cpp
shared/CustomerServiceConnection.h
shared/FirstConnectionServer.h
shared/GameConnection.cpp
shared/GameConnection.h
shared/SessionApiClient.cpp
shared/SessionApiClient.h
shared/PseudoClientConnection.cpp
shared/PseudoClientConnection.h
)
if(WIN32)
set(PLATFORM_SOURCES
win32/FirstConnectionServer.cpp
win32/WinMain.cpp
)
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/sharedGame/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}/shared/library/sharedUtility/include/public
${SWG_ENGINE_SOURCE_DIR}/server/library/serverKeyShare/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/localization/include
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public
${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/platform/projects
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/platform/utils
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/udplibrary
)
link_directories(${STLPORT_LIBDIR})
add_executable(ConnectionServer
${SHARED_SOURCES}
${PLATFORM_SOURCES}
)
target_link_libraries(ConnectionServer
sharedCompression
sharedDebug
sharedFile
sharedFoundation
sharedGame
sharedLog
sharedMath
sharedMemoryManager
sharedMessageDispatch
sharedNetwork
sharedNetworkMessages
sharedRandom
sharedSynchronization
sharedThread
sharedUtility
serverKeyShare
serverMetrics
serverNetworkMessages
serverUtility
archive
crypto
fileInterface
localization
localizationArchive
unicode
unicodeArchive
Base
CommonAPI
LoginAPI
udplibrary
${ZLIB_LIBRARY}
)
if(WIN32)
target_link_libraries(ConnectionServer mswsock ws2_32)
endif()
@@ -0,0 +1,58 @@
#include "FirstConnectionServer.h"
#include "ConfigConnectionServer.h"
#include "ConnectionServer.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"
// ======================================================================
void dumpPid(const char * argv)
{
pid_t p = getpid();
char fileName[1024];
sprintf(fileName, "%s.%d", argv, p);
FILE * f = fopen(fileName, "w+");
fclose(f);
}
int main(int argc, char ** argv)
{
SetupSharedThread::install();
SetupSharedDebug::install(1024);
//-- setup foundation
SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game);
setupFoundationData.lpCmdLine = ConvertCommandLine(argc,argv);
SetupSharedFoundation::install (setupFoundationData);
SetupSharedCompression::install();
SetupSharedFile::install(false);
SetupSharedNetworkMessages::install();
SetupSharedRandom::install(time(NULL));
//setup the server
NetworkHandler::install();
Os::setProgramName("ConnectionServer");
ConfigConnectionServer::install();
//-- run game
ConnectionServer::install();
SetupSharedFoundation::callbackWithExceptionHandling(ConnectionServer::run);
ConnectionServer::remove();
ConfigConnectionServer::remove();
NetworkHandler::remove();
SetupSharedFoundation::remove();
SetupSharedThread::remove();
return 0;
}
@@ -0,0 +1,134 @@
// CentralConnection.cpp
// copyright 2001 Verant Interactive
//-----------------------------------------------------------------------
#include "FirstConnectionServer.h"
#include "CentralConnection.h"
#include "Archive/ByteStream.h"
#include "ConnectionServer.h"
#include "PseudoClientConnection.h"
#include "serverKeyShare/KeyShare.h"
#include "serverNetworkMessages/CentralConnectionServerMessages.h"
#include "serverNetworkMessages/TransferCharacterData.h"
#include "serverNetworkMessages/TransferCharacterDataArchive.h"
#include "sharedLog/Log.h"
#include "sharedNetwork/NetworkSetupData.h"
#include "sharedNetwork/Service.h"
#include "sharedNetworkMessages/ErrorMessage.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
//-----------------------------------------------------------------------
CentralConnection::CentralConnection(const std::string & address, const unsigned short port) :
ServerConnection(address, port, NetworkSetupData())
{
}
//-----------------------------------------------------------------------
CentralConnection::CentralConnection(UdpConnectionMT * u, TcpClient * t) :
ServerConnection(u, t)
{
PseudoClientConnection::destroyAllPseudoClientConnectionInstances();
}
//-----------------------------------------------------------------------
CentralConnection::~CentralConnection()
{
PseudoClientConnection::destroyAllPseudoClientConnectionInstances();
}
//-----------------------------------------------------------------------
void CentralConnection::onConnectionClosed()
{
ServerConnection::onConnectionClosed();
static MessageConnectionCallback m("CentralConnectionClosed");
emitMessage(m);
}
//-----------------------------------------------------------------------
void CentralConnection::onConnectionOpened()
{
ServerConnection::onConnectionOpened();
static const MessageConnectionCallback m("CentralConnectionOpened");
emitMessage(m);
}
//-----------------------------------------------------------------------
void CentralConnection::onReceive(const Archive::ByteStream & message)
{
Archive::ReadIterator ri = message.begin();
const GameNetworkMessage msg(ri);
ri = message.begin();
if(msg.isType("TransferLoginCharacterToSourceServer"))
{
GenericValueTypeMessage<TransferCharacterData> login(ri);
// received a request to create a pseudoclient and connect it
// to a game server.
LOG("CustomerService", ("CharacterTransfer: ***ConnectionServer: Received TransferLoginCharacterToSourceServer request from CentralServer for %s\n", login.getValue().toString().c_str()));
IGNORE_RETURN(PseudoClientConnection::tryToDeliverMessageTo(login.getValue().getSourceStationId(), message));
}
else if(msg.isType("TransferLoginCharacterToDestinationServer"))
{
GenericValueTypeMessage<TransferCharacterData> login(ri);
LOG("CustomerService", ("CharacterTransfer: ***ConnectionServer: Received TransferLoginCharacterToDestinationServer request from CentralServer for %s", login.getValue().toString().c_str()));
IGNORE_RETURN(PseudoClientConnection::tryToDeliverMessageTo(login.getValue().getDestinationStationId(), message));
}
else if(msg.isType("CtsSrcCharWrongPlanet"))
{
GenericValueTypeMessage<std::pair<NetworkId, unsigned int> > const failureMsg(ri);
LOG("CustomerService", ("CharacterTransfer: ***ConnectionServer: Received CtsSrcCharWrongPlanet error from CentralServer for character (%s) stationId (%u) because character is not one of the 10 original ground planets", failureMsg.getValue().first.getValueString().c_str(), failureMsg.getValue().second));
IGNORE_RETURN(PseudoClientConnection::tryToDeliverMessageTo(failureMsg.getValue().second, message));
}
else if(msg.isType("TransferKickConnectedClients"))
{
GenericValueTypeMessage<unsigned int> kick(ri);
ClientConnection * clientConnection = ConnectionServer::getClientConnection(kick.getValue());
if(clientConnection)
{
ConnectionServer::dropClient(clientConnection, "TransferServer requests client drop");
}
}
else if(msg.isType("TransferClosePseudoClientConnection"))
{
GenericValueTypeMessage<unsigned int> closeRequest(ri);
PseudoClientConnection * pseudoClient = PseudoClientConnection::getPseudoClientConnection(closeRequest.getValue());
delete pseudoClient;
}
else if(msg.isType("LoginDeniedRecentCTS"))
{
GenericValueTypeMessage<std::pair<NetworkId, uint32> > loginDeniedRecentCTS(ri);
ClientConnection * clientConnection = ConnectionServer::getClientConnection(loginDeniedRecentCTS.getValue().second);
if (clientConnection)
{
LOG("CustomerService", ("Login:%s, character %s (%s) is a recent CTS that has not been persisted yet.", ClientConnection::describeAccount(clientConnection).c_str(), clientConnection->getCharacterName().c_str(), clientConnection->getCharacterId().getValueString().c_str()));
ErrorMessage err("Login Failed", "The selected character has just been recently transferred and has not been completely initialized. In most cases, it takes about 15 minutes (but in some cases can take up to 2 hours) to complete initialization. Please try again later.");
clientConnection->send(err, true);
}
}
else if(msg.isType("LoginDeniedPendingPlayerRenameRequest"))
{
GenericValueTypeMessage<std::pair<NetworkId, uint32> > loginDeniedPendingPlayerRenameRequest(ri);
ClientConnection * clientConnection = ConnectionServer::getClientConnection(loginDeniedPendingPlayerRenameRequest.getValue().second);
if (clientConnection)
{
LOG("CustomerService", ("Login:%s, character %s (%s) has a pending player requested character rename request.", ClientConnection::describeAccount(clientConnection).c_str(), clientConnection->getCharacterName().c_str(), clientConnection->getCharacterId().getValueString().c_str()));
ErrorMessage err("Login Failed", "The selected character currently has a pending character rename request. It can take up to 30 minutes for the rename request to complete.");
clientConnection->send(err, true);
}
}
else
{
ServerConnection::onReceive(message);
}
}
//-----------------------------------------------------------------------
@@ -0,0 +1,32 @@
// CentralConnection.h
// copyright 2000 Verant Interactive
// Author: Justin Randall
#ifndef _CentralConnection_H
#define _CentralConnection_H
//-----------------------------------------------------------------------
#include "serverUtility/ServerConnection.h"
//-----------------------------------------------------------------------
class CentralConnection : public ServerConnection
{
public:
CentralConnection (const std::string & address, const unsigned short port);
CentralConnection(UdpConnectionMT *, TcpClient *);
~CentralConnection();
void onConnectionClosed();
void onConnectionOpened();
void onReceive(const Archive::ByteStream & message);
private:
CentralConnection();
CentralConnection(const CentralConnection&);
CentralConnection& operator=(const CentralConnection&);
};
//-----------------------------------------------------------------------
#endif // _CentralConnection_H
@@ -0,0 +1,228 @@
// ChatServerConnection.cpp
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstConnectionServer.h"
#include "ChatServerConnection.h"
#include "ClientConnection.h"
#include "serverNetworkMessages/GameConnectionServerMessages.h"
#include "sharedNetwork/Service.h"
#include "sharedNetworkMessages/ChatOnChangeFriendStatus.h"
#include "sharedNetworkMessages/ChatOnChangeIgnoreStatus.h"
#include "sharedNetworkMessages/ChatOnEnteredRoom.h"
#include "sharedNetworkMessages/ChatOnGetFriendsList.h"
#include "sharedNetworkMessages/ChatOnGetIgnoreList.h"
#include "sharedNetworkMessages/ChatOnLeaveRoom.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
//-----------------------------------------------------------------------
/*
void putClientsInRoom(const unsigned int roomId, const std::vector<NetworkId> & clients)
{
std::vector<NetworkId>::const_iterator i;
for(i = clients.begin(); i != clients.end(); ++i)
{
Client* client = ConnectionServer::getClient((*i));
DEBUG_REPORT_LOG(!client, ("Error, could not map %s to a client\n", (*i).getValueString().c_str()));
if (client)
client->enterRoom(roomId);
}
}
*/
//-----------------------------------------------------------------------
/*
void removeClientsFromRoom(const unsigned int roomId, const std::vector<NetworkId> & clients)
{
std::vector<NetworkId>::const_iterator i;
for(i = clients.begin(); i != clients.end(); ++i)
{
Client* client = ConnectionServer::getClient((*i));
DEBUG_REPORT_LOG(!client, ("Error, could not map %s to a client\n", (*i).getValueString().c_str()));
if (client)
client->leaveRoom(roomId);
}
}
*/
//-----------------------------------------------------------------------
ChatServerConnection::ChatServerConnection(UdpConnectionMT * u, TcpClient * t) :
ServerConnection(u, t),
clients()
{
}
//-----------------------------------------------------------------------
ChatServerConnection::~ChatServerConnection()
{
}
//-----------------------------------------------------------------------
void ChatServerConnection::addClient(Client * newClient)
{
if (clients.find(newClient) == clients.end())
IGNORE_RETURN( clients.insert(newClient) );
else
DEBUG_WARNING(true, ("called ChatServerConnection::addClient with a client that already exists in the map."));
}
//-----------------------------------------------------------------------
void ChatServerConnection::onConnectionClosed()
{
ServerConnection::onConnectionClosed();
static MessageConnectionCallback m("ChatServerConnectionClosed");
emitMessage(m);
}
//-----------------------------------------------------------------------
const std::set<Client *> & ChatServerConnection::getClients() const
{
return clients;
}
//-----------------------------------------------------------------------
void ChatServerConnection::onConnectionOpened()
{
ServerConnection::onConnectionOpened();
static MessageConnectionCallback m("ChatServerConnectionOpened");
emitMessage(m);
}
//-----------------------------------------------------------------------
void ChatServerConnection::onReceive(const Archive::ByteStream & message)
{
Archive::ReadIterator ri = message.begin();
GameNetworkMessage m(ri);
ri = message.begin();
if (m.isType("GameClientMessage"))
{
//we're receiving a message to forward to the client.
//it is prefixed with NetworkId and reliable.
const GameClientMessage msg(ri);
Archive::ReadIterator mri(msg.getByteStream());
GameNetworkMessage gnm(mri);
mri = msg.getByteStream().begin();
// The connection server wants to trap room
// enter/leave messages to cache clients
// in particular rooms for autorecovery when
// a chat server process is stopped then later
// restarted
//
// ************ THIS CODE DOES NOT WORK ***********
// The following code has been commented out since
// everyone in the group is sent these messages but
// the logic assumes that only the person entering
// or leaving a chat room is sent the message.
/*
if(gnm.isType("ChatOnEnteredRoom"))
{
Archive::ReadIterator cri(msg.getByteStream());
ChatOnEnteredRoom chat(cri);
putClientsInRoom(chat.getRoomId(), msg.getDistributionList());
}
else if(gnm.isType("ChatOnLeaveRoom"))
{
Archive::ReadIterator cri(msg.getByteStream());
ChatOnLeaveRoom chat(cri);
removeClientsFromRoom(chat.getRoomId(), msg.getDistributionList());
}
*/
const std::vector<NetworkId> & d = msg.getDistributionList();
std::vector<NetworkId>::const_iterator i;
for(i = d.begin(); i != d.end(); ++i)
{
if ((*i) == NetworkId::cms_invalid)
{
//broadcast to everyone
Service *service = ConnectionServer::getClientServicePrivate();
LogicalPacket const * p = service->createPacket(msg.getByteStream().getBuffer(), msg.getByteStream().getSize());
const ConnectionServer::ClientMap clientMap(ConnectionServer::getClientMap());
ConnectionServer::ClientMap::const_iterator i;
for(i = clientMap.begin(); i != clientMap.end(); ++i)
{
Client* client = (*i).second;
if (client)
{
client->getClientConnection()->sendSharedPacket(p, msg.getReliable());
}
}
service->releasePacket(p);
break;
}
Client* client = ConnectionServer::getClient((*i));
DEBUG_REPORT_LOG(!client, ("Error, could not map %s to a client\n", (*i).getValueString().c_str()));
if (client)
{
if (!gnm.isType("ChatStatisticsCS"))
client->getClientConnection()->sendByteStream(msg.getByteStream(), msg.getReliable());
GameConnection *gc = client->getGameConnection();
if (gc)
{
if (gnm.isType("ChatOnGetFriendsList"))
{
Archive::ReadIterator cri(msg.getByteStream());
ChatOnGetFriendsList c(cri);
gc->send(c, true);
//DEBUG_REPORT_LOG(true, ("Sending a ChatOnGetFriendsList msg to game server\n"));
}
else if (gnm.isType("ChatOnChangeIgnoreStatus"))
{
Archive::ReadIterator cri(msg.getByteStream());
ChatOnChangeIgnoreStatus c(cri);
gc->send(c, true);
//DEBUG_REPORT_LOG(true, ("Sending a ChatOnChangeIgnoreStatus msg to game server\n"));
}
else if (gnm.isType("ChatOnChangeFriendStatus"))
{
Archive::ReadIterator cri(msg.getByteStream());
ChatOnChangeFriendStatus c(cri);
gc->send(c, true);
//DEBUG_REPORT_LOG(true, ("Sending a ChatOnChangeFriendStatus msg to game server\n"));
}
else if (gnm.isType("ChatOnGetIgnoreList"))
{
Archive::ReadIterator cri(msg.getByteStream());
ChatOnGetIgnoreList c(cri);
gc->send(c, true);
//DEBUG_REPORT_LOG(true, ("Sending a ChatOnGetIgnoreList msg to game server\n"));
}
else if (gnm.isType("ChatStatisticsCS"))
{
Archive::ReadIterator cri(msg.getByteStream());
GenericValueTypeMessage<std::pair<std::pair<NetworkId, int>, std::pair<int, int> > > chatStatistics(cri);
gc->send(chatStatistics, true);
//DEBUG_REPORT_LOG(true, ("Sending a ChatStatisticsCS msg to game server\n"));
}
}
}
}
}
}
//-----------------------------------------------------------------------
void ChatServerConnection::removeClient(Client * oldClient)
{
std::set<Client *>::iterator f = clients.find(oldClient);
if(f != clients.end())
clients.erase(f);
}
//-----------------------------------------------------------------------
@@ -0,0 +1,36 @@
// ChatServerConnection.h
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_ChatServerConnection_H
#define _INCLUDED_ChatServerConnection_H
//-----------------------------------------------------------------------
#include "serverUtility/ServerConnection.h"
class Client;
//-----------------------------------------------------------------------
class ChatServerConnection : public ServerConnection
{
public:
explicit ChatServerConnection(UdpConnectionMT *, TcpClient *);
virtual ~ChatServerConnection();
void addClient(Client *);
void onConnectionClosed ();
void onConnectionOpened ();
void onReceive (const Archive::ByteStream &);
void removeClient(Client *);
const std::set<Client *> & getClients() const;
private:
ChatServerConnection();
ChatServerConnection & operator = (const ChatServerConnection & rhs);
ChatServerConnection(const ChatServerConnection & source);
std::set<Client *> clients;
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_ChatServerConnection_H
@@ -0,0 +1,313 @@
// -----------------------------------------
// Client.cpp
// copyright 2001 Sony Online Entertainment
// -----------------------------------------
#include "FirstConnectionServer.h"
#include "ChatServerConnection.h"
#include "CustomerServiceConnection.h"
#include "Client.h"
#include "ClientConnection.h"
#include "serverNetworkMessages/ChatConnectAvatar.h"
#include "serverNetworkMessages/ChatDisconnectAvatar.h"
#include "serverNetworkMessages/GameConnectionServerMessages.h"
#include "sharedGame/PlatformFeatureBits.h"
#include "sharedLog/Log.h"
#include "sharedMessageDispatch/Transceiver.h"
#include "sharedNetworkMessages/ChatEnterRoomById.h"
#include "sharedNetworkMessages/ChatServerStatus.h"
#include "sharedNetworkMessages/DisconnectPlayerMessage.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
//----------------------------------------------------------------------
Client::Client(ClientConnection * cconn, const NetworkId& oid) :
Receiver(),
m_chatConnection(0),
m_customerServiceConnection(0),
m_clientConnection(cconn),
m_deferredChatMessages(),
m_hasBeenKicked(false),
m_oid(oid),
m_gameConnection(0),
//m_roomCache(),
m_sceneName(),
m_skipLoadScreen(false),
m_callback(new MessageDispatch::Callback)
{
static const std::string loginTrace("TRACE_LOGIN");
LOG(loginTrace, ("new Client(%s)", m_oid.getValueString().c_str()));
// until/unless a chat server connection is set, the client will
// listen for a new chat server coming online.
// This handles the case where a client connects and there
// are no chat servers currently running (e.g. a crash happens
// at the point in time a client is connecting)
connectToMessage("ChatServerConnectionOpened");
connectToMessage("CustomerServiceConnectionOpened");
m_callback->connect(*this, &Client::onChatConnectionClosed);
}
//----------------------------------------------------------------------
Client::~Client()
{
ConnectionServer::dropClient(m_clientConnection, "Destroying Client Object");
if(m_chatConnection)
{
m_chatConnection->removeClient(this);
m_chatConnection = 0;
}
if(m_customerServiceConnection)
{
std::vector<NetworkId> v;
v.clear();
v.push_back(getNetworkId());
DisconnectPlayerMessage message;
GameClientMessage gcm(v, true, message);
m_customerServiceConnection->send(gcm, true);
m_customerServiceConnection->removeClient(this);
m_customerServiceConnection = 0;
}
if (m_oid != NetworkId::cms_invalid && ConnectionServer::getClient(m_oid))
{
WARNING_STRICT_FATAL(true, ("Attempting to delete client %d without removing him from map\n", m_oid.getValueString().c_str()));
}
m_clientConnection = 0;
setGameConnection(0);
m_gameConnection = 0;
delete m_callback;
}
//-----------------------------------------------------------------------
void Client::onChatConnectionClosed(Connection * closedConnection)
{
if(m_chatConnection == closedConnection)
{
m_chatConnection->removeClient(this);
m_chatConnection = 0;
}
}
//-----------------------------------------------------------------------
void Client::deferChatMessage(const Archive::ByteStream & message)
{
m_deferredChatMessages.push_back(message);
}
//-----------------------------------------------------------------------
/*
void Client::enterRoom(const unsigned int roomId)
{
IGNORE_RETURN ( m_roomCache.insert(roomId) );
}
*/
//-----------------------------------------------------------------------
void Client::flushChatMessages()
{
if(m_chatConnection)
{
std::vector<Archive::ByteStream>::const_iterator i;
for(i = m_deferredChatMessages.begin(); i != m_deferredChatMessages.end(); ++i)
{
m_chatConnection->Connection::send((*i), true);
}
m_deferredChatMessages.clear();
}
}
//------------------------------------------------------------
void Client::handleTransfer(const std::string & sceneName, GameConnection* conn)
{
NOT_NULL(conn);
//Set the new scene name
setSceneName(sceneName);
//If we are already connected to a game server drop them
if (getGameConnection() && getGameConnection() != conn)
{
DropClient msg(getNetworkId());
getGameConnection()->send(msg, true);
}
//Set the new game server
setGameConnection(conn);
m_skipLoadScreen = false;
}
//-----------------------------------------------------------------------
/*
void Client::leaveRoom(const unsigned int roomId)
{
std::set<unsigned int>::iterator f = m_roomCache.find(roomId);
if(f != m_roomCache.end())
m_roomCache.erase(f);
}
*/
//------------------------------------------------------------
void Client::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message)
{
if(message.isType("GameConnectionClosed"))
{
// Game server has crashed. With luck, we'll get transferred to a new server shortly
// So, clear our connection and put us on a queue. If we don't get transferred in a
// reasonable about of time, we'll be dropped.
m_gameConnection = 0;
ConnectionServer::addRecoveringClient(getNetworkId());
}
else if(message.isType("ChatServerConnectionOpened"))
{
const ChatServerConnection & chatConnection = static_cast<const ChatServerConnection &>(source);
setChatConnection(const_cast<ChatServerConnection*>(&chatConnection));
}
else if(message.isType("CustomerServiceConnectionOpened"))
{
const CustomerServiceConnection & customerServiceConnection = static_cast<const CustomerServiceConnection &>(source);
setCustomerServiceConnection(const_cast<CustomerServiceConnection*>(&customerServiceConnection));
}
}
//-----------------------------------------------------------------------
void Client::setChatConnection(ChatServerConnection * c)
{
if(m_chatConnection)
{
disconnectFromEmitter(*m_chatConnection, "ChatServerConnectionClosed");
// advise the old chat server that this client is disconnecting
// from it
NOT_NULL(m_clientConnection);
ChatDisconnectAvatar m(m_clientConnection->getCharacterId());
m_chatConnection->send(m, true);
}
else
{
disconnectFromMessage("ChatServerConnectionOpened");
}
m_chatConnection = c;
if(c && m_clientConnection)
{
// advise the new chat server that the client is connecting
connectToEmitter(*m_chatConnection, "ChatServerConnectionClosed");
ChatConnectAvatar connectAvatar(m_clientConnection->getCharacterName(), m_clientConnection->getCharacterId(), m_clientConnection->getSUID(), m_clientConnection->getIsSecure(), ((m_clientConnection->getSubscriptionFeatures() & ClientSubscriptionFeature::Base) != 0));
m_chatConnection->send(connectAvatar, true);
m_chatConnection->addClient(this);
/*
std::vector<NetworkId> id;
id.push_back(getNetworkId());
std::set<unsigned int>::const_iterator i;
for(i = m_roomCache.begin(); i != m_roomCache.end(); ++i)
{
ChatEnterRoomById chat(0, (*i));
GameClientMessage gcm(id, true, chat);
c->send(gcm, true);
}
m_roomCache.clear();
*/
flushChatMessages();
ChatServerStatus status(true);
m_clientConnection->send(status, true);
}
else
{
connectToMessage("ChatServerConnectionOpened");
ChatServerStatus status(false);
NOT_NULL(m_clientConnection);
m_clientConnection->send(status, false);
}
}
//-----------------------------------------------------------------------
void Client::setCustomerServiceConnection(CustomerServiceConnection * c)
{
if(m_customerServiceConnection)
{
disconnectFromEmitter(*m_customerServiceConnection, "CustomerServiceConnectionClosed");
NOT_NULL(m_clientConnection);
}
else
{
disconnectFromMessage("CustomerServiceConnectionOpened");
}
m_customerServiceConnection = c;
if(c && m_clientConnection)
{
connectToEmitter(*m_customerServiceConnection, "CustomerServiceConnectionClosed");
m_customerServiceConnection->addClient(this);
}
else
{
connectToMessage("CustomerServiceConnectionOpened");
}
}
//------------------------------------------------------------
void Client::setGameConnection(GameConnection* conn)
{
if (m_gameConnection != conn)
{
if (m_gameConnection)
{
disconnectFromEmitter(*m_gameConnection, "GameConnectionClosed");
}
if (conn)
{
connectToEmitter(*conn, "GameConnectionClosed");
}
m_gameConnection = conn;
}
}
//------------------------------------------------------------
void Client::kick(const std::string& reason)
{
ClientConnection *c = getClientConnection();
ConnectionServer::dropClient(c, reason);
m_hasBeenKicked = true;
if (getClientConnection())
{
LOG("CustomerService", ("Login:%s Dropped Reason: %s. Character: %s (%s). Play time: %s. Active play time: %s", ClientConnection::describeAccount(c).c_str(), reason.c_str(), getClientConnection()->getCharacterName().c_str(), getClientConnection()->getCharacterId().getValueString().c_str(), getClientConnection()->getPlayTimeDuration().c_str(), getClientConnection()->getActivePlayTimeDuration().c_str()));
}
else
{
LOG("CustomerService", ("Login: Account unknown (lost client connection) id %s Dropped Reason: %s. Character: <unknown>. Play time: <unknown>. Active play time: <unknown>", m_oid.getValueString().c_str(), reason.c_str()));
}
}
//------------------------------------------------------------
bool Client::getSkipLoadScreen() const
{
return m_skipLoadScreen;
}
//------------------------------------------------------------
void Client::skipLoadScreen()
{
m_skipLoadScreen = true;
}
//----------------------------------------------------------------------
@@ -0,0 +1,146 @@
// -----------------------------------------
// Client.h
// copyright 2001 Sony Online Entertainment
// -----------------------------------------
#ifndef _Included_Client_H_
#define _Included_Client_H_
#include "ChatServerConnection.h"
#include "ClientConnection.h"
#include "CustomerServiceConnection.h"
#include "GameConnection.h"
#include "sharedFoundation/NetworkId.h"
#include "sharedFoundation/Watcher.h"
#include "sharedMessageDispatch/Receiver.h"
#include <string>
class ChatServerConnection;
class CustomerServiceConnection;
class ClientConnection;
class GameConnection;
namespace MessageDispatch
{
class Callback;
}
/**
* class Client represents one actual player logged into the cluster.
* it knows what client connection they are on, as well as their oids and
* game server mappings
*/
//----------------------------------------------------------------------
class Client : public MessageDispatch::Receiver
{
public:
Client(ClientConnection* cconn, const NetworkId& oid); //ControlAssumed message should set the rest, GameConnection* gconn, std::string sceneName);
~Client();
void deferChatMessage (const Archive::ByteStream & message);
// void enterRoom (const unsigned int roomId);
void flushChatMessages ();
ClientConnection* getClientConnection ();
const NetworkId& getNetworkId () const;
GameConnection* getGameConnection () const;
ChatServerConnection* getChatConnection () const;
CustomerServiceConnection* getCustomerServiceConnection () const;
const std::string& getSceneName () const;
bool getSkipLoadScreen () const;
bool hasBeenKicked() const;
void skipLoadScreen ();
void handleTransfer (const std::string & sceneName, GameConnection* conn);
void kick (const std::string& reason);
// void leaveRoom (const unsigned int roomId);
void receiveMessage (const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message);
void setChatConnection (ChatServerConnection * chatServerConnection);
void setCustomerServiceConnection (CustomerServiceConnection * customerServiceConnection);
private:
Client();
Client(const Client&);
Client & operator= (const Client&);
void setGameConnection(GameConnection* conn);
void setSceneName(const std::string &name);
void onChatConnectionClosed(Connection *);
private:
//@todo...right now there is a one to one mapping between oid and client.
//this may not always be the case.
Watcher<ChatServerConnection> m_chatConnection;
Watcher<CustomerServiceConnection> m_customerServiceConnection;
ClientConnection* m_clientConnection;
std::vector<Archive::ByteStream> m_deferredChatMessages;
bool m_hasBeenKicked;
NetworkId m_oid;
GameConnection* m_gameConnection;
// std::set<unsigned int> m_roomCache;
std::string m_sceneName;
bool m_skipLoadScreen;
MessageDispatch::Callback * m_callback;
};
//-----------------------------------------------------------------------
inline ChatServerConnection * Client::getChatConnection() const
{
return m_chatConnection;
}
//-----------------------------------------------------------------------
inline CustomerServiceConnection * Client::getCustomerServiceConnection() const
{
return m_customerServiceConnection;
}
//------------------------------------------------------------
inline ClientConnection* Client::getClientConnection()
{
return m_clientConnection;
}
//------------------------------------------------------------
inline const NetworkId& Client::getNetworkId() const
{
return m_oid;
}
//------------------------------------------------------------
inline GameConnection* Client::getGameConnection() const
{
return m_gameConnection;
}
//------------------------------------------------------------
inline const std::string& Client::getSceneName() const
{
return m_sceneName;
}
//------------------------------------------------------------
inline bool Client::hasBeenKicked() const
{
return m_hasBeenKicked;
}
//------------------------------------------------------------
inline void Client::setSceneName(const std::string & name)
{
m_sceneName = name;
}
//------------------------------------------------------------
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,354 @@
// ClientConnection.h
// copyright 2001 Verant Interactive
#ifndef _ClientConnection_H
#define _ClientConnection_H
//-----------------------------------------------------------------------
#include "Client.h"
#include "Unicode.h"
#include "serverUtility/ServerConnection.h"
#include "sharedFoundation/NetworkId.h"
#include "sharedFoundation/StationId.h"
#include "sharedMath/Vector.h"
#include <map>
class ClientIdMsg;
class SelectCharacter;
class GameConnection;
class GameClientMessage;
class ConnectionCreateCharacter;
//-----------------------------------------------------------------------
class ClientConnection : public ServerConnection
{
public:
struct CharacterData
{
Unicode::String name;
std::string narrowName;
std::string location;
std::string objectTemplate;
NetworkId characterId;
NetworkId containerId;
Vector coordinates;
};
explicit ClientConnection(UdpConnectionMT *, TcpClient *);
virtual ~ClientConnection();
void addCharacter (const Unicode::String & name,
const NetworkId &characterId,
const std::string & location,
const std::string & objectTemplate,
const NetworkId &containerId,
const Vector & coordinates);
const std::string & getAccountName () const;
const NetworkId & getCharacterId () const;
const std::string & getCharacterName () const;
void setStartPlayTime (time_t startPlayTime);
time_t getStartPlayTime () const;
std::string getPlayTimeDuration () const;
std::string getActivePlayTimeDuration() const;
std::string getCurrentActivePlayTimeDuration() const;
void sendPlayTimeInfoToGameServer() const;
const Client * getClient () const;
Client * getClient ();
void setClient (Client* client);
uint32 getSUID () const;
const bool getHasSelectedCharacter () const;
bool getHasBeenSentToGameServer () const;
bool getIsSecure () const;
const std::string & getSessionId() const;
const std::string & getTargetSecene () const;
unsigned int getGameFeatures() const;
unsigned int getSubscriptionFeatures() const;
bool getHasCSLoggedAccountFeatureIds() const;
void setHasCSLoggedAccountFeatureIds(bool hasCSLoggedAccountFeatureIds);
unsigned int getEntitlementTotalTime () const;
unsigned int getEntitlementEntitledTime () const;
unsigned int getEntitlementTotalTimeSinceLastLogin () const;
unsigned int getEntitlementEntitledTimeSinceLastLogin () const;
int getBuddyPoints() const;
std::vector<std::pair<NetworkId, std::string> > const & getConsumedRewardEvents() const;
std::vector<std::pair<NetworkId, std::string> > const & getClaimedRewardItems() const;
bool isUsingAdminLogin () const;
bool getCanSkipTutorial () const;
virtual void onConnectionClosed ();
virtual void onConnectionOpened ();
virtual void onConnectionOverflowing (const unsigned int bytesPending);
virtual void onReceive (const Archive::ByteStream & message);
virtual void send (const GameNetworkMessage & message, const bool reliable);
void sendByteStream (const Archive::ByteStream &bs, bool reliable);
const bool sendToGameServer (uint32 gameServerId);
const bool sendToGameServer ();
void handleGameServerForLoginMessage(uint32 serverId);
void onIdValidated(bool canLogin, bool canCreateRegularCharacter, bool canCreateJediCharacter, bool canSkipTutorial, std::vector<std::pair<NetworkId, std::string> > const & consumedRewardEvents, std::vector<std::pair<NetworkId, std::string> > const & claimedRewardItems);
void onValidateClient (uint32 id, const std::string & username, bool, const char*, uint32 gameFeatures, uint32 subscriptionFeatures, unsigned int entitlementTotalTime, unsigned int entitlementEntitledTime, unsigned int entitlementTotalTimeSinceLastLogin, unsigned int entitlementEntitledTimeSinceLastLogin, int buddyPoints);
void onCharacterValidated(bool isValid, const NetworkId &character, const std::string &characterName, const NetworkId &container, const std::string &scene, const Vector &coordinates);
static std::string describeAccount(const ClientConnection *);
static std::map< std::string, uint32 >& getPacketBytesPerMinStats();
void handleChatEnterRoomValidationResponse(unsigned int sequence, unsigned int result);
void handleChatQueryRoomValidationResponse(unsigned int sequence, bool success);
void setHasRequestedCharacterCreate(bool value);
void setHasCreatedCharacter(bool value);
private:
ClientConnection();
ClientConnection(const ClientConnection&);
ClientConnection& operator=(const ClientConnection&);
void handleLagRequest ();
bool checkSpamLimit (unsigned int messageSize);
static std::map< std::string, uint32 > sm_outgoingBytesMap_Working; // working stats that will rotate after 1 minute
static std::map< std::string, uint32 > sm_outgoingBytesMap_Stats; // computed stats from the last minute
static uint32 sm_outgoingBytesMap_Worktime; // time we started filling in the working map
std::string m_accountName;
bool m_canCreateRegularCharacter;
bool m_canCreateJediCharacter;
// to prevent exploit, a connection to the client is allowed to only request
// creating a new character once; we will disconnect the connection if we
// receive a second request; this will force the client to connect again,
// at which time another validation will be done to see if creating a new
// character is allowed
bool m_hasRequestedCharacterCreate;
// to prevent exploit, a connection to the client is allowed to
// create a new character once; we will disconnect the connection if we
// receive a request to create another character; this will force the
// client to connect again, at which time another validation will be
// done to see if creating a new character is allowed
bool m_hasCreatedCharacter;
// hang on to a character create request while we check with the LoginServer
// one last time to make sure the account can create a new character
ConnectionCreateCharacter * m_pendingCharacterCreate;
bool m_canSkipTutorial;
NetworkId m_characterId;
std::string m_characterName;
time_t m_startPlayTime; // time when the player started playing the character
time_t m_lastActiveTime; // the client will detect when the player is "active" or "inactive"; this keeps track of the last time that the client said the player was "active"; if 0, it means the client is currently "inactive"
unsigned long m_activePlayTimeDuration; // total amount of play time player was active (i.e. at the mouse/keyboard/joystick)
Client * m_client;
NetworkId m_containerId;
uint32 m_featureBitsGame;
uint32 m_featureBitsSubscription;
uint32 m_gameBitsToClear;
bool m_hasBeenSentToGameServer;
bool m_hasBeenValidated;
bool m_hasSelectedCharacter;
bool m_isSecure;
bool m_isAdminAccount; // Note: means this account is on the admin list, not that the account has god powers in this session. Using SecureId and being on the right IP subnet are also required to run god commands. m_isAdminAccount will be true for admins playing from home, for example.
bool m_hasCSLoggedAccountFeatureIds;
StationId m_suid;
StationId m_requestedSuid;
bool m_usingAdminLogin;
Vector m_targetCoordinates;
std::string m_targetScene;
bool m_validatingCharacter;
unsigned int m_receiveHistoryBytes;
unsigned int m_receiveHistoryPackets;
unsigned long m_receiveHistoryMs;
unsigned long m_receiveLastTimeMs;
mutable unsigned long m_sendLastTimeMs;
std::string m_sessionId;
bool m_sessionValidated;
int m_connectionServerLag;
int m_gameServerLag;
unsigned long m_countSpamLimitResetTime;
unsigned int m_entitlementTotalTime;
unsigned int m_entitlementEntitledTime;
unsigned int m_entitlementTotalTimeSinceLastLogin;
unsigned int m_entitlementEntitledTimeSinceLastLogin;
int m_buddyPoints;
std::vector<std::pair<NetworkId, std::string> > m_consumedRewardEvents;
std::vector<std::pair<NetworkId, std::string> > m_claimedRewardItems;
bool m_sendToStarport;
// chat enter room requests that came from the client that's awaiting
// game sever approval before being forwarded to the chat server
std::map<unsigned long, GameClientMessage*> m_pendingChatEnterRoomRequests;
// ChatQueryRoom requests that came from the client that's awaiting
// game sever approval before being forwarded to the chat server
std::map<unsigned long, GameClientMessage*> m_pendingChatQueryRoomRequests;
//Message handler functions
void handleClientIdMessage(const ClientIdMsg& msg);
void handleSelectCharacterMessage(const SelectCharacter& msg);
bool validateSelection(const Unicode::String & characterName);
bool sendToGameServer(GameConnection *c);
};
//-----------------------------------------------------------------------
inline const std::string & ClientConnection::getAccountName() const
{
return m_accountName;
}
//-----------------------------------------------------------------------
inline void ClientConnection::setStartPlayTime(time_t startPlayTime)
{
m_startPlayTime = startPlayTime;
}
//-----------------------------------------------------------------------
inline time_t ClientConnection::getStartPlayTime() const
{
return m_startPlayTime;
}
//-----------------------------------------------------------------------
inline const Client* ClientConnection::getClient() const
{
return m_client;
}
//-----------------------------------------------------------------------
inline Client* ClientConnection::getClient()
{
return m_client;
}
//-----------------------------------------------------------------------
inline const bool ClientConnection::getHasSelectedCharacter() const
{
return m_hasSelectedCharacter;
}
//-----------------------------------------------------------------------
inline const std::string & ClientConnection::getTargetSecene() const
{
return m_targetScene;
}
//-----------------------------------------------------------------------
inline uint32 ClientConnection::getSUID() const
{
return m_suid;
}
//-----------------------------------------------------------------------
inline bool ClientConnection::getHasBeenSentToGameServer() const
{
return m_hasBeenSentToGameServer;
}
// ----------------------------------------------------------------------
inline bool ClientConnection::getIsSecure() const
{
return m_isSecure;
}
// ----------------------------------------------------------------------
inline const std::string & ClientConnection::getSessionId() const
{
return m_sessionId;
}
// ----------------------------------------------------------------------
inline unsigned int ClientConnection::getGameFeatures() const
{
return m_featureBitsGame;
}
// ----------------------------------------------------------------------
inline unsigned int ClientConnection::getSubscriptionFeatures() const
{
return m_featureBitsSubscription;
}
// ----------------------------------------------------------------------
inline unsigned int ClientConnection::getEntitlementTotalTime() const
{
return m_entitlementTotalTime;
}
// ----------------------------------------------------------------------
inline unsigned int ClientConnection::getEntitlementEntitledTime() const
{
return m_entitlementEntitledTime;
}
// ----------------------------------------------------------------------
inline unsigned int ClientConnection::getEntitlementTotalTimeSinceLastLogin() const
{
return m_entitlementTotalTimeSinceLastLogin;
}
// ----------------------------------------------------------------------
inline unsigned int ClientConnection::getEntitlementEntitledTimeSinceLastLogin() const
{
return m_entitlementEntitledTimeSinceLastLogin;
}
// ----------------------------------------------------------------------
inline bool ClientConnection::getCanSkipTutorial() const
{
return m_canSkipTutorial;
}
// ----------------------------------------------------------------------
inline void ClientConnection::setHasRequestedCharacterCreate(bool value)
{
m_hasRequestedCharacterCreate = value;
}
// ----------------------------------------------------------------------
inline void ClientConnection::setHasCreatedCharacter(bool value)
{
m_hasCreatedCharacter = value;
}
// ----------------------------------------------------------------------
inline bool ClientConnection::getHasCSLoggedAccountFeatureIds() const
{
return m_hasCSLoggedAccountFeatureIds;
}
// ----------------------------------------------------------------------
inline void ClientConnection::setHasCSLoggedAccountFeatureIds(bool hasCSLoggedAccountFeatureIds)
{
m_hasCSLoggedAccountFeatureIds = hasCSLoggedAccountFeatureIds;
}
// ----------------------------------------------------------------------
#endif // _ClientConnection_H
@@ -0,0 +1,166 @@
// ConfigConnectionServer.cpp
// copyright 2001 Verant Interactive
//-----------------------------------------------------------------------
#include "FirstConnectionServer.h"
#include "ConfigConnectionServer.h"
#include "SessionApiClient.h"
#include "serverUtility/ConfigServerUtility.h"
#include "sharedFoundation/ConfigFile.h"
#include "sharedGame/PlatformFeatureBits.h"
#include "sharedNetwork/SetupSharedNetwork.h"
//-----------------------------------------------------------------------
ConfigConnectionServer::Data * ConfigConnectionServer::data = 0;
#define KEY_INT(a,b) (data->a = ConfigFile::getKeyInt("ConnectionServer", #a, b))
#define KEY_BOOL(a,b) (data->a = ConfigFile::getKeyBool("ConnectionServer", #a, b))
#define KEY_FLOAT(a,b) (data->a = ConfigFile::getKeyFloat("ConnectionServer", #a, b))
#define KEY_STRING(a,b) (data->a = ConfigFile::getKeyString("ConnectionServer", #a, b))
//-----------------------------------------------------------------------
namespace ConfigConnectionServerNamespace
{
typedef std::vector<char const *> StringPtrArray;
StringPtrArray ms_sessionServer; // ConfigFile owns the pointer
}
using namespace ConfigConnectionServerNamespace;
// ======================================================================
int ConfigConnectionServer::getNumberOfSessionServers()
{
return static_cast<int>(ms_sessionServer.size());
}
// ----------------------------------------------------------------------
char const * ConfigConnectionServer::getSessionServer(int index)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfSessionServers());
return ms_sessionServer[static_cast<size_t>(index)];
}
void ConfigConnectionServer::install(void)
{
ConfigServerUtility::install();
SetupSharedNetwork::SetupData networkSetupData;
SetupSharedNetwork::getDefaultServerSetupData(networkSetupData);
SetupSharedNetwork::install(networkSetupData);
data = new ConfigConnectionServer::Data;
KEY_STRING (centralServerAddress, "swo-dev5.station.sony.com");
KEY_INT (centralServerPort, 0);
KEY_STRING (clientServiceBindInterface, "");
KEY_INT (clientServicePortPrivate, 44464);
KEY_INT (clientServicePortPublic, 44463);
KEY_INT (clientOverflowLimit, 1024 * 1024); // 1MB overflow
KEY_INT (gameServicePort, 0);
KEY_INT (pingPort, 0);
KEY_STRING (clusterName, "devcluster");
KEY_INT (maxClients, 200);
KEY_BOOL (spamLimitEnabled, false);
KEY_INT (spamLimitResetTimeMs, 30*1000);
KEY_INT (spamLimitResetScaleFactor, 8);
KEY_INT (spamLimitBytesPerSec, 32000);
KEY_INT (spamLimitPacketsPerSec, 50);
KEY_BOOL (startPublicServer, true);
KEY_BOOL (disableWorldSnapshot, true);
KEY_STRING (gameServiceBindInterface, "");
KEY_STRING (chatServiceBindInterface, "");
KEY_STRING (customerServiceBindInterface, "");
KEY_BOOL (compressClientNetworkTraffic, true);
KEY_INT (crashRecoveryTimeout, 15*1000); // timeout for players to recover from a server crash
KEY_BOOL (shouldSleep, true);
KEY_INT (clientMaxOutstandingPackets, 1000);
KEY_INT (clientMaxRawPacketSize, 500);
KEY_INT (clientMaxConnections, 200);
KEY_INT (clientFragmentSize, 500);
KEY_INT (clientMaxDataHoldTime, 20);
KEY_INT (clientHashTableSize, 200);
KEY_INT (lagReportThreshold, 10000);
KEY_INT (defaultGameFeatures, 0xFFFFFFFF);
KEY_INT (defaultSubscriptionFeatures, 0xFFFFFFFF);
KEY_BOOL (validateStationKey, false);
KEY_STRING (sessionServers, "");
KEY_INT (sessionType, SESSION_TYPE_STARWARS);
KEY_BOOL (disableSessionLogout, false);
KEY_BOOL (sessionRecordPlayTime, true);
KEY_BOOL (disconnectOnInactive, false);
KEY_BOOL (disconnectFreeTrialOnInactive, false);
KEY_STRING (adminAccountDataTable, "datatables/admin/us_admin.iff");
KEY_INT (requiredSubscriptionBits, 0);
KEY_INT (requiredGameBits, 0);
KEY_BOOL (setJtlRetailIfBetaIsSet, false);
KEY_BOOL (validateClientVersion, true);
KEY_BOOL (setEpisode3RetailIfBetaIsSet, false);
KEY_BOOL (setTrialsOfObiwanRetailIfBetaIsSet, false);
KEY_INT (disabledFeatureBits, 0);
KEY_FLOAT (timeBetweenSessionUpdates, 60.0f * 5.0f);
KEY_INT (connectionServerNumber, 0);
KEY_INT (fakeBuddyPoints, 0);
int index = 0;
char const * result = 0;
do
{
result = ConfigFile::getKeyString("ConnectionServer", "sessionServer", index++, 0);
if (result != 0)
{
ms_sessionServer.push_back(result);
}
}
while (result);
}
//-----------------------------------------------------------------------
void ConfigConnectionServer::remove(void)
{
delete data;
data = 0;
ConfigServerUtility::remove();
}
//-----------------------------------------------------------------------
int ConfigConnectionServer::getDisabledFeatureBits()
{
return data->disabledFeatureBits;
}
// ----------------------------------------------------------------------
bool ConfigConnectionServer::getDisconnectOnInactive()
{
return data->disconnectOnInactive;
}
// ----------------------------------------------------------------------
bool ConfigConnectionServer::getDisconnectFreeTrialOnInactive()
{
return data->disconnectFreeTrialOnInactive;
}
// ----------------------------------------------------------------------
int ConfigConnectionServer::getFakeBuddyPoints()
{
return data->fakeBuddyPoints;
}
// ======================================================================
@@ -0,0 +1,465 @@
// ConfigConnectionServer.h
// copyright 2000 Verant Interactive
// Author: Justin Randall
#ifndef _ConfigConnectionServer_H
#define _ConfigConnectionServer_H
//-----------------------------------------------------------------------
class ConfigConnectionServer
{
public:
struct Data
{
const char* centralServerAddress;
int centralServerPort;
int clientServicePortPublic;
int clientServicePortPrivate;
int clientOverflowLimit;
int gameServicePort;
const char * clusterName;
bool disableWorldSnapshot;
int maxClients;
int pingPort;
bool spamLimitEnabled;
int spamLimitResetTimeMs;
int spamLimitResetScaleFactor;
int spamLimitBytesPerSec;
int spamLimitPacketsPerSec;
bool startPublicServer;
const char * chatServiceBindInterface;
const char * clientServiceBindInterface;
const char * customerServiceBindInterface;
const char * gameServiceBindInterface;
bool compressClientNetworkTraffic;
int crashRecoveryTimeout;
bool shouldSleep;
int clientMaxOutstandingPackets;
int clientMaxRawPacketSize;
int clientMaxConnections;
int clientFragmentSize;
int clientMaxDataHoldTime;
int clientHashTableSize;
int lagReportThreshold;
bool validateStationKey;
const char * sessionServers;
int sessionType;
bool disableSessionLogout;
bool sessionRecordPlayTime;
bool disconnectOnInactive;
bool disconnectFreeTrialOnInactive;
const char * adminAccountDataTable;
float timeBetweenSessionUpdates;
int defaultGameFeatures;
int defaultSubscriptionFeatures;
int requiredSubscriptionBits;
int requiredGameBits;
bool setJtlRetailIfBetaIsSet;
bool setEpisode3RetailIfBetaIsSet;
bool setTrialsOfObiwanRetailIfBetaIsSet;
int disabledFeatureBits;
bool validateClientVersion;
int connectionServerNumber;
int fakeBuddyPoints;
};
static const char * getCentralServerAddress ();
static const uint16 getCentralServerPort ();
static const int getClientOverflowLimit ();
static const char * getClientServiceBindInterface ();
static const uint16 getClientServicePortPrivate ();
static const uint16 getClientServicePortPublic ();
static const char * getClusterName ();
static bool getDisableWorldSnapshot ();
static const uint16 getGameServicePort ();
static const int getMaxClients ();
static const uint16 getPingPort ();
static const bool getSpamLimitEnabled ();
static const unsigned int getSpamLimitResetTimeMs ();
static const unsigned int getSpamLimitResetScaleFactor ();
static const unsigned int getSpamLimitBytesPerSec ();
static const unsigned int getSpamLimitPacketsPerSec ();
static const bool getStartPublicServer ();
static const char * getChatServiceBindInterface ();
static const char * getCustomerServiceBindInterface ();
static const char * getGameServiceBindInterface ();
static const bool getCompressClientNetworkTraffic ();
static void install ();
static void remove ();
static const uint getCrashRecoveryTimeout ();
static bool getShouldSleep ();
static const int getClientMaxOutstandingPackets();
static const int getClientMaxRawPacketSize ();
static const int getClientMaxConnections ();
static const int getClientFragmentSize ();
static const int getClientMaxDataHoldTime ();
static const int getClientHashTableSize ();
static const int getLagReportThreshold ();
static bool getValidateStationKey();
static const char * getSessionServers();
static const int getSessionType();
static bool getDisableSessionLogout();
static bool getSessionRecordPlayTime();
static bool getDisconnectOnInactive();
static bool getDisconnectFreeTrialOnInactive();
static const char * getAdminAccountDataTable (void);
static int getNumberOfSessionServers();
static char const * getSessionServer(int index);
static float getTimeBetweenSessionUpdates();
static const uint32 getDefaultGameFeatures ();
static const uint32 getDefaultSubscriptionFeatures();
static uint32 getRequiredSubscriptionBits();
static uint32 getRequiredGameBits();
static bool getSetJtlRetailIfBetaIsSet();
static bool getSetEpisode3RetailIfBetaIsSet();
static bool getSetTrialsOfObiwanRetailIfBetaIsSet();
static int getDisabledFeatureBits();
static bool getValidateClientVersion();
static int getConnectionServerNumber();
static int getFakeBuddyPoints();
private:
static Data * data;
};
//-----------------------------------------------------------------------
inline bool ConfigConnectionServer::getShouldSleep()
{
return data->shouldSleep;
}
//-----------------------------------------------------------------------
inline const bool ConfigConnectionServer::getCompressClientNetworkTraffic()
{
return data->compressClientNetworkTraffic;
}
//-----------------------------------------------------------------------
inline const char * ConfigConnectionServer::getCentralServerAddress ()
{
return data->centralServerAddress;
}
//-----------------------------------------------------------------------
inline const uint16 ConfigConnectionServer::getCentralServerPort ()
{
return static_cast<const uint16>(data->centralServerPort);
}
//-----------------------------------------------------------------------
inline const char* ConfigConnectionServer::getClientServiceBindInterface()
{
return data->clientServiceBindInterface;
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getClientOverflowLimit()
{
return data->clientOverflowLimit;
}
//-----------------------------------------------------------------------
inline const uint16 ConfigConnectionServer::getClientServicePortPrivate()
{
return static_cast<const uint16>(data->clientServicePortPrivate);
}
//-----------------------------------------------------------------------
inline const uint16 ConfigConnectionServer::getClientServicePortPublic()
{
return static_cast<const uint16>(data->clientServicePortPublic);
}
//-----------------------------------------------------------------------
inline const char * ConfigConnectionServer::getClusterName()
{
return data->clusterName;
}
//-----------------------------------------------------------------------
inline bool ConfigConnectionServer::getDisableWorldSnapshot()
{
return data->disableWorldSnapshot;
}
//-----------------------------------------------------------------------
inline const uint16 ConfigConnectionServer::getGameServicePort()
{
return static_cast<const uint16>(data->gameServicePort);
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getMaxClients()
{
return data->maxClients;
}
//-----------------------------------------------------------------------
inline const uint16 ConfigConnectionServer::getPingPort ()
{
return static_cast<const uint16>(data->pingPort);
}
//-----------------------------------------------------------------------
inline const bool ConfigConnectionServer::getSpamLimitEnabled ()
{
return data->spamLimitEnabled;
}
//-----------------------------------------------------------------------
inline const unsigned int ConfigConnectionServer::getSpamLimitResetTimeMs ()
{
return static_cast<const unsigned int>(data->spamLimitResetTimeMs);
}
//-----------------------------------------------------------------------
inline const unsigned int ConfigConnectionServer::getSpamLimitResetScaleFactor ()
{
return static_cast<const unsigned int>(data->spamLimitResetScaleFactor);
}
//-----------------------------------------------------------------------
inline const unsigned int ConfigConnectionServer::getSpamLimitBytesPerSec ()
{
return static_cast<const unsigned int>(data->spamLimitBytesPerSec);
}
//-----------------------------------------------------------------------
inline const unsigned int ConfigConnectionServer::getSpamLimitPacketsPerSec ()
{
return static_cast<const unsigned int>(data->spamLimitPacketsPerSec);
}
//-----------------------------------------------------------------------
inline const bool ConfigConnectionServer::getStartPublicServer()
{
return data->startPublicServer;
}
//-----------------------------------------------------------------------
inline const char * ConfigConnectionServer::getChatServiceBindInterface()
{
return data->chatServiceBindInterface;
}
//-----------------------------------------------------------------------
inline const char * ConfigConnectionServer::getCustomerServiceBindInterface()
{
return data->customerServiceBindInterface;
}
//-----------------------------------------------------------------------
inline const char * ConfigConnectionServer::getGameServiceBindInterface()
{
return data->gameServiceBindInterface;
}
// ----------------------------------------------------------------------
inline const uint ConfigConnectionServer::getCrashRecoveryTimeout()
{
return static_cast<uint>(data->crashRecoveryTimeout);
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getClientMaxOutstandingPackets()
{
return data->clientMaxOutstandingPackets;
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getClientMaxRawPacketSize()
{
return data->clientMaxRawPacketSize;
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getClientMaxConnections()
{
return data->clientMaxConnections;
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getClientFragmentSize()
{
return data->clientFragmentSize;
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getClientMaxDataHoldTime()
{
return data->clientMaxDataHoldTime;
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getClientHashTableSize()
{
return data->clientHashTableSize;
}
//-----------------------------------------------------------------------
inline const int ConfigConnectionServer::getLagReportThreshold()
{
return data->lagReportThreshold;
}
// ----------------------------------------------------------------------
//------------------------------------------------------------------------------------------
inline bool ConfigConnectionServer::getValidateStationKey()
{
return data->validateStationKey;
}
//------------------------------------------------------------------------------------------
inline const char * ConfigConnectionServer::getSessionServers()
{
return data->sessionServers;
}
//------------------------------------------------------------------------------------------
inline const int ConfigConnectionServer::getSessionType()
{
return data->sessionType;
}
//------------------------------------------------------------------------------------------
inline bool ConfigConnectionServer::getDisableSessionLogout()
{
return data->disableSessionLogout;
}
//------------------------------------------------------------------------------------------
inline bool ConfigConnectionServer::getSessionRecordPlayTime()
{
return data->sessionRecordPlayTime;
}
// ----------------------------------------------------------------------
inline const char * ConfigConnectionServer::getAdminAccountDataTable(void)
{
return data->adminAccountDataTable;
}
//-----------------------------------------------------------------------
inline float ConfigConnectionServer::getTimeBetweenSessionUpdates()
{
return data->timeBetweenSessionUpdates;
}
//-----------------------------------------------------------------------
inline uint32 ConfigConnectionServer::getRequiredSubscriptionBits()
{
return static_cast<uint32>(data->requiredSubscriptionBits);
}
//-----------------------------------------------------------------------
inline uint32 ConfigConnectionServer::getRequiredGameBits()
{
return static_cast<uint32>(data->requiredGameBits);
}
//-----------------------------------------------------------------------
inline const uint32 ConfigConnectionServer::getDefaultGameFeatures()
{
return static_cast<uint32>(data->defaultGameFeatures);
}
// ----------------------------------------------------------------------
inline const uint32 ConfigConnectionServer::getDefaultSubscriptionFeatures()
{
return static_cast<uint32>(data->defaultSubscriptionFeatures);
}
//------------------------------------------------------------------------------------------
inline bool ConfigConnectionServer::getSetJtlRetailIfBetaIsSet()
{
return data->setJtlRetailIfBetaIsSet;
}
//------------------------------------------------------------------------------------------
inline bool ConfigConnectionServer::getSetEpisode3RetailIfBetaIsSet()
{
return data->setEpisode3RetailIfBetaIsSet;
}
//------------------------------------------------------------------------------------------
inline bool ConfigConnectionServer::getSetTrialsOfObiwanRetailIfBetaIsSet()
{
return data->setTrialsOfObiwanRetailIfBetaIsSet;
}
//------------------------------------------------------------------------------------------
inline bool ConfigConnectionServer::getValidateClientVersion()
{
return data->validateClientVersion;
}
// ----------------------------------------------------------------------
inline int ConfigConnectionServer::getConnectionServerNumber()
{
return data->connectionServerNumber;
}
#endif // _ConfigConnectionServer_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,138 @@
// ConnectionServer.h
// copyright 2001 Verant Interactive
#ifndef _ConnectionServer_H
#define _ConnectionServer_H
//-----------------------------------------------------------------------
#include <hash_map>
#include <set>
#include <string>
#include "CentralConnection.h"
#include "Client.h"
#include "GameConnection.h"
#include "Singleton/Singleton.h"
#include "serverKeyShare/KeyServer.h"
#include "serverKeyShare/KeyShare.h"
#include "sharedFoundation/StationId.h"
#include "sharedMessageDispatch/Receiver.h"
class ClientConnection;
class CharacterListMessageData;
class ChatServerConnection;
class ConnectionServerId;
class CustomerServiceConnection;
class ConnectionServerMetricsData;
class NetworkBarrier;
class SessionApiClient;
class UdpSock;
//-----------------------------------------------------------------------
class ConnectionServer : public MessageDispatch::Receiver
{
public:
static void install();
static void remove();
void setDone(char const *reasonfmt, ...);
~ConnectionServer ();
typedef std::hash_map<uint32, GameConnection *> GameServerMap;
typedef std::hash_map<NetworkId, Client *,NetworkId::Hash> ClientMap;
typedef std::hash_map<uint32, ClientConnection *> SuidMap;
typedef std::set<uint32> FreeTrialsSet;
static void addNewClient(ClientConnection* cconn, const NetworkId &oid, GameConnection* gconn, const std::string &sceneName, bool sendToStarport );
static void addConnectedClient(uint32 suid, ClientConnection* conn);
static void addGameConnection(unsigned long gameServerId, GameConnection* gc);
static bool decryptToken(const KeyShare::Token & token, uint32 & stationUserId, bool & secure, std::string & accountName);
static bool decryptToken(const KeyShare::Token & token, char* sessionKey, StationId & stationId);
static CentralConnection * getCentralConnection();
static void dropClient(ClientConnection * conn, const std::string &description);
static const Service * getChatService ();
static const Service * getCustomerService ();
static const CustomerServiceConnection * getCustomerServiceConnection ();
static Client* getClient(const NetworkId & oid);
static const ClientMap & getClientMap();
static Service * getClientServicePrivate ();
static Service * getClientServicePublic ();
static ClientConnection* getClientConnection(uint32 suid);
static uint16 getPingPort ();
static int getPingTrafficNumBytes();
static int getNumberOfClients();
static int getNumberOfFreeTrials();
static int getNumberOfGameServers();
static GameConnection* getGameConnection(uint32 gameServerId);
static GameConnection* getGameConnection(const std::string &sceneName);
static GameConnection* getAnyGameConnection();
static const Service * getGameService ();
static SessionApiClient* getSessionApiClient();
void handleConnectionServerIdMessage(const ConnectionServerId& msg);
static KeyShare::Token makeToken(const unsigned char * newData, const uint32 dataLen);
static void pushKey(const KeyShare::Key & newKey);
void receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message);
static void removeConnectedCharacter(uint32 suid);
static void run(void);
static void sendToCentralProcess(const GameNetworkMessage& msg);
static void addRecoveringClient(const NetworkId& networkId);
private:
ConnectionServer ();
ConnectionServer (const ConnectionServer & source);
ConnectionServer & operator=(const ConnectionServer & rhs);
static ConnectionServer & instance();
void setupConnections();
void unsetupConnections();
void update();
void updateRecoveringClientList(uint elapsedTime);
void installSessionValidation();
void addToClientMap(const NetworkId &oid, ClientConnection* cconn);
void removeFromClientMap(const NetworkId &oid);
void addToConnectedMap(uint32 suid, ClientConnection* conn);
void removeFromConnectedMap(uint32 suid);
void updatePopulationOnCentralServer();
private:
Service * chatService;
Service * customerService;
Service * clientServicePrivate;
Service * clientServicePublic;
Service * gameService;
KeyServer* loginServerKeys;
bool done;
int m_id;
ConnectionServerMetricsData* m_metricsData;
CentralConnection * centralConnection;
std::set<ChatServerConnection *> chatServers;
std::set<CustomerServiceConnection *> customerServiceServers;
ClientMap clientMap;
SuidMap connectedMap;
GameServerMap gameServerMap;
FreeTrialsSet freeTrials;
NetworkBarrier * networkBarrier;
UdpSock * pingSocket;
uint m_recoverTime;
SessionApiClient* m_sessionApiClient;
int m_pingTrafficNumBytes;
typedef std::vector<std::pair<uint, NetworkId> > RecoveringClientListType;
RecoveringClientListType m_recoveringClientList;
};
//-----------------------------------------------------------------------
#endif //_ConnectionServer_H
@@ -0,0 +1,62 @@
//ConnectionServerMetricsData.cpp
//Copyright 2002 Sony Online Entertainment
#include "FirstConnectionServer.h"
#include "ConnectionServerMetricsData.h"
#include "ConnectionServer.h"
#include "serverNetworkMessages/MetricsDataMessage.h"
#include "sharedNetworkMessages/GameNetworkMessage.h"
#include "ClientConnection.h"
#include "sharedLog/Log.h"
//-----------------------------------------------------------------------
ConnectionServerMetricsData::ConnectionServerMetricsData() :
MetricsData()
{
MetricsPair p;
ADD_METRICS_DATA(numUsers, 0, false);
ADD_METRICS_DATA(numGameServers, 0, false);
ADD_METRICS_DATA(pingTrafficNumBytes, 0, false);
}
//-----------------------------------------------------------------------
ConnectionServerMetricsData::~ConnectionServerMetricsData()
{
}
//-----------------------------------------------------------------------
void ConnectionServerMetricsData::updateData()
{
MetricsData::updateData();
m_data[m_numUsers].m_value = ConnectionServer::getNumberOfClients();
m_data[m_numGameServers].m_value = ConnectionServer::getNumberOfGameServers();
m_data[m_pingTrafficNumBytes].m_value = ConnectionServer::getPingTrafficNumBytes();
/****************** disabled due to stats failing to update on live *********************
std::map< std::string, uint32 >& cpmap = ClientConnection::getPacketBytesPerMinStats();
std::map< std::string, uint32 >::iterator cpiter;
// Shared packet metrics
for ( cpiter = cpmap.begin(); cpiter != cpmap.end(); ++cpiter )
{
std::map< std::string, unsigned long>::iterator miter = m_packetDataMap.find( cpiter->first );
if ( miter == m_packetDataMap.end() ) // If we haven't added this packet metric yet....
{
MetricsData* p_met = MetricsData::getInstance();
std::string s_key("ConnectionClientPackets_BytesPerMin.");
s_key+=cpiter->first;
m_packetDataMap[ cpiter->first ] = p_met->addMetric(s_key.c_str(), 0, 0, true, true); // add the ID to the local map
miter = m_packetDataMap.find( cpiter->first );
}
m_data[ miter->second ].m_value = cpiter->second;
}
***********************************************************************************************/
}
//-----------------------------------------------------------------------
@@ -0,0 +1,39 @@
//ConnectionServerMetricsData.h
//Copyright 2002 Sony Online Entertainment
#ifndef _ConnectionServerMetricsData_H
#define _ConnectionServerMetricsData_H
//-----------------------------------------------------------------------
#include "serverMetrics/MetricsData.h"
#include <map>
//-----------------------------------------------------------------------
class ConnectionServerMetricsData : public MetricsData
{
public:
ConnectionServerMetricsData();
~ConnectionServerMetricsData();
virtual void updateData();
private:
unsigned long m_numUsers;
unsigned long m_numGameServers;
unsigned long m_pingTrafficNumBytes;
std::map< std::string, unsigned long > m_packetDataMap;
private:
// Disabled.
ConnectionServerMetricsData(const ConnectionServerMetricsData&);
ConnectionServerMetricsData &operator =(const ConnectionServerMetricsData&);
};
//-----------------------------------------------------------------------
#endif
@@ -0,0 +1,104 @@
// CustomerServiceConnection.cpp
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "FirstConnectionServer.h"
#include "CustomerServiceConnection.h"
#include "ClientConnection.h"
#include "serverNetworkMessages/GameConnectionServerMessages.h"
//-----------------------------------------------------------------------
CustomerServiceConnection::CustomerServiceConnection(UdpConnectionMT * u, TcpClient * t) :
ServerConnection(u, t),
clients()
{
}
//-----------------------------------------------------------------------
CustomerServiceConnection::~CustomerServiceConnection()
{
}
//-----------------------------------------------------------------------
void CustomerServiceConnection::addClient(Client * newClient)
{
if (clients.find(newClient) == clients.end())
IGNORE_RETURN( clients.insert(newClient) );
else
DEBUG_WARNING(true, ("called CustomerServiceConnection::addClient with a client that already exists in the map."));
}
//-----------------------------------------------------------------------
void CustomerServiceConnection::onConnectionClosed()
{
ServerConnection::onConnectionClosed();
static MessageConnectionCallback m("CustomerServiceConnectionClosed");
emitMessage(m);
}
//-----------------------------------------------------------------------
const std::set<Client *> & CustomerServiceConnection::getClients() const
{
return clients;
}
//-----------------------------------------------------------------------
void CustomerServiceConnection::onConnectionOpened()
{
ServerConnection::onConnectionOpened();
static MessageConnectionCallback m("CustomerServiceConnectionOpened");
emitMessage(m);
}
//-----------------------------------------------------------------------
void CustomerServiceConnection::onReceive(const Archive::ByteStream & message)
{
Archive::ReadIterator ri = message.begin();
GameNetworkMessage m(ri);
ri = message.begin();
if (m.isType("GameClientMessage"))
{
//we're receiving a message to forward to the client.
//it is prefixed with NetworkId and reliable.
const GameClientMessage msg(ri);
Archive::ReadIterator mri(msg.getByteStream());
GameNetworkMessage gnm(mri);
mri = msg.getByteStream().begin();
const std::vector<NetworkId> & d = msg.getDistributionList();
std::vector<NetworkId>::const_iterator i;
for(i = d.begin(); i != d.end(); ++i)
{
Client* client = ConnectionServer::getClient((*i));
DEBUG_REPORT_LOG(!client, ("Error, could not map %s to a client\n", (*i).getValueString().c_str()));
if (client)
{
client->getClientConnection()->sendByteStream(msg.getByteStream(), msg.getReliable());
}
}
}
}
//-----------------------------------------------------------------------
void CustomerServiceConnection::removeClient(Client * oldClient)
{
std::set<Client *>::iterator f = clients.find(oldClient);
if(f != clients.end())
clients.erase(f);
}
//-----------------------------------------------------------------------
@@ -0,0 +1,34 @@
// CustomerServiceConnection.h
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_CustomerServiceConnection_H
#define _INCLUDED_CustomerServiceConnection_H
//-----------------------------------------------------------------------
#include "serverUtility/ServerConnection.h"
//-----------------------------------------------------------------------
class CustomerServiceConnection : public ServerConnection
{
public:
CustomerServiceConnection(UdpConnectionMT *, TcpClient *);
virtual ~CustomerServiceConnection();
void addClient(Client *);
void onConnectionClosed ();
void onConnectionOpened ();
void onReceive (const Archive::ByteStream &);
void removeClient(Client *);
const std::set<Client *> & getClients() const;
private:
CustomerServiceConnection();
CustomerServiceConnection & operator = (const CustomerServiceConnection & rhs);
CustomerServiceConnection(const CustomerServiceConnection & source);
std::set<Client *> clients;
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_CustomerServiceConnection_H
@@ -0,0 +1,23 @@
// ======================================================================
//
// FirstConnectionServer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_FirstConnectionServer_H
#define INCLUDED_FirstConnectionServer_H
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedMemoryManager/FirstSharedMemoryManager.h"
#include "sharedDebug/FirstSharedDebug.h"
#include "ConnectionServer.h"
#include "sharedFoundation/NetworkIdArchive.h"
#include "sharedNetworkMessages/GameNetworkMessage.h"
// ======================================================================
#endif
@@ -0,0 +1,348 @@
// GameConnection.cpp
// copyright 2001 Verant Interactive
//-----------------------------------------------------------------------
#include "FirstConnectionServer.h"
#include "GameConnection.h"
#include "Archive/ByteStream.h"
#include "Client.h"
#include "ClientConnection.h"
#include "ConfigConnectionServer.h"
#include "ConnectionServer.h"
#include "CustomerServiceConnection.h"
#include "PseudoClientConnection.h"
#include "serverKeyShare/KeyShare.h"
#include "serverNetworkMessages/AccountFeatureIdRequest.h"
#include "serverNetworkMessages/AdjustAccountFeatureIdRequest.h"
#include "serverNetworkMessages/ClaimRewardsMessage.h"
#include "serverNetworkMessages/GameConnectionServerMessages.h"
#include "serverNetworkMessages/NewClient.h"
#include "serverNetworkMessages/TransferCharacterData.h"
#include "serverNetworkMessages/TransferCharacterDataArchive.h"
#include "SessionApiClient.h"
#include "sharedGame/PlatformFeatureBits.h"
#include "sharedLog/Log.h"
#include "sharedNetwork/NetworkSetupData.h"
#include "sharedNetwork/Service.h"
#include "sharedNetworkMessages/CommandChannelMessages.h"
#include "sharedNetworkMessages/CreateTicketMessage.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
#include "unicodeArchive/UnicodeArchive.h"
//-----------------------------------------------------------------------
GameConnection::GameConnection(const std::string & a, const unsigned short p) :
ServerConnection(a, p, NetworkSetupData()),
gameServerId(0),
sceneName()
{
}
//-----------------------------------------------------------------------
GameConnection::GameConnection(UdpConnectionMT * u, TcpClient * t) :
ServerConnection(u, t),
gameServerId(0),
sceneName()
{
}
//-----------------------------------------------------------------------
GameConnection::~GameConnection()
{
}
//-----------------------------------------------------------------------
void GameConnection::onConnectionClosed()
{
ServerConnection::onConnectionClosed();
static MessageConnectionCallback m("GameConnectionClosed");
emitMessage(m);
}
//-----------------------------------------------------------------------
void GameConnection::onConnectionOpened()
{
ServerConnection::onConnectionOpened();
static MessageConnectionCallback m("GameConnectionOpened");
emitMessage(m);
}
//-----------------------------------------------------------------------
void GameConnection::onReceive(const Archive::ByteStream & message)
{
ServerConnection::onReceive(message);
Archive::ReadIterator ri = message.begin();
GameNetworkMessage m(ri);
ri = message.begin();
if (m.isType("GameClientMessage"))
{
//we're receiving a message to forward to the client.
//it is prefixed with NetworkId and reliable.
const GameClientMessage msg(ri);
const std::vector<NetworkId> & v = msg.getDistributionList();
std::vector<NetworkId>::const_iterator i;
const bool reliable = msg.getReliable();
Service *service = ConnectionServer::getClientServicePrivate();
LogicalPacket const * p = service->createPacket(msg.getByteStream().getBuffer(), static_cast<int>(msg.getByteStream().getSize()));
for(i = v.begin(); i != v.end(); ++i)
{
Client* client = ConnectionServer::getClient((*i));
if (client)
{
client->getClientConnection()->sendSharedPacket(p, reliable);
}
}
service->releasePacket(p);
}
else if (m.isType("CreateTicketMessage"))
{
Archive::ReadIterator cri(m.getByteStream());
CreateTicketMessage const c(cri);
CustomerServiceConnection * const customerServiceConnection =
const_cast<CustomerServiceConnection *>(ConnectionServer::getCustomerServiceConnection());
if (customerServiceConnection)
{
customerServiceConnection->send(c, true);
}
}
else if(m.isType("ControlAssumed"))
{
ControlAssumed ca(ri);
static const std::string loginTrace("TRACE_LOGIN");
LOG(loginTrace, ("Received Control Assumed Message from game server %lu for %s skipLoadScreen=%s", getGameServerId(), ca.getNetworkId().getValueString().c_str(), (ca.getSkipLoadScreen() ? "yes" : "no")));
Client *client = ConnectionServer::getClient(ca.getNetworkId());
if (!client)
{
// perhaps it's a transfer client?
PseudoClientConnection * pseudoClient = PseudoClientConnection::getPseudoClientConnection(ca.getNetworkId());
if(! pseudoClient)
{
DEBUG_REPORT_LOG(true, ("Client %s was already dropped, notifying GameServer.\n", ca.getNetworkId().getValueString().c_str()));
DropClient const drop(ca.getNetworkId());
send(drop, true);
return;
}
else
{
pseudoClient->controlAssumed();
return;
}
}
if (!client->getClientConnection())
{
WARNING_STRICT_FATAL(true, ("We have a client with no client connection\n"));
return;
}
if (ca.getSkipLoadScreen())
client->skipLoadScreen();
if (!client->getSkipLoadScreen())
{
CmdStartScene const startScene(
ca.getNetworkId(),
ca.getSceneName(),
ca.getStartPosition(),
ca.getStartYaw(),
ca.getTemplateName(),
ca.getTimeSeconds(),
static_cast<int32>(::time(NULL)),
ConfigConnectionServer::getDisableWorldSnapshot());
client->getClientConnection()->send(startScene, true);
}
client->handleTransfer(ca.getSceneName(), this);
// record the time when play started for the character
if (client->getClientConnection()->getStartPlayTime() == 0)
{
client->getClientConnection()->setStartPlayTime(::time(NULL));
}
// update the play time info on the game server
// must be called after client->handleTransfer() so the
// client object has been updated to point to the correct
// game server for the client->sendPlayTimeInfoToGameServer()
// call to work properly
client->getClientConnection()->sendPlayTimeInfoToGameServer();
}
else if (m.isType("ReplyBankCTSLoaded"))
{
LOG("CustomerService", ("CharacterTransfer: Game Connection received ReplyBankCTSLoaded message"));
GenericValueTypeMessage<NetworkId> characterId(ri);
IGNORE_RETURN(PseudoClientConnection::tryToDeliverMessageTo(characterId.getValue(), message));
}
else if (m.isType("PackedHousesLoaded"))
{
LOG("CustomerService", ("CharacterTransfer: Game Connection received PackedHousesLoaded message"));
GenericValueTypeMessage<NetworkId> characterId(ri);
IGNORE_RETURN(PseudoClientConnection::tryToDeliverMessageTo(characterId.getValue(), message));
}
else if (m.isType("NewGameServer"))
{
DEBUG_REPORT_LOG(true, ("Received NewGameServerMessage.\n"));
// a game server has connected. Add it to the map
const NewGameServer newGameServer(ri);
setGameServerId(newGameServer.getServerId());
setSceneName(newGameServer.getSceneName());
// set the GameServerId @todo
// add it to the map if a game process
ConnectionServer::addGameConnection(newGameServer.getServerId(), this);
}
else if (m.isType("KickPlayer"))
{
const KickPlayer kickPlayer(ri);
Client *client = ConnectionServer::getClient(kickPlayer.getNetworkId());
if (client)
client->kick(kickPlayer.getReason());
}
else if (m.isType("TransferControlMessage"))
{
// a game server is giving up authority for an object we control
const TransferControlMessage transferControl(ri);
DEBUG_REPORT_LOG(true, ("Received TransferControlMessage for %s.\n", transferControl.getNetworkId().getValueString().c_str()));
//question, do we need to check scene here?
Client* client = ConnectionServer::getClient(transferControl.getNetworkId());
if(client)
{
if (transferControl.getSkipLoadScreen())
client->skipLoadScreen();
if (client->getClientConnection())
{
ClientConnection* cconn = client->getClientConnection();
GameConnection* newConnection = ConnectionServer::getGameConnection(transferControl.getGameServerId());
if(cconn && newConnection)
{
//We have a client, and a game connection, so send the newClient message off to the game server in question.
//It will respond with a control assumed message.
NewClient const newClient(transferControl.getNetworkId(), cconn->getAccountName(), cconn->getRemoteAddress(), cconn->getIsSecure(), transferControl.getSkipLoadScreen(), cconn->getSUID(), &transferControl.getObservedObjects(), cconn->getGameFeatures(), cconn->getSubscriptionFeatures(), cconn->getEntitlementTotalTime(), cconn->getEntitlementEntitledTime(), cconn->getEntitlementTotalTimeSinceLastLogin(), cconn->getEntitlementEntitledTimeSinceLastLogin(), cconn->getBuddyPoints(), cconn->getConsumedRewardEvents(), cconn->getClaimedRewardItems(), cconn->isUsingAdminLogin(), cconn->getCanSkipTutorial());
newConnection->send(newClient, true);
}
else
{
WARNING_STRICT_FATAL(true, ("A TransferControl message was received to transfer client %s to GameServer %lu, but that game server is no longer available. The client will be dropped.", transferControl.getNetworkId().getValueString().c_str(), transferControl.getGameServerId()));
DropClient const drop(transferControl.getNetworkId());
send(drop, true);
}
}
}
else
{
DEBUG_WARNING(true, ("Received a TransferControllMessage but the client is no longer available. This might be a lost race between the connection server notifiying a game server that the client has disconnected, and the game server notifying the connection server that the client is transferring."));
DropClient const drop(transferControl.getNetworkId());
send(drop, true);
}
}
else if(m.isType("ReplyTransferData") || m.isType("ApplyTransferDataSuccess") || m.isType("ApplyTransferDataFail"))
{
GenericValueTypeMessage<TransferCharacterData> reply(ri);
IGNORE_RETURN(PseudoClientConnection::tryToDeliverMessageTo(reply.getValue().getCharacterId(), message));
}
else if (m.isType("ChatEnterRoomValidationResponse"))
{
GenericValueTypeMessage<std::pair<std::pair<NetworkId, unsigned int>, unsigned int> > const reply(ri);
Client* client = ConnectionServer::getClient(reply.getValue().first.first);
if (client && client->getClientConnection())
{
client->getClientConnection()->handleChatEnterRoomValidationResponse(reply.getValue().second, reply.getValue().first.second);
}
}
else if (m.isType("ChatQueryRoomValidationResponse"))
{
GenericValueTypeMessage<std::pair<std::pair<NetworkId, bool>, unsigned int> > const reply(ri);
Client* client = ConnectionServer::getClient(reply.getValue().first.first);
if (client && client->getClientConnection())
{
client->getClientConnection()->handleChatQueryRoomValidationResponse(reply.getValue().second, reply.getValue().first.second);
}
}
else if (m.isType("AccountFeatureIdRequest"))
{
AccountFeatureIdRequest * const msg = new AccountFeatureIdRequest(ri);
SessionApiClient * const sessionApiClient = ConnectionServer::getSessionApiClient();
if (sessionApiClient)
{
// SessionApiClient will own (and delete) msg
sessionApiClient->getFeatures(msg->getTargetStationId(), msg->getGameCode(), msg);
}
else
{
// a cluster running without session authentication stores
// account feature id information on the LoginServer, so
// pass request to the LoginServer (via CentralServer)
CentralConnection * const cc = ConnectionServer::getCentralConnection();
if (cc)
cc->send(*msg, true);
delete msg;
}
}
else if (m.isType("AdjustAccountFeatureIdRequest"))
{
AdjustAccountFeatureIdRequest * const msg = new AdjustAccountFeatureIdRequest(ri);
SessionApiClient * const sessionApiClient = ConnectionServer::getSessionApiClient();
if (sessionApiClient)
{
// SessionApiClient will own (and delete) msg
sessionApiClient->getFeatures(msg->getTargetStationId(), msg->getGameCode(), msg);
}
else
{
// a cluster running without session authentication stores
// account feature id information on the LoginServer, so
// pass request to the LoginServer (via CentralServer)
CentralConnection * const cc = ConnectionServer::getCentralConnection();
if (cc)
cc->send(*msg, true);
delete msg;
}
}
else if (m.isType("ClaimRewardsMessage"))
{
ClaimRewardsMessage * const msg = new ClaimRewardsMessage(ri);
SessionApiClient * const sessionApiClient = ConnectionServer::getSessionApiClient();
if ((msg->getAccountFeatureId() > 0) && sessionApiClient)
{
// SessionApiClient will own (and delete) msg
sessionApiClient->getFeatures(msg->getStationId(), PlatformGameCode::SWG, msg);
}
else
{
// a cluster running without session authentication stores
// account feature id information on the LoginServer, so
// pass request to the LoginServer (via CentralServer)
CentralConnection * const cc = ConnectionServer::getCentralConnection();
if (cc)
cc->send(*msg, true);
delete msg;
}
}
}
//-----------------------------------------------------------------------
@@ -0,0 +1,76 @@
// GameConnection.h
// copyright 2000 Verant Interactive
// Author: Justin Randall
#ifndef _GameConnection_H
#define _GameConnection_H
//-----------------------------------------------------------------------
#include "serverUtility/ServerConnection.h"
class GameCommandChannel;
//-----------------------------------------------------------------------
class GameConnection : public ServerConnection
{
public:
GameConnection(const std::string & remoteAddress, const unsigned short port);
GameConnection(UdpConnectionMT *, TcpClient *);
virtual ~GameConnection();
uint32 getGameServerId() const;
const std::string & getSceneName() const;
void setGameServerId(uint32 id);
void setSceneName(const std::string & name);
void onConnectionClosed ();
void onConnectionOpened ();
void onReceive (const Archive::ByteStream & message);
private:
GameConnection();
GameConnection(const GameConnection&);
GameConnection& operator=(const GameConnection&);
uint32 gameServerId; ///< The DB assigned Id of the connecting gameserver.
std::string sceneName;
};
//-----------------------------------------------------------------------
inline uint32 GameConnection::getGameServerId() const
{
return gameServerId;
}
//-----------------------------------------------------------------------
inline const std::string & GameConnection::getSceneName() const
{
return sceneName;
}
//-----------------------------------------------------------------------
inline void GameConnection::setGameServerId(uint32 id)
{
gameServerId = id;
}
//-----------------------------------------------------------------------
inline void GameConnection::setSceneName(const std::string & name)
{
sceneName = name;
}
//-----------------------------------------------------------------------
#endif // _GameConnection_H
@@ -0,0 +1,502 @@
// PseudoClientConnection.cpp
// copyright 2001 Verant Interactive
//-----------------------------------------------------------------------
#include "FirstConnectionServer.h"
#include "PseudoClientConnection.h"
#include "CentralConnection.h"
#include "ConnectionServer.h"
#include "UnicodeUtils.h"
#include "serverNetworkMessages/CentralConnectionServerMessages.h"
#include "serverNetworkMessages/GameConnectionServerMessages.h"
#include "serverNetworkMessages/GameServerForLoginMessage.h"
#include "serverNetworkMessages/NewClient.h"
#include "serverNetworkMessages/RequestGameServerForLoginMessage.h"
#include "serverNetworkMessages/TransferCharacterDataArchive.h"
#include "sharedLog/Log.h"
#include "sharedMath/Vector.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
#include "sharedUtility/StartingLocationData.h"
#include "sharedUtility/StartingLocationManager.h"
//-----------------------------------------------------------------------
namespace PseudoClientConnectionNamespace
{
std::map<unsigned int, PseudoClientConnection *> s_pseudoClientConnectionMap;
std::map<NetworkId, PseudoClientConnection *> s_pseudoClientConnectionMapByCharacterId;
}
using namespace PseudoClientConnectionNamespace;
//-----------------------------------------------------------------------
/*
Constructed by way of CentralServerConnection to create a psueudo-client.
The CentralServer sends TransferCharacterData when it receives a
TransferLoginRequest from the TransferServer
*/
PseudoClientConnection::PseudoClientConnection(const TransferCharacterData & transferDataFromCentralServer, unsigned int stationId) :
m_transferCharacterData(transferDataFromCentralServer),
m_gameConnection(0),
m_trackStationId(stationId)
{
REPORT_LOG(true, ("ConnectionServer: creating a PseudoClientConnection from transferCharacterData: %s\n", transferDataFromCentralServer.toString().c_str()));
// tell CentralServer about this PseudoClientConnection
GenericValueTypeMessage<std::pair<unsigned int, int8> > info("NewPseudoClientConnection", std::make_pair(m_trackStationId, static_cast<int8>(m_transferCharacterData.getTransferRequestSource())));
CentralConnection * centralServerConnection = ConnectionServer::getCentralConnection();
if(centralServerConnection)
{
centralServerConnection->send(info, true);
}
s_pseudoClientConnectionMap[m_trackStationId] = this;
s_pseudoClientConnectionMapByCharacterId[m_transferCharacterData.getCharacterId()] = this;
}
//-----------------------------------------------------------------------
PseudoClientConnection::~PseudoClientConnection()
{
// tell CentralServer that this PseudoClientConnection is no longer relevant
GenericValueTypeMessage<unsigned int> info("DestroyPseudoClientConnection", m_trackStationId);
CentralConnection * centralServerConnection = ConnectionServer::getCentralConnection();
if(centralServerConnection)
{
centralServerConnection->send(info, true);
}
std::map<unsigned int, PseudoClientConnection *>::iterator f = s_pseudoClientConnectionMap.find(m_trackStationId);
if(f != s_pseudoClientConnectionMap.end())
{
s_pseudoClientConnectionMap.erase(f);
}
std::map<NetworkId, PseudoClientConnection *>::iterator cf = s_pseudoClientConnectionMapByCharacterId.find(m_transferCharacterData.getCharacterId());
if(cf !=s_pseudoClientConnectionMapByCharacterId.end())
{
s_pseudoClientConnectionMapByCharacterId.erase(cf);
}
cf = s_pseudoClientConnectionMapByCharacterId.find(m_transferCharacterData.getDestinationCharacterId());
if(cf !=s_pseudoClientConnectionMapByCharacterId.end())
{
s_pseudoClientConnectionMapByCharacterId.erase(cf);
}
m_gameConnection = 0;
}
//-----------------------------------------------------------------------
const TransferCharacterData & PseudoClientConnection::getTransferCharacterData() const
{
return m_transferCharacterData;
}
//-----------------------------------------------------------------------
void PseudoClientConnection::controlAssumed()
{
if(m_transferCharacterData.getCSToolId() > 0)
{
LOG("CustomerService", ("CharacterTransfer: Received ControlAssumedMessage from GameServer for CS Tool login character request (or from \"remote object loginCharacter\" console command). The request has been completed and the character is now logged in."));
// disconnect them, we logged them in for the CS Tool.
DropClient dropMsg(m_transferCharacterData.getCharacterId());
if(m_gameConnection)
{
dropMsg.setImmediate(true);
m_gameConnection->send(dropMsg, true);
}
delete this;
return;
}
LOG("CustomerService", ("CharacterTransfer: Received ControlAssumedMessage from GameServer, ready to request bank to be loaded (if source character) or to apply transfer data (if target character)!"));
if(m_gameConnection)
{
if(m_transferCharacterData.getScriptDictionaryData().size())
{
LOG("CustomerService", ("CharacterTransfer: controlAssumed, already have transfer data, sending ApplyTransferData"));
// already have the transfer data, this character is headed to the destination galaxy
GenericValueTypeMessage<TransferCharacterData> applyTransferData("ApplyTransferData", m_transferCharacterData);
m_gameConnection->send(applyTransferData, true);
}
else
{
LOG("CustomerService", ("CharacterTransfer: controlAssumed, sending RequestLoadCTSBank message"));
GenericValueTypeMessage<NetworkId> requestTransferData("RequestLoadCTSBank", m_transferCharacterData.getCharacterId());
m_gameConnection->send(requestTransferData, true);
}
}
}
//-----------------------------------------------------------------------
void PseudoClientConnection::onBankLoaded()
{
LOG("CustomerService", ("CharacterTransfer: Received BankLoaded from GameServer, ready to request transfer data!"));
if(m_gameConnection)
{
if(!m_transferCharacterData.getScriptDictionaryData().size())
{
GenericValueTypeMessage<NetworkId> requestTransferData("RequestLoadPackedHouses", m_transferCharacterData.getCharacterId());
m_gameConnection->send(requestTransferData, true);
}
else
LOG("CustomerService", ("CharacterTransfer: OnBankLoaded, RequestTransferData already has data"));
}
}
//-----------------------------------------------------------------------
void PseudoClientConnection::onPackedHousesLoaded()
{
LOG("CustomerService", ("CharacterTransfer: Received PackedHousesLoadedMessage from GameServer, ready to request transfer data!"));
if(m_gameConnection)
{
if(!m_transferCharacterData.getScriptDictionaryData().size())
{
GenericValueTypeMessage<TransferCharacterData> requestTransferData("RequestTransferData", m_transferCharacterData);
m_gameConnection->send(requestTransferData, true);
}
else
LOG("CustomerService", ("CharacterTransfer: onPackedHousesLoaded, RequestTransferData already has data"));
}
}
//-----------------------------------------------------------------------
PseudoClientConnection * PseudoClientConnection::getPseudoClientConnection(const NetworkId & characterId)
{
PseudoClientConnection * result = 0;
std::map<NetworkId, PseudoClientConnection *>::iterator f = s_pseudoClientConnectionMapByCharacterId.find(characterId);
if(f != s_pseudoClientConnectionMapByCharacterId.end())
{
result = f->second;
}
return result;
}
//-----------------------------------------------------------------------
PseudoClientConnection * PseudoClientConnection::getPseudoClientConnection (unsigned int stationId)
{
PseudoClientConnection * result = 0;
std::map<unsigned int, PseudoClientConnection *>::iterator f = s_pseudoClientConnectionMap.find(stationId);
if(f != s_pseudoClientConnectionMap.end())
{
result = f->second;
}
return result;
}
//-----------------------------------------------------------------------
/**
Find a game server to connect the pseudo client using the source
station id indicated by m_transferCharacterData.m_sourceStationId
*/
void PseudoClientConnection::requestGameServerForLogin() const
{
NetworkId characterId = m_transferCharacterData.getCharacterId();
unsigned int stationId = m_trackStationId;
NetworkId containerId = m_transferCharacterData.getContainerId();
if(m_transferCharacterData.getScriptDictionaryData().size())
{
characterId = m_transferCharacterData.getDestinationCharacterId();
containerId = NetworkId::cms_invalid;
}
RequestGameServerForLoginMessage requestmsg(stationId, characterId, containerId, m_transferCharacterData.getScene(), m_transferCharacterData.getStartingCoordinates(), (m_transferCharacterData.getScriptDictionaryData().empty() && (m_transferCharacterData.getCSToolId() == 0)));
if(ConnectionServer::getCentralConnection())
{
ConnectionServer::getCentralConnection()->send(requestmsg, true);
LOG("CustomerService", ("CharacterTransfer: ***ConnectionServer: sending RequestGameServerForLoginMessage(%d, %s, %s, %s)\n", m_transferCharacterData.getSourceStationId(), m_transferCharacterData.getCharacterId().getValueString().c_str(), m_transferCharacterData.getContainerId().getValueString().c_str(), m_transferCharacterData.getScene().c_str()));
}
}
//-----------------------------------------------------------------------
void PseudoClientConnection::receiveMessage(const Archive::ByteStream & message)
{
Archive::ReadIterator ri = message.begin();
const GameNetworkMessage msg(ri);
ri = message.begin();
if(msg.isType("GameServerForLoginMessage"))
{
const GameServerForLoginMessage gameServerForLogin(ri);
LOG("CustomerService", ("CharacterTransfer: *** ConnectionServer: Received GameServerForLoginMessage for %d, server=%d\n", gameServerForLogin.getStationId(), gameServerForLogin.getServer()));
m_gameConnection = ConnectionServer::getGameConnection(gameServerForLogin.getServer());
if(m_gameConnection)
{
NetworkId characterId = m_transferCharacterData.getCharacterId();
unsigned int stationId = m_trackStationId;
if(m_transferCharacterData.getScriptDictionaryData().size())
{
LOG("CustomerService", ("CharacterTransfer: Setting up login for destination server"));
characterId = m_transferCharacterData.getDestinationCharacterId();
}
std::vector<std::pair<NetworkId, std::string> > static const emptyStringVector;
NewClient m(characterId, "TransferServer", NetworkHandler::getHostName(), true, false, stationId, NULL, 0, 0, 0, 0, 0, 0, 0, emptyStringVector, emptyStringVector, m_transferCharacterData.getCSToolId() != 0, true);
m_gameConnection->send(m, true);
LOG("CustomerService", ("CharacterTransfer: Sent NewClient(%s, \"TransferServer\", \"%s\", true, false, %d, NULL, 0, 0)\n", characterId.getValueString().c_str(), NetworkHandler::getHostName().c_str(), stationId));
}
}
else if(msg.isType("TransferLoginCharacterToSourceServer"))
{
// this is a message that will create a new pseudoclient connection
LOG("CustomerService", ("CharacterTransfer: requestGameServerForLogin()"));
GenericValueTypeMessage<TransferCharacterData> loginRequest(ri);
const NetworkId & requestCharacterId = loginRequest.getValue().getCharacterId();
if(requestCharacterId == NetworkId::cms_invalid || requestCharacterId != m_transferCharacterData.getCharacterId())
{
LOG("CustomerService", ("CharacterTransfer: *** ERROR *** Received a request to login to source server for %s, but a transfer for %s is already in progress. Sending failure.", loginRequest.getValue().toString().c_str(), m_transferCharacterData.toString().c_str()));
GenericValueTypeMessage<TransferCharacterData> fail("ReplyTransferDataFail", m_transferCharacterData);
ConnectionServer::sendToCentralProcess(fail);
}
else
{
requestGameServerForLogin();
}
}
else if(msg.isType("TransferLoginCharacterToDestinationServer"))
{
GenericValueTypeMessage<TransferCharacterData> loginRequest(ri);
const NetworkId & requestCharacterId = loginRequest.getValue().getCharacterId();
if(requestCharacterId == NetworkId::cms_invalid || requestCharacterId != m_transferCharacterData.getCharacterId())
{
LOG("CustomerService", ("CharacterTransfer: *** ERROR *** Received a request to login to destination server for %s, but a transfer for %s is already in progress. Sending failure.", loginRequest.getValue().toString().c_str(), m_transferCharacterData.toString().c_str()));
GenericValueTypeMessage<TransferCharacterData> fail("ReplyTransferDataFail", m_transferCharacterData);
ConnectionServer::sendToCentralProcess(fail);
}
else
{
// find a valid starting location
std::vector<StartingLocationData> startingLocations;
StartingLocationData bestLocation;
startingLocations = StartingLocationManager::getLocations();
if(! startingLocations.empty())
{
bestLocation = *(startingLocations.begin());
}
m_transferCharacterData.setScene(bestLocation.planet);
m_transferCharacterData.setStartingCoordinates(Vector(bestLocation.x, bestLocation.y, bestLocation.z));
// start character creation process
ConnectionCreateCharacter connectionCreate(
m_transferCharacterData.getDestinationStationId(),
Unicode::narrowToWide(m_transferCharacterData.getDestinationCharacterName()),
m_transferCharacterData.getObjectTemplateName(),
m_transferCharacterData.getScaleFactor(),
bestLocation.name,
m_transferCharacterData.getCustomizationData(),
m_transferCharacterData.getHairTemplateName(),
m_transferCharacterData.getHairAppearanceData(),
m_transferCharacterData.getProfession(),
false,
m_transferCharacterData.getBiography(),
false,
m_transferCharacterData.getSkillTemplate(),
m_transferCharacterData.getWorkingSkill(),
false,
true,
0xFFFFFFFF); // assume all feature bits set, so that character creation will not be blocked by account features
LOG("CustomerService", ("CharacterTransfer: Sending ConnectionCreateCharacter to CentralServer : %s", m_transferCharacterData.toString().c_str()));
ConnectionServer::sendToCentralProcess(connectionCreate);
}
}
else if(msg.isType("CtsSrcCharWrongPlanet"))
{
LOG("CustomerService", ("CharacterTransfer: *** ERROR *** Source character is not one of the 10 original ground planets. Sending failure for %s.", m_transferCharacterData.toString().c_str()));
GenericValueTypeMessage<TransferCharacterData> fail("ReplyTransferDataFail", m_transferCharacterData);
ConnectionServer::sendToCentralProcess(fail);
}
else if(msg.isType("ReplyTransferData"))
{
// the game server has responded with valid transfer information.
// upload the data to the transfer server (by way of the CentralServer)
// and disconnect the client since there's nothing more needed to be
// done here
GenericValueTypeMessage<TransferCharacterData> reply(ri);
m_transferCharacterData = reply.getValue();
LOG("CustomerService", ("CharacterTransfer: Received ReplyTransferData %s", m_transferCharacterData.toString().c_str()));
CentralConnection * centralServerConnection = ConnectionServer::getCentralConnection();
if(centralServerConnection)
{
const GenericValueTypeMessage<TransferCharacterData> transferReply("TransferReceiveDataFromGameServer", m_transferCharacterData);
centralServerConnection->send(transferReply, true);
}
DropClient dropMsg(m_transferCharacterData.getCharacterId());
if(m_gameConnection)
{
m_gameConnection->send(dropMsg, true);
}
delete this;
}
else if(msg.isType("ConnectionCreateCharacterSuccess"))
{
const ConnectionCreateCharacterSuccess success(ri);
// woohoo! character has been created on the server!
// Log the character back in, run the transfer scripts to
// apply data in the script dictionary associated with the character
LOG("CustomerService", ("CharacterTransfer: Received ConnectionCreateCharacterSuccess for %s", m_transferCharacterData.toString().c_str()));
m_transferCharacterData.setDestinationCharacterId(success.getNetworkId());
requestGameServerForLogin();
s_pseudoClientConnectionMapByCharacterId[m_transferCharacterData.getDestinationCharacterId()] = this;
}
else if(msg.isType("ConnectionCreateCharacterFailed"))
{
const ConnectionCreateCharacterFailed failed(ri);
LOG("CustomerService", ("CharacterTransfer: Received ConnectionCreateCharacterFailed [%s, %s] for %s", failed.getErrorMessage().getDebugString().c_str(), failed.getOptionalDetailedErrorMessage().c_str(), m_transferCharacterData.toString().c_str()));
s_pseudoClientConnectionMapByCharacterId[m_transferCharacterData.getDestinationCharacterId()] = this;
GenericValueTypeMessage<TransferCharacterData> reply("TransferCreateCharacterFailed", m_transferCharacterData);
CentralConnection * centralServerConnection = ConnectionServer::getCentralConnection();
if(centralServerConnection)
{
centralServerConnection->send(reply, true);
}
}
else if(msg.isType("ApplyTransferDataSuccess"))
{
GenericValueTypeMessage<TransferCharacterData> success(ri);
LOG("CustomerService", ("CharacterTransfer: Received ApplyTransferDataSuccess from GameServer! %s", success.getValue().toString().c_str()));
CentralConnection * centralServerConnection = ConnectionServer::getCentralConnection();
if(centralServerConnection)
{
centralServerConnection->send(success, true);
}
}
else if(msg.isType("ApplyTransferDataFail"))
{
GenericValueTypeMessage<TransferCharacterData> fail(ri);
LOG("CustomerService", ("CharacterTransfer: Received ApplyTransferDataFail from GameServer! %s", fail.getValue().toString().c_str()));
CentralConnection * centralServerConnection = ConnectionServer::getCentralConnection();
if(centralServerConnection)
{
centralServerConnection->send(fail, true);
}
}
else if(msg.isType("ReplyBankCTSLoaded"))
{
LOG("CustomerService", ("CharacterTransfer: Received ReplyBankCTSLoaded from GameServer!"));
onBankLoaded();
}
else if(msg.isType("PackedHousesLoaded"))
{
onPackedHousesLoaded();
}
}
//-----------------------------------------------------------------------
void PseudoClientConnection::destroyAllPseudoClientConnectionInstances()
{
std::map<unsigned int, PseudoClientConnection *> instances = s_pseudoClientConnectionMap;
std::map<unsigned int, PseudoClientConnection *>::iterator i = instances.begin();
for(; i != instances.end(); ++i)
{
PseudoClientConnection * c = i->second;
delete c;
}
}
//-----------------------------------------------------------------------
bool PseudoClientConnection::tryToDeliverMessageTo(const NetworkId & characterId, const Archive::ByteStream & msg)
{
bool result = false;
std::map<NetworkId, PseudoClientConnection *>::iterator f = s_pseudoClientConnectionMapByCharacterId.find(characterId);
if(f != s_pseudoClientConnectionMapByCharacterId.end())
{
result = true;
f->second->receiveMessage(msg);
}
return result;
}
//-----------------------------------------------------------------------
bool PseudoClientConnection::tryToDeliverMessageTo(unsigned int stationId, const Archive::ByteStream & message)
{
Archive::ReadIterator ri = message.begin();
const GameNetworkMessage msg(ri);
ri = message.begin();
bool result = false;
if(msg.isType("TransferLoginCharacterToSourceServer") || msg.isType("TransferLoginCharacterToDestinationServer"))
{
// this is a message that will create a new pseudoclient connection
const GenericValueTypeMessage<TransferCharacterData> login(ri);
unsigned int trackStationId = login.getValue().getSourceStationId();
if(msg.isType("TransferLoginCharacterToSourceServer"))
{
LOG("CustomerService", ("CharacterTransfer: Creating a PseudoClientConnection on source server for %s", login.getValue().toString().c_str()));
}
else
{
LOG("CustomerService", ("CharacterTransfer: Creating a PseudoClientConnection on destination server for %s", login.getValue().toString().c_str()));
trackStationId = login.getValue().getDestinationStationId();
}
// remove old sessions if they exist
PseudoClientConnection * oldConnection = PseudoClientConnection::getPseudoClientConnection(trackStationId);
delete oldConnection;
// setup new pseudoclient connection
PseudoClientConnection * newConnection = new PseudoClientConnection(login.getValue(), trackStationId);
newConnection->receiveMessage(message);
}//lint !e429 // leak // suppressed because this is tracked in the map and it is the responsibility of the sender to send a destroy message or the receiving connection to be destroyed, in this case CentralConnection
else
{
std::map<unsigned int, PseudoClientConnection *>::const_iterator const f = s_pseudoClientConnectionMap.find(stationId);
if(f != s_pseudoClientConnectionMap.end())
{
result = true;
f->second->receiveMessage(message);
}
else
{
LOG("CustomerService", ("CharacterTransfer: *** FAILED TO DELIVER MESSAGE TO PseudoClientConnection(%d)!! ***", stationId));
}
}
return result;
}
//-----------------------------------------------------------------------
void PseudoClientConnection::gameConnectionClosed(const GameConnection * gameConnection)
{
std::map<unsigned int, PseudoClientConnection *>::iterator i;
for(i = s_pseudoClientConnectionMap.begin(); i != s_pseudoClientConnectionMap.end(); ++i)
{
if(i->second->m_gameConnection == gameConnection)
{
i->second->gameConnectionClosed();
}
}
}
//-----------------------------------------------------------------------
void PseudoClientConnection::gameConnectionClosed()
{
CentralConnection * centralConnection = ConnectionServer::getCentralConnection();
if(centralConnection)
{
GenericValueTypeMessage<TransferCharacterData> gameServerDown("TransferFailGameServerClosedConnectionWithConnectionServer", m_transferCharacterData);
centralConnection->send(gameServerDown, true);
}
}
// ======================================================================
@@ -0,0 +1,57 @@
// PseudoClientConnection.h
// copyright 2001 Verant Interactive
#ifndef _PseudoClientConnection_H
#define _PseudoClientConnection_H
#include "serverNetworkMessages/TransferCharacterData.h"
namespace Archive
{
class ByteStream;
}
class GameConnection;
//-----------------------------------------------------------------------
class PseudoClientConnection
{
public:
PseudoClientConnection(const TransferCharacterData & transferDataFromCentralServer, unsigned int stationId);
virtual ~PseudoClientConnection();
void controlAssumed ();
void onBankLoaded ();
void onPackedHousesLoaded ();
static PseudoClientConnection * getPseudoClientConnection (const NetworkId & characterId);
static PseudoClientConnection * getPseudoClientConnection (unsigned int stationId);
static void install ();
void requestGameServerForLogin () const;
static bool tryToDeliverMessageTo (unsigned int stationId, const Archive::ByteStream & msg);
static bool tryToDeliverMessageTo (const NetworkId & characterId, const Archive::ByteStream & msg);
static void gameConnectionClosed (const GameConnection *);
const TransferCharacterData & getTransferCharacterData () const;
protected:
friend class CentralConnection;
static void destroyAllPseudoClientConnectionInstances ();
private:
PseudoClientConnection();
PseudoClientConnection(const PseudoClientConnection&);
PseudoClientConnection& operator=(const PseudoClientConnection&);
void receiveMessage (const Archive::ByteStream &);
void gameConnectionClosed ();
TransferCharacterData m_transferCharacterData;
GameConnection * m_gameConnection;
unsigned int m_trackStationId;
};
//-----------------------------------------------------------------------
#endif // _PseudoClientConnection_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,146 @@
// SessionApiClient.h
// copyright 2002 Sony Online Entertainment
#ifndef _SessionApiClient_H
#define _SessionApiClient_H
#include <map>
#pragma warning(push)
#pragma warning(disable: 4100) // Client.h has inlined functions with unreferenced formal parameters
#include "Session/LoginAPI/Client.h"
#pragma warning(pop)
#include "sharedFoundation/Clock.h"
#include "sharedFoundation/Timer.h"
class ClientConnection;
class SessionApiClient : public LoginAPI::Client
{
public:
SessionApiClient(const char ** serverList, int serverCount);
~SessionApiClient();
virtual void OnSessionLogin(const apiTrackingNumber trackingNumber,
const apiResult result,
const apiAccount & account,
const apiSubscription & subscription,
const apiSession & session,
const LoginAPI::UsageLimit & usageLimit,
const LoginAPI::Entitlement & entitlement,
void * userData);
virtual void OnSessionLoginInternal(const apiTrackingNumber trackingNumber,
const apiResult result,
const apiAccount & account,
const apiSubscription & subscription,
const apiSession & session,
const LoginAPI::UsageLimit & usageLimit,
const LoginAPI::Entitlement & entitlement,
void * userData);
virtual void OnSessionValidate(const apiTrackingNumber trackingNumber,
const apiResult result,
const apiAccount & account,
const apiSubscription & subscription,
const apiSession & session,
const LoginAPI::UsageLimit & usageLimit,
const LoginAPI::Entitlement & entitlement,
void * userData);
virtual void OnSessionConsume(const apiTrackingNumber trackingNumber,
const apiResult result,
const apiAccount & account,
const apiSubscription & subscription,
const apiSession & session,
const LoginAPI::UsageLimit & usageLimit,
const LoginAPI::Entitlement & entitlement,
void * userData);
virtual void OnSessionStartPlay(const apiTrackingNumber trackingNumber,
const apiResult result,
void * userData);
virtual void OnSessionStopPlay(const apiTrackingNumber trackingNumber,
const apiResult result,
void * userData);
virtual void OnSessionKick(const unsigned trackingNumber,
const apiResult result,
void * userData);
virtual void OnGetSessions(const apiTrackingNumber trackingNumber,
const apiResult result,
const unsigned count,
const apiSession session[],
const apiSubscription subscription[],
const LoginAPI::UsageLimit usageLimit[],
const unsigned timeCreated[],
const unsigned timeTouched[],
void * userData);
virtual void OnGetFeatures(const apiTrackingNumber trackingNumber,
const apiResult result,
const unsigned featureCount,
const LoginAPI::Feature featureArray[],
const void * userData = 0);
virtual void OnGrantFeature(const apiTrackingNumber trackingNumber,
const apiResult result,
void * userData);
virtual void OnGrantFeatureByStationID(const apiTrackingNumber trackingNumber,
const apiResult result,
void * userData);
virtual void OnModifyFeature(const apiTrackingNumber trackingNumber,
const apiResult result,
void * userData);
virtual void OnModifyFeature_v2(const apiTrackingNumber trackingNumber,
const apiResult result,
const LoginAPI::Feature & currentFeature,
void * userData);
virtual void OnRevokeFeature(const apiTrackingNumber trackingNumber,
const apiResult result,
void * userData);
virtual void OnEnumerateFeatures(const apiTrackingNumber trackingNumber,
const apiResult result,
const unsigned featureCount,
const LoginAPI::FeatureDescription featureArray[],
const void * userData = 0);
virtual void OnConnectionOpened(const char * address, unsigned port);
virtual void OnConnectionClosed(const char * address, unsigned port);
virtual void OnConnectionFailed(const char * address, unsigned port);
virtual void OnException();
virtual void NotifySessionKickRequest(const apiAccount & account,
const apiSession & session,
const apiKickReason reason);
virtual void NotifySessionKick(const char ** sessionList,
const unsigned sessionCount);
void getFeatures(apiAccountId accountId, apiGamecode gameCode, GameNetworkMessage* gnm);
void dropClient(const ClientConnection* client, bool forceSessionLogout);
void validateClient(ClientConnection* client, const std::string & key);
void startPlay(const ClientConnection& client);
void stopPlay(const ClientConnection& client);
void update();
static void FlushSessionQueue();
private:
static std::map<apiTrackingNumber, ClientConnection *> m_validationMap;
SessionApiClient();
Timer m_sessionTimer;
};
#endif
@@ -0,0 +1 @@
#include "FirstConnectionServer.h"
@@ -0,0 +1,58 @@
#include "FirstConnectionServer.h"
#include "ConfigConnectionServer.h"
#include "ConnectionServer.h"
#include "sharedCompression/SetupSharedCompression.h"
#include "sharedDebug/SetupSharedDebug.h"
#include "sharedFile/SetupSharedFile.h"
#include "sharedFoundation/PerThreadData.h"
#include "sharedFoundation/SetupSharedFoundation.h"
#include "sharedNetworkMessages/SetupSharedNetworkMessages.h"
#include "sharedRandom/SetupSharedRandom.h"
#include "sharedThread/SetupSharedThread.h"
#include <time.h>
int main(int argc, char ** argv)
{
// command line hack
std::string cmdLine;
for(int i = 1; i < argc; ++i)
{
cmdLine += argv[i];
if(i + 1 < argc)
{
cmdLine += " ";
}
}
SetupSharedThread::install();
SetupSharedDebug::install(1024);
//-- setup foundation
SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game);
// setupFoundationData.hInstance = hInstance;
setupFoundationData.commandLine = cmdLine.c_str();
setupFoundationData.createWindow = false;
setupFoundationData.clockUsesSleep = true;
SetupSharedFoundation::install (setupFoundationData);
SetupSharedFile::install(false);
SetupSharedCompression::install();
SetupSharedNetworkMessages::install();
SetupSharedRandom::install(int(time(NULL)));
//-- setup game server
ConfigConnectionServer::install ();
ConnectionServer::install();
//-- run game
SetupSharedFoundation::callbackWithExceptionHandling(ConnectionServer::run);
ConnectionServer::remove();
ConfigConnectionServer::remove();
SetupSharedFoundation::remove();
PerThreadData::threadRemove();
return 0;
}